From fbf3600e91d785c4a73998d9e3de2cf77c73089a Mon Sep 17 00:00:00 2001 From: Fabio Manganiello Date: Thu, 10 Jan 2019 23:45:13 +0100 Subject: [PATCH] Setting thread and process names properly through prctl --- platypush/__init__.py | 2 ++ platypush/backend/__init__.py | 6 ++++-- platypush/backend/http/__init__.py | 7 +++++-- platypush/backend/http/request/__init__.py | 4 +++- platypush/backend/mqtt.py | 4 +++- platypush/backend/music/snapcast.py | 4 +++- platypush/backend/tcp.py | 4 +++- platypush/event/hook.py | 5 +++-- platypush/plugins/light/hue/__init__.py | 4 +++- platypush/utils/__init__.py | 9 +++++++++ requirements.txt | 3 +++ setup.py | 1 + 12 files changed, 42 insertions(+), 11 deletions(-) diff --git a/platypush/__init__.py b/platypush/__init__.py index 735cf079e..6069be1e8 100644 --- a/platypush/__init__.py +++ b/platypush/__init__.py @@ -24,6 +24,7 @@ from .message.event import Event, StopEvent from .message.event.application import ApplicationStartedEvent, ApplicationStoppedEvent from .message.request import Request from .message.response import Response +from .utils import set_thread_name __author__ = 'Fabio Manganiello ' @@ -138,6 +139,7 @@ class Daemon: def start(self): """ Start the daemon """ + set_thread_name('platypush') print('---- Starting platypush v.{}'.format(__version__)) redis_conf = Config.get('backend.redis') diff --git a/platypush/backend/__init__.py b/platypush/backend/__init__.py index 34da89194..011150618 100644 --- a/platypush/backend/__init__.py +++ b/platypush/backend/__init__.py @@ -18,7 +18,7 @@ from platypush.message import Message from platypush.message.event import Event, StopEvent from platypush.message.request import Request from platypush.message.response import Response -from platypush.utils import get_redis_queue_name_by_message +from platypush.utils import get_redis_queue_name_by_message, set_thread_name class Backend(Thread): @@ -44,7 +44,8 @@ class Backend(Thread): :type kwargs: dict """ - super().__init__(name='PlatypushBackend_' + self.__class__.__name__) + self._thread_name = 'pp-' + self.__class__.__name__ + super().__init__(name=self._thread_name) # If no bus is specified, create an internal queue where # the received messages will be pushed @@ -216,6 +217,7 @@ class Backend(Thread): def run(self): """ Starts the backend thread. To be implemented in the derived classes """ self.thread_id = threading.get_ident() + set_thread_name(self._thread_name) def on_stop(self): """ Callback invoked when the process stops """ diff --git a/platypush/backend/http/__init__.py b/platypush/backend/http/__init__.py index b9a9df7bc..caef4f003 100644 --- a/platypush/backend/http/__init__.py +++ b/platypush/backend/http/__init__.py @@ -20,7 +20,7 @@ from platypush.message import Message from platypush.message.event import Event, StopEvent from platypush.message.event.web.widget import WidgetUpdateEvent from platypush.message.request import Request -from platypush.utils import get_ssl_server_context +from platypush.utils import get_ssl_server_context, set_thread_name from .. import Backend @@ -232,6 +232,8 @@ class HttpBackend(Backend): def webserver(self): """ Web server main process """ + set_thread_name('pp-web-server') + basedir = os.path.dirname(inspect.getfile(self.__class__)) template_dir = os.path.join(basedir, 'templates') app = Flask(__name__, template_folder=template_dir) @@ -416,6 +418,7 @@ class HttpBackend(Backend): def websocket(self): """ Websocket main server """ import websockets + set_thread_name('pp-websocket-server') async def register_websocket(websocket, path): address = websocket.remote_address[0] if websocket.remote_address \ @@ -456,7 +459,7 @@ class HttpBackend(Backend): webserver = self.webserver() self.server_proc = Process(target=webserver.run, - name='PlatypushWebServer', + name='pp-web-server', kwargs=kwargs) self.server_proc.start() diff --git a/platypush/backend/http/request/__init__.py b/platypush/backend/http/request/__init__.py index 968c94ecf..2872e8b98 100644 --- a/platypush/backend/http/request/__init__.py +++ b/platypush/backend/http/request/__init__.py @@ -11,6 +11,7 @@ from frozendict import frozendict from threading import Thread from platypush.message.event.http import HttpEvent +from platypush.utils import set_thread_name class HttpRequest(object): poll_seconds = 60 @@ -53,6 +54,7 @@ class HttpRequest(object): def execute(self): def _thread_func(): + set_thread_name('pp-http-poll') is_first_call = self.last_request_timestamp == 0 self.last_request_timestamp = time.time() @@ -77,7 +79,7 @@ class HttpRequest(object): self.logger.warning('Encountered an error while retrieving {}: {}'. format(self.args.url, str(e))) - Thread(target=_thread_func, name='PlatypushHttpPoll').start() + Thread(target=_thread_func, name='pp-http-poll').start() def get_new_items(self, response): diff --git a/platypush/backend/mqtt.py b/platypush/backend/mqtt.py index fc0246531..f6bb56660 100644 --- a/platypush/backend/mqtt.py +++ b/platypush/backend/mqtt.py @@ -9,6 +9,7 @@ from platypush.backend import Backend from platypush.context import get_plugin from platypush.message import Message from platypush.message.request import Request +from platypush.utils import set_thread_name class MqttBackend(Backend): @@ -97,6 +98,7 @@ class MqttBackend(Backend): def on_message(client, userdata, msg): def response_thread(msg): + set_thread_name('pp-mqtt-processor') response = self.get_message_response(msg) if not response: return @@ -122,7 +124,7 @@ class MqttBackend(Backend): if isinstance(msg, Request): threading.Thread(target=response_thread, - name='PlatypushMQTTResponseProcessor', + name='pp-mqtt-processor', args=(msg,)).start() super().run() diff --git a/platypush/backend/music/snapcast.py b/platypush/backend/music/snapcast.py index 772fa7903..8c8873a48 100644 --- a/platypush/backend/music/snapcast.py +++ b/platypush/backend/music/snapcast.py @@ -5,6 +5,7 @@ import time from platypush.backend import Backend from platypush.context import get_plugin +from platypush.utils import set_thread_name from platypush.message.event.music.snapcast import ClientVolumeChangeEvent, \ GroupMuteChangeEvent, ClientConnectedEvent, ClientDisconnectedEvent, \ ClientLatencyChangeEvent, ClientNameChangeEvent, GroupStreamChangeEvent, \ @@ -129,6 +130,7 @@ class MusicSnapcastBackend(Backend): def _client(self, host, port): def _thread(): + set_thread_name('pp-snapcast-' + host) status = None try: @@ -199,7 +201,7 @@ class MusicSnapcastBackend(Backend): port = self.ports[i] self._threads[host] = threading.Thread( target=self._client(host, port), - name='PlatypushSnapcastWorker' + name='pp-snapcast' ) self._threads[host].start() diff --git a/platypush/backend/tcp.py b/platypush/backend/tcp.py index 23c48d9c2..c62c6a59f 100644 --- a/platypush/backend/tcp.py +++ b/platypush/backend/tcp.py @@ -5,6 +5,7 @@ import threading from platypush.backend import Backend from platypush.message import Message from platypush.message.request import Request +from platypush.utils import set_thread_name class TcpBackend(Backend): @@ -83,12 +84,13 @@ class TcpBackend(Backend): sock.send(str(response).encode()) def _f_wrapper(): + set_thread_name('pp-tcp-listen') try: _f() finally: sock.close() - threading.Thread(target=_f_wrapper, name='PlatypushTCPListener').start() + threading.Thread(target=_f_wrapper, name='pp-tcp-listen').start() def run(self): super().run() diff --git a/platypush/event/hook.py b/platypush/event/hook.py index 467927ed7..a05cad082 100644 --- a/platypush/event/hook.py +++ b/platypush/event/hook.py @@ -8,7 +8,7 @@ from platypush.config import Config from platypush.message.event import Event, EventMatchResult from platypush.message.request import Request from platypush.procedure import Procedure -from platypush.utils import get_event_class_by_type +from platypush.utils import get_event_class_by_type, set_thread_name logger = logging.getLogger(__name__) @@ -150,6 +150,7 @@ class EventHook(object): runs the hook actions if the condition is met """ def _thread_func(result): + set_thread_name('pp-event-' + self.name) self.actions.execute(event=event, **result.parsed_args) result = self.matches_event(event) @@ -158,7 +159,7 @@ class EventHook(object): if result.is_match: logger.info('Running hook {} triggered by an event'.format(self.name)) threading.Thread(target=_thread_func, - name='PlatypushEventHook_' + self.name, + name='pp-event-' + self.name, args=(result,)).start() diff --git a/platypush/plugins/light/hue/__init__.py b/platypush/plugins/light/hue/__init__.py index 9d8be2d37..35eade163 100644 --- a/platypush/plugins/light/hue/__init__.py +++ b/platypush/plugins/light/hue/__init__.py @@ -11,6 +11,7 @@ from phue import Bridge from platypush.context import get_backend from platypush.plugins import action from platypush.plugins.light import LightPlugin +from platypush.utils import set_thread_name class LightHuePlugin(LightPlugin): @@ -666,6 +667,7 @@ class LightHuePlugin(LightPlugin): def _animate_thread(lights): + set_thread_name('pp-hue-animate') self.logger.info('Starting {} animation'.format( animation, (lights or groups))) @@ -720,7 +722,7 @@ class LightHuePlugin(LightPlugin): self.stop_animation() self.animation_thread = Thread(target=_animate_thread, - name='PlatypushLightHueAnimate', + name='pp-hue-animate', args=(lights,)) self.animation_thread.start() diff --git a/platypush/utils/__init__.py b/platypush/utils/__init__.py index 989f0bd0b..8b29533d6 100644 --- a/platypush/utils/__init__.py +++ b/platypush/utils/__init__.py @@ -163,6 +163,15 @@ def get_ssl_client_context(ssl_cert=None, ssl_key=None, ssl_cafile=None, ssl_cert=ssl_cert, ssl_key=ssl_key, ssl_cafile=ssl_cafile, ssl_capath=ssl_capath) +def set_thread_name(name): + global logger + + try: + import prctl + prctl.set_name(name) + except ImportError: + logger.debug('Unable to set thread name: prctl module is missing') + # vim:sw=4:ts=4:et: diff --git a/requirements.txt b/requirements.txt index 2c72bcc67..f5e106bb3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,6 +8,9 @@ # YAML configuration support pyyaml +# Support for setting thread/process name +prctl + # Apache Kafka backend support kafka-python diff --git a/setup.py b/setup.py index 7b529c649..76ea0323b 100755 --- a/setup.py +++ b/setup.py @@ -63,6 +63,7 @@ setup( 'pyyaml', 'redis', 'requests', + 'prctl', ], extras_require = { 'Support for Apache Kafka backend': ['kafka-python'],