Skip to content

Commit

Permalink
Store payloads in a queue when arriving in parallel
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
sisou committed Oct 7, 2021
1 parent 0155db2 commit edc8224
Showing 1 changed file with 15 additions and 1 deletion.
16 changes: 15 additions & 1 deletion client/ws.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ function isObject(obj: unknown): obj is Record<string, unknown> {
export class Remote {
private textDecoder?: TextDecoder;
private payloadData!: Promise<JsonValue>;
private payloadQueue: JsonValue[] = [];
socket: WebSocket;
[key: string]: any // necessary for es6 proxy
constructor(
Expand All @@ -24,6 +25,13 @@ export class Remote {

private async getPayloadData(socket: WebSocket): Promise<void> {
this.payloadData = new Promise<JsonValue>((resolve, reject) => {
if (this.payloadQueue.length > 0) {
const payload = this.payloadQueue.shift()!;
resolve(payload);
return;
}

let isResolved = false;
socket.onmessage = async (event: MessageEvent) => {
let msg: string;
if (event.data instanceof Blob) {
Expand All @@ -34,7 +42,13 @@ export class Remote {
msg = event.data;
}
try {
resolve(JSON.parse(msg));
const payload = JSON.parse(msg);
if (isResolved) {
this.payloadQueue.push(payload);
return;
}
resolve(payload);
isResolved = true;
} catch (err) {
reject(
new BadServerDataError(null, "The received data is invalid JSON."),
Expand Down

0 comments on commit edc8224

Please sign in to comment.