diff --git a/rq/worker.py b/rq/worker.py index 275306e..af77e4e 100644 --- a/rq/worker.py +++ b/rq/worker.py @@ -257,6 +257,10 @@ class Worker(object): p.expire(self.key, 60) 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): """Fetches birth date from Redis.""" @@ -264,6 +268,13 @@ class Worker(object): if birth_timestamp is not None: return utcparse(as_text(birth_timestamp)) + @property + 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): """Fetches death date from Redis.""" @@ -357,9 +368,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_shutdown_requested_date() self.log.debug('Stopping after current horse is finished. ' 'Press Ctrl+C again for a cold shutdown.') else: diff --git a/tests/test_worker.py b/tests/test_worker.py index a7a44b0..5921970 100644 --- a/tests/test_worker.py +++ b/tests/test_worker.py @@ -561,6 +561,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""" @@ -578,3 +582,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')