Break circular references when async request handler raises exception

This commit is contained in:
Konstantin Kopachev 2017-11-09 21:19:42 -08:00
parent cccd5fad38
commit 6e266a318b
No known key found for this signature in database
GPG Key ID: CECF757E656F4F62
3 changed files with 18 additions and 2 deletions

View File

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

View File

@ -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

View File

@ -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