Skip to content

fix(flowcontrol): add bounded request drop summaries#2132

Merged
LukeAVanDrie merged 6 commits into
llm-d:mainfrom
ishwar170695:flow-control-log-pass
Jul 24, 2026
Merged

fix(flowcontrol): add bounded request drop summaries#2132
LukeAVanDrie merged 6 commits into
llm-d:mainfrom
ishwar170695:flow-control-log-pass

Conversation

@ishwar170695

Copy link
Copy Markdown
Contributor

What type of PR is this?
/kind cleanup

What this PR does / why we need it:
This PR addresses the logging improvements tracked in #2101 by:

  • adding bounded periodic summaries of non-dispatched request outcomes at V(DEFAULT) during processor cleanup sweeps while preserving per-request drop logs at V(VERBOSE)
  • adding requestIDs to ManagedQueue cleanup and drain debug logs
  • unifying structured error keys to err
  • extending pool-empty rejection logs with queue capacity context
  • adding unit tests covering drop accounting and periodic summary behavior

Which issue(s) this PR fixes:
Fixes #2101

Release note:

Added periodic aggregate summary logging for flow control request drops.

Signed-off-by: Ishwar <ishwarcm@iitbhilai.ac.in>
Copilot AI review requested due to automatic review settings July 22, 2026 06:59
@ishwar170695
ishwar170695 requested review from a team, LukeAVanDrie and shmuelk as code owners July 22, 2026 06:59
@ishwar170695
ishwar170695 requested review from liu-cong and vMaroon July 22, 2026 06:59

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@github-actions github-actions Bot added size/L Denotes a PR that changes 100-499 lines, ignoring generated files. kind/cleanup labels Jul 22, 2026

@LukeAVanDrie LukeAVanDrie 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.

Thanks! This is almost ready, I just flagged some small edge cases in outcome accounting that should all be small fixes.

Non-blocking, but there is also no test for the sweep path (sweepFinalizedItems -> recordDrop), which is the main channel for TTL/cancellation drops.

We could also consider labeling by priority in the log summary (since this is cardinality bound). Per-flow is probably not worth it. Up to your discretion as I think it is already okay in its current state.

// Finalize buffered items.
item.FinalizeWithOutcome(types.QueueOutcomeRejectedOther,
fmt.Errorf("%w: %w", types.ErrRejected, types.ErrFlowControllerNotRunning))
p.recordDrop(types.QueueOutcomeRejectedOther)

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.

Everything recorded here and in evictAll() is never flushed. The only flushDropSummary() call site is the sweep ticker, and runCleanupSweep exits on the same ctx.Done() that drives us into shutdown(). The shutdown evictions, plus anything accumulated since the last tick, are counted and then silently discarded.

We can add a final flush at the end of shutdownOnce.Do, after p.evictAll() returns (as the worker pool's wg.Wait() inside processAllQueuesConcurrently guarantees all recordDrop calls have landed by then):

p.evictAll()
p.flushDropSummary()

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.

Done. Added a final flushDropSummary() after evictAll() in shutdown() so any outcomes accumulated since the last sweep (including shutdown evictions) are emitted before exit.

// Finalization is idempotent; safe to call even if already finalized externally.
// The per-request log is emitted by EnqueueAndWait when it unblocks.
item.FinalizeWithOutcome(outcome, errShutdown)
p.recordDrop(outcome)

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.

FinalizeWithOutcome is a sync.Once no-op when the item was already finalized externally, but this line unconditionally records the hardcoded EvictedOther. An item that actually finished as EvictedTTL or
EvictedContextCancelled (finalized by the controller but not yet swept when shutdown drains the queue) gets counted under the wrong bucket.

We can record the authoritative outcome instead (guaranteed non-nil after the finalize call):

Suggested change
p.recordDrop(outcome)
p.recordDrop(item.FinalState().Outcome)

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.

Updated this to record item.FinalState().Outcome so externally finalized items retain their authoritative outcome instead of always being counted as EvictedOther.

if finalState := outcome; finalState != nil {
p.logger.V(logutil.TRACE).Info("Item finalized externally before processing, discarding.",
"outcome", finalState.Outcome, "err", finalState.Err, "flowKey", key, "requestID", req.ID())
return

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.

Every terminal branch in enqueue() now records its drop except this early return for items finalized externally while buffered in enqueueChan. Those items never enter a queue, so the sweep can't count them either; they're absent from the summary entirely.

Maybe unlikely to trigger in practice, but we can harden against this by adding p.recordDrop(finalState.Outcome) to that branch.

You already guard against Dispatched/NotYetFinalized in recordDrop so this should be safe.

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.

Added p.recordDrop(finalState.Outcome) to this early-return path so externally finalized items contribute to the aggregate summary as well.

return
case <-ticker.C():
p.sweepFinalizedItems()
p.flushDropSummary()

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.

note: this binds log frequency to the expiry cleanup interval (1s); that coupling seems reasonable to me and probably doesn't warrant an independent ticker

Signed-off-by: Ishwar <ishwarcm@iitbhilai.ac.in>
@ishwar170695

Copy link
Copy Markdown
Contributor Author

Non-blocking, but there is also no test for the sweep path (sweepFinalizedItems -> recordDrop), which is the main channel for TTL/cancellation drops.

Added a test covering the sweep path by verifying that an externally finalized item increments the corresponding drop counter when swept.

LukeAVanDrie
LukeAVanDrie previously approved these changes Jul 24, 2026

@LukeAVanDrie LukeAVanDrie 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.

lgtm

@LukeAVanDrie

Copy link
Copy Markdown
Contributor

Once the linter issue is resolved, I can merge this

Signed-off-by: Ishwar <ishwarcm@iitbhilai.ac.in>
@ishwar170695

Copy link
Copy Markdown
Contributor Author

Once the linter issue is resolved, I can merge this

Fixed.

LukeAVanDrie
LukeAVanDrie previously approved these changes Jul 24, 2026
@LukeAVanDrie
LukeAVanDrie enabled auto-merge (squash) July 24, 2026 06:58
@LukeAVanDrie

Copy link
Copy Markdown
Contributor

Once the linter issue is resolved, I can merge this

Fixed.

Still tripping; can you run go fmt? That seems to be the issue

Signed-off-by: Ishwar <ishwarcm@iitbhilai.ac.in>
auto-merge was automatically disabled July 24, 2026 07:10

Head branch was pushed to by a user without write access

@ishwar170695

Copy link
Copy Markdown
Contributor Author

Once the linter issue is resolved, I can merge this

Fixed.

Still tripping; can you run go fmt? That seems to be the issue

Ran gofmt and pushed the fix.

@LukeAVanDrie
LukeAVanDrie merged commit 26df3f1 into llm-d:main Jul 24, 2026
34 of 46 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind/cleanup size/L Denotes a PR that changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Flow Control] [Graduation Blocker] Log quality pass; request drops visible at default verbosity

3 participants