fix(batcher): Reset lock and flusher in child after fork#6163
Merged
ericapisani merged 7 commits intomasterfrom Apr 30, 2026
Merged
fix(batcher): Reset lock and flusher in child after fork#6163ericapisani merged 7 commits intomasterfrom
ericapisani merged 7 commits intomasterfrom
Conversation
Uses the same fix introduced in #6148 to prevent deadlocks in the monitor when os.fork() is called while another thread holds the monitor's lock. If os.fork() runs while another thread holds Batcher._lock, the child inherits the lock locked but the holding thread does not exist in the child, so the lock can never be released and _ensure_thread deadlocks forever. Register an after-fork hook via os.register_at_fork that replaces _lock with a fresh lock and resets _flusher / _flusher_pid in the child. Use a weakref to the batcher so the hook does not keep the instance alive. Move shared init out of SpanBatcher into the base Batcher.__init__ so all batchers (log, metrics, span) get the fork-safety hook from a single place. Fixes PY-2391 Fixes #6149
Contributor
Codecov Results 📊✅ 13 passed | Total: 13 | Pass Rate: 100% | Execution Time: 7.93s All tests are passing successfully. ❌ Patch coverage is 40.00%. Project has 14925 uncovered lines. Files with missing lines (2)
Generated by Codecov Action |
…class from batcher but that will not be done in this set of changes. Update batcher deadlock fix to use weakmethod, to be consistent with the approach taken in monitor.py
Member
Author
|
bugbot run |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit b5073b2. Configure here.
alexander-alderman-webb
approved these changes
Apr 30, 2026
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.

Apply the same fork-safety fix introduced in #6148 (for the monitor) to all batchers (log, metrics, span).
If
os.fork()runs while another thread holdsBatcher._lock, the child inherits the lock locked but the holding thread does not exist in the child, so the lock can never be released and_ensure_threaddeadlocks forever. Register an after-fork hook viaos.register_at_forkthat replaces_lockwith a fresh lock and resets_flusher/_flusher_pidin the child. The hook holds aweakrefto the batcher so it does not keep the instance alive.Each batcher (log, metrics, span) gets a regression test that acquires the lock on the parent, forks, and asserts in the child that the lock object was replaced, the new lock is not held, and
_flusher/_flusher_pidwere reset. Tests are skipped on Windows and on Python builds withoutos.register_at_fork.Fixes PY-2391
Fixes #6149