From 47dac924fa82ea6a867dae4344b1a1723ff6da7f Mon Sep 17 00:00:00 2001 From: Hubert Deng Date: Fri, 30 May 2025 17:17:53 -0700 Subject: [PATCH 1/3] supervisorctl supports reloading config and restarting processes --- devservices/utils/supervisor.py | 12 +++++++++--- tests/utils/test_supervisor.py | 9 +++++++-- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/devservices/utils/supervisor.py b/devservices/utils/supervisor.py index 5e2a0317..e1a67610 100644 --- a/devservices/utils/supervisor.py +++ b/devservices/utils/supervisor.py @@ -184,10 +184,16 @@ def start_supervisor_daemon(self) -> None: try: client = self._get_rpc_client() client.supervisor.getState() - # Supervisor is already running, restart it since config may have changed - client.supervisor.restart() + # Supervisor is already running, run supervisord update to update config and restart running processes + # Note that xmlrpc.client.reloadConfig does not work well here, so we use supervisorctl update instead + subprocess.run( + ["supervisorctl", "-c", self.config_file_path, "update"], + check=True, + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, + ) - # Wait for supervisor to be ready after restart + # Wait for supervisor to be ready after config reload self._wait_for_supervisor_ready() return except xmlrpc.client.Fault as e: diff --git a/tests/utils/test_supervisor.py b/tests/utils/test_supervisor.py index e0e3e055..4179d7b0 100644 --- a/tests/utils/test_supervisor.py +++ b/tests/utils/test_supervisor.py @@ -195,8 +195,13 @@ def test_start_supervisor_daemon_already_running( } supervisor_manager.start_supervisor_daemon() assert mock_rpc_client.return_value.supervisor.getState.call_count == 2 - assert mock_rpc_client.return_value.supervisor.restart.call_count == 1 - assert mock_subprocess_run.call_count == 0 + mock_subprocess_run.assert_called_with( + ["supervisorctl", "-c", supervisor_manager.config_file_path, "update"], + check=True, + stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL, + ) + assert mock_subprocess_run.call_count == 1 @mock.patch("devservices.utils.supervisor.subprocess.run") From 1f8fb91d59fa6c4b63a1eb8cc3fa55c143fb9459 Mon Sep 17 00:00:00 2001 From: Hubert Deng Date: Fri, 30 May 2025 17:31:33 -0700 Subject: [PATCH 2/3] add another note --- devservices/utils/supervisor.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/devservices/utils/supervisor.py b/devservices/utils/supervisor.py index e1a67610..b0f7c2b8 100644 --- a/devservices/utils/supervisor.py +++ b/devservices/utils/supervisor.py @@ -185,7 +185,9 @@ def start_supervisor_daemon(self) -> None: client = self._get_rpc_client() client.supervisor.getState() # Supervisor is already running, run supervisord update to update config and restart running processes - # Note that xmlrpc.client.reloadConfig does not work well here, so we use supervisorctl update instead + # Notes: + # - xmlrpc.client.reloadConfig does not work well here as config changes don't appear to be reloaded, so we use `supervisorctl update` instead + # - processes that are edited/added will not be automatically started subprocess.run( ["supervisorctl", "-c", self.config_file_path, "update"], check=True, From 3c995d0c2ec0437f356f626d4d0a2859eaea788e Mon Sep 17 00:00:00 2001 From: Hubert Deng Date: Tue, 3 Jun 2025 16:05:42 -0700 Subject: [PATCH 3/3] catch another exception and handle gracefully --- devservices/utils/supervisor.py | 2 +- tests/utils/test_supervisor.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/devservices/utils/supervisor.py b/devservices/utils/supervisor.py index b0f7c2b8..a831c61c 100644 --- a/devservices/utils/supervisor.py +++ b/devservices/utils/supervisor.py @@ -198,7 +198,7 @@ def start_supervisor_daemon(self) -> None: # Wait for supervisor to be ready after config reload self._wait_for_supervisor_ready() return - except xmlrpc.client.Fault as e: + except (xmlrpc.client.Fault, subprocess.CalledProcessError) as e: capture_exception(e, level="info") pass except (SupervisorConnectionError, socket.error, ConnectionRefusedError): diff --git a/tests/utils/test_supervisor.py b/tests/utils/test_supervisor.py index 4179d7b0..8ac8502c 100644 --- a/tests/utils/test_supervisor.py +++ b/tests/utils/test_supervisor.py @@ -201,7 +201,7 @@ def test_start_supervisor_daemon_already_running( stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, ) - assert mock_subprocess_run.call_count == 1 + mock_subprocess_run.assert_called_once() @mock.patch("devservices.utils.supervisor.subprocess.run")