From 534333ca9cc3bc7dec91c3f4f9928e2c80149016 Mon Sep 17 00:00:00 2001 From: Boden R Date: Fri, 3 Feb 2017 09:31:28 -0700 Subject: [PATCH] rehome NeutronWorker class This patch rehomes neutron.worker.NeutronWorker as neutron_lib.worker.BaseWorker. While this class is only used by networking-ovn out of the neutron tree today [1], the ML2 MechanismDriver (publically extendable) supports workers directly [2] (ex: get_workers()). As a result the worker is part of our publicly extendable API and thus seems a likely candidate for neutron-lib. UTs and a release note are also included. [1] http://codesearch.openstack.org/?q=NeutronWorker [2] https://github.com/openstack/neutron/blob/master/neutron/plugins/ml2/driver_api.py#L981 Change-Id: Id1be78e483da7474e9007c7180e92fbf46863a52 --- neutron_lib/tests/unit/test_worker.py | 53 ++++++++++++++ neutron_lib/worker.py | 72 +++++++++++++++++++ .../notes/rehome-worker-b7e9c7f477bdb926.yaml | 4 ++ 3 files changed, 129 insertions(+) create mode 100644 neutron_lib/tests/unit/test_worker.py create mode 100644 neutron_lib/worker.py create mode 100644 releasenotes/notes/rehome-worker-b7e9c7f477bdb926.yaml diff --git a/neutron_lib/tests/unit/test_worker.py b/neutron_lib/tests/unit/test_worker.py new file mode 100644 index 0000000..94af5fb --- /dev/null +++ b/neutron_lib/tests/unit/test_worker.py @@ -0,0 +1,53 @@ +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import mock + +from neutron_lib.callbacks import events +from neutron_lib.callbacks import resources +from neutron_lib import fixture +from neutron_lib import worker + +from neutron_lib.tests import _base as base + + +class _BaseWorker(worker.BaseWorker): + + def reset(self): + pass + + def stop(self): + pass + + def wait(self): + pass + + +class TestBaseWorker(base.BaseTestCase): + + def setUp(self): + super(TestBaseWorker, self).setUp() + self._reg = mock.Mock() + self.useFixture(fixture.CallbackRegistryFixture( + callback_manager=self._reg)) + + def test_worker_process_count(self): + self.assertEqual(9, _BaseWorker( + worker_process_count=9).worker_process_count) + + def test_start_callback_event(self): + base_worker = _BaseWorker() + base_worker.start() + self._reg.notify.assert_called_once_with( + resources.PROCESS, events.AFTER_INIT, base_worker.start) diff --git a/neutron_lib/worker.py b/neutron_lib/worker.py new file mode 100644 index 0000000..2f97cf7 --- /dev/null +++ b/neutron_lib/worker.py @@ -0,0 +1,72 @@ +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from oslo_service import service + +from neutron_lib.callbacks import events +from neutron_lib.callbacks import registry +from neutron_lib.callbacks import resources + + +class BaseWorker(service.ServiceBase): + """Partial implementation of the ServiceBase ABC. + + Subclasses will still need to add the other abstract methods defined in + service.ServiceBase. See oslo_service for more details. + + If a plugin needs to handle synchronization with the Neutron database and + do this only once instead of in every API worker, for instance, it would + define a BaseWorker class and the plugin would have get_workers return + an array of BaseWorker instances. For example: + class MyPlugin(...): + def get_workers(self): + return [MyPluginWorker()] + + class MyPluginWorker(BaseWorker): + def start(self): + super(MyPluginWorker, self).start() + do_sync() + """ + + # default class value for case when super().__init__ is not called + _default_process_count = 1 + + def __init__(self, worker_process_count=_default_process_count): + """Initialize a worker instance. + + :param worker_process_count: Defines how many processes to spawn for + worker: + 0 - spawn 1 new worker thread, + 1..N - spawn N new worker processes + """ + self._worker_process_count = worker_process_count + + @property + def worker_process_count(self): + """The worker's process count. + + :returns: The number of processes to spawn for this worker. + """ + return self._worker_process_count + + def start(self): + """Start the worker. + + If worker_process_count is greater than 0, a callback notification + is sent. Subclasses should call this method before doing their + own start() work. + :returns: None + """ + if self.worker_process_count > 0: + registry.notify(resources.PROCESS, events.AFTER_INIT, self.start) diff --git a/releasenotes/notes/rehome-worker-b7e9c7f477bdb926.yaml b/releasenotes/notes/rehome-worker-b7e9c7f477bdb926.yaml new file mode 100644 index 0000000..6b1ecc1 --- /dev/null +++ b/releasenotes/notes/rehome-worker-b7e9c7f477bdb926.yaml @@ -0,0 +1,4 @@ +--- +features: + - The ``NeutronWorker`` class from the ``neutron.worker`` module is now + available as ``BaseWorker`` in ``neutron_lib.worker``.