Conversation
A listener that detects a gap fetches the worker's dump with a reqwest client whose total timeout was 10 s, and a failed fetch was final: the live batch that revealed the gap then advanced the watermark past it, so the missed range was lost for good. On DeepSeek-V4.1-Flash engines (DP=2, 28M-token KV pools) a TreeDump is ~70 MB serialized inside EngineCore. When three indexer flavors started against 39 such pods, each engine got six concurrent dump requests, a third of them ran past 10 s, the indexer logged "error decoding response body", the engine logged BrokenPipeError in kv_events.py do_GET, and the affected listeners carried orphaned chains (ParentBlockNotFound floods) from then on. - --recover-timeout-secs (default 120) replaces the hard-coded 10 s; connect timeout stays short at 5 s. - --recover-concurrency (default 8): a process-wide semaphore around the download, so a fleet-wide (re)subscription queues instead of stampeding every engine. - A failed download is retried up to 3 times with 2 s / 4 s backoff before the gap is given up; the final failure keeps the "kv_recover request failed" substring ops already grep for. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Validation (rustcheck:1.96 container,
Image built and pushed: |
A listener blocked in /kv_recover (now up to 120 s with the gate) can let its SUB pipe hit the default RCVHWM of 1000. With heartbeats enabled libzmq 4.3.4 then aborts on `Assertion failed: _input_stopped` (zeromq/libzmq#3596, ai-dynamo#3937). Hit in prod on frank/DeepSeek-V4.1-Flash kv-indexer:h24: 6 restarts in 10 min while 66 startup TreeDumps were applied under the single H24Indexer mutex. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
Prod trial on frank/DeepSeek-V4.1-Flash kv-indexer:reality and :routing (image kvtest-37e1b1a26b, 22:14 UTC): both pods healthy, 0 restarts. Indexer coverage of the engine's resident tree on the three (pod, dp_rank) units that were at 8-16% before the roll is now 100% (108/108, 113/113, 111/111 sampled chains fully present). reality_best moved from 0.83 to 0.86 = perfect within 12 min. Added ae7403c: unbounded RCVHWM on the SUB sockets. The h24 flavor of this change (#42) crash-looped on libzmq 4.3.4's |
Two concurrent build-indexer-image.sh runs on different branches share the /cargo-target cache mount. git archive gives every file the commit mtime, so the second build saw a kv-router rlib the first build had just written, judged it fresh, and failed compiling the bindings against a struct from the other branch. Touch the tree after extraction. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Stacked on #39 (base is
dp-rank-watch); this PR is the one commit37e1b1a26b.Why
A listener that detects a gap fetches the worker's dump with a reqwest client whose total timeout was hard-coded to 10 s, and a failed fetch was final: the live batch that revealed the gap then advanced the watermark past it, so the missed range was lost for good.
On DeepSeek-V4.1-Flash engines (DP=2, 28M-token KV pools) a TreeDump is about 70 MB, serialized inside EngineCore's
ThreadingHTTPServer. When the three indexer flavors were (re)started against frank's 39 pods, each engine received six concurrent dump requests; about a third ran past 10 s (reality 25/78, routing 5/78, h24 28/78). The indexer loggedkv_recover request failed ... error decoding response body, the engines loggedBrokenPipeErrorinkv_events.py do_GET, and the affected listeners carried orphaned chains (ParentBlockNotFoundfloods) from then on. Recreating one indexer pod at a time halved the contention but still lost 17 recoveries.What
--recover-timeout-secs(default 120) replaces the hard-coded 10 s total timeout; connect timeout stays short (5 s).--recover-concurrency(default 8): a process-wide semaphore around the download, so a fleet-wide (re)subscription queues rather than stampeding every engine. Live events buffer in the ZMQ SUB socket meanwhile, as they already do during recovery.kv_recover request failedsubstring that ops grep for, with an explicit "giving up, batches lost".docs.mdparagraph.Verification
cargo test -p dynamo-kv-router --features kube-discovery standalone_indexer: 51 passed.cargo fmt --checkon the crate only flags pre-existing drift inserver.rs, untouched here.🤖 Generated with Claude Code