]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
Port pseudo-singleton magic from AsyncHTTPClient to SimpleAsyncHTTPClient
authorBen Darnell <ben@bendarnell.com>
Tue, 16 Nov 2010 00:11:09 +0000 (16:11 -0800)
committerBen Darnell <ben@bendarnell.com>
Tue, 16 Nov 2010 00:11:09 +0000 (16:11 -0800)
tornado/simple_httpclient.py
tornado/test/simple_httpclient_test.py

index 86a6c0dd783d53b291d17c420ad9ca278128b3c9..07d655afb3e2cd378bec625d535e74ba969cb2c9 100644 (file)
@@ -16,6 +16,7 @@ import re
 import socket
 import time
 import urlparse
+import weakref
 import zlib
 
 try:
@@ -43,9 +44,30 @@ class SimpleAsyncHTTPClient(object):
     Python 2.6 or higher is required for HTTPS support.  Users of Python 2.5
     should use the curl-based AsyncHTTPClient if HTTPS support is required.
     """
-    # TODO: singleton magic?
-    def __init__(self, io_loop=None):
-        self.io_loop = io_loop or IOLoop.instance()
+    _ASYNC_CLIENTS = weakref.WeakKeyDictionary()
+
+    def __new__(cls, io_loop=None, max_clients=10,
+                max_simultaneous_connections=None):
+        """Creates a SimpleAsyncHTTPClient.
+
+        Only a single SimpleAsyncHTTPClient instance exists per IOLoop
+        in order to provide limitations on the number of pending connections.
+
+        max_clients is the number of concurrent requests that can be in
+        progress.  max_simultaneous_connections has no effect and is accepted
+        only for compatibility with the curl-based AsyncHTTPClient.  Note
+        that these arguments are only used when the client is first created,
+        and will be ignored when an existing client is reused.
+        """
+        io_loop = io_loop or IOLoop.instance()
+        if io_loop in cls._ASYNC_CLIENTS:
+            return cls._ASYNC_CLIENTS[io_loop]
+        else:
+            instance = super(SimpleAsyncHTTPClient, cls).__new__(cls)
+            instance.io_loop = io_loop
+            instance.max_clients = max_clients
+            cls._ASYNC_CLIENTS[io_loop] = instance
+            return instance
 
     def close(self):
         pass
index c99e547af9c6cbfcf5d04675925bd68f4911ab37..24b67b024f0875475f7fab6f561d512fd7eb1fdf 100644 (file)
@@ -5,6 +5,7 @@ import logging
 import socket
 
 from contextlib import closing
+from tornado.ioloop import IOLoop
 from tornado.simple_httpclient import SimpleAsyncHTTPClient
 from tornado.testing import AsyncHTTPTestCase, LogTrapTestCase, get_unused_port
 from tornado.web import Application, RequestHandler, asynchronous
@@ -122,3 +123,12 @@ class SimpleHTTPClientTestCase(AsyncHTTPTestCase, LogTrapTestCase):
         response = self.fetch('/hang', request_timeout=0.1)
         self.assertEqual(response.code, 599)
         self.assertEqual(str(response.error), "HTTP 599: Timeout")
+
+    def test_singleton(self):
+        # Class "constructor" reuses objects on the same IOLoop
+        self.assertTrue(SimpleAsyncHTTPClient(self.io_loop) is
+                        SimpleAsyncHTTPClient(self.io_loop))
+        # different IOLoops use different objects
+        io_loop2 = IOLoop()
+        self.assertTrue(SimpleAsyncHTTPClient(self.io_loop) is not
+                        SimpleAsyncHTTPClient(io_loop2))