Introduce IOLoop.current() as a thread-local counterpart to IOLoop.instance().
gen.engine now recognizes Futures directly.
import sys
import types
+from tornado.concurrent import Future
from tornado.ioloop import IOLoop
from tornado.stack_context import ExceptionStackContext
class YieldFuture(YieldPoint):
def __init__(self, future, io_loop=None):
self.future = future
- self.io_loop = io_loop or IOLoop.instance()
+ self.io_loop = io_loop or IOLoop.current()
def start(self, runner):
self.runner = runner
raise
if isinstance(yielded, list):
yielded = Multi(yielded)
+ if isinstance(yielded, Future):
+ # TODO: lists of futures
+ yielded = YieldFuture(yielded)
if isinstance(yielded, YieldPoint):
self.yield_point = yielded
try:
# Global lock for creating global IOLoop instance
_instance_lock = threading.Lock()
+ _current = threading.local()
+
def __init__(self, impl=None):
self._impl = impl or _poll()
if hasattr(self._impl, 'fileno'):
assert not IOLoop.initialized()
IOLoop._instance = self
+ @staticmethod
+ def current():
+ current = getattr(IOLoop._current, "instance", None)
+ if current is None:
+ raise ValueError("no current IOLoop")
+ return current
+
+ def make_current(self):
+ IOLoop._current.instance = self
+
+ def clear_current(self):
+ assert IOLoop._current.instance is self
+ IOLoop._current.instance = None
+
def close(self, all_fds=False):
"""Closes the IOLoop, freeing any resources used.
if self._stopped:
self._stopped = False
return
+ old_current = getattr(IOLoop._current, "instance", None)
+ IOLoop._current.instance = self
self._thread_ident = thread.get_ident()
self._running = True
while True:
self._stopped = False
if self._blocking_signal_threshold is not None:
signal.setitimer(signal.ITIMER_REAL, 0, 0)
+ IOLoop._current.instance = old_current
def stop(self):
"""Stop the loop after the current event loop iteration is complete.
def test_generator(self):
@gen.engine
def f():
- result = yield gen.YieldFuture(self.client.capitalize("hello"),
- io_loop=self.io_loop)
+ result = yield self.client.capitalize("hello")
self.assertEqual(result, "HELLO")
self.stop()
f()
@gen.engine
def f():
with self.assertRaisesRegexp(CapError, "already capitalized"):
- yield gen.YieldFuture(self.client.capitalize("HELLO"),
- io_loop=self.io_loop)
+ yield self.client.capitalize("HELLO")
self.stop()
f()
self.wait()
def setUp(self):
super(AsyncTestCase, self).setUp()
self.io_loop = self.get_new_ioloop()
+ self.io_loop.make_current()
def tearDown(self):
+ self.io_loop.clear_current()
if (not IOLoop.initialized() or
self.io_loop is not IOLoop.instance()):
# Try to clean up any file descriptors left open in the ioloop.