From 9fac314d7138f79091a9bd95eccd222bcd12e8ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Wed, 17 May 2017 12:56:14 +0200 Subject: [PATCH] SWU: restart asynchronously instead of synchronously Otherwise we will block ourselves, waiting for the restart command to complete which it only can when we are no longer there. Should reduce restart times on update significantly. Downside is that we no longer can wait for the return code of the call. However, that should be caught by our UI handler timing out for the restart and showing an error prompting the user to restart manually. --- src/octoprint/plugins/softwareupdate/__init__.py | 2 +- src/octoprint/plugins/softwareupdate/util.py | 4 ++-- src/octoprint/server/__init__.py | 5 ++++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/octoprint/plugins/softwareupdate/__init__.py b/src/octoprint/plugins/softwareupdate/__init__.py index 507c5593..ee0df3da 100644 --- a/src/octoprint/plugins/softwareupdate/__init__.py +++ b/src/octoprint/plugins/softwareupdate/__init__.py @@ -868,7 +868,7 @@ class SoftwareUpdatePlugin(octoprint.plugin.BlueprintPlugin, self._logger.info("Restarting...") try: - util.execute(restart_command) + util.execute(restart_command, evaluate_returncode=False, async=True) except exceptions.ScriptError as e: self._logger.exception("Error while restarting via command {}".format(restart_command)) self._logger.warn("Restart stdout:\n{}".format(e.stdout)) diff --git a/src/octoprint/plugins/softwareupdate/util.py b/src/octoprint/plugins/softwareupdate/util.py index 27335182..020fce3d 100644 --- a/src/octoprint/plugins/softwareupdate/util.py +++ b/src/octoprint/plugins/softwareupdate/util.py @@ -9,12 +9,12 @@ __copyright__ = "Copyright (C) 2014 The OctoPrint Project - Released under terms from .exceptions import ScriptError -def execute(command, cwd=None, evaluate_returncode=True): +def execute(command, cwd=None, evaluate_returncode=True, async=False): import sarge p = None try: - p = sarge.run(command, cwd=cwd, stdout=sarge.Capture(), stderr=sarge.Capture()) + p = sarge.run(command, cwd=cwd, stdout=sarge.Capture(), stderr=sarge.Capture(), async=async) except: returncode = p.returncode if p is not None else None stdout = p.stdout.text if p is not None and p.stdout is not None else "" diff --git a/src/octoprint/server/__init__.py b/src/octoprint/server/__init__.py index 20397ef7..4f17e23c 100644 --- a/src/octoprint/server/__init__.py +++ b/src/octoprint/server/__init__.py @@ -550,7 +550,7 @@ class Server(object): "on_shutdown", sorting_context="ShutdownPlugin.on_shutdown") - # wait for shutdown even to be processed, but maximally for 15s + # wait for shutdown event to be processed, but maximally for 15s event_timeout = 15.0 if eventManager.join(timeout=event_timeout): self._logger.warn("Event loop was still busy processing after {}s, shutting down anyhow".format(event_timeout)) @@ -565,13 +565,16 @@ class Server(object): def sigterm_handler(*args, **kwargs): # will stop tornado on SIGTERM, making the program exit cleanly def shutdown_tornado(): + self._logger.debug("Shutting down tornado's IOLoop...") ioloop.stop() + self._logger.debug("SIGTERM received...") ioloop.add_callback_from_signal(shutdown_tornado) signal.signal(signal.SIGTERM, sigterm_handler) try: # this is the main loop - as long as tornado is running, OctoPrint is running ioloop.start() + self._logger.debug("Tornado's IOLoop stopped") except (KeyboardInterrupt, SystemExit): pass except: