From 14d523efd5d8aa7aced24287768c5bd662d25d1c Mon Sep 17 00:00:00 2001 From: vrde Date: Wed, 21 Feb 2018 17:54:50 +0100 Subject: [PATCH] Problem: processes don't have an intelligible name (#2078) Solution: when a process starts, update the "process title" as well. --- bigchaindb/log/setup.py | 3 ++- bigchaindb/tendermint/commands.py | 21 ++++++++++++--------- bigchaindb/utils.py | 12 ++++++++++++ setup.py | 1 + tests/test_utils.py | 17 +++++++++++++++++ 5 files changed, 44 insertions(+), 10 deletions(-) diff --git a/bigchaindb/log/setup.py b/bigchaindb/log/setup.py index d5df4a8f..9de9f726 100644 --- a/bigchaindb/log/setup.py +++ b/bigchaindb/log/setup.py @@ -7,7 +7,6 @@ import pickle from socketserver import StreamRequestHandler, ThreadingTCPServer import struct import sys -from multiprocessing import Process from .configs import ( DEFAULT_SOCKET_LOGGING_HOST, @@ -15,6 +14,7 @@ from .configs import ( PUBLISHER_LOGGING_CONFIG, SUBSCRIBER_LOGGING_CONFIG, ) +from bigchaindb.utils import Process from bigchaindb.common.exceptions import ConfigurationError @@ -46,6 +46,7 @@ def setup_sub_logger(*, user_log_config=None): server = LogRecordSocketServer(**kwargs) with server: server_proc = Process( + name='logging_server', target=server.serve_forever, kwargs={'log_config': user_log_config}, ) diff --git a/bigchaindb/tendermint/commands.py b/bigchaindb/tendermint/commands.py index 8ee39edb..6148d438 100644 --- a/bigchaindb/tendermint/commands.py +++ b/bigchaindb/tendermint/commands.py @@ -1,14 +1,16 @@ import logging import subprocess -import multiprocessing as mp from os import getenv +import setproctitle + import bigchaindb from bigchaindb.tendermint.lib import BigchainDB from bigchaindb.tendermint.core import App from bigchaindb.web import server, websocket_server from bigchaindb.tendermint import event_stream from bigchaindb.events import Exchange, EventTypes +from bigchaindb.utils import Process logger = logging.getLogger(__name__) @@ -28,7 +30,6 @@ BANNER = """ def start(): - # Exchange object for event stream api exchange = Exchange() @@ -37,7 +38,7 @@ def start(): settings=bigchaindb.config['server'], log_config=bigchaindb.config['log'], bigchaindb_factory=BigchainDB) - p_webapi = mp.Process(name='webapi', target=app_server.run) + p_webapi = Process(name='webapi', target=app_server.run) p_webapi.start() # start message @@ -51,15 +52,15 @@ def start(): ]) # start websocket server - p_websocket_server = mp.Process(name='ws', - target=websocket_server.start, - args=(exchange.get_subscriber_queue(EventTypes.BLOCK_VALID),)) + p_websocket_server = Process(name='ws', + target=websocket_server.start, + args=(exchange.get_subscriber_queue(EventTypes.BLOCK_VALID),)) p_websocket_server.start() # connect to tendermint event stream - p_websocket_client = mp.Process(name='ws_to_tendermint', - target=event_stream.start, - args=(exchange.get_publisher_queue(),)) + p_websocket_client = Process(name='ws_to_tendermint', + target=event_stream.start, + args=(exchange.get_publisher_queue(),)) p_websocket_client.start() # We need to import this after spawning the web server @@ -67,6 +68,8 @@ def start(): # for gevent. from abci import ABCIServer + setproctitle.setproctitle('bigchaindb') + app = ABCIServer(app=App()) app.run() diff --git a/bigchaindb/utils.py b/bigchaindb/utils.py index cf0bf625..52361296 100644 --- a/bigchaindb/utils.py +++ b/bigchaindb/utils.py @@ -3,6 +3,8 @@ import threading import queue import multiprocessing as mp +import setproctitle + class ProcessGroup(object): @@ -26,6 +28,16 @@ class ProcessGroup(object): self.processes.append(proc) +class Process(mp.Process): + """Wrapper around multiprocessing.Process that uses + setproctitle to set the name of the process when running + the target task.""" + + def run(self): + setproctitle.setproctitle(self.name) + super().run() + + # Inspired by: # - http://stackoverflow.com/a/24741694/597097 def pool(builder, size, timeout=None): diff --git a/setup.py b/setup.py index 0b143dd2..ad9b26b2 100644 --- a/setup.py +++ b/setup.py @@ -84,6 +84,7 @@ install_requires = [ 'aiohttp~=2.3', 'python-rapidjson-schema==0.1.1', 'abci~=0.3.0', + 'setproctitle~=1.1.0', ] setup( diff --git a/tests/test_utils.py b/tests/test_utils.py index 9620d0f9..d01ba633 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -3,6 +3,8 @@ from unittest.mock import patch, call import pytest +pytestmark = pytest.mark.tendermint + @pytest.fixture def mock_queue(monkeypatch): @@ -157,3 +159,18 @@ def test_lazy_execution(): lz.name.upper() result = lz.run(cat) assert result == 'SHMUI' + + +def test_process_set_title(): + from uuid import uuid4 + from multiprocessing import Queue + from setproctitle import getproctitle + from bigchaindb.utils import Process + + queue = Queue() + uuid = str(uuid4()) + + process = Process(target=lambda: queue.put(getproctitle()), + name=uuid) + process.start() + assert queue.get() == uuid