Merge "Introduce abstract base class for services"

This commit is contained in:
Jenkins 2015-06-07 04:00:16 +00:00 committed by Gerrit Code Review
commit e5c23386a8
3 changed files with 49 additions and 2 deletions

View File

@ -15,14 +15,27 @@
# License for the specific language governing permissions and limitations
# under the License.
"""Generic Node base class for all workers that run on hosts."""
"""Generic Node base class for all workers that run on hosts.
This module provides two launchers for running services:
* ServiceLauncher - used for running one or more service in
a parent process.
* ProcessLauncher - forks a given number of workers in which
service(s) are then started.
Please be informed that it is highly recommended to use no more than
one instance of ServiceLauncher and ProcessLauncher classes per process.
"""
import abc
import errno
import io
import logging
import os
import random
import signal
import six
import sys
import time
@ -87,6 +100,30 @@ def _set_signals_handler(handler):
signal.signal(signal.SIGHUP, handler)
@six.add_metaclass(abc.ABCMeta)
class ServiceBase(object):
"""Base class for all services."""
@abc.abstractmethod
def start(self):
"""Start service."""
@abc.abstractmethod
def stop(self):
"""Stop service."""
@abc.abstractmethod
def wait(self):
"""Wait for service to complete."""
@abc.abstractmethod
def reset(self):
"""Reset service.
Called in case service running in daemon mode receives SIGHUP.
"""
class Launcher(object):
"""Launch one or more services and wait for them to complete."""
@ -421,7 +458,7 @@ class ProcessLauncher(object):
self._wait_child()
class Service(object):
class Service(ServiceBase):
"""Service object for binaries running on hosts."""
def __init__(self, threads=1000):
@ -497,6 +534,9 @@ class Services(object):
def launch(service, workers=1):
if not isinstance(service, ServiceBase):
raise TypeError("Service %(service)s must be subclass of %(base)s!"
% {'service': service, 'base': ServiceBase})
if workers is None or workers == 1:
launcher = ServiceLauncher()
launcher.launch_service(service)

View File

@ -373,6 +373,12 @@ class LauncherTest(test_base.BaseTestCase):
service.launch(svc, workers=3)
mock_launch.assert_called_with(svc, workers=3)
def test_launch_wrong_service_base_class(self):
# check that services that do not subclass service.ServiceBase
# can not be launched.
svc = mock.Mock()
self.assertRaises(TypeError, service.launch, svc)
class ProcessLauncherTest(test_base.BaseTestCase):

View File

@ -5,4 +5,5 @@
Babel>=1.3
eventlet>=0.17.3
oslo.config>=1.11.0 # Apache-2.0
six>=1.9.0
oslo.i18n>=1.5.0 # Apache-2.0