1# Cluster 2 3<!--introduced_in=v0.10.0--> 4 5> Stability: 2 - Stable 6 7<!-- source_link=lib/cluster.js --> 8 9A single instance of Node.js runs in a single thread. To take advantage of 10multi-core systems, the user will sometimes want to launch a cluster of Node.js 11processes to handle the load. 12 13The cluster module allows easy creation of child processes that all share 14server ports. 15 16```js 17const cluster = require('cluster'); 18const http = require('http'); 19const numCPUs = require('os').cpus().length; 20 21if (cluster.isMaster) { 22 console.log(`Master ${process.pid} is running`); 23 24 // Fork workers. 25 for (let i = 0; i < numCPUs; i++) { 26 cluster.fork(); 27 } 28 29 cluster.on('exit', (worker, code, signal) => { 30 console.log(`worker ${worker.process.pid} died`); 31 }); 32} else { 33 // Workers can share any TCP connection 34 // In this case it is an HTTP server 35 http.createServer((req, res) => { 36 res.writeHead(200); 37 res.end('hello world\n'); 38 }).listen(8000); 39 40 console.log(`Worker ${process.pid} started`); 41} 42``` 43 44Running Node.js will now share port 8000 between the workers: 45 46```console 47$ node server.js 48Master 3596 is running 49Worker 4324 started 50Worker 4520 started 51Worker 6056 started 52Worker 5644 started 53``` 54 55On Windows, it is not yet possible to set up a named pipe server in a worker. 56 57## How it works 58 59<!--type=misc--> 60 61The worker processes are spawned using the [`child_process.fork()`][] method, 62so that they can communicate with the parent via IPC and pass server 63handles back and forth. 64 65The cluster module supports two methods of distributing incoming 66connections. 67 68The first one (and the default one on all platforms except Windows), 69is the round-robin approach, where the master process listens on a 70port, accepts new connections and distributes them across the workers 71in a round-robin fashion, with some built-in smarts to avoid 72overloading a worker process. 73 74The second approach is where the master process creates the listen 75socket and sends it to interested workers. The workers then accept 76incoming connections directly. 77 78The second approach should, in theory, give the best performance. 79In practice however, distribution tends to be very unbalanced due 80to operating system scheduler vagaries. Loads have been observed 81where over 70% of all connections ended up in just two processes, 82out of a total of eight. 83 84Because `server.listen()` hands off most of the work to the master 85process, there are three cases where the behavior between a normal 86Node.js process and a cluster worker differs: 87 881. `server.listen({fd: 7})` Because the message is passed to the master, 89 file descriptor 7 **in the parent** will be listened on, and the 90 handle passed to the worker, rather than listening to the worker's 91 idea of what the number 7 file descriptor references. 922. `server.listen(handle)` Listening on handles explicitly will cause 93 the worker to use the supplied handle, rather than talk to the master 94 process. 953. `server.listen(0)` Normally, this will cause servers to listen on a 96 random port. However, in a cluster, each worker will receive the 97 same "random" port each time they do `listen(0)`. In essence, the 98 port is random the first time, but predictable thereafter. To listen 99 on a unique port, generate a port number based on the cluster worker ID. 100 101Node.js does not provide routing logic. It is, therefore important to design an 102application such that it does not rely too heavily on in-memory data objects for 103things like sessions and login. 104 105Because workers are all separate processes, they can be killed or 106re-spawned depending on a program's needs, without affecting other 107workers. As long as there are some workers still alive, the server will 108continue to accept connections. If no workers are alive, existing connections 109will be dropped and new connections will be refused. Node.js does not 110automatically manage the number of workers, however. It is the application's 111responsibility to manage the worker pool based on its own needs. 112 113Although a primary use case for the `cluster` module is networking, it can 114also be used for other use cases requiring worker processes. 115 116## Class: `Worker` 117<!-- YAML 118added: v0.7.0 119--> 120 121* Extends: {EventEmitter} 122 123A `Worker` object contains all public information and method about a worker. 124In the master it can be obtained using `cluster.workers`. In a worker 125it can be obtained using `cluster.worker`. 126 127### Event: `'disconnect'` 128<!-- YAML 129added: v0.7.7 130--> 131 132Similar to the `cluster.on('disconnect')` event, but specific to this worker. 133 134```js 135cluster.fork().on('disconnect', () => { 136 // Worker has disconnected 137}); 138``` 139 140### Event: `'error'` 141<!-- YAML 142added: v0.7.3 143--> 144 145This event is the same as the one provided by [`child_process.fork()`][]. 146 147Within a worker, `process.on('error')` may also be used. 148 149### Event: `'exit'` 150<!-- YAML 151added: v0.11.2 152--> 153 154* `code` {number} The exit code, if it exited normally. 155* `signal` {string} The name of the signal (e.g. `'SIGHUP'`) that caused 156 the process to be killed. 157 158Similar to the `cluster.on('exit')` event, but specific to this worker. 159 160```js 161const worker = cluster.fork(); 162worker.on('exit', (code, signal) => { 163 if (signal) { 164 console.log(`worker was killed by signal: ${signal}`); 165 } else if (code !== 0) { 166 console.log(`worker exited with error code: ${code}`); 167 } else { 168 console.log('worker success!'); 169 } 170}); 171``` 172 173### Event: `'listening'` 174<!-- YAML 175added: v0.7.0 176--> 177 178* `address` {Object} 179 180Similar to the `cluster.on('listening')` event, but specific to this worker. 181 182```js 183cluster.fork().on('listening', (address) => { 184 // Worker is listening 185}); 186``` 187 188It is not emitted in the worker. 189 190### Event: `'message'` 191<!-- YAML 192added: v0.7.0 193--> 194 195* `message` {Object} 196* `handle` {undefined|Object} 197 198Similar to the `'message'` event of `cluster`, but specific to this worker. 199 200Within a worker, `process.on('message')` may also be used. 201 202See [`process` event: `'message'`][]. 203 204Here is an example using the message system. It keeps a count in the master 205process of the number of HTTP requests received by the workers: 206 207```js 208const cluster = require('cluster'); 209const http = require('http'); 210 211if (cluster.isMaster) { 212 213 // Keep track of http requests 214 let numReqs = 0; 215 setInterval(() => { 216 console.log(`numReqs = ${numReqs}`); 217 }, 1000); 218 219 // Count requests 220 function messageHandler(msg) { 221 if (msg.cmd && msg.cmd === 'notifyRequest') { 222 numReqs += 1; 223 } 224 } 225 226 // Start workers and listen for messages containing notifyRequest 227 const numCPUs = require('os').cpus().length; 228 for (let i = 0; i < numCPUs; i++) { 229 cluster.fork(); 230 } 231 232 for (const id in cluster.workers) { 233 cluster.workers[id].on('message', messageHandler); 234 } 235 236} else { 237 238 // Worker processes have a http server. 239 http.Server((req, res) => { 240 res.writeHead(200); 241 res.end('hello world\n'); 242 243 // Notify master about the request 244 process.send({ cmd: 'notifyRequest' }); 245 }).listen(8000); 246} 247``` 248 249### Event: `'online'` 250<!-- YAML 251added: v0.7.0 252--> 253 254Similar to the `cluster.on('online')` event, but specific to this worker. 255 256```js 257cluster.fork().on('online', () => { 258 // Worker is online 259}); 260``` 261 262It is not emitted in the worker. 263 264### `worker.disconnect()` 265<!-- YAML 266added: v0.7.7 267changes: 268 - version: v7.3.0 269 pr-url: https://github.com/nodejs/node/pull/10019 270 description: This method now returns a reference to `worker`. 271--> 272 273* Returns: {cluster.Worker} A reference to `worker`. 274 275In a worker, this function will close all servers, wait for the `'close'` event 276on those servers, and then disconnect the IPC channel. 277 278In the master, an internal message is sent to the worker causing it to call 279`.disconnect()` on itself. 280 281Causes `.exitedAfterDisconnect` to be set. 282 283After a server is closed, it will no longer accept new connections, 284but connections may be accepted by any other listening worker. Existing 285connections will be allowed to close as usual. When no more connections exist, 286see [`server.close()`][], the IPC channel to the worker will close allowing it 287to die gracefully. 288 289The above applies *only* to server connections, client connections are not 290automatically closed by workers, and disconnect does not wait for them to close 291before exiting. 292 293In a worker, `process.disconnect` exists, but it is not this function; 294it is [`disconnect()`][]. 295 296Because long living server connections may block workers from disconnecting, it 297may be useful to send a message, so application specific actions may be taken to 298close them. It also may be useful to implement a timeout, killing a worker if 299the `'disconnect'` event has not been emitted after some time. 300 301```js 302if (cluster.isMaster) { 303 const worker = cluster.fork(); 304 let timeout; 305 306 worker.on('listening', (address) => { 307 worker.send('shutdown'); 308 worker.disconnect(); 309 timeout = setTimeout(() => { 310 worker.kill(); 311 }, 2000); 312 }); 313 314 worker.on('disconnect', () => { 315 clearTimeout(timeout); 316 }); 317 318} else if (cluster.isWorker) { 319 const net = require('net'); 320 const server = net.createServer((socket) => { 321 // Connections never end 322 }); 323 324 server.listen(8000); 325 326 process.on('message', (msg) => { 327 if (msg === 'shutdown') { 328 // Initiate graceful close of any connections to server 329 } 330 }); 331} 332``` 333 334### `worker.exitedAfterDisconnect` 335<!-- YAML 336added: v6.0.0 337--> 338 339* {boolean} 340 341This property is `true` if the worker exited due to `.kill()` or 342`.disconnect()`. If the worker exited any other way, it is `false`. If the 343worker has not exited, it is `undefined`. 344 345The boolean [`worker.exitedAfterDisconnect`][] allows distinguishing between 346voluntary and accidental exit, the master may choose not to respawn a worker 347based on this value. 348 349```js 350cluster.on('exit', (worker, code, signal) => { 351 if (worker.exitedAfterDisconnect === true) { 352 console.log('Oh, it was just voluntary – no need to worry'); 353 } 354}); 355 356// kill worker 357worker.kill(); 358``` 359 360### `worker.id` 361<!-- YAML 362added: v0.8.0 363--> 364 365* {number} 366 367Each new worker is given its own unique id, this id is stored in the 368`id`. 369 370While a worker is alive, this is the key that indexes it in 371`cluster.workers`. 372 373### `worker.isConnected()` 374<!-- YAML 375added: v0.11.14 376--> 377 378This function returns `true` if the worker is connected to its master via its 379IPC channel, `false` otherwise. A worker is connected to its master after it 380has been created. It is disconnected after the `'disconnect'` event is emitted. 381 382### `worker.isDead()` 383<!-- YAML 384added: v0.11.14 385--> 386 387This function returns `true` if the worker's process has terminated (either 388because of exiting or being signaled). Otherwise, it returns `false`. 389 390```js 391const cluster = require('cluster'); 392const http = require('http'); 393const numCPUs = require('os').cpus().length; 394 395if (cluster.isMaster) { 396 console.log(`Master ${process.pid} is running`); 397 398 // Fork workers. 399 for (let i = 0; i < numCPUs; i++) { 400 cluster.fork(); 401 } 402 403 cluster.on('fork', (worker) => { 404 console.log('worker is dead:', worker.isDead()); 405 }); 406 407 cluster.on('exit', (worker, code, signal) => { 408 console.log('worker is dead:', worker.isDead()); 409 }); 410} else { 411 // Workers can share any TCP connection. In this case, it is an HTTP server. 412 http.createServer((req, res) => { 413 res.writeHead(200); 414 res.end(`Current process\n ${process.pid}`); 415 process.kill(process.pid); 416 }).listen(8000); 417} 418``` 419 420### `worker.kill([signal])` 421<!-- YAML 422added: v0.9.12 423--> 424 425* `signal` {string} Name of the kill signal to send to the worker 426 process. **Default**: `'SIGTERM'` 427 428This function will kill the worker. In the master, it does this by disconnecting 429the `worker.process`, and once disconnected, killing with `signal`. In the 430worker, it does it by disconnecting the channel, and then exiting with code `0`. 431 432Because `kill()` attempts to gracefully disconnect the worker process, it is 433susceptible to waiting indefinitely for the disconnect to complete. For example, 434if the worker enters an infinite loop, a graceful disconnect will never occur. 435If the graceful disconnect behavior is not needed, use `worker.process.kill()`. 436 437Causes `.exitedAfterDisconnect` to be set. 438 439This method is aliased as `worker.destroy()` for backward compatibility. 440 441In a worker, `process.kill()` exists, but it is not this function; 442it is [`kill()`][]. 443 444### `worker.process` 445<!-- YAML 446added: v0.7.0 447--> 448 449* {ChildProcess} 450 451All workers are created using [`child_process.fork()`][], the returned object 452from this function is stored as `.process`. In a worker, the global `process` 453is stored. 454 455See: [Child Process module][]. 456 457Workers will call `process.exit(0)` if the `'disconnect'` event occurs 458on `process` and `.exitedAfterDisconnect` is not `true`. This protects against 459accidental disconnection. 460 461### `worker.send(message[, sendHandle[, options]][, callback])` 462<!-- YAML 463added: v0.7.0 464changes: 465 - version: v4.0.0 466 pr-url: https://github.com/nodejs/node/pull/2620 467 description: The `callback` parameter is supported now. 468--> 469 470* `message` {Object} 471* `sendHandle` {Handle} 472* `options` {Object} The `options` argument, if present, is an object used to 473 parameterize the sending of certain types of handles. `options` supports 474 the following properties: 475 * `keepOpen` {boolean} A value that can be used when passing instances of 476 `net.Socket`. When `true`, the socket is kept open in the sending process. 477 **Default:** `false`. 478* `callback` {Function} 479* Returns: {boolean} 480 481Send a message to a worker or master, optionally with a handle. 482 483In the master this sends a message to a specific worker. It is identical to 484[`ChildProcess.send()`][]. 485 486In a worker this sends a message to the master. It is identical to 487`process.send()`. 488 489This example will echo back all messages from the master: 490 491```js 492if (cluster.isMaster) { 493 const worker = cluster.fork(); 494 worker.send('hi there'); 495 496} else if (cluster.isWorker) { 497 process.on('message', (msg) => { 498 process.send(msg); 499 }); 500} 501``` 502 503## Event: `'disconnect'` 504<!-- YAML 505added: v0.7.9 506--> 507 508* `worker` {cluster.Worker} 509 510Emitted after the worker IPC channel has disconnected. This can occur when a 511worker exits gracefully, is killed, or is disconnected manually (such as with 512`worker.disconnect()`). 513 514There may be a delay between the `'disconnect'` and `'exit'` events. These 515events can be used to detect if the process is stuck in a cleanup or if there 516are long-living connections. 517 518```js 519cluster.on('disconnect', (worker) => { 520 console.log(`The worker #${worker.id} has disconnected`); 521}); 522``` 523 524## Event: `'exit'` 525<!-- YAML 526added: v0.7.9 527--> 528 529* `worker` {cluster.Worker} 530* `code` {number} The exit code, if it exited normally. 531* `signal` {string} The name of the signal (e.g. `'SIGHUP'`) that caused 532 the process to be killed. 533 534When any of the workers die the cluster module will emit the `'exit'` event. 535 536This can be used to restart the worker by calling [`.fork()`][] again. 537 538```js 539cluster.on('exit', (worker, code, signal) => { 540 console.log('worker %d died (%s). restarting...', 541 worker.process.pid, signal || code); 542 cluster.fork(); 543}); 544``` 545 546See [`child_process` event: `'exit'`][]. 547 548## Event: `'fork'` 549<!-- YAML 550added: v0.7.0 551--> 552 553* `worker` {cluster.Worker} 554 555When a new worker is forked the cluster module will emit a `'fork'` event. 556This can be used to log worker activity, and create a custom timeout. 557 558```js 559const timeouts = []; 560function errorMsg() { 561 console.error('Something must be wrong with the connection ...'); 562} 563 564cluster.on('fork', (worker) => { 565 timeouts[worker.id] = setTimeout(errorMsg, 2000); 566}); 567cluster.on('listening', (worker, address) => { 568 clearTimeout(timeouts[worker.id]); 569}); 570cluster.on('exit', (worker, code, signal) => { 571 clearTimeout(timeouts[worker.id]); 572 errorMsg(); 573}); 574``` 575 576## Event: `'listening'` 577<!-- YAML 578added: v0.7.0 579--> 580 581* `worker` {cluster.Worker} 582* `address` {Object} 583 584After calling `listen()` from a worker, when the `'listening'` event is emitted 585on the server a `'listening'` event will also be emitted on `cluster` in the 586master. 587 588The event handler is executed with two arguments, the `worker` contains the 589worker object and the `address` object contains the following connection 590properties: `address`, `port` and `addressType`. This is very useful if the 591worker is listening on more than one address. 592 593```js 594cluster.on('listening', (worker, address) => { 595 console.log( 596 `A worker is now connected to ${address.address}:${address.port}`); 597}); 598``` 599 600The `addressType` is one of: 601 602* `4` (TCPv4) 603* `6` (TCPv6) 604* `-1` (Unix domain socket) 605* `'udp4'` or `'udp6'` (UDP v4 or v6) 606 607## Event: `'message'` 608<!-- YAML 609added: v2.5.0 610changes: 611 - version: v6.0.0 612 pr-url: https://github.com/nodejs/node/pull/5361 613 description: The `worker` parameter is passed now; see below for details. 614--> 615 616* `worker` {cluster.Worker} 617* `message` {Object} 618* `handle` {undefined|Object} 619 620Emitted when the cluster master receives a message from any worker. 621 622See [`child_process` event: `'message'`][]. 623 624## Event: `'online'` 625<!-- YAML 626added: v0.7.0 627--> 628 629* `worker` {cluster.Worker} 630 631After forking a new worker, the worker should respond with an online message. 632When the master receives an online message it will emit this event. 633The difference between `'fork'` and `'online'` is that fork is emitted when the 634master forks a worker, and `'online'` is emitted when the worker is running. 635 636```js 637cluster.on('online', (worker) => { 638 console.log('Yay, the worker responded after it was forked'); 639}); 640``` 641 642## Event: `'setup'` 643<!-- YAML 644added: v0.7.1 645--> 646 647* `settings` {Object} 648 649Emitted every time [`.setupMaster()`][] is called. 650 651The `settings` object is the `cluster.settings` object at the time 652[`.setupMaster()`][] was called and is advisory only, since multiple calls to 653[`.setupMaster()`][] can be made in a single tick. 654 655If accuracy is important, use `cluster.settings`. 656 657## `cluster.disconnect([callback])` 658<!-- YAML 659added: v0.7.7 660--> 661 662* `callback` {Function} Called when all workers are disconnected and handles are 663 closed. 664 665Calls `.disconnect()` on each worker in `cluster.workers`. 666 667When they are disconnected all internal handles will be closed, allowing the 668master process to die gracefully if no other event is waiting. 669 670The method takes an optional callback argument which will be called when 671finished. 672 673This can only be called from the master process. 674 675## `cluster.fork([env])` 676<!-- YAML 677added: v0.6.0 678--> 679 680* `env` {Object} Key/value pairs to add to worker process environment. 681* Returns: {cluster.Worker} 682 683Spawn a new worker process. 684 685This can only be called from the master process. 686 687## `cluster.isMaster` 688<!-- YAML 689added: v0.8.1 690--> 691 692* {boolean} 693 694True if the process is a master. This is determined 695by the `process.env.NODE_UNIQUE_ID`. If `process.env.NODE_UNIQUE_ID` is 696undefined, then `isMaster` is `true`. 697 698## `cluster.isWorker` 699<!-- YAML 700added: v0.6.0 701--> 702 703* {boolean} 704 705True if the process is not a master (it is the negation of `cluster.isMaster`). 706 707## `cluster.schedulingPolicy` 708<!-- YAML 709added: v0.11.2 710--> 711 712The scheduling policy, either `cluster.SCHED_RR` for round-robin or 713`cluster.SCHED_NONE` to leave it to the operating system. This is a 714global setting and effectively frozen once either the first worker is spawned, 715or [`.setupMaster()`][] is called, whichever comes first. 716 717`SCHED_RR` is the default on all operating systems except Windows. 718Windows will change to `SCHED_RR` once libuv is able to effectively 719distribute IOCP handles without incurring a large performance hit. 720 721`cluster.schedulingPolicy` can also be set through the 722`NODE_CLUSTER_SCHED_POLICY` environment variable. Valid 723values are `'rr'` and `'none'`. 724 725## `cluster.settings` 726<!-- YAML 727added: v0.7.1 728changes: 729 - version: 730 - v13.2.0 731 - v12.16.0 732 pr-url: https://github.com/nodejs/node/pull/30162 733 description: The `serialization` option is supported now. 734 - version: v9.5.0 735 pr-url: https://github.com/nodejs/node/pull/18399 736 description: The `cwd` option is supported now. 737 - version: v9.4.0 738 pr-url: https://github.com/nodejs/node/pull/17412 739 description: The `windowsHide` option is supported now. 740 - version: v8.2.0 741 pr-url: https://github.com/nodejs/node/pull/14140 742 description: The `inspectPort` option is supported now. 743 - version: v6.4.0 744 pr-url: https://github.com/nodejs/node/pull/7838 745 description: The `stdio` option is supported now. 746--> 747 748* {Object} 749 * `execArgv` {string[]} List of string arguments passed to the Node.js 750 executable. **Default:** `process.execArgv`. 751 * `exec` {string} File path to worker file. **Default:** `process.argv[1]`. 752 * `args` {string[]} String arguments passed to worker. 753 **Default:** `process.argv.slice(2)`. 754 * `cwd` {string} Current working directory of the worker process. **Default:** 755 `undefined` (inherits from parent process). 756 * `serialization` {string} Specify the kind of serialization used for sending 757 messages between processes. Possible values are `'json'` and `'advanced'`. 758 See [Advanced serialization for `child_process`][] for more details. 759 **Default:** `false`. 760 * `silent` {boolean} Whether or not to send output to parent's stdio. 761 **Default:** `false`. 762 * `stdio` {Array} Configures the stdio of forked processes. Because the 763 cluster module relies on IPC to function, this configuration must contain an 764 `'ipc'` entry. When this option is provided, it overrides `silent`. 765 * `uid` {number} Sets the user identity of the process. (See setuid(2).) 766 * `gid` {number} Sets the group identity of the process. (See setgid(2).) 767 * `inspectPort` {number|Function} Sets inspector port of worker. 768 This can be a number, or a function that takes no arguments and returns a 769 number. By default each worker gets its own port, incremented from the 770 master's `process.debugPort`. 771 * `windowsHide` {boolean} Hide the forked processes console window that would 772 normally be created on Windows systems. **Default:** `false`. 773 774After calling [`.setupMaster()`][] (or [`.fork()`][]) this settings object will 775contain the settings, including the default values. 776 777This object is not intended to be changed or set manually. 778 779## `cluster.setupMaster([settings])` 780<!-- YAML 781added: v0.7.1 782changes: 783 - version: v6.4.0 784 pr-url: https://github.com/nodejs/node/pull/7838 785 description: The `stdio` option is supported now. 786--> 787 788* `settings` {Object} See [`cluster.settings`][]. 789 790`setupMaster` is used to change the default 'fork' behavior. Once called, 791the settings will be present in `cluster.settings`. 792 793Any settings changes only affect future calls to [`.fork()`][] and have no 794effect on workers that are already running. 795 796The only attribute of a worker that cannot be set via `.setupMaster()` is 797the `env` passed to [`.fork()`][]. 798 799The defaults above apply to the first call only; the defaults for later 800calls are the current values at the time of `cluster.setupMaster()` is called. 801 802```js 803const cluster = require('cluster'); 804cluster.setupMaster({ 805 exec: 'worker.js', 806 args: ['--use', 'https'], 807 silent: true 808}); 809cluster.fork(); // https worker 810cluster.setupMaster({ 811 exec: 'worker.js', 812 args: ['--use', 'http'] 813}); 814cluster.fork(); // http worker 815``` 816 817This can only be called from the master process. 818 819## `cluster.worker` 820<!-- YAML 821added: v0.7.0 822--> 823 824* {Object} 825 826A reference to the current worker object. Not available in the master process. 827 828```js 829const cluster = require('cluster'); 830 831if (cluster.isMaster) { 832 console.log('I am master'); 833 cluster.fork(); 834 cluster.fork(); 835} else if (cluster.isWorker) { 836 console.log(`I am worker #${cluster.worker.id}`); 837} 838``` 839 840## `cluster.workers` 841<!-- YAML 842added: v0.7.0 843--> 844 845* {Object} 846 847A hash that stores the active worker objects, keyed by `id` field. Makes it 848easy to loop through all the workers. It is only available in the master 849process. 850 851A worker is removed from `cluster.workers` after the worker has disconnected 852_and_ exited. The order between these two events cannot be determined in 853advance. However, it is guaranteed that the removal from the `cluster.workers` 854list happens before last `'disconnect'` or `'exit'` event is emitted. 855 856```js 857// Go through all workers 858function eachWorker(callback) { 859 for (const id in cluster.workers) { 860 callback(cluster.workers[id]); 861 } 862} 863eachWorker((worker) => { 864 worker.send('big announcement to all workers'); 865}); 866``` 867 868Using the worker's unique id is the easiest way to locate the worker. 869 870```js 871socket.on('data', (id) => { 872 const worker = cluster.workers[id]; 873}); 874``` 875 876[Advanced serialization for `child_process`]: child_process.md#child_process_advanced_serialization 877[Child Process module]: child_process.md#child_process_child_process_fork_modulepath_args_options 878[`.fork()`]: #cluster_cluster_fork_env 879[`.setupMaster()`]: #cluster_cluster_setupmaster_settings 880[`ChildProcess.send()`]: child_process.md#child_process_subprocess_send_message_sendhandle_options_callback 881[`child_process.fork()`]: child_process.md#child_process_child_process_fork_modulepath_args_options 882[`child_process` event: `'exit'`]: child_process.md#child_process_event_exit 883[`child_process` event: `'message'`]: child_process.md#child_process_event_message 884[`cluster.settings`]: #cluster_cluster_settings 885[`disconnect()`]: child_process.md#child_process_subprocess_disconnect 886[`kill()`]: process.md#process_process_kill_pid_signal 887[`process` event: `'message'`]: process.md#process_event_message 888[`server.close()`]: net.md#net_event_close 889[`worker.exitedAfterDisconnect`]: #cluster_worker_exitedafterdisconnect 890