Repository navigation
fix(worker): wake the event loop on shutdown signals - #724
Open
AlexeyShalaev wants to merge 1 commit into
Open
AlexeyShalaev wants to merge 1 commit into
AlexeyShalaev wants to merge 1 commit into
Conversation
The worker's signal handler is installed with signal.signal and calls shutdown_event.set(). That only schedules the event's waiters, it doesn't wake the loop up. Without uvloop, a worker that is idle waiting for a message stays blocked in the selector, never shuts down, and the main process waits for it until it gets killed. Set the event with loop.call_soon_threadsafe, which also wakes the loop up, and create the loop before the handlers are installed. Closes taskiq-python#722
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #722
The worker's signal handler is registered with
signal.signaland callsshutdown_event.set(). That only schedules the event's waiters and doesn't wake the loop, so without uvloop a worker that is idle waiting for a message stays blocked in the selector. The main process then waits for it until it gets killed, andbroker.shutdown()doesn't run.The handler now sets the event through
loop.call_soon_threadsafe, which also wakes the loop. The loop is created before the handlers are installed, so it exists by the time a signal can arrive.The test starts a real worker the way the #686 test does and sits next to it to reuse its idle broker and CLI runner. A stub
uvloop.pyin the worker's directory makes it run on the default loop: CI installs uvloop, and with uvloop the test passes even without the fix. It sends SIGTERM to the main process and expects it to exit within 10 s. Without the fix it times out; with it, it passes on Python 3.10, 3.12 and 3.14. The full suite andprek run -apass.The repro from the issue, Python 3.12 without uvloop,
taskiq worker --workers 1, SIGTERM to the main process:broker.shutdown()runsListQueueBroker,socket_timeout=NoneMost of that second is the main process's 1 s polling loop. The worker starts shutting down the broker 3 to 4 ms after it gets the signal.