From d622f47affdfb064a49c8afc390c7618cf41765b Mon Sep 17 00:00:00 2001 From: Christophe Olinger Date: Fri, 11 Dec 2015 17:03:20 +0100 Subject: [PATCH 1/3] Save date in redis on which worker receives a warm shutdown request while busy --- rq/worker.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/rq/worker.py b/rq/worker.py index 8bcb02f..074cbc0 100644 --- a/rq/worker.py +++ b/rq/worker.py @@ -257,6 +257,12 @@ class Worker(object): p.expire(self.key, 60) p.execute() + def set_warm_shutdown_requested_date(self): + """Sets the date on which the worker received a warm shutdown request""" + with self.connection._pipeline() as p: + p.hset(self.key, 'warm_shutdown_requested_at', utcformat(utcnow())) + p.execute() + @property def birth_date(self): """Fetches birth date from Redis.""" @@ -264,6 +270,13 @@ class Worker(object): if birth_timestamp is not None: return utcparse(as_text(birth_timestamp)) + @property + def warm_shutdown_requested_date(self): + """Fetches warm_shutdown_requested_date from Redis.""" + warm_shutdown_requested_timestamp = self.connection.hget(self.key, 'warm_shutdown_requested_at') + if warm_shutdown_requested_timestamp is not None: + return utcparse(as_text(warm_shutdown_requested_timestamp)) + @property def death_date(self): """Fetches death date from Redis.""" @@ -357,9 +370,10 @@ class Worker(object): self.log.warning(msg) # If shutdown is requested in the middle of a job, wait until - # finish before shutting down + # finish before shutting down and save the request in redis if self.get_state() == 'busy': self._stop_requested = True + self.set_warm_shutdown_requested_date() self.log.debug('Stopping after current horse is finished. ' 'Press Ctrl+C again for a cold shutdown.') else: From 2be468a4044066cc289ea62a784a3f946033ff97 Mon Sep 17 00:00:00 2001 From: Christophe Olinger Date: Wed, 16 Dec 2015 15:24:42 +0100 Subject: [PATCH 2/3] - Rename paramter both in redis and python to shutdown_requested_date - Use connection instead of pipeline --- rq/worker.py | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/rq/worker.py b/rq/worker.py index 37fa15a..25720ff 100644 --- a/rq/worker.py +++ b/rq/worker.py @@ -257,11 +257,9 @@ class Worker(object): p.expire(self.key, 60) p.execute() - def set_warm_shutdown_requested_date(self): - """Sets the date on which the worker received a warm shutdown request""" - with self.connection._pipeline() as p: - p.hset(self.key, 'warm_shutdown_requested_at', utcformat(utcnow())) - p.execute() + def set_shutdown_requested_date(self): + """Sets the date on which the worker received a (warm) shutdown request""" + self.connection.hset(self.key, 'shutdown_requested_date', utcformat(utcnow())) @property def birth_date(self): @@ -271,11 +269,11 @@ class Worker(object): return utcparse(as_text(birth_timestamp)) @property - def warm_shutdown_requested_date(self): - """Fetches warm_shutdown_requested_date from Redis.""" - warm_shutdown_requested_timestamp = self.connection.hget(self.key, 'warm_shutdown_requested_at') - if warm_shutdown_requested_timestamp is not None: - return utcparse(as_text(warm_shutdown_requested_timestamp)) + def shutdown_requested_date(self): + """Fetches shutdown_requested_date from Redis.""" + shutdown_requested_timestamp = self.connection.hget(self.key, 'shutdown_requested_date') + if shutdown_requested_timestamp is not None: + return utcparse(as_text(shutdown_requested_timestamp)) @property def death_date(self): @@ -373,7 +371,7 @@ class Worker(object): # finish before shutting down and save the request in redis if self.get_state() == 'busy': self._stop_requested = True - self.set_warm_shutdown_requested_date() + self.set_shutdown_requested_date() self.log.debug('Stopping after current horse is finished. ' 'Press Ctrl+C again for a cold shutdown.') else: From b47c8efe274bdab90a59e4c27b14c9d18cbf66a3 Mon Sep 17 00:00:00 2001 From: Christophe Olinger Date: Wed, 16 Dec 2015 15:25:03 +0100 Subject: [PATCH 3/3] Add test cases for shutdown_requested_date --- tests/test_worker.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/test_worker.py b/tests/test_worker.py index a81444f..d2f5eae 100644 --- a/tests/test_worker.py +++ b/tests/test_worker.py @@ -545,6 +545,10 @@ class TestWorkerShutdown(RQTestCase): self.assertTrue(w._stop_requested) self.assertTrue(os.path.exists(sentinel_file)) + shutdown_requested_date = w.shutdown_requested_date + self.assertIsNotNone(shutdown_requested_date) + self.assertEqual(type(shutdown_requested_date).__name__, 'datetime') + @slow def test_working_worker_cold_shutdown(self): """worker with an ongoing job receiving double SIGTERM signal and shutting down immediately""" @@ -562,3 +566,6 @@ class TestWorkerShutdown(RQTestCase): self.assertTrue(w._stop_requested) self.assertFalse(os.path.exists(sentinel_file)) + shutdown_requested_date = w.shutdown_requested_date + self.assertIsNotNone(shutdown_requested_date) + self.assertEqual(type(shutdown_requested_date).__name__, 'datetime')