Skip to content

Send reliable data after a full reconnect instead of dropping it - #1277

Open
hiroshihorie wants to merge 2 commits into
hiroshi/fix-buffer-status-waitfrom
hiroshi/reliable-sends-full-reconnect
Open

hiroshihorie wants to merge 2 commits into
hiroshi/fix-buffer-status-waitfrom
hiroshi/reliable-sends-full-reconnect

Conversation

@hiroshihorie

@hiroshihorie hiroshihorie commented Nov 3, 2026 •

Copy link
Copy Markdown
Member

Stacked on #1267, which is stacked on #1268. This PR is one commit.

A reliable data packet sent while the engine does a full reconnect was reported as sent and never went out. sendDataPacket parked it for the resume replay, and a full reconnect never runs that replay. publishData, RPC and data stream writes all hit this. Found while checking Devin's finding on #1267.

Change

  • A reliable send waits the reconnect out, then goes out on the connection the reconnect leaves. It fails with UnexpectedConnectionState if the engine closes instead, which is how a reconnect that gives up ends.
  • Every wait happens before the sequence number is taken. A send that a full reconnect interrupts while it waits for the publisher goes round again instead of failing with Publisher connection reset. Nothing awaits between the last reconnect check and the send, so a reliable packet is no longer parked.
  • A full reconnect restarts the reliable sequence at 1 and clears the resend buffer.
  • Lossy packets are still dropped during a reconnect rather than sent late.
  • The wait uses Fix waiting for the data channel send buffer to drain #1267's state change signal, so a send resumes as soon as the reconnect ends.

Other SDKs

client-sdk-js client-sdk-swift rust-sdks
Reliable send during a full reconnect parked, never replayed, reported as sent queued sends fail with a cancelled error, later sends wait for the new channel waits for the reconnect, then sends on the new session
Sequence and resend buffer on a full reconnect reset reset new per session

This follows rust-sdks, where publish_data holds the reconnect lock's read guard. client-sdk-js has the same loss Flutter had.

Tests

  • test/core/reliable_send_reconnect_test.dart: a send during a full reconnect reaches the new channel only after the reconnect finishes, sequence numbers restart at 1, a waiting send fails when the engine closes, and a resume still sends once. The first three fail without this change.
  • Full unit suite: 518 passed, 1 skipped. flutter analyze, dart analyze web/, format, import order and version check pass.
  • livekit/e2e-flutter#20 adds the scenario "Reliable data during a full reconnect", run against a local livekit-server --dev. A sender publishes a numbered reliable packet every 20 ms and the server forces a full reconnect partway.
SDK Result
#1268 (2cc480e) fail twice: 2 and 7 packets reported sent and never arrived
#1267 (daf740d) fail: 9 reported sent and never arrived, 1 send failed with Publisher connection reset
this PR (dc41370) pass 3 of 3, every packet arrived in order

The reconnect group (full reconnect, disconnect during a full reconnect, migration, node failure) and both data channel scenarios also pass on an earlier revision of this branch.

sendDataPacket parked a reliable packet sent during any reconnect for the
resume replay. A full reconnect never runs that replay, so the packet was
reported as sent and never went out. publishData, RPC and data stream
writes all hit this.

A reliable send now waits the reconnect out and goes out on the connection
it leaves, the way rust-sdks waits for reconnection in publish_data. It
fails with UnexpectedConnectionState if the engine closes instead. All
waits happen before the sequence number is taken, a send that a full
reconnect interrupts while it waits for the publisher goes round again
instead of failing, and nothing awaits between the last reconnect check
and the send. A full reconnect restarts the reliable sequence and clears
the resend buffer, as client-sdk-js, client-sdk-swift and rust-sdks do for
a new session. Lossy packets are still dropped during a reconnect rather
than sent late.
@hiroshihorie
hiroshihorie added this pull request to stack #1276 November 3, 2026 07:18
@hiroshihorie
hiroshihorie marked this pull request as ready for review November 3, 2026 07:19

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no bugs or issues to report.

Devin Review

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant