Fix Tornado memory leak of handler objects.

In 2ea0daab19, handlers were moved to
being tracked via the handlers_by_id dict, but nothing cleared this
dict, resulting in every handler object being leaked.  Since a Tornado
process uses a different handler object for every request, this
resulted in a significant memory leak.  We fix this by clearing the
handlers_by_id dict in the two code paths that would result in a
Tornado handler being de-allocated: the exception codepath and the
handler disconnect codepath.

Fixes #463.
This commit is contained in:
Tim Abbott
2016-02-12 21:34:14 -08:00
parent 753ccf67b1
commit 1396eb7022
3 changed files with 11 additions and 4 deletions

View File

@@ -20,7 +20,8 @@ from zerver.decorator import RespondAsynchronously, JsonableError
from zerver.lib.cache import cache_get_many, message_cache_key, \
user_profile_by_id_cache_key, cache_save_user_profile
from zerver.lib.cache_helpers import cache_with_key
from zerver.lib.handlers import get_handler_by_id, finish_handler
from zerver.lib.handlers import clear_handler_by_id, get_handler_by_id, \
finish_handler
from zerver.lib.utils import statsd
from zerver.middleware import async_request_restart
from zerver.lib.narrow import build_narrow_filter
@@ -160,7 +161,7 @@ class ClientDescriptor(object):
def disconnect_handler(self, client_closed=False):
if self.current_handler_id:
delete_descriptor_by_handler_id(self.current_handler_id, None)
clear_descriptor_by_handler_id(self.current_handler_id, None)
if client_closed:
logging.info("Client disconnected for queue %s (%s via %s)" %
(self.event_queue.id, self.user_profile_email,
@@ -184,7 +185,7 @@ def get_descriptor_by_handler_id(handler_id):
def set_descriptor_by_handler_id(handler_id, client_descriptor):
descriptors_by_handler_id[handler_id] = client_descriptor
def delete_descriptor_by_handler_id(handler_id, client_descriptor):
def clear_descriptor_by_handler_id(handler_id, client_descriptor):
del descriptors_by_handler_id[handler_id]
def compute_full_event_type(event):