Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Run AsyncHTTPClient callbacks on the IOLoop for a clean stack.

Closes #652.
  • Loading branch information...
commit 6d9407f9876f52ad000c159acbc0b3ee330b3846 1 parent 5b4f028
@bdarnell bdarnell authored
View
2  tornado/simple_httpclient.py
@@ -309,7 +309,7 @@ def _run_callback(self, response):
if self.final_callback is not None:
final_callback = self.final_callback
self.final_callback = None
- final_callback(response)
+ self.io_loop.add_callback(final_callback, response)
@contextlib.contextmanager
def cleanup(self):
View
23 tornado/test/httpclient_test.py
@@ -7,12 +7,13 @@
from contextlib import closing
import functools
import re
+import sys
from tornado.escape import utf8
from tornado.httpclient import HTTPRequest, _RequestProxy
from tornado.iostream import IOStream
from tornado import netutil
-from tornado.stack_context import ExceptionStackContext
+from tornado.stack_context import ExceptionStackContext, NullContext
from tornado.testing import AsyncHTTPTestCase, bind_unused_port
from tornado.test.util import unittest
from tornado.util import b, bytes_type
@@ -289,6 +290,26 @@ def test_304_with_content_length(self):
self.assertEqual(response.code, 304)
self.assertEqual(response.headers['Content-Length'], '42')
+ def test_final_callback_stack_context(self):
+ # The final callback should be run outside of the httpclient's
+ # stack_context. We want to ensure that there is not stack_context
+ # between the user's callback and the IOLoop, so monkey-patch
+ # IOLoop.handle_callback_exception and disable the test harness's
+ # context with a NullContext.
+ # Note that this does not apply to secondary callbacks (header
+ # and streaming_callback), as errors there must be seen as errors
+ # by the http client so it can clean up the connection.
+ exc_info = []
+ def handle_callback_exception(callback):
+ exc_info.append(sys.exc_info())
+ self.stop()
+ self.io_loop.handle_callback_exception = handle_callback_exception
+ with NullContext():
+ self.http_client.fetch(self.get_url('/hello'),
+ lambda response: 1 / 0)
+ self.wait()
+ self.assertEqual(exc_info[0][0], ZeroDivisionError)
+
class RequestProxyTest(unittest.TestCase):
def test_request_set(self):
proxy = _RequestProxy(HTTPRequest('http://example.com/',
View
2  website/sphinx/releases/next.rst
@@ -198,3 +198,5 @@ In progress
``*args, **kwargs`` to pass along to the callback.
* When gzip is enabled in a `tornado.web.Application`, appropriate
``Vary: Accept-Encoding`` headers are now sent.
+* Fixed a bug in which `SimpleAsyncHTTPClient` callbacks were being run in the
+ client's ``stack_context``.

0 comments on commit 6d9407f

Please sign in to comment.
Something went wrong with that request. Please try again.