From 0498e2ad76d9a198e10a0418995f76e76486a258 Mon Sep 17 00:00:00 2001 From: Balazs Gibizer Date: Fri, 31 Oct 2025 10:43:20 +0100 Subject: [PATCH] Do not fork compute workers in native threading mode Force running the Compute Service within the main Process with native threading to keep the baseline behavior. In eventlet mode with workers=1 or workers=None it is oslo.service's default behavior[1]. But with native threading we need to explicitly pass no_fork=True to oslo to get this behavior instead of forking a single worker [2]. Forking a single worker for compute would also be problematic as compute initializes the conductor RPC client before such fork and the rabbitmq oslo.messaging driver does not support forking with a connected client [3]. Patch bumps the minimum oslo.service version to 4.4.1 to pick up the fix https://review.opendev.org/c/openstack/oslo.service/+/966458 nova now depends on. [1] https://github.com/openstack/oslo.service/blob/37b90521ea01baa0c8e6412453c42972a28e3b12/oslo_service/backend/_eventlet/service.py#L749C1-L753 [2] https://github.com/openstack/oslo.service/blob/37b90521ea01baa0c8e6412453c42972a28e3b12/oslo_service/backend/_threading/service.py#L296-L300 [3] https://docs.openstack.org/oslo.messaging/latest/reference/transport.html#forking-processes-and-oslo-messaging-transport-objects Change-Id: If6daffc25d737f53b1a478d42fd85a0446b09e6d Signed-off-by: Balazs Gibizer --- nova/cmd/compute.py | 3 ++- nova/service.py | 4 ++-- nova/tests/unit/test_service.py | 17 +++++++++++++++-- requirements.txt | 2 +- 4 files changed, 20 insertions(+), 6 deletions(-) diff --git a/nova/cmd/compute.py b/nova/cmd/compute.py index 5f4f83694f..9007d4b79b 100644 --- a/nova/cmd/compute.py +++ b/nova/cmd/compute.py @@ -61,5 +61,6 @@ def main(): objects.Service.enable_min_version_cache() server = service.Service.create(binary='nova-compute', topic=compute_rpcapi.RPC_TOPIC) - service.serve(server) + # Compute service should never fork worker processes + service.serve(server, workers=1, no_fork=True) service.wait() diff --git a/nova/service.py b/nova/service.py index 50c353cef8..b307fb18d9 100644 --- a/nova/service.py +++ b/nova/service.py @@ -322,13 +322,13 @@ class Service(service.Service): _launcher = None -def serve(server, workers=None): +def serve(server, workers=None, no_fork=False): global _launcher if _launcher: raise RuntimeError(_('serve() can only be called once')) _launcher = service.launch(CONF, server, workers=workers, - restart_method='mutate') + restart_method='mutate', no_fork=no_fork) def wait(): diff --git a/nova/tests/unit/test_service.py b/nova/tests/unit/test_service.py index 6a6a708010..0a7aed2458 100644 --- a/nova/tests/unit/test_service.py +++ b/nova/tests/unit/test_service.py @@ -324,7 +324,8 @@ class TestLauncher(test.NoDBTestCase): mock_launch.assert_called_once_with(mock.ANY, mock.sentinel.service, workers=None, - restart_method='mutate') + restart_method='mutate', + no_fork=False) @mock.patch.object(_service, 'launch') def test_launch_app_with_workers(self, mock_launch): @@ -333,7 +334,19 @@ class TestLauncher(test.NoDBTestCase): mock_launch.assert_called_once_with(mock.ANY, mock.sentinel.service, workers=mock.sentinel.workers, - restart_method='mutate') + restart_method='mutate', + no_fork=False) + + @mock.patch.object(_service, 'launch') + def test_launch_app_with_workers_no_fork(self, mock_launch): + service._launcher = None + service.serve( + mock.sentinel.service, workers=mock.sentinel.workers, no_fork=True) + mock_launch.assert_called_once_with(mock.ANY, + mock.sentinel.service, + workers=mock.sentinel.workers, + restart_method='mutate', + no_fork=True) @mock.patch.object(_service, 'launch') def test_launch_app_more_than_once_raises(self, mock_launch): diff --git a/requirements.txt b/requirements.txt index d5ea240636..fe3f6ca99a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -43,7 +43,7 @@ oslo.messaging>=14.1.0 # Apache-2.0 oslo.policy>=4.5.0 # Apache-2.0 oslo.privsep>=2.6.2 # Apache-2.0 oslo.i18n>=5.1.0 # Apache-2.0 -oslo.service[threading]>=4.2.0 # Apache-2.0 +oslo.service[threading]>=4.4.1 # Apache-2.0 rfc3986>=1.2.0 # Apache-2.0 oslo.middleware>=3.31.0 # Apache-2.0 psutil>=3.2.2 # BSD