parent: discard cancelled events in TimerList.get_timeout().

Otherwise get_timeout() keeps broker alive via keep_alive() for a
cancelled timer during shutdown.
pull/607/head
David Wilson 6 years ago
parent 5aca9d6c3f
commit 70ff4b674c

@ -628,6 +628,8 @@ class TimerList(object):
Floating point delay, or 0.0, or :data:`None` if no events are Floating point delay, or 0.0, or :data:`None` if no events are
scheduled. scheduled.
""" """
while self._lst and self._lst[0].cancelled:
heapq.heappop(self._lst)
if self._lst: if self._lst:
return max(0, self._lst[0].when - self._now()) return max(0, self._lst[0].when - self._now())

@ -56,6 +56,21 @@ class GetTimeoutTest(TimerListMixin, testlib.TestCase):
self.list._now = lambda: 30 self.list._now = lambda: 30
self.assertEquals(0, self.list.get_timeout()) self.assertEquals(0, self.list.get_timeout())
def test_one_cancelled(self):
t1 = self.list.schedule(2, lambda: None)
t2 = self.list.schedule(3, lambda: None)
self.list._now = lambda: 0
t1.cancel()
self.assertEquals(3, self.list.get_timeout())
def test_two_cancelled(self):
t1 = self.list.schedule(2, lambda: None)
t2 = self.list.schedule(3, lambda: None)
self.list._now = lambda: 0
t1.cancel()
t2.cancel()
self.assertEquals(None, self.list.get_timeout())
class ScheduleTest(TimerListMixin, testlib.TestCase): class ScheduleTest(TimerListMixin, testlib.TestCase):
def test_in_past(self): def test_in_past(self):
@ -105,7 +120,7 @@ class ExpireTest(TimerListMixin, testlib.TestCase):
self.list._now = lambda: 29 self.list._now = lambda: 29
timer = self.list.schedule(29, mock.Mock()) timer = self.list.schedule(29, mock.Mock())
timer.cancel() timer.cancel()
self.assertEquals(0, self.list.get_timeout()) self.assertEquals(None, self.list.get_timeout())
self.list._now = lambda: 29 self.list._now = lambda: 29
self.list.expire() self.list.expire()
self.assertEquals(0, len(timer.func.mock_calls)) self.assertEquals(0, len(timer.func.mock_calls))

Loading…
Cancel
Save