feat(mls,bindings): bound resume_streams + return partial catch-up summary on deadline#3881
feat(mls,bindings): bound resume_streams + return partial catch-up summary on deadline#3881tylerhawkes wants to merge 1 commit into
Conversation
…mmary on deadline
|
Claude finished @tylerhawkes's task —— View job Code Review — July 21, 2026 22:00 UTCTodo List
SummaryThis PR successfully addresses two real robustness issues in the app-backgrounding lifecycle. The implementation is sound and well-designed. The timeout handling is cancel-safe, the partial-count accumulation correctly survives deadline cuts, and the test coverage validates the key properties. Detailed Review✅
|
| &self, | ||
| timeout: Option<Duration>, | ||
| ) -> Result<CatchUpSummary, CatchUpError> { | ||
| let deadline = timeout.map(|d| tokio::time::Instant::now() + d); |
There was a problem hiding this comment.
🟡 Medium subscriptions/catch_up.rs:221
catch_up_to_live computes the deadline with tokio::time::Instant::now() + d. When a caller passes an oversized Duration (e.g. derived from a large u64 millisecond value), the addition panics because the resulting Instant is not representable. Consider using checked_add and falling back to no deadline (or clamping) when the sum overflows.
| let deadline = timeout.map(|d| tokio::time::Instant::now() + d); | |
| let deadline = timeout.and_then(|d| tokio::time::Instant::now().checked_add(d)); |
🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @crates/xmtp_mls/src/subscriptions/catch_up.rs around line 221:
`catch_up_to_live` computes the deadline with `tokio::time::Instant::now() + d`. When a caller passes an oversized `Duration` (e.g. derived from a large `u64` millisecond value), the addition panics because the resulting `Instant` is not representable. Consider using `checked_add` and falling back to no deadline (or clamping) when the sum overflows.
ApprovabilityVerdict: Needs human review 1 blocking correctness issue found. An unresolved review comment identifies a potential panic when computing deadlines with oversized Duration values. This substantive bug concern should be addressed before approval. You can customize Macroscope's approvability policy. Learn more. |
Two robustness fixes to the app-backgrounding stream lifecycle, both patchable post-ship but worth landing before the surface freezes for the release.
resume_streamsis now bounded (10s)Previously it awaited reconnect with no deadline, so a foreground while offline could hang the caller — and the SDK's serial lifecycle reconciler — indefinitely (
join_allhangs on one wedged wire). It now returns after the deadline and logs; the background reconnect keeps retrying independently, so dropping the wait is safe.catch_up_to_livereturns partial counts on a deadlinePreviously a background-fetch that delivered N messages then hit its
timeout_msreportedmessages: 0(the FFI wrapped the future intokio::time::timeoutand threw away the accumulator), so the host reportednoDataand the OS throttled future background wakeups — despite N messages being persisted.The deadline now lives in the core loop (
catch_up_bidi), where the accumulated&mut summaryis owned and survives the cancelled attempt. CoreCatchUpSummarygains acompletedflag. The legacy fallback (a terminal store-diff, no partial to hand back) returnscompleted = false/ zero on the deadline, documented.Also regenerates
xmtpv3.swiftfor the updated FFI doc comments and flips the cancel-safe lifecycle test to assert partial counts.Verification
cargo check+ clippy — clean on the changed crates--features d14n🤖 Generated with Claude Code
Note
Bound
resume_streamsand return partial catch-up summary on deadlineresume_streamsnow times out after 10 seconds viatokio::time::timeout, returningOk(())while the reconnect continues in the background instead of awaiting it unboundedly.catch_up_to_liveaccepts an optionaltimeout: Option<Duration>; bidi catch-up returns partial counts withcompleted=falseon deadline, and legacy catch-up returns zeros withcompleted=falseon deadline.CatchUpSummarygains acompletedboolean field so callers can distinguish full runs from deadline-cut runs; the FFI converter now maps this field instead of hardcodingtrue.catch_up_to_livenow receive partial (non-zero) counts rather than zeroed counts when the deadline is hit.📊 Macroscope summarized 8f42e44. 3 files reviewed, 0 issues evaluated, 0 issues filtered, 0 comments posted
🗂️ Filtered Issues
No issues evaluated.