Add async lock to WebSocket create-transport handler in webrtcSignaling.js #39

Open
opened 2026-08-02 21:40:24 +00:00 by Jasper · 0 comments
Collaborator

Summary

The WebSocket signaling path (server/utils/webrtcSignaling.js) handles create-transport messages without an async lock, while the REST endpoint at server/api/live/webrtc/create-transport.post.js uses acquire('create-transport-${sessionId}'). Concurrent WebSocket clients can race on calling getRouter(sessionId) and createTransport(router) before reaching updateLiveSession, potentially creating duplicate transports for the same session.

Note: updateLiveSession itself acquires a lock (session-update-${id}), so writes are serialized, but reads and transport creation happen outside any lock in the WS path. This means two concurrent WS calls can each create a separate mediasoup transport before either reaches the serialized write — both succeed, but only one transport ID survives in session state.

Acceptance criteria

  • Wrap the create-transport case in handleWebSocketMessage with an async lock keyed by create-transport-${sessionId} (same key as the REST endpoint to prevent cross-path races)
  • The entire handler body for create-transport — including getRouter, createTransport, and updateLiveSession — must be inside the locked region
  • Existing tests pass; add a test verifying concurrent WebSocket create-transport messages for the same session do not produce duplicate transports
## Summary The WebSocket signaling path (`server/utils/webrtcSignaling.js`) handles `create-transport` messages without an async lock, while the REST endpoint at `server/api/live/webrtc/create-transport.post.js` uses `acquire('create-transport-${sessionId}')`. Concurrent WebSocket clients can race on calling `getRouter(sessionId)` and `createTransport(router)` before reaching `updateLiveSession`, potentially creating duplicate transports for the same session. Note: `updateLiveSession` itself acquires a lock (`session-update-${id}`), so writes are serialized, but reads and transport creation happen outside any lock in the WS path. This means two concurrent WS calls can each create a separate mediasoup transport before either reaches the serialized write — both succeed, but only one transport ID survives in session state. ## Acceptance criteria - [ ] Wrap the `create-transport` case in `handleWebSocketMessage` with an async lock keyed by `create-transport-${sessionId}` (same key as the REST endpoint to prevent cross-path races) - [ ] The entire handler body for `create-transport` — including `getRouter`, `createTransport`, and `updateLiveSession` — must be inside the locked region - [ ] Existing tests pass; add a test verifying concurrent WebSocket `create-transport` messages for the same session do not produce duplicate transports <!-- jasper-fp:2333e3299204f265 -->
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: keligrubb/kestrelos#39