Repository navigation
Fix cache lock orphaned by a signal right after acquisition - #1227
Conversation
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.
|
The changes in this PR will be included in the next version bump.
|
📦 Bundle size
dist/ only; native binaries are versioned separately and not counted here. |
varlock
@varlock/native-helper-darwin
@varlock/native-helper-linux-arm64
@varlock/native-helper-linux-x64
@varlock/native-helper-win32-x64
commit: |
There was a problem hiding this comment.
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.jsonthrough 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
varlockpatch entry for interrupted lock acquisition.
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.
There was a problem hiding this comment.
✅ 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
SIGHUPdoes not disable cleanup for a later lock. All 17 focused cache-lock tests pass, and a separate probe withcreateChildSignalForwarder()also confirms the original contention case is fixed.
gpt-6.1-sol | 𝕏



Fixes the flaky
cache-lock-crossprocSIGINT test seen on CI.withDirLockwroteowner.jsonbefore installing its signal handlers, so a SIGINT landing in that window hit the OS default action and left the lock dir behind. The test treatsowner.jsonas "lock held" and signals immediately, so it occasionally hit the gap on loaded runners.heldLocksright aftermkdir. With a listener installed, signals are dispatched on the event loop, so mkdir + tracking can't be split.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.owner.jsonvia temp file + rename so readers never see a partial file.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
oncelisteners).