From: Ben Darnell Date: Thu, 4 Mar 2010 19:52:18 +0000 (-0800) Subject: Use a WeakKeyDictionary instead of a regular dictionary to associate X-Git-Tag: v1.0.0~76^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f4359bc12864f0c5dd5d4f92403c8c19c34e5f8c;p=thirdparty%2Ftornado.git Use a WeakKeyDictionary instead of a regular dictionary to associate IOLoop and AsyncHTTPClients. This prevents leaks of memory and file descriptors when one process (in my case a unit test runner) create many IOLoop/AsyncHTTPClient pairs. --- diff --git a/tornado/httpclient.py b/tornado/httpclient.py index dc243ca0a..a67a3c5c6 100644 --- a/tornado/httpclient.py +++ b/tornado/httpclient.py @@ -27,6 +27,7 @@ import ioloop import logging import pycurl import time +import weakref class HTTPClient(object): @@ -100,14 +101,14 @@ class AsyncHTTPClient(object): determines the maximum number of simultaneous fetch() operations that can execute in parallel on each IOLoop. """ - _ASYNC_CLIENTS = {} + _ASYNC_CLIENTS = weakref.WeakKeyDictionary() def __new__(cls, io_loop=None, max_clients=10, max_simultaneous_connections=None): # There is one client per IOLoop since they share curl instances io_loop = io_loop or ioloop.IOLoop.instance() - if id(io_loop) in cls._ASYNC_CLIENTS: - return cls._ASYNC_CLIENTS[id(io_loop)] + if io_loop in cls._ASYNC_CLIENTS: + return cls._ASYNC_CLIENTS[io_loop] else: instance = super(AsyncHTTPClient, cls).__new__(cls) instance.io_loop = io_loop @@ -120,7 +121,7 @@ class AsyncHTTPClient(object): instance._events = {} instance._added_perform_callback = False instance._timeout = None - cls._ASYNC_CLIENTS[id(io_loop)] = instance + cls._ASYNC_CLIENTS[io_loop] = instance return instance def fetch(self, request, callback, **kwargs):