Skip to content

Commit edc8224

Browse files
committed
Store payloads in a queue when arriving in parallel
When messages arrive very quickly after each other, or the message handler is waiting for the Blob arraybuffer to resolve (it's async), it can happen that another message that arrived in parallel resolves the promise already, loosing the first message. This commit introduces a payload queue, in which payloads that take longer are stored, and taken out on the next iteration. Attention: The queue is only processed when a new message arrives.
1 parent 0155db2 commit edc8224

File tree

1 file changed

+15
-1
lines changed

1 file changed

+15
-1
lines changed

client/ws.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ function isObject(obj: unknown): obj is Record<string, unknown> {
1313
export class Remote {
1414
private textDecoder?: TextDecoder;
1515
private payloadData!: Promise<JsonValue>;
16+
private payloadQueue: JsonValue[] = [];
1617
socket: WebSocket;
1718
[key: string]: any // necessary for es6 proxy
1819
constructor(
@@ -24,6 +25,13 @@ export class Remote {
2425

2526
private async getPayloadData(socket: WebSocket): Promise<void> {
2627
this.payloadData = new Promise<JsonValue>((resolve, reject) => {
28+
if (this.payloadQueue.length > 0) {
29+
const payload = this.payloadQueue.shift()!;
30+
resolve(payload);
31+
return;
32+
}
33+
34+
let isResolved = false;
2735
socket.onmessage = async (event: MessageEvent) => {
2836
let msg: string;
2937
if (event.data instanceof Blob) {
@@ -34,7 +42,13 @@ export class Remote {
3442
msg = event.data;
3543
}
3644
try {
37-
resolve(JSON.parse(msg));
45+
const payload = JSON.parse(msg);
46+
if (isResolved) {
47+
this.payloadQueue.push(payload);
48+
return;
49+
}
50+
resolve(payload);
51+
isResolved = true;
3852
} catch (err) {
3953
reject(
4054
new BadServerDataError(null, "The received data is invalid JSON."),

0 commit comments

Comments
 (0)