fix: detect and exit processing when a MultiPool worker terminates/crashes#1426
Open
fix: detect and exit processing when a MultiPool worker terminates/crashes#1426
Conversation
73e9cb4 to
d119dfa
Compare
d119dfa to
1209048
Compare
qkaiser
reviewed
Mar 12, 2026
| self._clear_input_queue() | ||
| self._request_workers_to_quit() | ||
| self._clear_output_queue() | ||
| except BaseException: |
Contributor
There was a problem hiding this comment.
Do we want to capture this exception and raise it at the end of close() if it exists ? Say a Ctrl-C/SIGTERM is received while we're draining the queues/waiting for workers to quit.
…ashes `process_until_done()` and `_clear_output_queue()` block on `.get()`. If a worker dies, the expected result never arrives and the main process hangs forever. Use `multiprocessing.connection.wait()`[^1] to wait on both the output queue pipe and worker process sentinels[^2] Replace the global pool registry and custom SIGTERM/SIGINT handler with a plain `raise SystemExit(128 + signum)`. This works because `SystemExit` propagates through `connection.wait()` (the underlying `poll(2)` returns EINTR, CPython invokes the signal handler before retrying per PEP 475[^3]), through `__exit__` which calls `close(immediate=True)`. SIGINT needs no custom handler as Python's default already raises `KeyboardInterrupt`, which propagates the same way. Wrap the graceful shutdown path in `close()` with `except BaseException` to fall back to immediate termination if anything goes wrong mid-teardown. [^1]: https://docs.python.org/3/library/multiprocessing.html#multiprocessing.connection.wait [^2]: https://docs.python.org/3/library/multiprocessing.html#multiprocessing.Process.sentinel [^3]: https://peps.python.org/pep-0475/
1209048 to
51c6446
Compare
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.
process_until_done()and_clear_output_queue()block on.get(). If a worker dies, the expected result never arrives and the main process hangs forever.Use
multiprocessing.connection.wait()1 to wait on both the output queue pipe and worker process sentinels2Replace the global pool registry and custom SIGTERM/SIGINT handler with a plain
raise SystemExit(128 + signum). This works becauseSystemExitpropagates throughconnection.wait()(the underlyingpoll(2)returns EINTR, CPython invokes the signal handler before retrying per PEP 4753), through__exit__which callsclose(immediate=True). SIGINT needs no custom handler as Python's default already raisesKeyboardInterrupt, which propagates the same way.Wrap the graceful shutdown path in
close()withexcept BaseExceptionto fall back to immediate termination if anything goes wrong mid-teardown.This is an alternative to #1422
Footnotes
https://docs.python.org/3/library/multiprocessing.html#multiprocessing.connection.wait ↩
https://docs.python.org/3/library/multiprocessing.html#multiprocessing.Process.sentinel ↩
https://peps.python.org/pep-0475/ ↩