]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
Break circular references when async request handler raises exception 2195/head
authorKonstantin Kopachev <tenzzor@gmail.com>
Fri, 10 Nov 2017 05:19:42 +0000 (21:19 -0800)
committerKonstantin Kopachev <tenzzor@gmail.com>
Fri, 10 Nov 2017 05:19:42 +0000 (21:19 -0800)
maint/circlerefs/circlerefs.py
tornado/gen.py
tornado/web.py

index 0fb59c6f9f2aceb6ac65eb3f59247fb250265c93..fe91a09b47a7eab814372e45a917c1e5319e7bf8 100644 (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)
index 533ccb749d99df9ecf76c881981ec3ddd801f45b..b56b0efd9bb9ca3c71ce158b531c33c3deaa4ea9 100644 (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
index 0cc34b8e4b9e07bd84dbd2101044283f28e9eff6..f2749f7c416a6f14fc6c55dd3968d20c7e438adc 100644 (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