Up to 10 connected users — each interaction is processed by a background worker thread, keeping the UI thread free.
A WorkerPool of 10 inline workers is created once on page load. When a user sends a message, the task is dispatched to the next worker in round-robin fashion — keeping the main thread unblocked regardless of how many users are active simultaneously.
// ── Inline WorkerPool (no separate file needed) ──────────────────────
function createWorkerPool(workerFn, size = 10) {
const slots = Array.from({ length: size }, (_, i) => {
const blob = new Blob([
`self.onmessage = (e) => {
const taskId = e.data && e.data.__taskId;
try {
const result = (${workerFn.toString()})(e, ${i});
self.postMessage({ __taskId: taskId, result });
} catch (err) {
self.postMessage({ __taskId: taskId, error: err && err.message ? err.message : String(err) });
}
}`
], { type: 'application/javascript' });
const url = URL.createObjectURL(blob);
const worker = new Worker(url, { type: 'classic' });
URL.revokeObjectURL(url); // safe to revoke after construction
const pending = new Map();
worker.onmessage = (e) => {
const { __taskId, result, error } = e.data || {};
const callbacks = pending.get(__taskId);
if (!callbacks) return;
pending.delete(__taskId);
if (error) callbacks.reject(new Error(error));
else callbacks.resolve(result);
};
return { worker, pending };
});
let index = 0;
let taskId = 0;
return {
send(data) {
const slot = slots[index++ % size];
const currentTaskId = ++taskId;
return new Promise((resolve, reject) => {
slot.pending.set(currentTaskId, { resolve, reject });
slot.worker.postMessage({ ...data, __taskId: currentTaskId });
});
},
terminate() { slots.forEach(({ worker }) => worker.terminate()); },
};
}
// ── Worker function (runs in background thread) ───────────────────────
function processMessage(event, workerId) {
const { userId, text } = event.data;
// Simulate processing (e.g. sanitise, filter, analyse sentiment …)
const wordCount = text.trim().split(/\s+/).filter(Boolean).length;
const charCount = text.length;
return { userId, wordCount, charCount, workerId };
}
// ── Usage ─────────────────────────────────────────────────────────────
const pool = createWorkerPool(processMessage, 10);
const result = await pool.send({ userId: 'alice', text: 'Hello world!' });
// → { userId: 'alice', wordCount: 2, charCount: 12, workerId: 0 }