Merge "Optimize pid property in AsyncProcess class"
This commit is contained in:
commit
d20c0edfc6
neutron
@ -78,6 +78,7 @@ class AsyncProcess(object):
|
|||||||
raise ValueError(_('respawn_interval must be >= 0 if provided.'))
|
raise ValueError(_('respawn_interval must be >= 0 if provided.'))
|
||||||
self.respawn_interval = respawn_interval
|
self.respawn_interval = respawn_interval
|
||||||
self._process = None
|
self._process = None
|
||||||
|
self._pid = None
|
||||||
self._is_running = False
|
self._is_running = False
|
||||||
self._kill_event = None
|
self._kill_event = None
|
||||||
self._reset_queues()
|
self._reset_queues()
|
||||||
@ -95,8 +96,8 @@ class AsyncProcess(object):
|
|||||||
|
|
||||||
def is_active(self):
|
def is_active(self):
|
||||||
# If using sudo rootwrap as a root_helper, we have to wait until sudo
|
# If using sudo rootwrap as a root_helper, we have to wait until sudo
|
||||||
# spawns rootwrap and rootwrap spawns the process.
|
# spawns rootwrap and rootwrap spawns the process. self.pid will make
|
||||||
|
# sure to get the correct pid.
|
||||||
return utils.pid_invoked_with_cmdline(
|
return utils.pid_invoked_with_cmdline(
|
||||||
self.pid, self.cmd_without_namespace)
|
self.pid, self.cmd_without_namespace)
|
||||||
|
|
||||||
@ -137,6 +138,7 @@ class AsyncProcess(object):
|
|||||||
def _spawn(self):
|
def _spawn(self):
|
||||||
"""Spawn a process and its watchers."""
|
"""Spawn a process and its watchers."""
|
||||||
self._is_running = True
|
self._is_running = True
|
||||||
|
self._pid = None
|
||||||
self._kill_event = eventlet.event.Event()
|
self._kill_event = eventlet.event.Event()
|
||||||
self._process, cmd = utils.create_process(self._cmd,
|
self._process, cmd = utils.create_process(self._cmd,
|
||||||
run_as_root=self.run_as_root)
|
run_as_root=self.run_as_root)
|
||||||
@ -154,16 +156,19 @@ class AsyncProcess(object):
|
|||||||
@property
|
@property
|
||||||
def pid(self):
|
def pid(self):
|
||||||
if self._process:
|
if self._process:
|
||||||
return utils.get_root_helper_child_pid(
|
if not self._pid:
|
||||||
self._process.pid,
|
self._pid = utils.get_root_helper_child_pid(
|
||||||
self.cmd_without_namespace,
|
self._process.pid,
|
||||||
run_as_root=self.run_as_root)
|
self.cmd_without_namespace,
|
||||||
|
run_as_root=self.run_as_root)
|
||||||
|
return self._pid
|
||||||
|
|
||||||
def _kill(self, kill_signal):
|
def _kill(self, kill_signal):
|
||||||
"""Kill the process and the associated watcher greenthreads."""
|
"""Kill the process and the associated watcher greenthreads."""
|
||||||
pid = self.pid
|
pid = self.pid
|
||||||
if pid:
|
if pid:
|
||||||
self._is_running = False
|
self._is_running = False
|
||||||
|
self._pid = None
|
||||||
self._kill_process(pid, kill_signal)
|
self._kill_process(pid, kill_signal)
|
||||||
|
|
||||||
# Halt the greenthreads if they weren't already.
|
# Halt the greenthreads if they weren't already.
|
||||||
|
@ -56,6 +56,25 @@ class TestAsyncProcess(base.BaseTestCase):
|
|||||||
])
|
])
|
||||||
self.assertEqual(len(proc._watchers), 2)
|
self.assertEqual(len(proc._watchers), 2)
|
||||||
|
|
||||||
|
def test__pid_none(self):
|
||||||
|
pid = 1
|
||||||
|
self.proc._pid = None
|
||||||
|
with mock.patch.object(self.proc, '_process') as _process:
|
||||||
|
with mock.patch.object(utils,
|
||||||
|
'get_root_helper_child_pid') as func:
|
||||||
|
func.return_value = pid
|
||||||
|
self.assertEqual(self.proc.pid, pid)
|
||||||
|
func.assert_called_once_with(_process.pid, ['fake'],
|
||||||
|
run_as_root=False)
|
||||||
|
self.assertEqual(self.proc._pid, pid)
|
||||||
|
|
||||||
|
def test__pid_not_none(self):
|
||||||
|
self.proc._pid = 1
|
||||||
|
with mock.patch.object(self.proc, '_process'),\
|
||||||
|
mock.patch.object(utils, 'get_root_helper_child_pid') as func:
|
||||||
|
self.assertEqual(self.proc.pid, 1)
|
||||||
|
func.assert_not_called()
|
||||||
|
|
||||||
def test__handle_process_error_kills_with_respawn(self):
|
def test__handle_process_error_kills_with_respawn(self):
|
||||||
with mock.patch.object(self.proc, '_kill') as kill:
|
with mock.patch.object(self.proc, '_kill') as kill:
|
||||||
self.proc._handle_process_error()
|
self.proc._handle_process_error()
|
||||||
@ -185,6 +204,7 @@ class TestAsyncProcess(base.BaseTestCase):
|
|||||||
|
|
||||||
self.assertIsNone(self.proc._kill_event)
|
self.assertIsNone(self.proc._kill_event)
|
||||||
self.assertFalse(self.proc._is_running)
|
self.assertFalse(self.proc._is_running)
|
||||||
|
self.assertIsNone(self.proc._pid)
|
||||||
|
|
||||||
mock_kill_event.send.assert_called_once_with()
|
mock_kill_event.send.assert_called_once_with()
|
||||||
if pid:
|
if pid:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user