Skip to content

Conversation

@715d
Copy link
Contributor

@715d 715d commented Jan 30, 2026

Socket.currentRender was read and written from multiple goroutines (WebSocket reader, broadcast handler, upload POST handler) without synchronization. The render, diff, send, and update steps are also not atomic — a concurrent event can interleave between diffing and updating the stored render tree, producing corrupt patches.

The same applies to Socket.uploads and Socket.uploadConfigs, which are accessed from both the HTTP POST upload handler and WebSocket event handlers concurrently.

I added a new test, socket_race_test.go, which triggers the race detector.

I took the simple approach for the fix, which was to introduce a mutex to protect both the render and upload state.

I added Socket.Render(ctx) which is the replacement for RenderSocket, using the mutex to synchronize the render->diff->patch cycle.

A more controversial change might be that I changed RenderSocket, UpdateRender, and LatestRender to be un-exported, so that an outside caller can't do the wrong thing accidentally.

I also changed UploadConfigs and Uploads to return copies so the caller can't mess with the slice that might be concurrently changed by AssignUpload/ClearUpload/etc

@715d 715d force-pushed the fix/protect-render-and-upload-mutex branch from b7e170a to 2114418 Compare January 30, 2026 03:34
@715d 715d marked this pull request as ready for review January 30, 2026 03:36
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