Skip to content

fix(python): use weak per-object locks instead of stripes - #5039

Merged
dbrattli merged 3 commits into
fix/python-lock-stripesfrom
fix/python-lock-weak-values
Oct 4, 2026
Merged

dbrattli merged 3 commits into
fix/python-lock-stripesfrom
fix/python-lock-weak-values

Conversation

@dbrattli

@dbrattli dbrattli commented Oct 4, 2026 •

Copy link
Copy Markdown
Collaborator

The fixed stripes in #5035 can make distinct lock objects share an RLock, adding contention and potentially introducing lock dependencies into otherwise independent nested locking. Replace the stripes with a weak-value registry keyed by object identity.

Lookup and creation happen under a short registry guard. Each caller keeps a strong reference to its selected RLock while waiting and executing, so an active lock cannot disappear. The guard is released before acquisition and user code. Weak references target the locks, so arbitrary unhashable and non-weak-referenceable lock objects remain supported.

This changes the decision documented beside the implementation: there is no fixed capacity or stripe collision, and unused entries disappear when their lock references are released. Separate calls can recreate locks; this deliberately avoids adding a pool or manual reference counting. Remove the unused runtime MAX_LOCKS constant; the former stripe count belongs only to the collision regression helper, and the cleanup test uses its own iteration count.

The generated F# regressions now check that distinct objects which collided under the old stripe mapping acquire independently, that an active entry survives, and that idle entries are reclaimed after successful calls and exceptions. Existing contention, reentrancy, return-value, and exception tests remain.

Describe the child-timeout behavior directly in _start_child_timeout, removing the comment about a previous implementation.

Validation:

  • 2,399 .NET tests and 2,495 generated Python tests pass in an isolated worktree. Used the existing local Fable 5.19.0 compiler and a copied generated runtime with this PR's util.py, retaining the existing Rust extension.
  • After removing the obsolete runtime constant and test capacity interface, regenerated the tests and reran all six lock regressions successfully; focused Pyright and Ruff checks also pass with the same existing warning/export-list finding.
  • Restoring the former stripe identity mapping in an isolated Python process makes the new independence regression fail (Expected: False - Actual: True).
  • Pyright reports no errors in the changed runtime, helper, or generated TestMisc.py; the latter retains one existing TypeVar warning. Full generated checking reports the same 34 errors / 45 warnings reported by fix(python): share per-object locks and align StartChild timeouts #5035.
  • Ruff format, Ruff lint excluding the existing RUF022 export-list finding, source Fantomas, and git diff --check pass. The export-list finding was also verified against the parent version. Repository Fantomas policy excludes tests/**.
  • The full Python run emitted an async timer warning (Event loop is closed) outside the changed code, plus a generated syntax warning. All tests passed.

Targets fix/python-lock-stripes, the branch for #5035, so this PR shows only the proposed alternative.

@dbrattli
dbrattli marked this pull request as ready for review October 4, 2026 08:52
@dbrattli
dbrattli merged commit c065be3 into fix/python-lock-stripes Oct 4, 2026
8 checks passed
@dbrattli
dbrattli deleted the fix/python-lock-weak-values branch October 4, 2026 08:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant