Skip to content

fix(bridge): retake the transport when its owner dies later - #5

Merged
Sycatle merged 1 commit into
mainfrom
fix/reclaim-lock-late
Aug 11, 2026
Merged

fix(bridge): retake the transport when its owner dies later#5
Sycatle merged 1 commit into
mainfrom
fix/reclaim-lock-late

Conversation

@Sycatle

@Sycatle Sycatle commented Aug 11, 2026

Copy link
Copy Markdown
Member

Reclaiming a stale lock at startup was already right. The mistake was treating that one decision as final.

A daemon that lost the race stayed degraded for its whole life, even once the winner exited. health went on reporting owns: false and naming a dead PID, and the conflict message told the operator to close a session that was already closed.

How it surfaced

A second session hit it today: it removed the stale lock file and nothing changed, because the losing daemon had read that file once at boot and kept the verdict in memory. It ended up killing its own daemon and losing the transport until a human reconnected it — a self-inflicted outage caused entirely by the tool describing a competitor that no longer existed.

Same family as the three map-reading bugs fixed earlier today: not wrong about the bytes, wrong about what they designate.

The fix

status() re-attempts the acquisition whenever it does not hold the lock.

It deliberately does not test the recorded PID first. The acquisition is atomic (wx) and already refuses a live owner, so retrying blind is safe — and it covers what a liveness test misses: an owner that released the file cleanly while its process is still around. My first attempt did gate on isAlive, and the new test caught it.

Two negative controls, both watched red

  • Never reclaim → the late-death test fails.
  • Reclaim unconditionally → three tests fail, including the one asserting a live owner keeps the directory. That is the two-daemon failure this lock exists to prevent, and the reason the retry has to go through acquireTransportLock rather than around it.

132 tests.

Reclaiming a stale lock at startup was already right. The mistake was
treating that one decision as final: a daemon that lost the race stayed
degraded for its whole life, even once the winner exited. health went on
reporting owns:false and naming a dead PID, and the conflict message
told the operator to close a session that was already closed.

Observed today by a second session: it removed the stale lock file and
nothing changed, because the losing daemon had read it once at boot and
kept the verdict in memory. It ended up killing its own daemon and
losing the transport until a human reconnected it.

status() now re-attempts the acquisition whenever it does not hold the
lock. It does NOT test the recorded PID first: the acquisition is atomic
and already refuses a live owner, and retrying blind also covers what a
liveness test misses -- an owner that released the file cleanly while
its process is still around.

Two negative controls, both watched red. Never reclaiming leaves the
late-death test failing. Reclaiming unconditionally turns three red,
including the one asserting a live owner keeps the directory -- which is
the two-daemon failure this lock exists to prevent, and the reason the
blind retry has to go through acquireTransportLock rather than around it.
@Sycatle
Sycatle merged commit 2c11dd3 into main Aug 11, 2026
0 of 2 checks passed
@Sycatle
Sycatle deleted the fix/reclaim-lock-late branch August 11, 2026 15: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