Skip to content

feat(router): expose policy queue lifecycle operations - #15625

Closed
Harrilee wants to merge 1 commit into
mainfrom
harrli/router-policy-queue-lifecycle
Closed

Harrilee wants to merge 1 commit into
mainfrom
harrli/router-policy-queue-lifecycle

Conversation

@Harrilee

@Harrilee Harrilee commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Allow a host of Dynamo's native PolicyQueue to recover canceled or invalidated requests and retry blocked worker lanes without dispatching requests to extract them. This is the independent native-queue prerequisite extracted from #15240; it does not call AISimulate or change any AISimulate, Python, Rust, container, or release dependency.

  • Make the existing recheck_all_workers operation public. It marks blocked lanes for rechecking on the next pop_next call.
  • Add take_if, reusing existing class removal/accounting machinery to return ownership of matching entries. Retained entries keep their scheduling keys, deadlines and order; removal does not spend DRR credit. Empty classes retain the existing credit-reset behavior.
  • Document the backlog scan and unspecified returned order. Existing selector and SessionAffinity implementations are unchanged.

retain discards removed payloads, whereas cancellation/retry needs their ownership. Extracting through pop_next would perform dispatch and spend scheduling credit. Both methods remain useful without the replay consumer.

Validation

  • cargo test --locked -p dynamo-kv-router scheduling::policy_queue::tests --lib: 26 passed, including deadline/accounting/credit preservation, ownership transfer across classes, and existing blocked-worker recheck regressions.
  • rustfmt --check --edition 2024 lib/kv-router/src/scheduling/policy_queue.rs and git diff --check passed.
  • Only lib/kv-router/src/scheduling/policy_queue.rs changes; dependency manifests, lockfiles and Ops files are unchanged.

Where should the reviewer start?

PolicyQueue::take_if and its two contract tests in lib/kv-router/src/scheduling/policy_queue.rs.

Related Issues

Relates to #15240 (consumer follow-up) and AIC-1817.

AISimulate #307 has merged. The consumer in #15240 also requires AISimulate #306 and a subsequently published matching AISimulate wheel/crate version. This small PR is independently mergeable; it does not deliver the complete conversation-aware CLI feature. #15149 remains closed.

Summary by CodeRabbit

  • New Features
    • Queue entries can now be selectively removed across scheduling classes without dispatching them. Entries that remain keep their scheduling order and deadlines.
    • Worker rechecks are now available to callers outside the crate.

Signed-off-by: Harry Lee <harrli@nvidia.com>
@coderabbitai

coderabbitai Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

🧰 Additional context used
📚 Code guidelines (2)
lib/kv-router/src/scheduling/AGENTS.md — auto-discovered
lib/kv-router/AGENTS.md — auto-discovered

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: ai-dynamo/dynamo/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Enterprise
  • Run ID: 06e01669-a1a9-46c8-8786-7908fca4fd3e
📥 Commits

Reviewing files that changed from the base of the PR and between 519e735 and 5cadd92.

📒 Files selected for processing (1)
  • lib/kv-router/src/scheduling/policy_queue.rs

Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 11 remain after this review.


Walkthrough

The policy queue exposes recheck_all_workers and adds take_if to remove matching entries across classes. Tests check retained entry ordering and deadlines, DRR credit, queue counts, token statistics, and removal of non-Clone payloads.

Changes

Policy queue APIs

Layer / File(s) Summary
Queue operations and validation
lib/kv-router/src/scheduling/policy_queue.rs
recheck_all_workers is now public. The new take_if removes matching entries without dispatching them or spending DRR credit. Tests check retained queue state and accounting, including with non-Clone payloads.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~15 minutes

Merge Risk: ⚪ Minimal · up to 5cadd

This change exposes two policy queue operations and adds tests for them. No merge-blocking risk is apparent.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 77.78% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 9 functions across 1 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and clearly describes the policy queue lifecycle operations exposed by this change.
Description check ✅ Passed The description explains the changes, provides validation results, identifies where reviewers should start, and includes related issues. The Summary section covers the template’s overview and details,…
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.
  • Fix all pre-merge checks with AI
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

pub fn take_if(&mut self, mut predicate: impl FnMut(&T) -> bool) -> Vec<PolicyQueueEntry<T>> {
let mut removed = Vec::new();
for class_index in 0..self.classes.len() {
removed.extend(self.take_if_in_class(class_index, &mut predicate).0);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

take_if discards the removed_ready_head result from take_if_in_class. If a worker lane was marked blocked and this method removes that lane's head while retaining another entry, rebuild_worker_heads preserves the blocked marker and excludes the new head from candidate_worker_heads. Subsequent pop_next calls therefore return None even when the new head is dispatchable, until an unrelated worker recheck occurs. Recheck affected classes whenever removal changes a ready head.

🤖 AI Fix

Capture removed_ready_head for each class and schedule a blocked-worker recheck for that class before returning.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Confirmed: dropping removed_ready_head can strand the retained successor. I reproduced the case and checked a local recheck fix (27 queue tests passed). That fix is not in this public head. We are withdrawing these queue helpers because the corrected A/B/C boundary no longer needs them: #15631 exposes the native policy interface, AISimulate #306 consumes it, and the simplified #15240 removes this helper dependency. Closing this PR rather than merging the defective or unnecessary API.

pub fn take_if(&mut self, mut predicate: impl FnMut(&T) -> bool) -> Vec<PolicyQueueEntry<T>> {
let mut removed = Vec::new();
for class_index in 0..self.classes.len() {
removed.extend(self.take_if_in_class(class_index, &mut predicate).0);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

take_if discards the helper's removed_ready_head signal without scheduling a worker-lane recheck. If pop_next previously blocked an exact-worker lane because its head failed a request-dependent dispatch predicate, removing that head leaves the worker in blocked_workers; a dispatchable successor is then never examined until an unrelated recheck_all_workers call. Mark affected blocked lanes for lazy rechecking during removal and add a regression test covering blocked-head removal followed directly by pop_next.

🤖 AI Fix

Schedule a blocked-worker recheck whenever take_if removes a ready lane head so the next pop_next evaluates the retained successor.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Confirmed: dropping removed_ready_head can strand the retained successor. I reproduced the case and checked a local recheck fix (27 queue tests passed). That fix is not in this public head. We are withdrawing these queue helpers because the corrected A/B/C boundary no longer needs them: #15631 exposes the native policy interface, AISimulate #306 consumes it, and the simplified #15240 removes this helper dependency. Closing this PR rather than merging the defective or unnecessary API.

@Harrilee

Harrilee commented Oct 5, 2026

Copy link
Copy Markdown
Contributor Author

Superseded by #15631, which is the actual independent native-policy interface consumed by AISimulate #306. This PR only adds queue helpers used by the former #15240 implementation; it does not satisfy that provider boundary. The revised consumer removes its need for these helpers.

Closing this PR to keep the intended sequence: Dynamo #15631 (A) → AISimulate #306 (B) → publish a matching AISimulate nightly → Dynamo #15240 (C). #307 is merged and #15149 remains closed. The blocked-head issue identified in review is valid; a local fix and regression were checked, but no fix was pushed to this now-withdrawn implementation.

@Harrilee Harrilee closed this Oct 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant