74 lines
1.7 KiB
TypeScript
74 lines
1.7 KiB
TypeScript
// the emitter setup
|
|
// TODO: validate if we want to add event back in later..
|
|
// let emitFn: ((roomId: string, event: string, payload: unknown) => void) | null =
|
|
// null;
|
|
|
|
import { createLogger } from "../logger/logger.controller.js";
|
|
|
|
type QueuedPayload = unknown;
|
|
|
|
let emitFn: ((roomId: string, payload: QueuedPayload[]) => void) | null = null;
|
|
|
|
const queues = new Map<string, QueuedPayload[]>();
|
|
const timers = new Map<string, NodeJS.Timeout>();
|
|
|
|
const FLUSH_MS = 500;
|
|
const MAX_QUEUE_SIZE = 200;
|
|
|
|
export const registerEmitter = (
|
|
fn: (roomId: string, payload: QueuedPayload) => void,
|
|
) => {
|
|
emitFn = fn;
|
|
};
|
|
|
|
export const emitToRoom = (roomId: string, payload: QueuedPayload) => {
|
|
const log = createLogger({ module: "socket.io", subModule: "emitter" });
|
|
if (!emitFn) {
|
|
console.error("Socket emitter not initialized");
|
|
return;
|
|
}
|
|
|
|
const queue = queues.get(roomId) ?? [];
|
|
|
|
if (queue.length > MAX_QUEUE_SIZE) {
|
|
log.error(
|
|
{ stack: { roomId, size: queue.length }, notify: true },
|
|
`Socket queue exceeded max size for ${roomId}`,
|
|
);
|
|
}
|
|
queue.push(payload);
|
|
queues.set(roomId, queue);
|
|
|
|
if (timers.has(roomId)) return;
|
|
|
|
const timer = setTimeout(() => {
|
|
try {
|
|
const payloads = queues.get(roomId) ?? [];
|
|
|
|
if (payloads.length === 0) return;
|
|
emitFn?.(roomId, payloads);
|
|
|
|
queues.delete(roomId);
|
|
} catch (e) {
|
|
console.error("Socket emit failed", { roomId, e });
|
|
} finally {
|
|
timers.delete(roomId);
|
|
}
|
|
}, FLUSH_MS);
|
|
|
|
timers.set(roomId, timer);
|
|
};
|
|
|
|
/*
|
|
example emitToRoom(room, payload)
|
|
|
|
payload can be anything json serilized example below.
|
|
|
|
emitToRoom("inventory:ppoo", {
|
|
type: "snapshot",
|
|
location: "ppoo",
|
|
items,
|
|
createdAt: new Date().toISOString(),
|
|
});
|
|
*/
|