From: Ben Darnell Date: Sun, 3 Nov 2013 21:18:40 +0000 (-0500) Subject: Don't make the request if it timed out in the queue. X-Git-Tag: v3.2.0b1~51 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b61ce6dcc3b7ea3345bd7024c4ceb3d85c87a04a;p=thirdparty%2Ftornado.git Don't make the request if it timed out in the queue. Use IOLoop time instead of request.start_time (which is wall time). Misc test fixes. --- diff --git a/tornado/simple_httpclient.py b/tornado/simple_httpclient.py index 7dfd3f43d..271b25be5 100644 --- a/tornado/simple_httpclient.py +++ b/tornado/simple_httpclient.py @@ -94,9 +94,12 @@ class SimpleAsyncHTTPClient(AsyncHTTPClient): self.queue.append((key, request, callback)) if not len(self.active) < self.max_clients: timeout_handle = self.io_loop.add_timeout( - request.start_time + min(request.connect_timeout, request.request_timeout), + self.io_loop.time() + min(request.connect_timeout, + request.request_timeout), functools.partial(self._on_timeout, key)) - self.waiting[key] = (request, callback, timeout_handle) + else: + timeout_handle = None + self.waiting[key] = (request, callback, timeout_handle) self._process_queue() if self.queue: gen_log.debug("max_clients limit reached, request queued. " @@ -107,6 +110,8 @@ class SimpleAsyncHTTPClient(AsyncHTTPClient): with stack_context.NullContext(): while self.queue and len(self.active) < self.max_clients: key, request, callback = self.queue.popleft() + if key not in self.waiting: + continue self._remove_timeout(key) self.active[key] = (request, callback) release_callback = functools.partial(self._release_fetch, key) @@ -123,7 +128,8 @@ class SimpleAsyncHTTPClient(AsyncHTTPClient): def _remove_timeout(self, key): if key in self.waiting: request, callback, timeout_handle = self.waiting[key] - self.io_loop.remove_timeout(timeout_handle) + if timeout_handle is not None: + self.io_loop.remove_timeout(timeout_handle) del self.waiting[key] def _on_timeout(self, key): diff --git a/tornado/test/simple_httpclient_test.py b/tornado/test/simple_httpclient_test.py index c923c0728..407275314 100644 --- a/tornado/test/simple_httpclient_test.py +++ b/tornado/test/simple_httpclient_test.py @@ -296,6 +296,22 @@ class SimpleHTTPClientTestMixin(object): self.assertTrue(expected_message in str(response.error), response.error) + def test_queue_timeout(self): + with closing(self.create_client(max_clients=1)) as client: + client.fetch(self.get_url('/trigger'), self.stop, + request_timeout=10) + # Wait for the trigger request to block, not complete. + self.wait() + client.fetch(self.get_url('/hello'), self.stop, + connect_timeout=0.1) + response = self.wait() + + self.assertEqual(response.code, 599) + self.assertTrue(response.request_time < 1, response.request_time) + self.assertEqual(str(response.error), "HTTP 599: Timeout") + self.triggers.popleft()() + self.wait() + class SimpleHTTPClientTestCase(SimpleHTTPClientTestMixin, AsyncHTTPTestCase): def setUp(self): @@ -396,21 +412,3 @@ class HostnameMappingTestCase(AsyncHTTPTestCase): response = self.wait() response.rethrow() self.assertEqual(response.body, b'Hello world!') - - -class HeavyloadAsyncHTTPClientTestCase(SimpleHTTPClientTestMixin, AsyncHTTPTestCase): - def create_client(self, **kwargs): - return SimpleAsyncHTTPClient(self.io_loop, force_instance=True, **kwargs) - - def test_heavyload_timeout(self): - with closing(self.create_client(max_clients=1)) as client: - client.fetch(self.get_url('/trigger?wake=false'), self.stop, request_timeout=10) - client.fetch(self.get_url('/hello'), self.stop, connect_timeout=3) - response = self.wait() - - self.assertEqual(response.code, 599) - self.assertTrue(2.9 < response.request_time < 3.1, response.request_time) - self.assertEqual(str(response.error), "HTTP 599: Timeout") - self.triggers.popleft()() - -