From ec8e5974259d10be85389779145b242f67586e0c Mon Sep 17 00:00:00 2001 From: Peter Dahlberg Date: Mon, 13 Jun 2016 23:10:52 +0200 Subject: [PATCH] better shutdown handling --- develop_main.py | 35 ++++++++++++++++++++++++----------- pelican_deploy/deploy.py | 15 ++++++++------- pelican_deploy/gittool.py | 3 ++- 3 files changed, 34 insertions(+), 19 deletions(-) diff --git a/develop_main.py b/develop_main.py index e85cc22..6eb6cab 100755 --- a/develop_main.py +++ b/develop_main.py @@ -5,36 +5,49 @@ from apscheduler.schedulers.background import BackgroundScheduler from importlib.machinery import SourceFileLoader from operator import methodcaller from bottle import run, default_app +from wsgiref.simple_server import make_server import pelican_deploy.webhookbottle import logging - - +import atexit +import sys if __name__ == "__main__": config = SourceFileLoader("config", "deploy_config.py").load_module() runners = {name: DeploymentRunner(name, conf) - for name, conf in config.RUNNERS.items()} + for name, conf in config.RUNNERS.items()} #for r in runners.values(): # print(r.build(wait=True)) - schedulers = {r: BackgroundScheduler(daemon=False) for r in runners} + for r in runners.values(): + atexit.register(r.shutdown) # finally, wait for builds to finish + + for r in runners.values(): + atexit.register(r.try_abort_build) # then try to abort running builds + + schedulers = {r: BackgroundScheduler(daemon=True) for r in runners} for s in schedulers.values(): s.start() + atexit.register(s.shutdown) # first stop the schedulers + + atexit.register(print, + "<><><><><><><><><><><><><><><><><><><><><><><><><>\n", + ">>>>> Shutting down gracefully, please wait! <<<<<\n", + "<><><><><><><><><><><><><><><><><><><><><><><><><>", + file=sys.stderr, sep="") for i, (rname, trigger) in enumerate(config.SCHEDULED_BUILD_JOBS): - schedulers[rname].add_job(runners[rname].build, trigger=trigger, - name="{} ({})".format(rname, i), - id="{}_{}".format(rname, i), max_instances=1, - kwars={"wait" : True}) - - + schedulers[rname].add_job(runners[rname].build, + trigger=trigger, + name="{} ({})".format(rname, i), + id="{}_{}".format(rname, i), + max_instances=1, + kwars={"wait": True}) pelican_deploy.webhookbottle.set_runners(**runners) pelican_deploy.webhookbottle.set_github_secret(config.GITHUB_SECRET) default_app().mount("/hooks/", pelican_deploy.webhookbottle.app) run(host='0.0.0.0', port=4000, debug=True) - diff --git a/pelican_deploy/deploy.py b/pelican_deploy/deploy.py index 7a9808d..9f93808 100644 --- a/pelican_deploy/deploy.py +++ b/pelican_deploy/deploy.py @@ -10,7 +10,6 @@ import sys import logging import shlex import os -import atexit log = logging.getLogger(__name__) @@ -137,11 +136,10 @@ class DeploymentRunner: def final_install(self): args = shlex.split(self.final_install_command) log.info("%s: Starting final_install `%s`", self.name, args) - proc = Popen(args, stdout=PIPE, stderr=PIPE, universal_newlines=True) - atexit.register(proc.kill) + proc = Popen(args, stdout=PIPE, stderr=PIPE, universal_newlines=True, + start_new_session=True) outs, errs = proc.communicate() status = proc.wait() - atexit.unregister(proc.kill) if status < 0: log.info("%s: killed final_install_command (%s)", self.name, status) @@ -169,11 +167,10 @@ class DeploymentRunner: self._build_proc = Popen(args, stdout=PIPE, stderr=PIPE, cwd=str(self.build_repo_path), env=self._build_proc_env, - universal_newlines=True) - atexit.register(self._build_proc.kill) + universal_newlines=True, + start_new_session=True) outs, errs = self._build_proc.communicate() status = self._build_proc.wait() - atexit.unregister(self._build_proc.kill) if status < 0: log.info("%s: killed build_command", self.name) @@ -184,3 +181,7 @@ class DeploymentRunner: log.info('%s build_command stderr: %s\n', self.name, errs) if status == 0: self.final_install() + + def shutdown(self): + self.try_abort_build() + self._executor.shutdown(wait=True) diff --git a/pelican_deploy/gittool.py b/pelican_deploy/gittool.py index 5af5342..8a85407 100644 --- a/pelican_deploy/gittool.py +++ b/pelican_deploy/gittool.py @@ -41,7 +41,8 @@ class Repo: def popen_cmd(self, *args, env=None, universal_newlines=True): return Popen(args, stdout=PIPE, stderr=PIPE, cwd=self.repo_dir, env=env, - universal_newlines=universal_newlines) + universal_newlines=universal_newlines, + start_new_session=True) def is_bare(self): result = self.rev_parse("--is-bare-repository")