Skip to content

feat(kv-router): add standalone selector peer sync - #10745

Merged
PeaBrane merged 4 commits into
mainfrom
codex/standalone-selector-peer-sync
Jun 16, 2026
Merged

feat(kv-router): add standalone selector peer sync#10745
PeaBrane merged 4 commits into
mainfrom
codex/standalone-selector-peer-sync

Conversation

@PeaBrane

@PeaBrane PeaBrane commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add standalone selector startup recovery from HTTP indexer peers and expose a compatible /dump endpoint.
  • Synchronize admission, prefill-complete, and free lifecycle events between selector replicas over best-effort ZMQ. Output-block events remain local to avoid replica-sync bandwidth growth.
  • Configure selector and standalone slot-tracker synchronization with --replica-sync-port and optional startup --replica-sync-peers; add /replica_sync/register_peer, /replica_sync/deregister_peer, and /replica_sync/peers for dynamic in-memory membership.
  • Update /select and /select_and_reserve to return Mooncake-style token overlap summaries and effective_prefill_tokens; remove the redundant public cached_tokens and effective_overlap_blocks fields.
  • Allow /reservations to accept validated effective_prefill_tokens as the authoritative prefill-load hint while preserving the existing fallback when omitted.
  • Share tiered-overlap conversion, weighted cache credit, effective-prefill calculation, reservation-hint construction, and common ZMQ/replica-sync service code so integrated and standalone routing use the same accounting semantics.
  • Document the Ray select-then-reserve flow, peer-plane distinction, dynamic peer APIs, deployment configuration, and best-effort consistency invariants.

Validation

  • cargo test --no-default-features --features standalone-selection,standalone-slot-tracker services::
  • cargo clippy --no-deps --all-targets --features standalone-selection,standalone-slot-tracker -- -D warnings
  • cargo test --no-default-features --features standalone-indexer services::indexer
  • cargo clippy --no-deps --all-targets --features standalone-indexer -- -D warnings
  • Python binding Clippy with select-service and slot-tracker
  • cargo fmt --check
  • git diff --check

Signed-off-by: PeaBrane <yanrpei@gmail.com>
@PeaBrane
PeaBrane requested a review from a team as a code owner June 16, 2026 06:56
@PeaBrane
PeaBrane requested a review from a team June 16, 2026 06:56
@github-actions github-actions Bot added feat documentation Improvements or additions to documentation router Relates to routing, KV-aware routing, etc. labels Jun 16, 2026

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 1 potential issue.

Open in Devin Review

Comment thread lib/kv-router/src/services/selection/server.rs
@github-actions

github-actions Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

@coderabbitai

coderabbitai Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Walkthrough

Introduces a standalone-selection service feature with ZMQ-based replica synchronization. Refactors effective_prefill_tokens into a shared helper propagated across all scheduling callsites. Consolidates overlap computation (CacheHitEstimates, MooncakeOverlapSummary) into dedicated modules. Updates SelectResponse and ReservationRequest API shapes. Adds comprehensive documentation for the new standalone selection service.

Changes

Standalone Selection Service, Replica Sync, and Overlap Refactor

Layer / File(s) Summary
effective_prefill_tokens helper extraction and propagation
lib/kv-router/src/scheduling/prefill_load.rs, lib/kv-router/src/scheduling/mod.rs, lib/kv-router/src/scheduling/local.rs, lib/kv-router/src/scheduling/queue.rs, lib/kv-router/src/scheduling/selector.rs, lib/kv-router/src/scheduling/types.rs, lib/llm/src/kv_router.rs
Adds effective_prefill_tokens, prefill_load_hint_from_effective_tokens, and InvalidEffectivePrefillTokens in prefill_load.rs, re-exports them via scheduling/mod.rs, and replaces multiple inline saturating_sub/checked_sub patterns across all scheduling callsites.
Overlap computation consolidation
lib/kv-router/src/scheduling/overlap.rs, lib/kv-router/src/services/overlap.rs, lib/kv-router/src/services/indexer/server.rs, lib/kv-router/src/services/selection/scoring.rs, lib/llm/src/kv_router/scheduler_inputs.rs
Creates scheduling/overlap.rs with CacheHitEstimates and tier_overlap_blocks_from_tiered_matches. Creates services/overlap.rs with MooncakeOverlapSummary and build_mooncake_overlap_summaries. Removes duplicate local implementations from scoring.rs and scheduler_inputs.rs. Updates indexer/server.rs to use build_mooncake_overlap_summaries for ScoreResponse.instances.
Replica sync generalization: ScopedReplicaEvent and callback-based PeerManager
lib/kv-router/src/services/replica_sync.rs, lib/kv-router/src/services/mod.rs, lib/kv-router/src/services/slot_tracker/..., lib/kv-router/src/services/zmq.rs
Replaces SlotReplicaEvent with ScopedReplicaEvent, makes PeerManager::start generic over a callback instead of taking a registry, moves replica_sync to a shared service module, updates slot-tracker to use closure-based dispatch, and broadens ZMQ feature gating to include standalone-selection.
Selection HTTP API types: SelectResponse, ReservationRequest, NormalizedReservation
lib/kv-router/src/services/selection/types.rs, lib/kv-router/src/services/selection/input.rs, lib/kv-router/src/services/selection/README.md
Replaces effective_overlap_blocks/cached_tokens in SelectResponse with overlap: MooncakeOverlapSummary and effective_prefill_tokens: usize. Adds effective_prefill_tokens: Option<usize> to ReservationRequest and isl_tokens to NormalizedReservation. Condenses README to invariants and external doc pointer.
SelectionCore: replica wiring, scheduling refactor, and server startup
lib/kv-router/src/services/selection/core/mod.rs, lib/kv-router/src/services/selection/server.rs
Extends SelectionServiceConfig with indexer/replica-sync fields, adds SelectionCore::new_for_server with optional replica runtime wiring, refactors select/select_and_reserve through SelectionOperation/schedule_selection to produce richer SelectResponse, updates create_reservation to derive prefill_load_hint from effective_prefill_tokens, and wires PeerManager plus a /dump endpoint in run_server.
CLI bindings and selection service tests
lib/bindings/python/rust/llm/kv.rs, lib/kv-router/src/services/selection/tests.rs
Adds --indexer-peers, --replica-sync-bind, --replica-sync-advertise, --replica-sync-peers to SelectServiceCli and forwards them into SelectionServiceConfig. Updates test assertions for new response fields, adds invalid-reservation rejection test, and adds a full multi-core replica sync lifecycle integration test.
Documentation and inline comments
docs/components/router/standalone-selection.md, docs/components/router/standalone-slot-tracker.md, docs/components/router/README.md, docs/components/router/router-guide.md, docs/index.yml, lib/kv-router/src/protocols.rs, lib/kv-router/src/sequences/multi_worker.rs
Adds the full 251-line standalone selection service user guide with CLI, API, peer-plane, and invariant documentation. Adds nav entries in index, README, and router guide. Adds inline comments to protocols and multi-worker clarifying intentional replica-sync exclusion for output blocks.

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 36.78% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly identifies the main change: adding standalone selector peer sync functionality to the kv-router component.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The PR description is comprehensive and covers all key aspects: features added (startup recovery, replica sync, new APIs), validation steps, and implementation details.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (4)
lib/kv-router/src/services/selection/tests.rs (1)

587-588: ⚡ Quick win

Make the local-only output-block assertion time-bounded, not snapshot-based.

A single 50ms sleep plus one assert_core_load can miss a delayed replica event, so this test may still pass if output-block replication is accidentally queued later. Assert the remote core stays unchanged for a short bounded window.

Suggested test tightening
-    tokio::time::sleep(Duration::from_millis(50)).await;
-    assert_core_load(&core_b, 1, 1, 4);
+    assert_core_load_stays(&core_b, 1, 1, 4, Duration::from_millis(100)).await;

Add a helper near the existing load helpers:

async fn assert_core_load_stays(
    core: &SelectionCore,
    expected_requests: usize,
    expected_blocks: usize,
    expected_tokens: usize,
    duration: Duration,
) {
    let deadline = tokio::time::Instant::now() + duration;
    loop {
        assert_core_load(core, expected_requests, expected_blocks, expected_tokens);
        if tokio::time::Instant::now() >= deadline {
            break;
        }
        tokio::time::sleep(Duration::from_millis(10)).await;
    }
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/kv-router/src/services/selection/tests.rs` around lines 587 - 588,
Replace the snapshot-based assertion with a time-bounded assertion that ensures
the core state remains stable over a duration window. Add a new helper function
assert_core_load_stays that takes a SelectionCore reference, expected values for
requests, blocks, and tokens, and a Duration parameter. This helper should loop
from the current time until the deadline (current time plus the duration),
repeatedly calling the existing assert_core_load function and sleeping briefly
between iterations. Then replace the current tokio::time::sleep call followed by
a single assert_core_load call for core_b with a call to assert_core_load_stays
passing the expected values (1, 1, 4) and an appropriate duration to catch
delayed replica events.
lib/kv-router/src/services/selection/scoring.rs (1)

7-10: ⚡ Quick win

Use the hot-path map type for mooncake_summaries.

mooncake_summaries is a private selection input keyed by numeric WorkerId; use the project’s FxHashMap convention here, while keeping standard maps for text-keyed wire responses.

As per coding guidelines, "lib/kv-router/**/*.rs: Use FxHashMap / FxHashSet when possible for internal numeric keys and hot paths in lib/kv-router."

Also applies to: 14-19

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/kv-router/src/services/selection/scoring.rs` around lines 7 - 10, The
mooncake_summaries map uses a standard map type for numeric WorkerId keys on a
hot path, which should use the faster FxHashMap per project conventions for
numeric keys in lib/kv-router. Replace the map type used for mooncake_summaries
with FxHashMap while keeping standard maps for any text-keyed wire responses.
This change should be applied to the mooncake_summaries declaration and any
similar internal numeric-keyed maps in the same scope.

Source: Coding guidelines

lib/kv-router/src/scheduling/overlap.rs (2)

4-15: ⚡ Quick win

Use FxHashMap for new internal numeric worker-keyed hot-path maps. The shared issue is that the new overlap/selection maps are keyed by numeric worker identifiers in lib/kv-router, but use standard HashMap.

  • lib/kv-router/src/scheduling/overlap.rs#L4-L15: change CacheHitEstimates.effective_overlap_blocks and CacheHitEstimates.cached_tokens to the project-standard FxHashMap type.
  • lib/kv-router/src/services/selection/scoring.rs#L7-L19: change OverlapInputs.mooncake_summaries to the same FxHashMap type.

As per coding guidelines, "lib/kv-router/**/*.rs: Use FxHashMap / FxHashSet when possible for internal numeric keys and hot paths in lib/kv-router."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/kv-router/src/scheduling/overlap.rs` around lines 4 - 15, Replace
standard HashMap with FxHashMap for numeric worker-keyed hot-path maps in both
affected locations. In lib/kv-router/src/scheduling/overlap.rs (lines 4-15),
change the type of CacheHitEstimates.effective_overlap_blocks and
CacheHitEstimates.cached_tokens fields from HashMap to FxHashMap. In
lib/kv-router/src/services/selection/scoring.rs (lines 7-19), change the type of
OverlapInputs.mooncake_summaries field from HashMap to FxHashMap. Ensure
FxHashMap is imported from the appropriate crate (typically rustc_hash or
similar) in both files.

Source: Coding guidelines


4-4: ⚡ Quick win

Use FxHashMap for worker-keyed overlap estimates.

These new maps are keyed by internal numeric WorkerWithDpRank values on the overlap/scheduling path, so they should follow the lib/kv-router hot-path collection guidance instead of standard HashMap.

As per coding guidelines, "lib/kv-router/**/*.rs: Use FxHashMap / FxHashSet when possible for internal numeric keys and hot paths in lib/kv-router."

Also applies to: 13-15, 23-24

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/kv-router/src/scheduling/overlap.rs` at line 4, Replace the HashMap
import with FxHashMap from the appropriate module at the import statement. Then,
replace all usages of HashMap with FxHashMap throughout the overlap.rs file,
particularly in the worker-keyed overlap estimate structures. Since these maps
use internal numeric WorkerWithDpRank keys on the hot scheduling path, they must
follow lib/kv-router guidelines by using FxHashMap instead of the standard
HashMap for better performance. The comment indicates this change applies at
multiple locations (lines 13-15 and 23-24 in addition to the import), so ensure
all HashMap references keyed by WorkerWithDpRank or used in hot-path code are
updated to FxHashMap.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/components/router/standalone-selection.md`:
- Around line 170-178: The reservation example in the `/reservations` request
body shows effective_prefill_tokens set to 4, but the `/select` response example
returns effective_prefill_tokens: 384. Since the documentation instructs to pass
the exact value from the `/select` response into the `/reservations` call,
update the effective_prefill_tokens value in this reservation example from 4 to
384 to demonstrate the correct forwarding of the value and maintain consistency
across the examples.

In `@docs/components/router/standalone-slot-tracker.md`:
- Around line 77-79: Remove the NOTE paragraph about output-block updates not
being replica-synchronized from the standalone-slot-tracker.md file (the text
spanning lines 77-79 that begins with "NOTE: Output-block updates remain
local..."). This note is redundant since the file already states that slot
tracker excludes output-block updates. If the bandwidth caveat is considered
important documentation, move it to the standalone-selection.md file instead,
but the primary action is to delete this redundant paragraph from the current
location.

---

Nitpick comments:
In `@lib/kv-router/src/scheduling/overlap.rs`:
- Around line 4-15: Replace standard HashMap with FxHashMap for numeric
worker-keyed hot-path maps in both affected locations. In
lib/kv-router/src/scheduling/overlap.rs (lines 4-15), change the type of
CacheHitEstimates.effective_overlap_blocks and CacheHitEstimates.cached_tokens
fields from HashMap to FxHashMap. In
lib/kv-router/src/services/selection/scoring.rs (lines 7-19), change the type of
OverlapInputs.mooncake_summaries field from HashMap to FxHashMap. Ensure
FxHashMap is imported from the appropriate crate (typically rustc_hash or
similar) in both files.
- Line 4: Replace the HashMap import with FxHashMap from the appropriate module
at the import statement. Then, replace all usages of HashMap with FxHashMap
throughout the overlap.rs file, particularly in the worker-keyed overlap
estimate structures. Since these maps use internal numeric WorkerWithDpRank keys
on the hot scheduling path, they must follow lib/kv-router guidelines by using
FxHashMap instead of the standard HashMap for better performance. The comment
indicates this change applies at multiple locations (lines 13-15 and 23-24 in
addition to the import), so ensure all HashMap references keyed by
WorkerWithDpRank or used in hot-path code are updated to FxHashMap.

In `@lib/kv-router/src/services/selection/scoring.rs`:
- Around line 7-10: The mooncake_summaries map uses a standard map type for
numeric WorkerId keys on a hot path, which should use the faster FxHashMap per
project conventions for numeric keys in lib/kv-router. Replace the map type used
for mooncake_summaries with FxHashMap while keeping standard maps for any
text-keyed wire responses. This change should be applied to the
mooncake_summaries declaration and any similar internal numeric-keyed maps in
the same scope.

In `@lib/kv-router/src/services/selection/tests.rs`:
- Around line 587-588: Replace the snapshot-based assertion with a time-bounded
assertion that ensures the core state remains stable over a duration window. Add
a new helper function assert_core_load_stays that takes a SelectionCore
reference, expected values for requests, blocks, and tokens, and a Duration
parameter. This helper should loop from the current time until the deadline
(current time plus the duration), repeatedly calling the existing
assert_core_load function and sleeping briefly between iterations. Then replace
the current tokio::time::sleep call followed by a single assert_core_load call
for core_b with a call to assert_core_load_stays passing the expected values (1,
1, 4) and an appropriate duration to catch delayed replica events.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 3b352a0e-7224-4be7-a3e4-e30957a42591

📥 Commits

Reviewing files that changed from the base of the PR and between 7e28276 and 5ea3d18.

📒 Files selected for processing (32)
  • docs/components/router/README.md
  • docs/components/router/router-guide.md
  • docs/components/router/standalone-selection.md
  • docs/components/router/standalone-slot-tracker.md
  • docs/index.yml
  • lib/bindings/python/rust/llm/kv.rs
  • lib/kv-router/src/protocols.rs
  • lib/kv-router/src/scheduling/local.rs
  • lib/kv-router/src/scheduling/mod.rs
  • lib/kv-router/src/scheduling/overlap.rs
  • lib/kv-router/src/scheduling/prefill_load.rs
  • lib/kv-router/src/scheduling/queue.rs
  • lib/kv-router/src/scheduling/selector.rs
  • lib/kv-router/src/scheduling/types.rs
  • lib/kv-router/src/sequences/multi_worker.rs
  • lib/kv-router/src/services/indexer/server.rs
  • lib/kv-router/src/services/mod.rs
  • lib/kv-router/src/services/overlap.rs
  • lib/kv-router/src/services/replica_sync.rs
  • lib/kv-router/src/services/selection/README.md
  • lib/kv-router/src/services/selection/core/mod.rs
  • lib/kv-router/src/services/selection/input.rs
  • lib/kv-router/src/services/selection/scoring.rs
  • lib/kv-router/src/services/selection/server.rs
  • lib/kv-router/src/services/selection/tests.rs
  • lib/kv-router/src/services/selection/types.rs
  • lib/kv-router/src/services/slot_tracker/mod.rs
  • lib/kv-router/src/services/slot_tracker/registry.rs
  • lib/kv-router/src/services/slot_tracker/server.rs
  • lib/kv-router/src/services/zmq.rs
  • lib/llm/src/kv_router.rs
  • lib/llm/src/kv_router/scheduler_inputs.rs

Comment thread docs/components/router/standalone-selection.md
Comment thread docs/components/router/standalone-slot-tracker.md Outdated
Signed-off-by: PeaBrane <yanrpei@gmail.com>
Signed-off-by: PeaBrane <yanrpei@gmail.com>
Signed-off-by: PeaBrane <yanrpei@gmail.com>
@PeaBrane
PeaBrane merged commit d1a3029 into main Jun 16, 2026
95 checks passed
@PeaBrane
PeaBrane deleted the codex/standalone-selector-peer-sync branch June 16, 2026 15:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation feat router Relates to routing, KV-aware routing, etc. size/XXL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants