patterntypescriptModerate
Message Ordering Guarantees Require Sequence Numbers and Reorder Buffers
Viewed 0 times
message orderingsequence numberreorder bufferout of ordermessage deliveryreplayreal-time reliability
Problem
A real-time system assumes WebSocket messages arrive in order, but messages can arrive out of order after a reconnection or when the server processes them through concurrent workers.
Solution
Assign monotonically increasing sequence numbers on the server. Clients buffer out-of-order messages and deliver them in sequence order.
type SequencedMessage = { seq: number; data: unknown };
class OrderedMessageProcessor {
private nextSeq = 1;
private buffer = new Map<number, SequencedMessage>();
process(msg: SequencedMessage, onDeliver: (data: unknown) => void) {
this.buffer.set(msg.seq, msg);
// Deliver all contiguous messages from nextSeq
while (this.buffer.has(this.nextSeq)) {
const m = this.buffer.get(this.nextSeq)!;
this.buffer.delete(this.nextSeq);
onDeliver(m.data);
this.nextSeq++;
}
// Detect a gap — request resend if buffer grows too large
if (this.buffer.size > 50) {
requestResync(this.nextSeq);
}
}
}Why
WebSocket connections over TCP guarantee in-order delivery within a single connection. But after reconnection, the client creates a new TCP stream and any buffered server messages from the old stream may be missed or received out of order.
Gotchas
- Buffer size must be bounded — a malicious or buggy server that skips a sequence number will grow the buffer forever.
- On reconnect, send the last received sequence number so the server can replay missed messages.
- Use 64-bit integers for sequence numbers in high-volume systems — 32-bit wraps at ~4 billion messages.
- Acknowledge processed messages so the server can garbage-collect its replay buffer.
Revisions (0)
No revisions yet.