Finish event handlers when disconnecting from an event queue.

This should help prevent timeouts from clients whose requests have
been supplanted.

(imported from commit fdb3a89c4ec02bb23d0fba50ea558d48cb786916)
This commit is contained in:
Tim Abbott 2013-12-12 12:59:02 -05:00
parent 950e4c800b
commit cc0ce6b437
3 changed files with 15 additions and 4 deletions

View File

@ -91,8 +91,15 @@ class ClientDescriptor(object):
async_request_restart(self.current_handler._request)
self.event_queue.push(event)
self.finish_current_handler()
def finish_current_handler(self):
if self.current_handler is not None:
try:
# We call async_request_restart here in case we are
# being finished without any events (because another
# get_events request has supplanted this request)
async_request_restart(self.current_handler._request)
self.current_handler._request._log_data['extra'] = "[%s/1]" % (self.event_queue.id,)
self.current_handler.zulip_finish(dict(result='success', msg='',
events=self.event_queue.contents(),
@ -100,9 +107,11 @@ class ClientDescriptor(object):
self.current_handler._request,
apply_markdown=self.apply_markdown)
except Exception:
logging.exception("Got error adding event to queue %s" % (self.event_queue.id))
logging.exception("Got error finishing handler for queue %s" % (self.event_queue.id))
finally:
self.disconnect_handler()
return True
return False
def accepts_event_type(self, type):
if self.event_types is None:
@ -129,13 +138,11 @@ class ClientDescriptor(object):
self._timeout_handle = ioloop.add_timeout(heartbeat_time, timeout_callback)
def disconnect_handler(self):
was_connected = (self.current_handler is not None)
self.current_handler = None
if self._timeout_handle is not None:
ioloop = tornado.ioloop.IOLoop.instance()
ioloop.remove_timeout(self._timeout_handle)
self._timeout_handle = None
return was_connected
def cleanup(self):
do_gc_event_queues([self.event_queue.id], [self.user_profile_id],

View File

@ -38,6 +38,10 @@ def record_request_restart_data(log_data):
log_data['bugdown_requests_restarted'] = get_bugdown_requests()
def async_request_restart(request):
if "time_restarted" in request._log_data:
# Don't destroy data when being called from
# finish_current_handler
return
record_request_restart_data(request._log_data)
def record_request_start_data(log_data):

View File

@ -71,7 +71,7 @@ def get_events_backend(request, user_profile, handler = None,
if user_profile.id != client.user_profile_id:
return json_error("You are not authorized to get events from this queue")
client.event_queue.prune(last_event_id)
was_connected = client.disconnect_handler()
was_connected = client.finish_current_handler()
if not client.event_queue.empty() or dont_block:
ret = {'events': client.event_queue.contents()}