From a5e7ee7a7fc673dcc6829142a7e35e8f1a17437b Mon Sep 17 00:00:00 2001 From: Philipp Engel Date: Tue, 16 Dec 2014 15:43:06 +0100 Subject: [PATCH] modified method _schedule_next of PeriodicCallback to handle sudden changes of the system time differently: * calculating next timeout value directly while advancing by a multiple of callback_time * when the system time changes, jumps into the future make the _schedule_next method do a busy wait. * on slow machines (RPi), jumps of a few months into the future can block the loop for a few minutes => added a check for big differences in current system time and the current value of the next scheduled timeout On a first boot of an older RPi image, tornado sometime starts before the date&time were updated through NTP, hence blocking the ioloop for several minutes. --- tornado/ioloop.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tornado/ioloop.py b/tornado/ioloop.py index a8f662acb..ac8443cfd 100644 --- a/tornado/ioloop.py +++ b/tornado/ioloop.py @@ -41,6 +41,7 @@ import sys import threading import time import traceback +import math from tornado.concurrent import TracebackFuture, is_future from tornado.log import app_log, gen_log @@ -982,6 +983,9 @@ class PeriodicCallback(object): def _schedule_next(self): if self._running: current_time = self.io_loop.time() - while self._next_timeout <= current_time: - self._next_timeout += self.callback_time / 1000.0 + + if self._next_timeout <= current_time: + callback_time_sec = self.callback_time / 1000.0 + self._next_timeout += (math.floor((current_time - self._next_timeout) / callback_time_sec) + 1) * callback_time_sec + self._timeout = self.io_loop.add_timeout(self._next_timeout, self._run) -- 2.47.2