From: Antoine Pitrou Date: Tue, 24 Oct 2017 09:09:44 +0000 (+0200) Subject: Fetch IOLoop in PeriodicCallback.start(), not __init__() X-Git-Tag: v5.0.0~48^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F2179%2Fhead;p=thirdparty%2Ftornado.git Fetch IOLoop in PeriodicCallback.start(), not __init__() See motivation at https://github.com/dask/distributed/pull/1172 --- diff --git a/tornado/ioloop.py b/tornado/ioloop.py index 5686576cf..631f15a20 100644 --- a/tornado/ioloop.py +++ b/tornado/ioloop.py @@ -1082,12 +1082,15 @@ class PeriodicCallback(object): if callback_time <= 0: raise ValueError("Periodic callback must have a positive callback_time") self.callback_time = callback_time - self.io_loop = IOLoop.current() self._running = False self._timeout = None def start(self): """Starts the timer.""" + # Looking up the IOLoop here allows to first instantiate the + # PeriodicCallback in another thread, then start it using + # IOLoop.add_callback(). + self.io_loop = IOLoop.current() self._running = True self._next_timeout = self.io_loop.time() self._schedule_next() diff --git a/tornado/test/ioloop_test.py b/tornado/test/ioloop_test.py index f3cd32ae4..bde351f60 100644 --- a/tornado/test/ioloop_test.py +++ b/tornado/test/ioloop_test.py @@ -747,6 +747,21 @@ class TestPeriodicCallback(unittest.TestCase): self.io_loop.start() self.assertEqual(calls, expected) + def test_io_loop_set_at_start(self): + # Check PeriodicCallback uses the current IOLoop at start() time, + # not at instantiation time. + calls = [] + io_loop = FakeTimeIOLoop() + + def cb(): + calls.append(io_loop.time()) + pc = PeriodicCallback(cb, 10000) + io_loop.make_current() + pc.start() + io_loop.call_later(50, io_loop.stop) + io_loop.start() + self.assertEqual(calls, [1010, 1020, 1030, 1040, 1050]) + class TestIOLoopConfiguration(unittest.TestCase): def run_python(self, *statements):