Skip to content

enhance(websocket): improve client synchronization - #38847

Open
silverwind wants to merge 4 commits into
go-gitea:mainfrom
silverwind:fix-websocket-connect-snapshot
Open

enhance(websocket): improve client synchronization#38847
silverwind wants to merge 4 commits into
go-gitea:mainfrom
silverwind:fix-websocket-connect-snapshot

Conversation

@silverwind

@silverwind silverwind commented Aug 9, 2026

Copy link
Copy Markdown
Member

Between when HTML is written and the websocket has connected, there is a short time window where clients miss state updates, which is the cause of this flake.

Now we send the state to all websocket clients as the first message and frontend has a cache in the worker to replay the last event per type to new tabs.

This also removes the previous hacky fetch-based reconcillation when opening tabs.

Also refactor the backend to contain all code for a event in a single file, so adding a new event is a single file addition in backend.

State reached the client over two channels with no order between them, so a
push could be lost or overwritten.

The server subscribed to the user's topic only after the handshake completed,
and publishers skip topics without subscribers, so anything fired in that
window was discarded. The client compensated by reconciling over a separate
HTTP request on connect, whose answer could arrive after a newer push and
overwrite it. Closing an issue then left the navbar stopwatch running.

Subscribe before the handshake and hand the connection its current state as
the first frames, so the socket is the only source and the client no longer
reconciles.

Also stop logging an error when a queued notification finds its issue gone,
which is expected once its repository has been deleted.

Assisted-by: Claude Code:claude-opus-5
@GiteaBot GiteaBot added the lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. label Aug 9, 2026
The router had to decode a logout payload to decide which connection may
receive it, so generic transport code knew one event's constant, struct and
wire JSON. The broker payload now carries the target session in its header,
making per-session delivery a transport concern and leaving the router with
an opaque payload it forwards or drops.

Each event now owns its constant, payload, builder and publisher in a single
file, with the generic file holding transport only, so adding an event
touches one file.

The SharedWorker keeps the last message per event type and replays it to a
tab attaching to an already-open socket, which the server cannot reach
because it sees one connection per worker rather than one per tab.

Assisted-by: Claude Code:claude-opus-5
@silverwind silverwind changed the title fix(websocket): open each connection with a state snapshot fix(websocket): improve client synchronization Aug 11, 2026
@silverwind

Copy link
Copy Markdown
Member Author

More cleanup done, description is updated.

@silverwind silverwind changed the title fix(websocket): improve client synchronization enhance(websocket): improve client synchronization Aug 11, 2026
@github-actions github-actions Bot added type/enhancement An improvement of existing functionality and removed type/bug labels Aug 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lgtm/need 2 This PR needs two approvals by maintainers to be considered for merging. type/enhancement An improvement of existing functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants