* 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.
import threading
import time
import traceback
+import math
from tornado.concurrent import TracebackFuture, is_future
from tornado.log import app_log, gen_log
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)