Repository navigation
fix(remote-connect): isolate host stream readers and recover live sync - #3877
Merged
Merged
Conversation
- Give every host stream reader its own optional subscription_id lease. A capable host echoes it and removes only that lease on unsubscribe, so a retired reader's late cleanup no longer cancels its replacement. Readers talking to older hosts skip cleanup and let the existing lease expire. - Retry a failed live read on a timer with capped backoff instead of sleeping inside the subscriber loop, also during older-page IO, and report recovery with a live ready event that does not complete an unrelated history page. - Tag desktop session events with a controller-local subscriptionId and mark retryable sync errors so a stale reader cannot fail its successor. - Install hint and reconnect listeners before the opening read in the shared TS and KMP readers so a final hint during that read is not lost. - HarmonyOS stream cleanup keeps the socket it opened, so closing after an account switch cannot touch the new account's connection.
3 tasks done
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
Make remote session streams survive retired readers and transient read failures, across the host, desktop controller, shared TS reader, KMP and HarmonyOS clients.
unsubscribe_streamfrom a retired reader (reopened session, second view on the same device) removed the lease of the live reader, which then stopped receiving hints.read_streamnow offers an optionalsubscription_id; a capable host echoes it instream_pageandunsubscribe_streamremoves only that lease. Readers connected to older hosts get no echo, skip the unscoped unsubscribe and let the existing 10-minute lease expire. Leases per device are bounded (64) and validated.relay://session-readycarryinglive: true.account_subscribe_sessiontags every event with a controller-localsubscriptionIdand marks sync errorsretrying: true.RelaySessionHistoryignores events from other subscriptions (untagged legacy events stay accepted), keeps the reader alive on retrying errors, does not let aliveready complete an unrelated history page, and a failed older-page read no longer closes the live subscription.hostStreamsubscribed to hints only after the first page, so a final hint sent while that page was in flight was lost until the next keepalive. Listeners are now installed before the opening read.subscribeSessionlooked up the socket lazily inunsubscribe/onReconnect, so closing a stream after a sign-out or account switch could close the new account's socket. It now keeps the socket it opened.Type and Areas
Type: bug fix
Areas: services-integrations (host stream), assembly core (remote connect), desktop/Tauri, web UI, shared relay transport, mobile web, mobile KMP, HarmonyOS
Motivation / Impact
Remote control and Peer Device Mode sessions could silently stop updating after a session was reopened or viewed twice on one device, or after a single lost live read, until the user reloaded. Wire changes are additive and optional (
subscription_id,subscriptionId,live,retrying); older hosts and clients keep working through the existing lease-expiry path.Verification
cargo test --locked -p openbitfun-services-integrations --no-default-features --features remote-connect --lib remote_connect::host_stream(42 passed, includes new lease and live-retry tests)cargo test --locked -p openbitfun-core --no-default-features --features remote-connect --lib service::remote_connect::(includeshost_stream_command_tests)cargo test --locked -p openbitfun-desktop --lib relay_routes_tests(desktop crate compiles; route tests pass)npx vitest run src/flow_chat/services/RelaySessionHistory.test.ts src/flow_chat/store/FlowChatStore.test.tsinsrc/web-ui;tsc --noEmitfor web-ui and mobile-webnode --test tests/host-stream.test.mjs tests/session-stream-browser.test.mjsinsrc/mobile-web(18 passed)node --test src/apps/mobile/harmonyos/tools/tests/host-stream.test.cjs(11 passed)./gradlew :core-transport:jvmTest :core-protocol:jvmTest(HostStreamTest,CloudAccountClientTestpass)Remote scenarios: exercised only with local loopback fixtures and fakes (remote control / Peer Device stream paths). Not verified against a live Relay or real devices.
Reviewer Notes
AI-assisted change, lightly tested as listed above.
Checklist