-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Send a "reconnect" hydrate whenever the socket reconnects #5969
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
* "reconnect" hydrate doesn't reset client storage or trigger on_load, it just returns the latest complete state dict * this event is driven by the frontend after the socket connects * update `link_token_to_sid` to NOT emit a delta when the sid changes for a token; the client will be informed of this during the initial hydrate or "reconnect" hydrate. Fix #5963
CodSpeed Performance ReportMerging #5969 will not alter performanceComparing Summary
|
Greptile OverviewGreptile SummaryThis PR implements a frontend-driven reconnection hydration mechanism to fix issue #5963 where stale state would linger on the client after socket reconnection when backend state expired. The solution introduces a Key Changes:
Architecture: Confidence Score: 4/5
Important Files ChangedFile Analysis
Sequence DiagramsequenceDiagram
participant Client as Frontend (state.js)
participant Socket as WebSocket
participant Backend as EventNamespace
participant Middleware as HydrateMiddleware
participant State as State Manager
Note over Client,State: Normal Reconnection Flow
Client->>Client: Detect disconnection
Client->>Client: Call socket.reconnect()
Client->>Client: Set rehydrate flag = true
Client->>Socket: Connect with token
Socket->>Backend: on_connect(sid, token)
Backend->>Backend: link_token_to_sid(sid, token)
Backend->>State: state_manager.modify_state()
Note right of Backend: No delta emitted (changed from app.modify_state)
Backend->>State: Update router_data[SESSION_ID] = sid
Socket-->>Client: "connect" event
Client->>Client: Check rehydrate flag = true
Client->>Client: Get initialEvents()[0]
Client->>Client: Set payload.is_reconnect = true
Client->>Client: Reset rehydrate flag = false
Client->>Socket: Queue hydrate event with is_reconnect=true
Socket->>Backend: Process hydrate event
Backend->>Middleware: preprocess(event)
alt is_reconnect = true
Note over Middleware: Skip _reset_client_storage()
Note over Middleware: Skip setting is_hydrated = False
Note over Middleware: On_load events will NOT run
else is_reconnect = false (normal hydrate)
Middleware->>State: _reset_client_storage()
Middleware->>State: Set is_hydrated = False
Note over Middleware: On_load events WILL run
end
Middleware->>State: Get full state dict via _resolve_delta()
Middleware->>State: _clean()
Middleware-->>Backend: Return StateUpdate with full delta
Backend->>Socket: Emit state update
Socket-->>Client: Receive full state
Client->>Client: Apply state update to frontend
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
3 files reviewed, 1 comment
reflex/.templates/web/utils/state.js
Outdated
| const hydrate_event = initialEvents()[0]; | ||
| hydrate_event.payload.is_reconnect = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
style: Accessing initialEvents()[0] without checking if it exists could cause runtime error if array is empty
| const hydrate_event = initialEvents()[0]; | |
| hydrate_event.payload.is_reconnect = true; | |
| const hydrate_event = initialEvents()[0]; | |
| if (!hydrate_event) { | |
| console.error("No hydrate event found in initialEvents()"); | |
| return; | |
| } | |
| hydrate_event.payload.is_reconnect = true; |
Prompt To Fix With AI
This is a comment left during a code review.
Path: reflex/.templates/web/utils/state.js
Line: 622:623
Comment:
**style:** Accessing `initialEvents()[0]` without checking if it exists could cause runtime error if array is empty
```suggestion
const hydrate_event = initialEvents()[0];
if (!hydrate_event) {
console.error("No hydrate event found in initialEvents()");
return;
}
hydrate_event.payload.is_reconnect = true;
```
How can I resolve this? If you propose a fix, please make it concise.if the app is stateless, then presumably we don't end up connecting a websocket at all, so we wouldn't hit this code. also if `initialEvents` was empty for whatever reason, then the app probably wouldn't work... but lets make it look a bit safer.
link_token_to_sidto NOT emit a delta when the sid changes for a token; the client will be informed of this during the initial hydrate or "reconnect" hydrate.Fix #5963