A released lock could come back as a ghost. `Lock::unlock` signalled the
background hold task and sent UnLock immediately; if the task had an
idempotent re-acquire RPC in flight, `race_stop` dropped the future
client-side but the server kept processing it — once UnLock had removed
the original lease, the same request_id re-WON the key with a fresh id
that no client held. On graylin prod that ghost writer sat on
`shutdown:pod:<id>:barrier` (created ~1 ms after "released :barrier
writer", then "lease_ttl pq has a removed node" and never reaped) and
parked every proxied request on the pod for the full 120 s restart wait.
- hold_loop no longer races the acquire RPC against stop; it lets the
RPC finish (bounded by HOLD_RPC_TIMEOUT), then honours a level
`stopped` flag and releases any lease it won while stopping.
- unlock() sets `stopped`, notifies, JOINS the hold task (abort only as
a backstop past every bound), then UnLocks the *current* id.
- Drop sets the flag and notifies but no longer aborts mid-RPC.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MCwe5Sf5NU8Ei13oqTcesj
Mirrors the new waymaker-server HllMultiAdd: one call writes several reserved
HLLs (e.g. a presence flush across scope/bucket sketches), returning per-entry
result codes. Vendored proto synced. Processed locally server-side for now
(multi-name batch can't ring-route).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add ttl: Option<Duration> to Hll/Bloom/Cms/TopK/TDigest configs; create_* sends
ttl_ms (0 = never). For time-bucketed sketch keys (rolling-window cardinality
etc.) the server auto-evicts, so callers don't hand-purge old buckets.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Extract the waymaker client into a standalone, polyglot repo versioned in
lockstep with the waymaker server (this tag == server v0.1.27).
- proto/ vendored client-facing protos (source of truth: waymaker repo).
internal_proxy (server-internal ProxyService + replication) is
intentionally excluded — it is a server concern, not a client one.
- rust/ standalone crate; build.rs generates from proto/. Quorum fence
scope + Lock auto-reacquire / fence-watch (watch/is_lost) API.
- go/ module git.awesomike.com/pub/waymaker-client/go — generated stubs
+ ergonomic wrappers (locks/streams/kv/collections/sketches/object).
- ts/ @waymaker/client — generated stubs + ergonomic wrappers.
- scripts/ sync-protos.sh (re-vendor + align VERSION) + gen-go.sh + gen-ts.sh.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>