diff options
author | Zane Bitter <zbitter@redhat.com> | 2014-10-03 14:22:10 -0400 |
---|---|---|
committer | Zane Bitter <zbitter@redhat.com> | 2014-10-08 10:08:48 -0400 |
commit | 9027ee5e8e9d9976c29a47e4063b783a43ec2d04 (patch) | |
tree | 7329bde7f2583e351913e36a66f9ade278dfea2d | |
parent | 1eee0560548cafe7ca7ee533f46dfbae9a7681d2 (diff) | |
download | heat-9027ee5e8e9d9976c29a47e4063b783a43ec2d04.tar.gz |
Clean up signalling events after stack updates
We provide an Event object to every stack update in order to signal it that
we need to cancel the update; this change ensures that we delete it when
the thread is complete. Previously we were leaking memory on every update.
Change-Id: Ie0fbe3ec3ab57a2cb9dd5e551db15285b2b423c0
Closes-Bug: #1376857
(cherry picked from commit 6f13c2d0a4ff2004654a690c1e84a0c9d40ed577)
-rw-r--r-- | heat/engine/service.py | 21 | ||||
-rw-r--r-- | heat/tests/test_engine_service.py | 13 |
2 files changed, 28 insertions, 6 deletions
diff --git a/heat/engine/service.py b/heat/engine/service.py index cd3ab0730..32f1a7b06 100644 --- a/heat/engine/service.py +++ b/heat/engine/service.py @@ -118,7 +118,9 @@ class ThreadGroupManager(object): """ lock = stack_lock.StackLock(cnxt, stack, engine_id) with lock.thread_lock(stack.id): - self.start_with_acquired_lock(stack, lock, func, *args, **kwargs) + th = self.start_with_acquired_lock(stack, lock, + func, *args, **kwargs) + return th def start_with_acquired_lock(self, stack, lock, func, *args, **kwargs): """ @@ -143,6 +145,7 @@ class ThreadGroupManager(object): th = self.start(stack.id, func, *args, **kwargs) th.link(release, stack.id) + return th def add_timer(self, stack_id, func, *args, **kwargs): """ @@ -157,6 +160,11 @@ class ThreadGroupManager(object): def add_event(self, stack_id, event): self.events[stack_id].append(event) + def remove_event(self, stack_id, event): + for e in self.events.pop(stack_id, []): + if e is not event: + self.add_event(stack_id, e) + def stop_timers(self, stack_id): if stack_id in self.groups: self.groups[stack_id].stop_timers() @@ -686,12 +694,13 @@ class EngineService(service.Service): updated_stack.validate() event = eventlet.event.Event() + th = self.thread_group_mgr.start_with_lock(cnxt, current_stack, + self.engine_id, + current_stack.update, + updated_stack, + event=event) + th.link(self.thread_group_mgr.remove_event, current_stack.id, event) self.thread_group_mgr.add_event(current_stack.id, event) - self.thread_group_mgr.start_with_lock(cnxt, current_stack, - self.engine_id, - current_stack.update, - updated_stack, - event=event) return dict(current_stack.identifier()) @request_context diff --git a/heat/tests/test_engine_service.py b/heat/tests/test_engine_service.py index a9e55f67f..ff6d61def 100644 --- a/heat/tests/test_engine_service.py +++ b/heat/tests/test_engine_service.py @@ -1792,6 +1792,8 @@ class StackServiceTest(HeatTestCase): thread = self.m.CreateMockAnything() thread.link(mox.IgnoreArg(), self.stack.id).AndReturn(None) + thread.link(mox.IgnoreArg(), self.stack.id, + mox.IgnoreArg()).AndReturn(None) def run(stack_id, func, *args, **kwargs): func(*args) @@ -3445,6 +3447,17 @@ class ThreadGroupManagerTest(HeatTestCase): thm.add_event(stack_id, e2) self.assertEqual(thm.events[stack_id], [e1, e2]) + def test_tgm_remove_event(self): + stack_id = 'add_events_test' + e1, e2 = mock.Mock(), mock.Mock() + thm = service.ThreadGroupManager() + thm.add_event(stack_id, e1) + thm.add_event(stack_id, e2) + thm.remove_event(stack_id, e2) + self.assertEqual(thm.events[stack_id], [e1]) + thm.remove_event(stack_id, e1) + self.assertNotIn(stack_id, thm.events) + def test_tgm_send(self): stack_id = 'send_test' e1, e2 = mock.MagicMock(), mock.Mock() |