Skip to main content

Module cluster

Module cluster 

Source
Expand description

Node cluster — real process-fork model over std::process::Command.

§What is real

  • cluster.fork([env]) spawns a genuine OS child process. It re-launches the SAME runtime binary (std::env::current_exe()) on the SAME entry script (process.argv[1], i.e. settings.exec), with an env marker (CLUSTER_WORKER=<id> + Node’s own NODE_UNIQUE_ID=<id>) plus any caller env overrides. The child therefore runs the whole program again, but this time in worker mode. This is the actual Unix master/worker fork model, not a simulation.
  • cluster.isPrimary/isMaster/isWorker are derived from that env marker: the primary has neither CLUSTER_WORKER nor NODE_UNIQUE_ID set; a forked child has one set, so it reports isWorker === true.
  • Worker lifecycle events are real, best-effort: 'fork' fires synchronously from fork(), 'online' is posted onto the event loop immediately after the child launches, and 'exit' fires when a background reaper thread observes the child process actually exit (via Child::wait). Each live worker incr_handles the loop so the primary stays alive while workers run, and 'exit' decr_handles it.
  • Worker.kill([signal]) delivers a real signal to the child pid (libc::kill), so cluster.workers[id].kill() truly terminates the process.
  • cluster.workers maps live worker id → Worker, and cluster.worker in a forked child is a Worker for itself (id from the env marker).

§Documented limitations (honest, never a silent fake)

  • No primary↔worker IPC channel. Node connects each fork over a pipe and ships worker.send(msg) / process.on('message') across it. node-js does not wire a cross-process pipe here, so Worker.send() is a documented no-op that returns false, and there is no 'message' delivery between primary and cluster workers. (In-process message passing exists in worker_threads, which shares one address space; cluster workers are separate OS processes and would need a real socket/pipe channel.)
  • No shared listening socket. Node’s primary opens the listen socket once and hands the same file descriptor to every worker so N workers accept on ONE port (SO_REUSEPORT / fd passing). node-js does not pass fds across the fork, so each worker that calls server.listen(port) binds its OWN socket — true round-robin load balancing across workers on a single port is NOT provided. Consequently 'listening' is not emitted (no fd hand-off to observe) and Worker.disconnect() cannot gracefully drain an IPC/socket channel: it marks the worker disconnected and emits 'disconnect', but the real way to stop a worker is Worker.kill().

Constants§

METHODS
Callable module members. The EventEmitter surface is included so that cluster.on('exit', …) / cluster.emit(…) route through stdlib::call (cluster.<method>) to the process-wide cluster emitter.
WORKER_METHODS
Instance methods on a Worker (@@native tag "ClusterWorker"), beyond the shared EventEmitter surface.

Functions§

call
constant
Non-function members of the cluster namespace.
instance_call