]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
Add IOLoop.add_future to return to the IOLoop after a future has completed.
authorBen Darnell <ben@bendarnell.com>
Fri, 31 Aug 2012 01:58:40 +0000 (21:58 -0400)
committerBen Darnell <ben@bendarnell.com>
Fri, 31 Aug 2012 01:58:40 +0000 (21:58 -0400)
tornado/ioloop.py
tornado/test/ioloop_test.py

index 70eb5564b217d8e5fbf199bc33916f3d451e679a..7525bb0996dfa103949d5e7037397d30bc292b82 100644 (file)
@@ -30,6 +30,7 @@ from __future__ import absolute_import, division, with_statement
 
 import datetime
 import errno
+import functools
 import heapq
 import os
 import logging
@@ -46,6 +47,11 @@ try:
 except ImportError:
     signal = None
 
+try:
+    from concurrent import futures
+except ImportError:
+    futures = None
+
 from tornado.platform.auto import set_close_exec, Waker
 
 
@@ -416,6 +422,17 @@ class IOLoop(object):
             # avoid it when we can.
             self._waker.wake()
 
+    def add_future(self, future, callback):
+        """Schedules a callback on the IOLoop when the given future is finished.
+
+        Requires the concurrent.futures module (standard in python 3.2+,
+        available via "pip install futures" in older versions).
+        """
+        assert isinstance(future, futures.Future)
+        future.add_done_callback(
+            lambda future: self.add_callback(
+                functools.partial(callback, future)))
+
     def _run_callback(self, callback):
         try:
             callback()
index 4e5e123c9ac2b2a8c9672f1c89d6117efa9d7eb8..1413a1846bb933a365c137ededb66f9c98cfb61f 100644 (file)
@@ -11,6 +11,11 @@ from tornado.netutil import bind_sockets
 from tornado.testing import AsyncTestCase, LogTrapTestCase, get_unused_port
 from tornado.test.util import unittest
 
+try:
+    from concurrent import futures
+except ImportError:
+    futures = None
+
 
 class TestIOLoop(AsyncTestCase, LogTrapTestCase):
     def test_add_callback_wakeup(self):
@@ -49,5 +54,17 @@ class TestIOLoop(AsyncTestCase, LogTrapTestCase):
             sock.close()
 
 
+class TestIOLoopFutures(AsyncTestCase, LogTrapTestCase):
+    def test_add_future_threads(self):
+        with futures.ThreadPoolExecutor(1) as pool:
+            self.io_loop.add_future(pool.submit(lambda: None),
+                                    lambda future: self.stop(future))
+            future = self.wait()
+            self.assertTrue(future.done())
+            self.assertTrue(future.result() is None)
+TestIOLoopFutures = unittest.skipIf(
+    futures is None, "futures module is not present")(TestIOLoopFutures)
+
+
 if __name__ == "__main__":
     unittest.main()