Make _spawn_service more flexible
I need to tweak the launcher used, as it stands this isn't possible. Also I find it ugly muddling the service arguments with the _spawn_service arguments. Pass in constructors for each of these. This allows us to pass whatever arguments, set up extra things, whatever we want. It's important that at least the launcher is created in the child process so we can't pass in objects. This patch also fixes Launcher.launch_service to accept a workers argument (which must be 1 or a ValueError will be raised). This makes ServiceLauncher.launch_service compatible with ProcessLauncher.launch_service, avoiding awkward "if isinstance" or "if workers == 1" logic when you're not sure of the type of the launcher. Change-Id: Ia309828c0c7e7599d4b82994dd36165106dc6513
This commit is contained in:
parent
c8499ee28a
commit
1393c85f32
|
@ -194,14 +194,19 @@ class Launcher(object):
|
|||
self.backdoor_port = (
|
||||
eventlet_backdoor.initialize_if_enabled(self.conf))
|
||||
|
||||
def launch_service(self, service):
|
||||
def launch_service(self, service, workers=1):
|
||||
"""Load and start the given service.
|
||||
|
||||
:param service: The service you would like to start, must be an
|
||||
instance of :class:`oslo_service.service.ServiceBase`
|
||||
:param workers: This param makes this method compatible with
|
||||
ProcessLauncher.launch_service. It must be None, 1 or
|
||||
omitted.
|
||||
:returns: None
|
||||
|
||||
"""
|
||||
if workers is not None and workers != 1:
|
||||
raise ValueError(_("Launcher asked to start multiple workers"))
|
||||
_check_service_base(service)
|
||||
service.backdoor_port = self.backdoor_port
|
||||
self.services.add(service)
|
||||
|
@ -700,9 +705,8 @@ def launch(conf, service, workers=1):
|
|||
|
||||
if workers is None or workers == 1:
|
||||
launcher = ServiceLauncher(conf)
|
||||
launcher.launch_service(service)
|
||||
else:
|
||||
launcher = ProcessLauncher(conf)
|
||||
launcher.launch_service(service, workers=workers)
|
||||
launcher.launch_service(service, workers=workers)
|
||||
|
||||
return launcher
|
||||
|
|
|
@ -84,8 +84,8 @@ class ServiceTestBase(base.ServiceBaseTestCase):
|
|||
|
||||
def _spawn_service(self,
|
||||
workers=1,
|
||||
service_to_launch=ServiceWithTimer,
|
||||
*args, **kwargs):
|
||||
service_maker=None,
|
||||
launcher_maker=None):
|
||||
self.workers = workers
|
||||
pid = os.fork()
|
||||
if pid == 0:
|
||||
|
@ -99,8 +99,12 @@ class ServiceTestBase(base.ServiceBaseTestCase):
|
|||
# os._exit() which doesn't have this problem.
|
||||
status = 0
|
||||
try:
|
||||
serv = service_to_launch(*args, **kwargs)
|
||||
launcher = service.launch(self.conf, serv, workers=workers)
|
||||
serv = service_maker() if service_maker else ServiceWithTimer()
|
||||
if launcher_maker:
|
||||
launcher = launcher_maker()
|
||||
launcher.launch_service(serv, workers=workers)
|
||||
else:
|
||||
launcher = service.launch(self.conf, serv, workers=workers)
|
||||
status = launcher.wait()
|
||||
except SystemExit as exc:
|
||||
status = exc.code
|
||||
|
@ -212,7 +216,8 @@ class ServiceLauncherTest(ServiceTestBase):
|
|||
self.assertEqual(os.WEXITSTATUS(status), 0)
|
||||
|
||||
def test_crashed_service(self):
|
||||
self.pid = self._spawn_service(service_to_launch=ServiceCrashOnStart)
|
||||
service_maker = lambda: ServiceCrashOnStart()
|
||||
self.pid = self._spawn_service(service_maker=service_maker)
|
||||
status = self._reap_test()
|
||||
self.assertTrue(os.WIFEXITED(status))
|
||||
self.assertEqual(os.WEXITSTATUS(status), 1)
|
||||
|
@ -251,8 +256,8 @@ class ServiceRestartTest(ServiceTestBase):
|
|||
|
||||
def _spawn(self):
|
||||
ready_event = multiprocessing.Event()
|
||||
self.pid = self._spawn_service(workers=1,
|
||||
ready_event=ready_event)
|
||||
service_maker = lambda: ServiceWithTimer(ready_event=ready_event)
|
||||
self.pid = self._spawn_service(service_maker=service_maker)
|
||||
return ready_event
|
||||
|
||||
def test_service_restart(self):
|
||||
|
@ -315,7 +320,7 @@ class LauncherTest(base.ServiceBaseTestCase):
|
|||
def _test_launch_single(self, workers, mock_launch):
|
||||
svc = service.Service()
|
||||
service.launch(self.conf, svc, workers=workers)
|
||||
mock_launch.assert_called_with(svc)
|
||||
mock_launch.assert_called_with(svc, workers=workers)
|
||||
|
||||
def test_launch_none(self):
|
||||
self._test_launch_single(None)
|
||||
|
|
Loading…
Reference in New Issue