Skip to content

Commit d5fa55f

Browse files
committed
fix(client-ws-transport): Flush send queue in close() to avoid race
Before this there were a race between `setTimeout` in `sendMessage` and `close`. Even for a good citizen, that calls `unsubscribe()` and awaits result there were no synchronization between unsubscribe adding message to `messageQueue` and restarting timer, and actually sending this message to WebSocket. When `close()` is called close frame is sent immediately to WebSocket. If at that moment messageQueue is not empty, and timer is armed it can wake up, and discover socket in CLOSING state: send side closed, recv side open. For now - just flush everything queued, and send close frame after, so it would look like close was queued after. More complete solution is to add synchronization between unsubscribe call and sending message, or even receiving ack for it.
1 parent c8f24f7 commit d5fa55f

File tree

1 file changed

+3
-0
lines changed
  • packages/cubejs-client-ws-transport/src

1 file changed

+3
-0
lines changed

packages/cubejs-client-ws-transport/src/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ class WebSocketTransport implements ITransport<WebSocketTransportResult> {
9191

9292
public async close(): Promise<void> {
9393
if (this.ws) {
94+
// Flush send queue before sending close frame
95+
this.ws.sendQueue();
96+
9497
this.ws.close();
9598
}
9699
}

0 commit comments

Comments
 (0)