Create watch tasks in its own thread
This change moves the creation of stack watch tasks into its own thread which retries until it has been done without error. The intent is to prevent create_periodic_tasks from raising an error when the database is not available, and retry stack watch creation until the database becomes available. Once execution gets past create_periodic_tasks() then systemd is notified that the service is up, and heat will recover when the database comes back. Change-Id: I4d61022db505581f0c1b2feed009c56df18a9ee5 Closes-Bug: #1545885
This commit is contained in:
parent
2a167504d0
commit
d4e270cd9f
@ -332,6 +332,9 @@ class EngineService(service.Service):
|
|||||||
self.stack_watch = service_stack_watch.StackWatch(
|
self.stack_watch = service_stack_watch.StackWatch(
|
||||||
self.thread_group_mgr)
|
self.thread_group_mgr)
|
||||||
|
|
||||||
|
def create_watch_tasks():
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
# Create a periodic_watcher_task per-stack
|
# Create a periodic_watcher_task per-stack
|
||||||
admin_context = context.get_admin_context()
|
admin_context = context.get_admin_context()
|
||||||
stacks = stack_object.Stack.get_all(
|
stacks = stack_object.Stack.get_all(
|
||||||
@ -340,9 +343,19 @@ class EngineService(service.Service):
|
|||||||
show_hidden=True)
|
show_hidden=True)
|
||||||
for s in stacks:
|
for s in stacks:
|
||||||
self.stack_watch.start_watch_task(s.id, admin_context)
|
self.stack_watch.start_watch_task(s.id, admin_context)
|
||||||
|
LOG.info(_LI("Watch tasks created"))
|
||||||
|
return
|
||||||
|
except Exception as e:
|
||||||
|
LOG.error(_LE("Watch task creation attempt failed, %s"), e)
|
||||||
|
eventlet.sleep(5)
|
||||||
|
|
||||||
|
if self.manage_thread_grp is None:
|
||||||
|
self.manage_thread_grp = threadgroup.ThreadGroup()
|
||||||
|
self.manage_thread_grp.add_thread(create_watch_tasks)
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
self.engine_id = stack_lock.StackLock.generate_engine_id()
|
self.engine_id = stack_lock.StackLock.generate_engine_id()
|
||||||
|
if self.thread_group_mgr is None:
|
||||||
self.thread_group_mgr = ThreadGroupManager()
|
self.thread_group_mgr = ThreadGroupManager()
|
||||||
self.listener = EngineListener(self.host, self.engine_id,
|
self.listener = EngineListener(self.host, self.engine_id,
|
||||||
self.thread_group_mgr)
|
self.thread_group_mgr)
|
||||||
@ -370,6 +383,7 @@ class EngineService(service.Service):
|
|||||||
|
|
||||||
self._configure_db_conn_pool_size()
|
self._configure_db_conn_pool_size()
|
||||||
self.service_manage_cleanup()
|
self.service_manage_cleanup()
|
||||||
|
if self.manage_thread_grp is None:
|
||||||
self.manage_thread_grp = threadgroup.ThreadGroup()
|
self.manage_thread_grp = threadgroup.ThreadGroup()
|
||||||
self.manage_thread_grp.add_timer(cfg.CONF.periodic_interval,
|
self.manage_thread_grp.add_timer(cfg.CONF.periodic_interval,
|
||||||
self.service_manage_report)
|
self.service_manage_report)
|
||||||
|
@ -35,9 +35,12 @@ class StackWatchTest(common.HeatTestCase):
|
|||||||
|
|
||||||
self.ctx = utils.dummy_context(tenant_id='stack_watch_test_tenant')
|
self.ctx = utils.dummy_context(tenant_id='stack_watch_test_tenant')
|
||||||
self.eng = service.EngineService('a-host', 'a-topic')
|
self.eng = service.EngineService('a-host', 'a-topic')
|
||||||
self.eng.create_periodic_tasks()
|
|
||||||
# self.eng.engine_id = 'engine-fake-uuid'
|
# self.eng.engine_id = 'engine-fake-uuid'
|
||||||
|
|
||||||
|
def _create_periodic_tasks(self):
|
||||||
|
self.eng.create_periodic_tasks()
|
||||||
|
self.eng.manage_thread_grp.wait()
|
||||||
|
|
||||||
@mock.patch.object(service_stack_watch.StackWatch, 'start_watch_task')
|
@mock.patch.object(service_stack_watch.StackWatch, 'start_watch_task')
|
||||||
@mock.patch.object(stack_object.Stack, 'get_all')
|
@mock.patch.object(stack_object.Stack, 'get_all')
|
||||||
@mock.patch.object(service.service.Service, 'start')
|
@mock.patch.object(service.service.Service, 'start')
|
||||||
@ -49,7 +52,7 @@ class StackWatchTest(common.HeatTestCase):
|
|||||||
start_watch_task.return_value = None
|
start_watch_task.return_value = None
|
||||||
|
|
||||||
self.eng.thread_group_mgr = None
|
self.eng.thread_group_mgr = None
|
||||||
self.eng.create_periodic_tasks()
|
self._create_periodic_tasks()
|
||||||
|
|
||||||
mock_get_all.assert_called_once_with(mock.ANY, tenant_safe=False,
|
mock_get_all.assert_called_once_with(mock.ANY, tenant_safe=False,
|
||||||
show_hidden=True)
|
show_hidden=True)
|
||||||
@ -162,6 +165,7 @@ class StackWatchTest(common.HeatTestCase):
|
|||||||
@tools.stack_context('service_show_watch_state_test_stack')
|
@tools.stack_context('service_show_watch_state_test_stack')
|
||||||
@mock.patch.object(stack.Stack, 'resource_by_refid')
|
@mock.patch.object(stack.Stack, 'resource_by_refid')
|
||||||
def test_set_watch_state(self, mock_ref):
|
def test_set_watch_state(self, mock_ref):
|
||||||
|
self._create_periodic_tasks()
|
||||||
# Insert dummy watch rule into the DB
|
# Insert dummy watch rule into the DB
|
||||||
rule = {u'EvaluationPeriods': u'1',
|
rule = {u'EvaluationPeriods': u'1',
|
||||||
u'AlarmActions': [u'WebServerRestartPolicy'],
|
u'AlarmActions': [u'WebServerRestartPolicy'],
|
||||||
|
Loading…
Reference in New Issue
Block a user