harness: race in-flight unary model calls against cancellation#37
Conversation
The streaming path drops the provider call on cancel, but the unary path ran to completion and was billed. Race the wall-clock-bounded unary call against the run cancellation token (biased select!, mirroring the streaming branch), so a cancel mid-call drops the future and unwinds with Cancelled.
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 33 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThe unary (non-streaming) model invocation path now races the wall-clock budgeted call against cooperative cancellation via ChangesUnary cancellation fix and test
Estimated code review effort: 2 (Simple) | ~15 minutes Sequence Diagram(s)sequenceDiagram
participant RetryLoop as Model Call Retry Loop
participant BudgetWrapper as with_call_budget Future
participant Model as Model Provider
participant Cancellation as ctx.cancellation
RetryLoop->>BudgetWrapper: await budgeted invoke()
BudgetWrapper->>Model: invoke(request)
par racing
Cancellation-->>RetryLoop: cancelled() fires
and
Model-->>BudgetWrapper: response (in-flight)
end
alt cancellation fired first
RetryLoop->>RetryLoop: return TinyAgentsError::Cancelled
else budget future completes first
BudgetWrapper-->>RetryLoop: return response
end
Possibly related issues
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Comment |
collapsible_if in StreamAccumulator::push_tool_chunk and a duplicated #[cfg(test)] on the stream test module both fail CI's cargo clippy --all-targets -- -D warnings under rust 1.96. Behavior-neutral.
|
CI guardian: the |
Summary
In the model-call retry loop, the streaming branch races the provider call against the run's cancellation token, but the unary (non-streamed) branch did not — it awaited
model.invoke(...)bounded only by the wall-clock timeout. Cancelling a run during a long buffered call (structured-output extraction, summarizer sub-calls, any non-streaming provider) did not drop the in-flight request; it ran to completion and was billed until it returned or the deadline fired. Streaming turns cancelled promptly, unary turns didn't.Change
Race the wall-clock-bounded unary call against
ctx.cancellation.cancelled()with a biasedselect!(mirroring the streaming path), returningTinyAgentsError::Cancelledand dropping the future — reqwest cancels the underlying request. The pre-callis_cancelled()checkpoint still short-circuits before the request is issued.Tests
cancelled_during_unary_model_call_drops_the_in_flight_call: a model whose unaryinvokeblocks onfuture::pendingis cancelled mid-flight; without the race the run would hang (guarded by an outer 5s timeout), with it the run unwinds asCancelled.cargo fmt --check,cargo clippy --lib --tests -- -D warnings, andcargo test --liball pass.Closes tinyhumansai/openhuman#4635
Summary by CodeRabbit
Bug Fixes
Tests