Skip to content

standalone-indexer (h24 line): bound, gate and retry /kv_recover downloads - #42

Draft
Shang-Pin wants to merge 3 commits into
dp-rank-watch-h24from
recover-hardening-h24
Draft

Shang-Pin wants to merge 3 commits into
dp-rank-watch-h24from
recover-hardening-h24

Conversation

@Shang-Pin

Copy link
Copy Markdown

Cherry-pick of #41 onto the h24 line (stacked on #40, base dp-rank-watch-h24). Two trivial both-sides-added conflicts in IndexerConfig and its CLI construction resolved by keeping both. Same change and tests; see #41 for the analysis and measurements.

🤖 Generated with Claude Code

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>
(cherry picked from commit 37e1b1a)
@Shang-Pin
Shang-Pin deployed to external_collaborator September 17, 2026 21:24 — with GitHub Actions Active
@github-actions github-actions Bot added the documentation Improvements or additions to documentation label Sep 17, 2026
@Shang-Pin

Copy link
Copy Markdown
Author

Validation (rustcheck:1.96 container, cargo test -p dynamo-kv-router --features kube-discovery standalone_indexer):

  • h24 line @ cbe6247: 57 passed, 1 failed. The failure was zmq_subscriber_connects_before_publisher_bind (pre-existing ZMQ socket test, 5s recv timeout under the parallel full-suite run). Rerun in isolation 3/3 passes on this branch and 3/3 on dp-rank-watch; it does not touch the recovery code path, so I am treating it as flaky.
  • Cherry-pick conflicts in mod.rs (IndexerConfig: h24 fields vs recover fields) and kv.rs resolved by keeping both.

Image built and pushed: localhost:30500/dynamo-indexer:kvtest-cbe6247d92. Not rolled out anywhere yet.

@Shang-Pin

Copy link
Copy Markdown
Author

Prod trial on frank/DeepSeek-V4.1-Flash kv-indexer:h24 (image kvtest-cbe6247d92, 2026-09-17 22:14 UTC): CrashLoopBackOff, 6 restarts in 10 min, exit 139, ~20 s after start while startup TreeDump recoveries were being applied (33 of 66 done, all successful, 3-26 s each). Last log line each time:

Assertion failed: _input_stopped (.../zeromq-src-0.2.6+4.3.4/vendor/src/stream_engine_base.cpp:417)

This is libzmq 4.3.4 zeromq/libzmq#3596 / ai-dynamo#3937: a slow receiver that hits its receive HWM while heartbeating is enabled. Our SUB sockets have heartbeats on and the default RCVHWM (1000). In h24 mode every listener applies its 270k-block dump under the single H24Indexer.inner mutex, so with recoveries now succeeding en masse the listeners stall long enough for the SUB queues to fill. The main-line image (reality/routing, #41) ran the same roll without restarts.

Rolled h24 back to kvtest-d57bab4a29. Follow-up commit: unbounded RCVHWM on the SUB socket so input is never stopped.

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>
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>
@Shang-Pin

Copy link
Copy Markdown
Author

Re-rolled frank/DeepSeek-V4.1-Flash kv-indexer:h24 on kvtest-05fee893c6 (this branch @ 05fee89, includes the RCVHWM=0 fix) at 22:48 UTC: 0 restarts, no assertion, 68/68 startup recoveries completed as TreeDumps, 0 retries, 0 parent misses. The earlier image crashed ~20 s after start every time.

Also in this push: indexer image: stamp archived sources with build time (05fee89). Two concurrent build-indexer-image.sh runs on different branches share the /cargo-target cache mount and git-archive mtimes let the second build reuse the first one's kv-router rlib (bindings failed with "IndexerConfig has no field named h24"). Tests on this branch: 59 passed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

container documentation Improvements or additions to documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant