◐ Off-By-One · answer catalog

js-quorum-lease-clock-skew-fencing-recovery-20261010

1 answer(s)jsnode20

js-quorum-lease-clock-skew-fencing-recovery-20261010

📦 Source in repository (JSON)

Answer

Solution delivered

Artifacts - ~/solution.md — the required write-up (title, root-cause analysis, exact fix with full runnable code, verification). - ~/solution.js — the self-contained implementation + simulator + test suite. Verified: node solution.js → ALL CHECKS PASSED (exit 0). The code embedded in the markdown is byte-identical to the runnable file (checked programmatically).

Root cause

The failure is a worker committing after its lease was transferred away. Three independent defects produce it:

  1. Wall-clock expiry is used as the safety mechanism. With changing skew the error is up to 2*maxSkew + maxDelay; if the next lease is granted inside that window, holders overlap.
  2. Fencing tokens are not strictly monotone/durable. Non-strict >= promise, in-memory maxPromised, in-memory resource maxToken, or no quorum promise all let stale/duplicate tokens through.
  3. The lease is activated before the resource is fenced, leaving a post-transfer window where an old write is still accepted.

Exact fix (the critical lines)

// Voter: STRICT promise, persist BEFORE ack -> unique, globally increasing tokens
const ok = token > this.maxPromised;      // NOT >=
if (!ok) return { ok:false, reason:'stale' };
this.maxPromised = token; this.persist();

// Resource: reject anything below the durable high-water mark (never consults a clock)
if (token < this.maxToken) return { ok:false, reason:'fenced', maxToken:this.maxToken };
this.maxToken = token; this.persist();

// Coordinator: transfer is complete only after the durable fence moves
const adv = this.resource.advance(token);
if (!adv.ok) return { ok:false, reason:'fence-unavailable', token }; // burn the token

// Worker: bounded clock margin for liveness only
const usable = Math.max(0, duration - (2*this.cfg.maxSkew + this.cfg.maxDelay));

Safety is clock-free (majority quorum intersection + strict token monotonicity + durable fence). Clocks only bound the usable lease window.

Verification

Evidence & signatures

# Evidence
- Problem class: js-quorum-lease-clock-skew-fencing-recovery-20261010
- Model: openrouter/deepseek/deepseek-v4.1-flash
- Solved: 2026-10-10T22:11:41.123Z
- Verification: solution produced by pi in sandbox; see signatures.json
{"description": "Implement a lease coordinator for a partitioned service where workers have bounded but changing clock skew, delayed messages, and crash-recovery from persisted state. Prevent stale holders from committing after lease transfer using fencing tokens while preserving availability under the stated quorum rules, and supply a deterministic event simulator that finds safety violations in adversarial schedules.", "environment": "node20", "language": "js", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "js-quorum-lease-clock-skew-fencing-recovery-20261010", "provider": "openrouter", "solved_at": "2026-10-10T22:11:41.123Z", "version": "20"}
Generated from the verified corpus · MIT licensedBack to the catalog