Skip to content

fix: the framework lock is a queue of owned tickets - #376

Merged
TheAmericanMaker merged 2 commits into
mainfrom
fix/lock-tickets
Sep 16, 2026
Merged

TheAmericanMaker merged 2 commits into
mainfrom
fix/lock-tickets

Conversation

@TheAmericanMaker

Copy link
Copy Markdown
Member

Summary

Closes #355. Verified before changing: the issue's two claims are true of main by construction — withRemovalLock broke a stale .break with a bare rm (the same race #344 fixed one level up), and acquireLock broke any lock older than STALE_LOCK_MS with no way for a live holder to say it was still there. The new "live holder past staleMs keeps the lock" test cannot pass on the old design.

The redesign replaces the shared file with owned tickets (Lamport's bakery on a filesystem):

Test plan

  • tests/state-store.test.mjs, rewritten lock section: a live holder older than staleMs is not broken (the waiter times out instead); a dead owner's ticket is removed at once and a hung one's after staleMs, with brokeStale recorded; release removes only the releaser's ticket ([self-audit D-H5] Status lock release removes whoever's lock is present, including a newer holder's #227 kept); eight waiters behind a dead ticket — one holder at a time, all served, exactly one breaker, nothing left behind; a dead chooser's marker is cleared and a live one blocks until withdrawn; a fresh legacy lock blocks and a stale one is removed. Run four times, stable.
  • npm run build + npm test — 923 pass (the concurrent-publish, usage-append, and completion-commit tests exercise the lock through its callers).

🤖 Generated with Claude Code

TheAmericanMaker and others added 2 commits September 15, 2026 21:29
One shared lock file, broken by removing and re-creating its path, is a
race between any two waiters that saw it stale (#344 closed one level of
it and left the next), and a fixed 60 s age broke live holders — a publish
across a full reindex reopened the version race #240 fixed. Each waiter now
owns a ticket beside the lock, refreshed on a timer while it waits and
holds; the holder is the first ticket whose owner is alive and refreshing;
a dead owner's ticket is removed at once and a hung one's after
STALE_LOCK_MS, each by its own unique name. Lamport's doorway keeps a
waiter from being overtaken between taking its number and writing it. A
pre-existing plain lock file is honoured while fresh.

Closes #355

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@TheAmericanMaker
TheAmericanMaker merged commit 358623f into main Sep 16, 2026
5 checks passed
@TheAmericanMaker
TheAmericanMaker deleted the fix/lock-tickets branch September 16, 2026 01:30
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.

Stale-lock breaking is racy by construction and breaks live long holders

1 participant