Repository navigation
fix(peer): bound the relay history observer read and surface first-page stalls - #3587
Draft
Raing5Days wants to merge 1 commit into
Draft
Raing5Days wants to merge 1 commit into
Raing5Days wants to merge 1 commit into
Conversation
Relay history reads acquired the per-session mutation lease without a bound. The lease owner is the Session's own Turn, which holds it for the Turn's whole life, so a Turn blocked on an unanswered AskUserQuestion also blocked the read that lets a controller answer it. Wait briefly for the consistent window and fall back to persisted records instead. A stalled relay stream likewise left a controller Surface hydrating forever. The first page now has a timeout that reads the runtime interaction mailbox directly and leaves hydration; the subscription stays open, so a late page still applies.
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.
Summary
Fixes a controller-side deadlock that leaves a peer Surface stuck on a loading placeholder, with no answerable
AskUserQuestioncard.Root cause:
load_relay_session_selectionacquired the per-session mutation lease through an unboundedacquire_session_mutation. That lease is owned by the Session's own Turn for the Turn's whole life. When that Turn is blocked on an unansweredAskUserQuestion, a controller's firstread_streamwaits on the same lease, so the stream never becomes ready, the transcript and the question card never arrive, and the answer that would release the Turn can never be sent.coordinator.rs: the relay history observer read now waits a bounded window for the lease and otherwise projects the persisted records. It still refuses to project while an unfinished undo transition needs the lease, rather than returning rows that transition is about to replace.RelaySessionHistory.ts: opening no longer waits forever forrelay://session-ready. After a timeout it reads the runtime interaction mailbox directly, publishes a ready-but-empty page and leaves hydration; the live subscription stays open, so a late page still applies.RelaySessionHistory.test.ts: regression test for the overdue-first-page path.Validation
pnpm --dir src/web-ui run test:run src/flow_chat/services/RelaySessionHistory.test.ts— passed (7 tests)pnpm --dir src/web-ui run test:run src/flow_chat/store/FlowChatStore.test.ts src/flow_chat/services/RelaySessionHistory.test.ts src/flow_chat/services/flow-chat-manager/PeerSessionRefreshModule.test.ts— passed (277 tests)pnpm --dir src/web-ui run type-check— passedcargo check -p openbitfun-core --lib— passed, with two pre-existingdead_codewarnings inservice/config/service.rsandutil/errors.rsunrelated to this changepnpm run fmt:rs— appliedNot verified: an end-to-end two-device Peer session over an SSH workspace. The deadlock analysis is static, and the 1.5s lease wait is a judgement call that only the local reproduction can confirm.
Risks
OutcomeUnknowninstead of hanging. Controllers surface that as a failed history load rather than a spinner that never resolves.Generated with OpenBitFun