feat: expose worker type in pool information
[poolifier.git] / src / pools / cluster / fixed.ts
CommitLineData
fc3e6586
JB
1import type { ClusterSettings, Worker } from 'node:cluster'
2import cluster from 'node:cluster'
deb85c12 3import type { MessageValue } from '../../utility-types'
c97c7edb 4import { AbstractPool } from '../abstract-pool'
184855e6
JB
5import {
6 type PoolOptions,
7 type PoolType,
8 PoolTypes,
9 type WorkerType,
10 WorkerTypes
11} from '../pool'
4ade5f1f 12
729c563d
S
13/**
14 * Options for a poolifier cluster pool.
15 */
c97c7edb 16export interface ClusterPoolOptions extends PoolOptions<Worker> {
325f50bc
S
17 /**
18 * Key/value pairs to add to worker process environment.
19 *
20 * @see https://nodejs.org/api/cluster.html#cluster_cluster_fork_env
21 */
22 // eslint-disable-next-line @typescript-eslint/no-explicit-any
23 env?: any
1a76932b
JB
24 /**
25 * Cluster settings.
26 *
27 * @see https://nodejs.org/api/cluster.html#cluster_cluster_settings
28 */
29 settings?: ClusterSettings
4ade5f1f
S
30}
31
32/**
729c563d
S
33 * A cluster pool with a fixed number of workers.
34 *
35 * It is possible to perform tasks in sync or asynchronous mode as you prefer.
4ade5f1f 36 *
729c563d
S
37 * This pool selects the workers in a round robin fashion.
38 *
38e795c1 39 * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
02706357 40 * @typeParam Response - Type of execution response. This can only be serializable data.
325f50bc
S
41 * @author [Christopher Quadflieg](https://github.com/Shinigami92)
42 * @since 2.0.0
4ade5f1f 43 */
d3c8a1a8 44export class FixedClusterPool<
deb85c12
JB
45 Data = unknown,
46 Response = unknown
d3c8a1a8 47> extends AbstractPool<Worker, Data, Response> {
4ade5f1f 48 /**
729c563d
S
49 * Constructs a new poolifier fixed cluster pool.
50 *
38e795c1
JB
51 * @param numberOfWorkers - Number of workers for this pool.
52 * @param filePath - Path to an implementation of a `ClusterWorker` file, which can be relative or absolute.
53 * @param opts - Options for this fixed cluster pool.
4ade5f1f
S
54 */
55 public constructor (
5c5a1fb7 56 numberOfWorkers: number,
c97c7edb 57 filePath: string,
ed6dd37f 58 public readonly opts: ClusterPoolOptions = {}
4ade5f1f 59 ) {
5c5a1fb7 60 super(numberOfWorkers, filePath, opts)
c97c7edb 61 }
4ade5f1f 62
afc003b2 63 /** @inheritDoc */
c97c7edb 64 protected setupHook (): void {
1a76932b 65 cluster.setupPrimary({ ...this.opts.settings, exec: this.filePath })
c97c7edb 66 }
325f50bc 67
afc003b2 68 /** @inheritDoc */
c97c7edb 69 protected isMain (): boolean {
7e0d447f 70 return cluster.isPrimary
4ade5f1f
S
71 }
72
afc003b2 73 /** @inheritDoc */
14a2e530 74 protected destroyWorker (worker: Worker): void {
cefac5ba 75 this.sendToWorker(worker, { kill: 1 })
c97c7edb 76 worker.kill()
4ade5f1f
S
77 }
78
afc003b2 79 /** @inheritDoc */
c97c7edb
S
80 protected sendToWorker (worker: Worker, message: MessageValue<Data>): void {
81 worker.send(message)
4ade5f1f
S
82 }
83
afc003b2 84 /** @inheritDoc */
c319c66b 85 protected registerWorkerMessageListener<Message extends Data | Response>(
4f7fa42a
S
86 worker: Worker,
87 listener: (message: MessageValue<Message>) => void
c97c7edb 88 ): void {
4f7fa42a 89 worker.on('message', listener)
c97c7edb
S
90 }
91
afc003b2 92 /** @inheritDoc */
280c2a77 93 protected createWorker (): Worker {
7e0d447f 94 return cluster.fork(this.opts.env)
4ade5f1f
S
95 }
96
afc003b2 97 /** @inheritDoc */
280c2a77 98 protected afterWorkerSetup (worker: Worker): void {
a05c10de 99 // Listen to worker messages.
be0676b3 100 this.registerWorkerMessageListener(worker, super.workerListener())
4ade5f1f 101 }
7c0ba920 102
afc003b2 103 /** @inheritDoc */
7c0ba920 104 public get type (): PoolType {
6b27d407 105 return PoolTypes.fixed
7c0ba920
JB
106 }
107
184855e6
JB
108 /** @inheritDoc */
109 protected get worker (): WorkerType {
110 return WorkerTypes.cluster
111 }
112
08f3f44c 113 /** @inheritDoc */
6b27d407
JB
114 protected get minSize (): number {
115 return this.numberOfWorkers
116 }
117
118 /** @inheritDoc */
119 protected get maxSize (): number {
08f3f44c
JB
120 return this.numberOfWorkers
121 }
122
afc003b2 123 /** @inheritDoc */
c319c66b 124 protected get full (): boolean {
1f68cede 125 return this.workerNodes.length >= this.numberOfWorkers
c2ade475
JB
126 }
127
afc003b2 128 /** @inheritDoc */
c319c66b 129 protected get busy (): boolean {
c2ade475 130 return this.internalBusy()
7c0ba920 131 }
4ade5f1f 132}