async def run(self) -> None: self.notify_event = asyncio.Event() self.stop_requested = False self.logger.info( f"Starting worker on {self.base_context.queues_display}", extra=self.base_context.log_extra(action="start_worker", queues=self.queues), ) with contextlib.ExitStack() as stack: if self.wait and self.listen_notify: stack.enter_context(self.listener()) stack.enter_context(self.periodic_deferrer()) stack.enter_context(signals.on_stop(self.stop)) await asyncio.gather(*(self.single_worker(worker_id=worker_id) for worker_id in range(self.concurrency))) self.logger.info( f"Stopped worker on {self.base_context.queues_display}", extra=self.base_context.log_extra(action="stop_worker", queues=self.queues), ) self.notify_event = None
async def run(self) -> None: self.notify_event = asyncio.Event() self.stop_requested = False self.logger.info( f"Starting worker on {self.base_context.queues_display}", extra=self.base_context.log_extra(action="start_worker", queues=self.queues), ) with signals.on_stop(self.stop): side_coros = [self.periodic_deferrer()] if self.wait and self.listen_notify: side_coros.append(self.listener()) await utils.run_tasks( main_coros=(self.single_worker(worker_id=worker_id) for worker_id in range(self.concurrency)), side_coros=side_coros, graceful_stop_callback=self.stop, ) self.logger.info( f"Stopped worker on {self.base_context.queues_display}", extra=self.base_context.log_extra(action="stop_worker", queues=self.queues), ) self.notify_event = None
def test_on_stop_signal_unused(kill_own_pid): before = signal.getsignal(signal.SIGINT) with signals.on_stop(callback=lambda: None): during = signal.getsignal(signal.SIGINT) after = signal.getsignal(signal.SIGINT) assert before is after assert before is not during
def test_do_nothing_on_secondary_thread(mocker): mocker.patch("threading.main_thread", return_value=None) signal = mocker.patch("signal.signal") def stop(): pass with signals.on_stop(callback=stop): pass signal.assert_not_called()
def test_on_stop_sync(one_signal, kill_own_pid): called = [] def stop(): called.append(True) before = signal.getsignal(one_signal) with signals.on_stop(callback=stop): kill_own_pid(signal=one_signal) assert called == [True] assert signal.getsignal(one_signal) is before
async def test_on_stop_async(one_signal, kill_own_pid): called = [] def stop(): called.append(True) before = signal.getsignal(one_signal) with signals.on_stop(callback=stop): kill_own_pid(signal=one_signal) await asyncio.sleep(0.001) # Signal takes some time to be processed. assert called == [True] assert signal.getsignal(one_signal) is before
async def test_on_stop_work_with_asyncio(kill_own_pid): # In this test, we want to make sure that interacting with synchronisation # primitives from within a signal handler works. event = asyncio.Event() def stop(): event.set() async def wait_and_kill(): await asyncio.sleep(0.001) kill_own_pid() try: with signals.on_stop(stop): asyncio.ensure_future(wait_and_kill()) await asyncio.wait_for(event.wait(), timeout=0.01) except asyncio.TimeoutError: pytest.fail("Signal did not awake coroutine")
async def run(self) -> None: await self.job_store.listen_for_jobs(queues=self.queues) with signals.on_stop(self.stop): while True: if self.stop_requested: break try: await self.process_jobs_once() except exceptions.StopRequested: break except exceptions.NoMoreJobs: logger.debug( "Waiting for new jobs", extra={"action": "waiting_for_jobs"} ) await self.job_store.wait_for_jobs() logger.debug("Stopped worker", extra={"action": "stopped_worker"})
async def run(self) -> None: self.notify_event = asyncio.Event() self.stop_requested = False self.logger.info( f"Starting worker on {self.base_context.queues_display}", extra=self.base_context.log_extra(action="start_worker", queues=self.queues), ) with self.listener(), signals.on_stop(self.stop): await asyncio.gather(*(self.single_worker(worker_id=worker_id) for worker_id in range(self.concurrency))) self.logger.info( f"Stopped worker on {self.base_context.queues_display}", extra=self.base_context.log_extra(action="stop_worker", queues=self.queues), ) self.notify_event = None
def test_on_stop_signal_twice(kill_own_pid): with pytest.raises(KeyboardInterrupt): with signals.on_stop(callback=lambda: None): kill_own_pid(signal=signal.SIGINT) kill_own_pid(signal=signal.SIGINT)