From 57de36a9d3fdded45329d02a6567eff7976ebd47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Mon, 16 Mar 2015 10:19:03 +0100 Subject: [PATCH] Monkey patching tornado to backport tornadoweb/tornado#1290 Should hopefully help with freezing/blocking issues upon first connect with the net on the Pi, more tests needed. --- src/octoprint/server/__init__.py | 9 ++------- src/octoprint/server/util/tornado.py | 30 ++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/src/octoprint/server/__init__.py b/src/octoprint/server/__init__.py index 28ef95cb..92b5329d 100644 --- a/src/octoprint/server/__init__.py +++ b/src/octoprint/server/__init__.py @@ -58,6 +58,7 @@ import octoprint.filemanager.analysis import octoprint.slicing from . import util +util.tornado.fix_ioloop_scheduling() UI_API_KEY = ''.join('%02X' % ord(z) for z in uuid.uuid4().bytes) @@ -656,13 +657,7 @@ class Server(): ## Tornado initialization starts here - try: - import monotime - import time - ioloop = IOLoop(time_func=time.monotonic) - except: - import time - ioloop = IOLoop(time_func=time.time) + ioloop = IOLoop() ioloop.install() self._router = SockJSRouter(self._createSocketConnection, "/sockjs") diff --git a/src/octoprint/server/util/tornado.py b/src/octoprint/server/util/tornado.py index 18e7281a..399dd4d7 100644 --- a/src/octoprint/server/util/tornado.py +++ b/src/octoprint/server/util/tornado.py @@ -29,6 +29,36 @@ import tornado.util import octoprint.util +#~~ Monkey patching + + +def fix_ioloop_scheduling(): + """ + This monkey patches tornado's :meth:`tornado.ioloop.PeriodicCallback._schedule_next` method so it no longer + blocks for long times on slow machines (RPi) when the system time happens to change by a large amount (e.g. due to + the first ever contact to an NTP server). + + Patch by @nosyjoe on Github. See this PR against tornado: https://github.com/tornadoweb/tornado/pull/1290 + """ + + import math + + # patched implementation taken from PR + def _schedule_next(self): + if self._running: + current_time = self.io_loop.time() + + 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) + + # replace original implementation with patched version + import tornado.ioloop + tornado.ioloop.PeriodicCallback._schedule_next = _schedule_next + + #~~ WSGI middleware