Port pseudo-singleton magic from AsyncHTTPClient to SimpleAsyncHTTPClient

This commit is contained in:
Ben Darnell 2010-11-15 16:11:09 -08:00
parent f2aa302bcb
commit 7750fe7773
2 changed files with 35 additions and 3 deletions

View 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

View 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))