Repository navigation
[fix] Keep inherited Ray lock handles alive in forked children #202
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -216,6 +216,7 @@ async def async_kv_local_lock(keys: str | list[str], partition_id: str, timeout: | |
| _managers: dict = {} # shard -> TransferQueueLockManager handle, looked up on first use | ||
| _owned: list = [] # the lock actors this process's tq.init() created, killed by its tq.close() | ||
| _closes = 0 # this process's tq.close() calls: a lease created before the latest one is given up | ||
| _inherited_after_fork: list = [] # a forked child's copies of the parent's handles, never released | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This trailing comment is a one-line description of what the variable contains and how long it lives, not the reason that retaining the references is necessary; the scoped comment rule requires a concise 2–4-line “why” explanation. AGENTS.md reference: AGENTS.md:L24-L26 Useful? React with 👍 / 👎. |
||
| # Longest one call waits inside a lock actor; waiting longer takes another call that keeps | ||
| # the queue position. The bound is long because every waiter spends one call per window, and | ||
| # those calls share the actor's limited throughput with everyone else's, renewals included. | ||
|
|
@@ -585,7 +586,10 @@ def _close_lock_managers() -> None: | |
|
|
||
| def _reset_after_fork() -> None: | ||
| # The child inherits keys, leases and Ray handles that belong to threads and connections it lacks. | ||
| # Releasing an inherited handle runs the parent's core worker in the child: that crashes the child, | ||
| # can report the parent's lock actors out of scope, and leaves the parent's GCS calls timing out. | ||
| global _state_lock, _table, _registry, _leases, _renewer_running, _managers, _owned | ||
| _inherited_after_fork.append((_owned, _managers, _leases)) | ||
| _state_lock, _table = threading.Lock(), {} | ||
| _registry, _leases, _renewer_running, _managers, _owned = threading.Condition(), {}, False, {}, [] | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be helpful to add a test for handles retained through
_leasesas well?