Break circular references when async request handler raises exception
This commit is contained in:
parent
cccd5fad38
commit
6e266a318b
|
@ -70,8 +70,16 @@ class DummyHandler(web.RequestHandler):
|
|||
self.write('ok\n')
|
||||
|
||||
|
||||
class DummyAsyncHandler(web.RequestHandler):
|
||||
@gen.coroutine
|
||||
def get(self):
|
||||
raise web.Finish('ok\n')
|
||||
|
||||
|
||||
|
||||
application = web.Application([
|
||||
(r'/dummy/', DummyHandler),
|
||||
(r'/dummyasync/', DummyAsyncHandler),
|
||||
(r'/collect/', CollectHandler),
|
||||
], debug=True)
|
||||
|
||||
|
@ -90,11 +98,12 @@ def main():
|
|||
# poke at it with a browser.
|
||||
client = httpclient.AsyncHTTPClient()
|
||||
yield client.fetch('http://127.0.0.1:8888/dummy/')
|
||||
yield client.fetch('http://127.0.0.1:8888/dummyasync/', raise_error=False)
|
||||
|
||||
# Now report on the results.
|
||||
gc.collect()
|
||||
resp = yield client.fetch('http://127.0.0.1:8888/collect/')
|
||||
print(resp.body)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
ioloop.IOLoop.current().run_sync(main)
|
||||
|
|
|
@ -290,7 +290,11 @@ def _make_coroutine_wrapper(func, replace_callback):
|
|||
result = _value_from_stopiteration(e)
|
||||
except Exception:
|
||||
future_set_exc_info(future, sys.exc_info())
|
||||
return future
|
||||
try:
|
||||
return future
|
||||
finally:
|
||||
# Avoid circular references
|
||||
future = None
|
||||
else:
|
||||
if isinstance(result, GeneratorType):
|
||||
# Inline the first iteration of Runner.run. This lets us
|
||||
|
|
|
@ -1537,6 +1537,9 @@ class RequestHandler(object):
|
|||
self._handle_request_exception(e)
|
||||
except Exception:
|
||||
app_log.error("Exception in exception handler", exc_info=True)
|
||||
finally:
|
||||
# Unset result to avoid circular references
|
||||
result = None
|
||||
if (self._prepared_future is not None and
|
||||
not self._prepared_future.done()):
|
||||
# In case we failed before setting _prepared_future, do it
|
||||
|
|
Loading…
Reference in New Issue