Skip to content

Commit

Permalink
Port pseudo-singleton magic from AsyncHTTPClient to SimpleAsyncHTTPCl…
Browse files Browse the repository at this point in the history
…ient
  • Loading branch information
bdarnell committed Nov 16, 2010
1 parent f2aa302 commit 7750fe7
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 3 deletions.
28 changes: 25 additions & 3 deletions tornado/simple_httpclient.py
Expand Up @@ -16,6 +16,7 @@
import socket
import time
import urlparse
import weakref
import zlib

try:
Expand Down Expand Up @@ -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
Expand Down
10 changes: 10 additions & 0 deletions tornado/test/simple_httpclient_test.py
Expand Up @@ -5,6 +5,7 @@
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
Expand Down Expand Up @@ -122,3 +123,12 @@ def test_request_timeout(self):
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))

0 comments on commit 7750fe7

Please sign in to comment.