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