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:
Jude Cross 2017-04-11 17:17:57 -07:00
parent 87bab9bf15
commit f37e776eb3
2 changed files with 17 additions and 33 deletions

View File

@ -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()

View File

@ -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()