]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
tornado.concurrent.Future is now always thread-unsafe.
authorBen Darnell <ben@bendarnell.com>
Sun, 26 Jan 2014 03:18:08 +0000 (22:18 -0500)
committerBen Darnell <ben@bendarnell.com>
Sun, 26 Jan 2014 03:18:08 +0000 (22:18 -0500)
This improves performance and provides more consistent semantics
(independent of the presence or absence of the concurrent.futures
package).

The parts of Tornado that accept Futures will accept both Tornado's
thread-unsafe Futures and the thread-safe concurrent.futures.Future.

tornado/concurrent.py
tornado/gen.py
tornado/ioloop.py
tornado/test/concurrent_test.py

index a9002b16a3fcf6f0edca247dbb955799324d7235..a1b2d57c87470dfac03a25f6a5a6b7d2be5ef5a7 100644 (file)
@@ -40,7 +40,7 @@ class ReturnValueIgnoredError(Exception):
     pass
 
 
-class _DummyFuture(object):
+class Future(object):
     def __init__(self):
         self._done = False
         self._result = None
@@ -97,11 +97,14 @@ class _DummyFuture(object):
             cb(self)
         self._callbacks = None
 
+
 if futures is None:
-    Future = _DummyFuture
+    FUTURES = Future
 else:
-    Future = futures.Future
+    FUTURES = (futures.Future, Future)
 
+def is_future(x):
+    return isinstance(x, FUTURES)
 
 class TracebackFuture(Future):
     """Subclass of `Future` which can store a traceback with
index aa931b45724af651827abce979aeb8db50c5ee3e..eacff4b8334dab543780f09b2699285ac1def83a 100644 (file)
@@ -87,7 +87,7 @@ import itertools
 import sys
 import types
 
-from tornado.concurrent import Future, TracebackFuture
+from tornado.concurrent import TracebackFuture, is_future
 from tornado.ioloop import IOLoop
 from tornado.stack_context import ExceptionStackContext, wrap
 
@@ -426,7 +426,7 @@ class Multi(YieldPoint):
             children = children.values()
         self.children = []
         for i in children:
-            if isinstance(i, Future):
+            if is_future(i):
                 i = YieldFuture(i)
             self.children.append(i)
         assert all(isinstance(i, YieldPoint) for i in self.children)
@@ -549,7 +549,7 @@ class Runner(object):
                     raise
                 if isinstance(yielded, (list, dict)):
                     yielded = Multi(yielded)
-                elif isinstance(yielded, Future):
+                elif is_future(yielded):
                     yielded = YieldFuture(yielded)
                 if isinstance(yielded, YieldPoint):
                     self.yield_point = yielded
index d69f25cc903fc63ce59ffbdef0b3fc1b06c55945..77fb46591a521fc864bf740436ba9e9e1a37305e 100644 (file)
@@ -41,7 +41,7 @@ import threading
 import time
 import traceback
 
-from tornado.concurrent import Future, TracebackFuture
+from tornado.concurrent import TracebackFuture, is_future
 from tornado.log import app_log, gen_log
 from tornado import stack_context
 from tornado.util import Configurable
@@ -391,7 +391,7 @@ class IOLoop(Configurable):
                 future_cell[0] = TracebackFuture()
                 future_cell[0].set_exc_info(sys.exc_info())
             else:
-                if isinstance(result, Future):
+                if is_future(result):
                     future_cell[0] = result
                 else:
                     future_cell[0] = TracebackFuture()
@@ -482,7 +482,7 @@ class IOLoop(Configurable):
         The callback is invoked with one argument, the
         `.Future`.
         """
-        assert isinstance(future, Future)
+        assert is_future(future)
         callback = stack_context.wrap(callback)
         future.add_done_callback(
             lambda future: self.add_callback(callback, future))
index 849337ed662f037dd5f4829e370beef84269c555..5e93ad6a42ba5fd55a9f100a3fbd448085088e89 100644 (file)
@@ -28,7 +28,6 @@ from tornado.iostream import IOStream
 from tornado import stack_context
 from tornado.tcpserver import TCPServer
 from tornado.testing import AsyncTestCase, LogTrapTestCase, bind_unused_port, gen_test
-from tornado.test.util import unittest
 
 
 try:
@@ -113,13 +112,6 @@ class ReturnFutureTest(AsyncTestCase):
         self.assertIs(future, future2)
         self.assertEqual(future.result(), 42)
 
-    @unittest.skipIf(futures is None, "futures module not present")
-    def test_timeout_future(self):
-        with self.assertRaises(futures.TimeoutError):
-            future = self.async_future()
-            # Do not call self.wait()
-            future.result(timeout=.1)
-
     @gen_test
     def test_async_future_gen(self):
         result = yield self.async_future()