Fix house_keeping daemon to use Event.wait()
When trying to exit out of the house_keeping daemon the terminal would hang until all threads finished their iteration of time.sleep(). Now the threads instead use the Event object so on keyboard intterupt the threads will exit without waiting. Change-Id: I4cb62977f647209ea87001a949fc42472ad53a70
This commit is contained in:
parent
87bab9bf15
commit
f37e776eb3
|
@ -44,10 +44,10 @@ def spare_amphora_check():
|
|||
LOG.info(_LI("Spare check interval is set to %d sec"), interval)
|
||||
|
||||
spare_amp = house_keeping.SpareAmphora()
|
||||
while spare_amp_thread_event.is_set():
|
||||
while not spare_amp_thread_event.is_set():
|
||||
LOG.debug("Initiating spare amphora check...")
|
||||
spare_amp.spare_check()
|
||||
time.sleep(interval)
|
||||
spare_amp_thread_event.wait(interval)
|
||||
|
||||
|
||||
def db_cleanup():
|
||||
|
@ -61,11 +61,11 @@ def db_cleanup():
|
|||
CONF.house_keeping.load_balancer_expiry_age)
|
||||
|
||||
db_cleanup = house_keeping.DatabaseCleanup()
|
||||
while db_cleanup_thread_event.is_set():
|
||||
while not db_cleanup_thread_event.is_set():
|
||||
LOG.debug("Initiating the cleanup of old resources...")
|
||||
db_cleanup.delete_old_amphorae()
|
||||
db_cleanup.cleanup_load_balancers()
|
||||
time.sleep(interval)
|
||||
db_cleanup_thread_event.wait(interval)
|
||||
|
||||
|
||||
def cert_rotation():
|
||||
|
@ -74,10 +74,10 @@ def cert_rotation():
|
|||
LOG.info(
|
||||
_LI("Expiring certificate check interval is set to %d sec"), interval)
|
||||
cert_rotate = house_keeping.CertRotation()
|
||||
while cert_rotate_thread_event.is_set():
|
||||
while not cert_rotate_thread_event.is_set():
|
||||
LOG.debug("Initiating certification rotation ...")
|
||||
cert_rotate.rotate()
|
||||
time.sleep(interval)
|
||||
cert_rotate_thread_event.wait(interval)
|
||||
|
||||
|
||||
def main():
|
||||
|
@ -91,19 +91,16 @@ def main():
|
|||
# Thread to perform spare amphora check
|
||||
spare_amp_thread = threading.Thread(target=spare_amphora_check)
|
||||
spare_amp_thread.daemon = True
|
||||
spare_amp_thread_event.set()
|
||||
spare_amp_thread.start()
|
||||
|
||||
# Thread to perform db cleanup
|
||||
db_cleanup_thread = threading.Thread(target=db_cleanup)
|
||||
db_cleanup_thread.daemon = True
|
||||
db_cleanup_thread_event.set()
|
||||
db_cleanup_thread.start()
|
||||
|
||||
# Thread to perform certificate rotation
|
||||
cert_rotate_thread = threading.Thread(target=cert_rotation)
|
||||
cert_rotate_thread.daemon = True
|
||||
cert_rotate_thread_event.set()
|
||||
cert_rotate_thread.start()
|
||||
|
||||
# Try-Exception block should be at the end to gracefully exit threads
|
||||
|
@ -112,9 +109,9 @@ def main():
|
|||
time.sleep(1)
|
||||
except KeyboardInterrupt:
|
||||
LOG.info(_LI("Attempting to gracefully terminate House-Keeping"))
|
||||
spare_amp_thread_event.clear()
|
||||
db_cleanup_thread_event.clear()
|
||||
cert_rotate_thread_event.clear()
|
||||
spare_amp_thread_event.set()
|
||||
db_cleanup_thread_event.set()
|
||||
cert_rotate_thread_event.set()
|
||||
spare_amp_thread.join()
|
||||
db_cleanup_thread.join()
|
||||
cert_rotate_thread.join()
|
||||
|
|
|
@ -25,8 +25,7 @@ class TestHouseKeepingCMD(base.TestCase):
|
|||
@mock.patch('octavia.cmd.house_keeping.spare_amp_thread_event')
|
||||
@mock.patch('octavia.controller.housekeeping.'
|
||||
'house_keeping.SpareAmphora')
|
||||
@mock.patch('time.sleep')
|
||||
def test_spare_amphora_check(self, sleep_mock, mock_SpareAmphora,
|
||||
def test_spare_amphora_check(self, mock_SpareAmphora,
|
||||
spare_amp_thread_event_mock):
|
||||
spare_amp_mock = mock.MagicMock()
|
||||
spare_check_mock = mock.MagicMock()
|
||||
|
@ -35,7 +34,7 @@ class TestHouseKeepingCMD(base.TestCase):
|
|||
|
||||
# mock spare_amp_thread_event.is_set() in the while loop
|
||||
spare_amp_thread_event_mock.is_set = mock.MagicMock()
|
||||
spare_amp_thread_event_mock.is_set.side_effect = [True,
|
||||
spare_amp_thread_event_mock.is_set.side_effect = [False,
|
||||
Exception('break')]
|
||||
|
||||
self.assertRaisesRegexp(Exception, 'break',
|
||||
|
@ -47,8 +46,7 @@ class TestHouseKeepingCMD(base.TestCase):
|
|||
@mock.patch('octavia.cmd.house_keeping.db_cleanup_thread_event')
|
||||
@mock.patch('octavia.controller.housekeeping.'
|
||||
'house_keeping.DatabaseCleanup')
|
||||
@mock.patch('time.sleep')
|
||||
def test_db_cleanup(self, sleep_mock, mock_DatabaseCleanup,
|
||||
def test_db_cleanup(self, mock_DatabaseCleanup,
|
||||
db_cleanup_event_mock):
|
||||
db_cleanup = mock.MagicMock()
|
||||
delete_old_amphorae = mock.MagicMock()
|
||||
|
@ -57,7 +55,7 @@ class TestHouseKeepingCMD(base.TestCase):
|
|||
|
||||
# mock db_cleanup_thread_event.is_set() in the while loop
|
||||
db_cleanup_event_mock.is_set = mock.MagicMock()
|
||||
db_cleanup_event_mock.is_set.side_effect = [True, Exception('break')]
|
||||
db_cleanup_event_mock.is_set.side_effect = [False, Exception('break')]
|
||||
|
||||
self.assertRaisesRegexp(Exception, 'break', house_keeping.db_cleanup)
|
||||
|
||||
|
@ -67,9 +65,7 @@ class TestHouseKeepingCMD(base.TestCase):
|
|||
@mock.patch('octavia.cmd.house_keeping.cert_rotate_thread_event')
|
||||
@mock.patch('octavia.controller.housekeeping.'
|
||||
'house_keeping.CertRotation')
|
||||
@mock.patch('time.sleep')
|
||||
def test_hk_cert_rotation_with_exception(self, sleep_mock,
|
||||
mock_CertRotation,
|
||||
def test_hk_cert_rotation_with_exception(self, mock_CertRotation,
|
||||
cert_rotate_event_mock):
|
||||
# mock cert_rotate object
|
||||
cert_rotate_mock = mock.MagicMock()
|
||||
|
@ -82,7 +78,7 @@ class TestHouseKeepingCMD(base.TestCase):
|
|||
|
||||
# mock cert_rotate_thread_event.is_set() in the while loop
|
||||
cert_rotate_event_mock.is_set = mock.MagicMock()
|
||||
cert_rotate_event_mock.is_set.side_effect = [True, Exception('break')]
|
||||
cert_rotate_event_mock.is_set.side_effect = [False, Exception('break')]
|
||||
|
||||
self.assertRaisesRegexp(Exception, 'break',
|
||||
house_keeping.cert_rotation)
|
||||
|
@ -93,9 +89,7 @@ class TestHouseKeepingCMD(base.TestCase):
|
|||
@mock.patch('octavia.cmd.house_keeping.cert_rotate_thread_event')
|
||||
@mock.patch('octavia.controller.housekeeping.'
|
||||
'house_keeping.CertRotation')
|
||||
@mock.patch('time.sleep')
|
||||
def test_hk_cert_rotation_without_exception(self, sleep_mock,
|
||||
mock_CertRotation,
|
||||
def test_hk_cert_rotation_without_exception(self, mock_CertRotation,
|
||||
cert_rotate_event_mock):
|
||||
# mock cert_rotate object
|
||||
cert_rotate_mock = mock.MagicMock()
|
||||
|
@ -108,7 +102,7 @@ class TestHouseKeepingCMD(base.TestCase):
|
|||
|
||||
# mock cert_rotate_thread_event.is_set() in the while loop
|
||||
cert_rotate_event_mock.is_set = mock.MagicMock()
|
||||
cert_rotate_event_mock.is_set.side_effect = [True, None]
|
||||
cert_rotate_event_mock.is_set.side_effect = [False, True]
|
||||
|
||||
self.assertIsNone(house_keeping.cert_rotation())
|
||||
|
||||
|
@ -142,10 +136,6 @@ class TestHouseKeepingCMD(base.TestCase):
|
|||
sleep_time.side_effect = [True, Exception('break')]
|
||||
self.assertRaisesRegexp(Exception, 'break', house_keeping.main)
|
||||
|
||||
spare_amp_thread_event_mock.set.assert_called_once_with()
|
||||
db_cleanup_thread_event_mock.set.assert_called_once_with()
|
||||
cert_rotate_thread_event_mock.set.assert_called_once_with()
|
||||
|
||||
spare_amp_thread_mock.start.assert_called_once_with()
|
||||
db_cleanup_thread_mock.start.assert_called_once_with()
|
||||
cert_rotate_thread_mock.start.assert_called_once_with()
|
||||
|
@ -182,13 +172,10 @@ class TestHouseKeepingCMD(base.TestCase):
|
|||
house_keeping.main()
|
||||
|
||||
spare_amp_thread_event_mock.set.assert_called_once_with()
|
||||
spare_amp_thread_event_mock.clear.assert_called_once_with()
|
||||
|
||||
db_cleanup_thread_event_mock.set.assert_called_once_with()
|
||||
db_cleanup_thread_event_mock.clear.assert_called_once_with()
|
||||
|
||||
cert_rotate_thread_event_mock.set.assert_called_once_with()
|
||||
cert_rotate_thread_event_mock.clear.assert_called_once_with()
|
||||
|
||||
spare_amp_thread_mock.start.assert_called_once_with()
|
||||
db_cleanup_thread_mock.start.assert_called_once_with()
|
||||
|
|
Loading…
Reference in New Issue