From 22b3e36010a53736c854aa67915283058bdfcba1 Mon Sep 17 00:00:00 2001 From: Isaku Yamahata Date: Tue, 2 May 2017 14:59:31 -0400 Subject: [PATCH] service: add callback AFTER_SPAWN Add callback (PRCESS, AFTER_SPAWN) to do housekeeping task. ML2 driver(in fact, networking-odl) wants to run house keeping task which needs to run only in api server. The following is very netwokring-odl specific as FYI: The task is to run a timer which is extended when rest requests are handled. The timer is fired to kick journal thread only when rest request is idle in order to check if there is journal entries that was created by other neutron servers that crash before processing them. Such timer isn't needed for each workers. Only single timer among api worker and rpc workers is enough. cf https://review.openstack.org/#/c/461620/ The current approach is to run timer unconditionally for all processes and stop it if it's worker process. With this patch, the timer can be simply run for main process(api worker). Change-Id: I9c07bc528c3a2fade0c835797889fc169f9bd1a6 --- neutron/callbacks/events.py | 1 + neutron/service.py | 6 +++++- neutron/tests/unit/test_service.py | 16 ++++++++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/neutron/callbacks/events.py b/neutron/callbacks/events.py index 4db83d85008..a253079914c 100644 --- a/neutron/callbacks/events.py +++ b/neutron/callbacks/events.py @@ -34,6 +34,7 @@ AFTER_REQUEST = 'after_request' # String literals representing events associated to process operations BEFORE_INIT = 'before_init' BEFORE_SPAWN = 'before_spawn' # sent per process +AFTER_SPAWN = 'after_spawn' # sent per process AFTER_INIT = 'after_init' # sent per worker # String literals representing events associated to error conditions diff --git a/neutron/service.py b/neutron/service.py index 4d4625b5ef6..9c71238c786 100644 --- a/neutron/service.py +++ b/neutron/service.py @@ -32,6 +32,7 @@ from oslo_utils import excutils from oslo_utils import importutils from neutron._i18n import _LE, _LI +from neutron.callbacks import events as n_events from neutron.common import config from neutron.common import profiler from neutron.common import rpc as n_rpc @@ -262,7 +263,10 @@ def _start_workers(workers): def start_all_workers(): workers = _get_rpc_workers() + _get_plugins_workers() - return _start_workers(workers) + launcher = _start_workers(workers) + # TODO(yamahata): replace n_events with neutron_lib.callback.events + registry.notify(resources.PROCESS, n_events.AFTER_SPAWN, None) + return launcher def start_rpc_workers(): diff --git a/neutron/tests/unit/test_service.py b/neutron/tests/unit/test_service.py index d05104b3704..31ffab2533e 100644 --- a/neutron/tests/unit/test_service.py +++ b/neutron/tests/unit/test_service.py @@ -15,8 +15,11 @@ import mock +from neutron_lib.callbacks import registry +from neutron_lib.callbacks import resources from oslo_config import cfg +from neutron.callbacks import events as n_events from neutron import service from neutron.tests import base from neutron.tests.unit import test_wsgi @@ -55,3 +58,16 @@ class TestRunWsgiApp(base.BaseTestCase): def test_api_workers_defined(self): self._test_api_workers(42, 42) + + def test_start_all_workers(self): + cfg.CONF.set_override('api_workers', 0) + mock.patch.object(service, '_get_rpc_workers').start() + mock.patch.object(service, '_get_plugins_workers').start() + mock.patch.object(service, '_start_workers').start() + + callback = mock.Mock() + # TODO(yamahata): replace n_events with neutron_lib.callback.events + registry.subscribe(callback, resources.PROCESS, n_events.AFTER_SPAWN) + service.start_all_workers() + callback.assert_called_once_with( + resources.PROCESS, n_events.AFTER_SPAWN, mock.ANY)