Skip to content

Fix cache lock orphaned by a signal right after acquisition - #1227

Merged
theoephraim merged 2 commits into
mainfrom
fix-cache-lock-sigint-race
Oct 14, 2026
Merged

theoephraim merged 2 commits into
mainfrom
fix-cache-lock-sigint-race

Conversation

@theoephraim

@theoephraim theoephraim commented Oct 14, 2026 •

Copy link
Copy Markdown
Member

Fixes the flaky cache-lock-crossproc SIGINT test seen on CI.

withDirLock wrote owner.json before installing its signal handlers, so a SIGINT landing in that window hit the OS default action and left the lock dir behind. The test treats owner.json as "lock held" and signals immediately, so it occasionally hit the gap on loaded runners.

  • Register signal cleanup before acquiring, and track the lock in heldLocks right after mkdir. With a listener installed, signals are dispatched on the event loop, so mkdir + tracking can't be split.
  • Make the cleanup signal listeners persistent instead of once, detaching only right before re-raising. Previously a signal handled by another listener (e.g. a SIGHUP reload forwarder) consumed them, and later locks were held with no signal cleanup.
  • Write owner.json via temp file + rename so readers never see a partial file.
  • Test now waits on a marker written by the producer (which only runs inside the lock) instead of inferring readiness from owner.json.

Reproduced by injecting a 300ms delay after the owner write (fails at the same assertion as CI); with the fix it passes, and the test file passed 50/50 runs. Added a regression test for a handled signal followed by the same signal while a later lock is held (fails on the old once listeners).

Signal handlers were installed only after owner.json was written, so a
SIGINT in that window hit the default action and left the lock dir behind
(flaky cache-lock-crossproc SIGINT test on CI). Register cleanup before
acquiring, track the lock immediately after mkdir, and write owner.json
via temp file + rename. The test now waits on a marker written by the
producer instead of inferring readiness from owner.json.
@github-actions

github-actions Bot commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

bumpy-frog

The changes in this PR will be included in the next version bump.

patch Patch releases

  • @varlock/native-helper-darwin 1.23.0 → 1.23.1
  • @varlock/native-helper-linux-arm64 1.23.0 → 1.23.1
  • @varlock/native-helper-linux-x64 1.23.0 → 1.23.1
  • @varlock/native-helper-win32-x64 1.23.0 → 1.23.1
  • varlock 1.23.0 → 1.23.1

Bump files in this PR

Click here if you want to add another bump file to this PR


This comment is maintained by bumpy.

@github-actions

github-actions Bot commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

📦 Bundle size

⚠️ grows the bundle by 1.2 KB (+0.0%)

Metric main This PR Δ
Total dist 5077.5 KB 5078.8 KB +1.2 KB (+0.0%)
JS 1921.5 KB 1921.7 KB +0.2 KB (+0.0%)
Sourcemaps 3025.4 KB 3026.4 KB +1.0 KB (+0.0%)
Type defs 130.7 KB 130.7 KB —
Other 0.0 KB 0.0 KB —

dist/ only; native binaries are versioned separately and not counted here.

@pkg-pr-new

pkg-pr-new Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

varlock

npm i https://pkg.pr.new/varlock@1227

@varlock/native-helper-darwin

npm i https://pkg.pr.new/@varlock/native-helper-darwin@1227

@varlock/native-helper-linux-arm64

npm i https://pkg.pr.new/@varlock/native-helper-linux-arm64@1227

@varlock/native-helper-linux-x64

npm i https://pkg.pr.new/@varlock/native-helper-linux-x64@1227

@varlock/native-helper-win32-x64

npm i https://pkg.pr.new/@varlock/native-helper-win32-x64@1227

commit: ba930e9

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important

A handled signal during contention can consume cleanup before the lock is acquired, leaving the acquired lock unresponsive to subsequent occurrences of that signal.

Reviewed changes: Reviewed acquisition tracking, atomic owner metadata publication, and cross-process test synchronization.

  • Acquisition cleanup: Registers cleanup before attempting acquisition and tracks the lock immediately after mkdirSync.
  • Owner metadata: Publishes owner.json through a temporary file and rename.
  • Cross-process readiness: Waits for a producer-written marker before signaling the holder; all 16 focused cache-lock tests pass.
  • Release entry: Adds a varlock patch entry for interrupted lock acquisition.

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using gpt-6.1-sol | 𝕏

The cleanup listeners were one-shot, so a signal handled by another
listener (e.g. a SIGHUP reload forwarder) consumed them and later locks
were held with no signal cleanup. Use persistent listeners and detach
only right before re-raising.

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes: Reviewed the signal-cleanup lifecycle fix added since the previous review.

  • Kept cleanup armed: Replaced one-shot signal listeners with persistent listeners, detaching only before re-raising when no other handler remains.
  • Added regression coverage: Verified that a handled SIGHUP does not disable cleanup for a later lock. All 17 focused cache-lock tests pass, and a separate probe with createChildSignalForwarder() also confirms the original contention case is fixed.

Pullfrog  | View workflow run | Using gpt-6.1-sol | 𝕏

@theoephraim
theoephraim merged commit 4c23b47 into main Oct 14, 2026
28 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant