refactor(socket.io): complete rewrite to manage dynamic rooms and seeding better

This commit is contained in:
2026-06-10 16:25:48 -05:00
parent a2d9a6c127
commit 9440b44f3b
7 changed files with 271 additions and 315 deletions

View File

@@ -1,27 +1,73 @@
// 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 type { RoomId } from "./roomDefinitions.socket.js";
import { createLogger } from "../logger/logger.controller.js";
let addDataToRoom: ((roomId: RoomId, payload: unknown[]) => void) | null = null;
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: RoomId, payload: unknown[]) => void,
fn: (roomId: string, payload: QueuedPayload) => void,
) => {
addDataToRoom = fn;
emitFn = fn;
};
export const emitToRoom = (roomId: RoomId, payload: unknown[]) => {
if (!addDataToRoom) {
export const emitToRoom = (roomId: string, payload: QueuedPayload) => {
const log = createLogger({ module: "socket.io", subModule: "emitter" });
if (!emitFn) {
console.error("Socket emitter not initialized");
return;
}
addDataToRoom(roomId, payload);
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);
};
/*
import { emitToRoom } from "../socket/socketEmitter.js";
// room name
// its payload
emitToRoom("logs", newLogRow);
example emitToRoom(room, payload)
payload can be anything json serilized example below.
emitToRoom("inventory:ppoo", {
type: "snapshot",
location: "ppoo",
items,
createdAt: new Date().toISOString(),
});
*/