Repository navigation
Fix the desktop window flashing endlessly after a flet run hot reload - #6945
Open
ndonkoHenri wants to merge 4 commits into
Open
ndonkoHenri wants to merge 4 commits into
ndonkoHenri wants to merge 4 commits into
Conversation
A connection reset or a broken pipe fires the socket stream's onError and then onDone, and both reported a disconnect. FletBackend then ran two reconnect chains that kept replacing each other's connection, so after a hot reload the desktop window flashed with a new session every few hundred milliseconds. Seen on Windows and Linux when the client was sending events while the app was restarted.
FletBackend scheduled a reconnect for every disconnect a channel reported, so any transport that reported a disconnect twice started two reconnect chains that kept replacing each other's connection. Only let the channel of the latest connection attempt trigger a reconnect, and schedule at most one reconnect at a time, so the backend is safe whatever the transport does. Checked with the socket reset test: without the channel fix from the previous commit, the backend now still reconnects exactly once.
ndonkoHenri
requested review from
FeodorFitsner
and
a balanced review from Copilot
October 10, 2026 18:38
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
The socket and backend regression tests described in the PR are not committed, leaving both concurrency guarantees unprotected.
2 open findings
What changed in this PR
Prevents competing reconnect loops that caused desktop flashing after hot reloads.
Changes:
- Makes socket disconnect notification idempotent.
- Rejects stale disconnect callbacks and duplicate reconnect scheduling.
- Adds user-facing and Flutter-package changelog entries.
| File | Description |
|---|---|
packages/flet/lib/src/transport/flet_backend_channel_socket.dart |
Reports each socket disconnect once. |
packages/flet/lib/src/flet_backend.dart |
Guards reconnect scheduling and stale channels. |
packages/flet/CHANGELOG.md |
Documents the Dart runtime fix. |
CHANGELOG.md |
Documents the user-facing hot-reload fix. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Deploying flet-website-v2 with
|
| Latest commit: |
c2cf7be
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://d0b9de69.flet-website-v2.pages.dev |
| Branch Preview URL: | https://fix-socket-single-disconnect.flet-website-v2.pages.dev |
socket_disconnect_test.dart runs FletSocketBackendChannel and FletBackend against a local TCP server: a connection reset and an orderly close each report one disconnect, and the backend reconnects exactly once after a reset. backend_reconnect_test.dart uses an injected channel: a disconnect reported twice reconnects once, and a late disconnect from a replaced channel doesn't reconnect while the current channel still does. Each test fails without its part of the fix.
1 task 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.

Fixes #6913
The bug
Under
flet run, the desktop client stays open across hot reloads. Each reload kills the Python app and the client reconnects to the new one. When the app is killed while the client is sending to it (window events, control events, method replies), the client's socket gets a reset:WSAECONNRESETon Windows,ECONNRESETorEPIPEon Linux. The chain from there:onErrorand thenonDone.FletSocketBackendChannelcalledonDisconnect()from both.FletBackend._onDisconnect()schedules a reconnect for every call. So one reset started two independent reconnect chains.That is the endless flashing in the report. The log shows
App session started/Session was garbage collectedevery few hundred ms from a single app process, untilflet runis restarted. It needs a reset at the exact moment of a reload, which is why it starts "randomly after a few minutes". An orderly close (FIN) fires onlyonDone.The fix
FletSocketBackendChanneldestroys the socket on either event but reports the disconnect only once. Each connection attempt gets a new channel, so later disconnects are still reported.FletBackendnow keeps at most one reconnect pending, and only the channel of the latest connection attempt may trigger one. This makes the backend safe whatever a transport does: an embedder-supplied channel, a future transport, or a late event from a replaced channel. On its own, without the channel change, it also reconnects exactly once after a reset.Testing
flet-1.1.0and from this branch:packages/flet/test/transport/:socket_disconnect_test.dartruns the socket channel andFletBackendagainst a local TCP server. A connection reset and an orderly close each report one disconnect, and the backend reconnects exactly once after a reset. Onflet-1.1.0the reset cases fail: 2 disconnect reports instead of 1, and 360 connections instead of 2.backend_reconnect_test.dartuses an injected channel. A disconnect reported twice by a channel reconnects once, and a late disconnect from a replaced channel doesn't reconnect, while the current channel still does. Both fail without the backend guard, even with the socket fix in place.packages/fletsuite passes, andflutter analyzeis clean.The VM runs above used the socket fix; the backend guard is covered by the Dart tests.
Summary by Sourcery
Prevent competing reconnect attempts from repeatedly replacing desktop sessions after hot reload connection resets.
Bug Fixes:
flet runhot reloads by ensuring connection resets produce only one valid reconnect.Enhancements:
Tests: