Skip to content

Commit

Permalink
Fix bug when max_clients kwarg is passed to AsyncHTTPClient.configure.
Browse files Browse the repository at this point in the history
  • Loading branch information
bdarnell committed May 7, 2012
1 parent 9ef20e3 commit 6dbce93
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 3 deletions.
21 changes: 19 additions & 2 deletions tornado/httpclient.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,14 +124,16 @@ def handle_request(response):
_impl_class = None
_impl_kwargs = None

_DEFAULT_MAX_CLIENTS = 10

@classmethod
def _async_clients(cls):
assert cls is not AsyncHTTPClient, "should only be called on subclasses"
if not hasattr(cls, '_async_client_dict'):
cls._async_client_dict = weakref.WeakKeyDictionary()
return cls._async_client_dict

def __new__(cls, io_loop=None, max_clients=10, force_instance=False,
def __new__(cls, io_loop=None, max_clients=None, force_instance=False,
**kwargs):
io_loop = io_loop or IOLoop.instance()
if cls is AsyncHTTPClient:
Expand All @@ -149,7 +151,13 @@ def __new__(cls, io_loop=None, max_clients=10, force_instance=False,
if cls._impl_kwargs:
args.update(cls._impl_kwargs)
args.update(kwargs)
instance.initialize(io_loop, max_clients, **args)
if max_clients is not None:
# max_clients is special because it may be passed
# positionally instead of by keyword
args["max_clients"] = max_clients
elif "max_clients" not in args:
args["max_clients"] = AsyncHTTPClient._DEFAULT_MAX_CLIENTS
instance.initialize(io_loop, **args)
if not force_instance:
impl._async_clients()[io_loop] = instance
return instance
Expand Down Expand Up @@ -204,6 +212,15 @@ def configure(impl, **kwargs):
AsyncHTTPClient._impl_class = impl
AsyncHTTPClient._impl_kwargs = kwargs

@staticmethod
def _save_configuration():
return (AsyncHTTPClient._impl_class, AsyncHTTPClient._impl_kwargs)

@staticmethod
def _restore_configuration(saved):
AsyncHTTPClient._impl_class = saved[0]
AsyncHTTPClient._impl_kwargs = saved[1]


class HTTPRequest(object):
"""HTTP client request object."""
Expand Down
41 changes: 40 additions & 1 deletion tornado/test/simple_httpclient_test.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
from __future__ import absolute_import, division, with_statement

import collections
from contextlib import closing
import gzip
import logging
import re
import socket

from tornado.httpclient import AsyncHTTPClient
from tornado.httputil import HTTPHeaders
from tornado.ioloop import IOLoop
from tornado.simple_httpclient import SimpleAsyncHTTPClient, _DEFAULT_CA_CERTS
from tornado.test.httpclient_test import HTTPClientCommonTestCase, ChunkHandler, CountdownHandler, HelloWorldHandler
from tornado.testing import AsyncHTTPTestCase, LogTrapTestCase
from tornado.testing import AsyncHTTPTestCase, AsyncTestCase, LogTrapTestCase
from tornado.util import b
from tornado.web import RequestHandler, Application, asynchronous, url

Expand Down Expand Up @@ -263,3 +265,40 @@ def test_host_header(self):
self.http_client.fetch(url, self.stop)
response = self.wait()
self.assertTrue(host_re.match(response.body), response.body)


class CreateAsyncHTTPClientTestCase(AsyncTestCase, LogTrapTestCase):
def setUp(self):
super(CreateAsyncHTTPClientTestCase, self).setUp()
self.saved = AsyncHTTPClient._save_configuration()

def tearDown(self):
AsyncHTTPClient._restore_configuration(self.saved)
super(CreateAsyncHTTPClientTestCase, self).tearDown()

def test_max_clients(self):
# The max_clients argument is tricky because it was originally
# allowed to be passed positionally; newer arguments are keyword-only.
AsyncHTTPClient.configure(SimpleAsyncHTTPClient)
with closing(AsyncHTTPClient(
self.io_loop, force_instance=True)) as client:
self.assertEqual(client.max_clients, 10)
with closing(AsyncHTTPClient(
self.io_loop, 11, force_instance=True)) as client:
self.assertEqual(client.max_clients, 11)
with closing(AsyncHTTPClient(
self.io_loop, max_clients=11, force_instance=True)) as client:
self.assertEqual(client.max_clients, 11)

# Now configure max_clients statically and try overriding it
# with each way max_clients can be passed
AsyncHTTPClient.configure(SimpleAsyncHTTPClient, max_clients=12)
with closing(AsyncHTTPClient(
self.io_loop, force_instance=True)) as client:
self.assertEqual(client.max_clients, 12)
with closing(AsyncHTTPClient(
self.io_loop, max_clients=13, force_instance=True)) as client:
self.assertEqual(client.max_clients, 13)
with closing(AsyncHTTPClient(
self.io_loop, max_clients=14, force_instance=True)) as client:
self.assertEqual(client.max_clients, 14)

0 comments on commit 6dbce93

Please sign in to comment.