]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
Split AsyncIOLoop to make it possible to use the global asyncio event loop.
authorBen Darnell <ben@bendarnell.com>
Fri, 18 Oct 2013 20:07:11 +0000 (16:07 -0400)
committerBen Darnell <ben@bendarnell.com>
Sat, 26 Oct 2013 23:49:22 +0000 (19:49 -0400)
AsyncIOLoop works more like Tornado's native IOLoop so it's better for
our tests, but AsyncIOMainLoop is more appropriate for most real-world
usage.

tornado/platform/asyncio.py
tornado/test/httpclient_test.py
tornado/test/process_test.py

index f59b110283df1743894ca3e94367a9ee8eb8a909..a8f5bad475fa7dd8d0fe8289bf9204566ab8a3fb 100644 (file)
@@ -2,7 +2,11 @@
 
 This is a work in progress and interfaces are subject to change.
 
-To test: python3.4 -m tornado.test.runtests --ioloop=tornado.platform.asyncio.AsyncIOLoop
+To test:
+python3.4 -m tornado.test.runtests --ioloop=tornado.platform.asyncio.AsyncIOLoop
+python3.4 -m tornado.test.runtests --ioloop=tornado.platform.asyncio.AsyncIOMainLoop
+(the tests log a few warnings with AsyncIOMainLoop because they leave some
+unfinished callbacks on the event loop that fail when it resumes)
 """
 import asyncio
 import datetime
@@ -12,11 +16,10 @@ import os
 from tornado.ioloop import IOLoop
 from tornado import stack_context
 
-# This name is really unfortunate.
-class AsyncIOLoop(IOLoop):
-    def initialize(self):
-        # TODO: we need a way to use the global get_event_loop.
-        self.asyncio_loop = asyncio.events.new_event_loop()
+class BaseAsyncIOLoop(IOLoop):
+    def initialize(self, asyncio_loop, close_loop=False):
+        self.asyncio_loop = asyncio_loop
+        self.close_loop = close_loop
         self.asyncio_loop.call_soon(self.make_current)
         # Maps fd to handler function (as in IOLoop.add_handler)
         self.handlers = {}
@@ -31,7 +34,8 @@ class AsyncIOLoop(IOLoop):
             self.remove_handler(fd)
             if all_fds:
                 os.close(fd)
-        self.asyncio_loop.close()
+        if self.close_loop:
+            self.asyncio_loop.close()
 
     def add_handler(self, fd, handler, events):
         if fd in self.handlers:
@@ -117,3 +121,14 @@ class AsyncIOLoop(IOLoop):
                 self._run_callback, stack_context.wrap(callback), *args)
 
     add_callback_from_signal = add_callback
+
+
+class AsyncIOMainLoop(BaseAsyncIOLoop):
+    def initialize(self):
+        super(AsyncIOMainLoop, self).initialize(asyncio.get_event_loop(),
+                                                close_loop=False)
+
+class AsyncIOLoop(BaseAsyncIOLoop):
+    def initialize(self):
+        super(AsyncIOLoop, self).initialize(asyncio.new_event_loop(),
+                                            close_loop=True)
index 0efef9b32703405bebad4a3ed962f935b8fd9593..15bb8e44bd8372e0aef16a4d0733b0aeb12f674f 100644 (file)
@@ -433,11 +433,16 @@ class HTTPResponseTestCase(unittest.TestCase):
 
 class SyncHTTPClientTest(unittest.TestCase):
     def setUp(self):
-        if IOLoop.configured_class().__name__ == 'TwistedIOLoop':
+        if IOLoop.configured_class().__name__ in ('TwistedIOLoop',
+                                                  'AsyncIOMainLoop'):
             # TwistedIOLoop only supports the global reactor, so we can't have
             # separate IOLoops for client and server threads.
+            # AsyncIOMainLoop doesn't work with the default policy
+            # (although it could with some tweaks to this test and a
+            # policy that created loops for non-main threads).
             raise unittest.SkipTest(
-                'Sync HTTPClient not compatible with TwistedIOLoop')
+                'Sync HTTPClient not compatible with TwistedIOLoop or '
+                'AsyncIOMainLoop')
         self.server_ioloop = IOLoop()
 
         sock, self.port = bind_unused_port()
index 86f5f141e81868abfac6b151d9386b9c463ae7ca..de727607ac85d15178196e9bd0c53fc092c9cab6 100644 (file)
@@ -19,8 +19,10 @@ from tornado.web import RequestHandler, Application
 
 
 def skip_if_twisted():
-    if IOLoop.configured_class().__name__.endswith('TwistedIOLoop'):
-        raise unittest.SkipTest("Process tests not compatible with TwistedIOLoop")
+    if IOLoop.configured_class().__name__.endswith(('TwistedIOLoop',
+                                                    'AsyncIOMainLoop')):
+        raise unittest.SkipTest("Process tests not compatible with "
+                                "TwistedIOLoop or AsyncIOMainLoop")
 
 # Not using AsyncHTTPTestCase because we need control over the IOLoop.