feat: CEP-22 - progress-aware timeouts, transfer watchdog, and default flip#92
Merged
ContextVM-org merged 1 commit intoJun 15, 2026
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #87
Final PR for CEP-22. Completes the oversized transfer implementation with timeout semantics, the receiver-side watchdog, and flipping the feature on by default.
What's in this PR:
Progress-aware timeout reset - inbound oversized frames (start, chunks, accept) are forwarded as stripped progress notifications to the rmcp service loop, so the requester's idle timer resets on each chunk. Without this, any chunked response longer than the idle timeout would time out mid-transfer even with steady progress. The numeric progressToken type is preserved through the restore path (rmcp's watcher map is type-exact, Number(5) ≠ String("5")).
Per-transfer watchdog -
transfer_timeout_ms(default 300s) is now enforced. Both transports sweepremove_expired()on a timer, reaped slots are re-admittable by a fresh transfer.transfer_timeout_ms = 0disables the watchdog without instant-expiry semantics.Consumer helper -
PeerRequestOptionsExt::call_tool_with_options+progress_aware_options(idle, max_total)insrc/rmcp_transport/progress.rs. Without this, plaincall_toolruns withno_options()- no timeout at all. Defaults: 60s idle (matches the TS SDK's default request timeout), 300s max-total (mirrors the receiver watchdog'stransfer_timeout_ms).Default flip - oversized transfer is enabled by default, matching the TS SDK. Safe because the negotiation gates remain: the server only fragments for peers that advertise support, and the client only fragments token-carrying requests above the threshold.
9 new e2e tests in
tests/oversized_timeout_e2e.rscovering idle timeout reset, stalled-transfer expiry, max-total cap, token type preservation, accept forwarding, watchdog reaping (client + server), and default-on roundtrip. 10 conformance tests intests/conformance_cep22_wire_format.rsasserting the wire format matches the spec (frame shapes, camelCase fields, digest format, progress slots). 562 tests passing.Note: plain
call_toolhas no default timeout (rmcp fork behavior, not something rs-sdk controls). For oversized transfers, usecall_tool_with_optionswithprogress_aware_optionsto get idle + max-total timeouts with per-chunk reset.