SYN-339: Cancel the notifier timeout when the notifier fires

This commit is contained in:
Mark Haines 2015-04-09 11:07:20 +01:00
parent 83f5125d52
commit 6f9dea7483

View File

@ -59,8 +59,8 @@ class _NotificationListener(object):
self.limit = limit self.limit = limit
self.timeout = timeout self.timeout = timeout
self.deferred = deferred self.deferred = deferred
self.rooms = rooms self.rooms = rooms
self.timer = None
def notified(self): def notified(self):
return self.deferred.called return self.deferred.called
@ -93,6 +93,13 @@ class _NotificationListener(object):
self.appservice, set() self.appservice, set()
).discard(self) ).discard(self)
# Cancel the timeout for this notifer if one exists.
if self.timer is not None:
try:
notifier.clock.cancel_call_later(self.timer)
except:
logger.exception("Failed to cancel notifier timer")
class Notifier(object): class Notifier(object):
""" This class is responsible for notifying any listeners when there are """ This class is responsible for notifying any listeners when there are
@ -325,14 +332,20 @@ class Notifier(object):
self._register_with_keys(listener[0]) self._register_with_keys(listener[0])
result = yield callback() result = yield callback()
timer = [None]
if timeout: if timeout:
timed_out = [False] timed_out = [False]
def _timeout_listener(): def _timeout_listener():
timed_out[0] = True timed_out[0] = True
timer[0] = None
listener[0].notify(self, [], from_token, from_token) listener[0].notify(self, [], from_token, from_token)
self.clock.call_later(timeout/1000., _timeout_listener) # We create multiple notification listeners so we have to manage
# canceling the timeout ourselves.
timer[0] = self.clock.call_later(timeout/1000., _timeout_listener)
while not result and not timed_out[0]: while not result and not timed_out[0]:
yield deferred yield deferred
deferred = defer.Deferred() deferred = defer.Deferred()
@ -347,6 +360,12 @@ class Notifier(object):
self._register_with_keys(listener[0]) self._register_with_keys(listener[0])
result = yield callback() result = yield callback()
if timer[0] is not None:
try:
self.clock.cancel_call_later(timer[0])
except:
logger.exception("Failed to cancel notifer timer")
defer.returnValue(result) defer.returnValue(result)
def get_events_for(self, user, rooms, pagination_config, timeout): def get_events_for(self, user, rooms, pagination_config, timeout):
@ -400,8 +419,11 @@ class Notifier(object):
if not timeout: if not timeout:
_timeout_listener() _timeout_listener()
else: else:
self.clock.call_later(timeout/1000.0, _timeout_listener) # Only add the timer if the listener hasn't been notified
if not listener.notified():
listener.timer = self.clock.call_later(
timeout/1000.0, _timeout_listener
)
return return
@log_function @log_function