From 1cbf92c16681fd56685d24b0dece5468bce4b148 Mon Sep 17 00:00:00 2001 From: Vincent Driessen Date: Thu, 24 Nov 2011 15:39:16 +0100 Subject: [PATCH] Workaround for os.waitpid() throwing an OSError on SIGINT. When SIGINT (``Ctrl+C``) is received when inside a blocking os.waitpid(), OSError is thrown, effectively cancelling the wait. However, to facilitate a "warm shutdown", as we intend, Ctrl+C is perfectly allowed and we want to keep waiting for the child. Therefore, we perform a trick here, catching OSError, checking whether its cause was SIGINT (errno == EINTR), and only in that case, loop to os.waitpid() again. --- rq/worker.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/rq/worker.py b/rq/worker.py index 5b56a36..4aeba54 100644 --- a/rq/worker.py +++ b/rq/worker.py @@ -244,7 +244,15 @@ class Worker(object): sys.exit(0) else: self.procline('Forked %d at %d' % (child_pid, time.time())) - os.waitpid(child_pid, 0) + while True: + try: + os.waitpid(child_pid, 0) + break + except OSError as e: + if e.errno == errno.EINTR: + self.log.info('Not waiting for child.... received SIGINT.') + else: + raise def perform_job(self, job): self.procline('Processing %s from %s since %s' % (