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
This commit is contained in:
Isaku Yamahata 2017-05-02 14:59:31 -04:00
parent db4ea430df
commit 22b3e36010
3 changed files with 22 additions and 1 deletions

View File

@ -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

View File

@ -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():

View File

@ -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)