This document defines the concrete interaction contracts between components: message shapes, function signatures, arguments, and return values.
The WorkerPool posts tasks to Node.js worker threads and expects standardized responses.
-
Incoming message to worker
- Function: worker message listener
- Signature:
(message: { id: number; data: any }) => void - Description: The pool sends a message with a unique
id(callback identifier) and arbitrarydatapayload.
-
Outgoing success message from worker
- Function:
parentPort.postMessage - Arguments:
{ callbackId: number; result: any } - Returns:
void(posts a message to the parent thread) - Description: Must include the same
callbackIdthat was received asid.
- Function:
-
Outgoing error message from worker
- Function:
parentPort.postMessage - Arguments:
{ callbackId: number; error: string | { message: string, [k: string]: any } } - Returns:
void - Description: Send when a task fails. Error can be a string or an object with a
message.
- Function:
-
Worker error/exit handling
- If a worker emits an
'error'event, the pool completes the current task promise withnew Error('Worker error: ...'). - If a worker exits with non-zero code, the pool rejects the current task promise with
new Error('Worker stopped with exit code <code>').
- If a worker emits an
-
WorkerPool API (caller-side expectations)
submit(data: any): Promise<any>- Arguments:
datawill be forwarded to worker as{ id, data }. - Returns:
Promise<any>resolved withresultor rejected witherrorfrom worker.
- Arguments:
stop(): void— pauses dispatching new tasks.resume(): void— resumes dispatching queued tasks.wait(): Promise<void>— resolves when all pending tasks complete.terminate(): Promise<number>— terminates workers, returns pool size after cleanup (expected 0).
The Scheduler builds on top of the WorkerPool and defines a specific task protocol.
-
Incoming message to scheduler worker
- Signature:
(message: { id: number; data: { type: string; payload: any } }) => void - Description:
typeis the task name.payloadis the task input object.
- Signature:
-
Special request handshake (optional)
- If
type === 'request', the worker should respond immediately with{ callbackId, type: 'request' }and return.
- If
-
Unknown task type
- Outgoing message:
{ callbackId: number; error: { message: string } } - Required when
handlers[type]is not found. The message must include a helpfulmessagestring:Unknown task type "<type>".
- Outgoing message:
-
Successful task execution
- The worker resolves the handler call and posts
{ callbackId: number; result: any }.
- The worker resolves the handler call and posts
-
Failed task execution
- The worker catches the error and posts
{ callbackId: number; error: string }whereerroris typicallyerr.message.
- The worker catches the error and posts
A handlers module is a plain CommonJS file that exports an object mapping task names to functions.
-
Module shape
module.exports = { [taskName: string]: (payload: any) => any | Promise<any> }
-
Handler function
- Name:
taskName(string key in the exported object) - Signature:
(payload: any) => any | Promise<any> - Arguments:
payload— arbitrary serializable input for the task - Returns: Either a direct value or a promise resolving to the task result
- Name:
-
Example
module.exports = { add: ({ a, b }) => a + b, multiply: async ({ a, b }) => a * b, };
Concurrency-safe operations are guaranteed within a single Node.js process. Do not mutate internal buffers/collections directly; use the provided methods.
- Use
CountingSemaphoreto bound concurrent IO. - Use
WorkerPool/Schedulerfor CPU-bound tasks.