build: comment out JSR include
[poolifier.git] / src / pools / pool.ts
CommitLineData
c3719753 1import type { ClusterSettings } from 'node:cluster'
ded253e2
JB
2import type { EventEmitterAsyncResource } from 'node:events'
3import type { TransferListItem, WorkerOptions } from 'node:worker_threads'
4
d35e5717 5import type { TaskFunction } from '../worker/task-functions.js'
ded253e2
JB
6import type {
7 WorkerChoiceStrategy,
8 WorkerChoiceStrategyOptions
9} from './selection-strategies/selection-strategies-types.js'
bdaf31cd
JB
10import type {
11 ErrorHandler,
12 ExitHandler,
50e66724 13 IWorker,
4b628b48 14 IWorkerNode,
bdaf31cd 15 MessageHandler,
c4855468 16 OnlineHandler,
4b628b48 17 WorkerType
d35e5717 18} from './worker.js'
bdaf31cd 19
c4855468 20/**
6b27d407 21 * Enumeration of pool types.
c4855468 22 */
6b27d407 23export const PoolTypes = Object.freeze({
c4855468
JB
24 /**
25 * Fixed pool type.
26 */
6b27d407 27 fixed: 'fixed',
c4855468
JB
28 /**
29 * Dynamic pool type.
30 */
6b27d407
JB
31 dynamic: 'dynamic'
32} as const)
33
34/**
35 * Pool type.
36 */
37export type PoolType = keyof typeof PoolTypes
c4855468 38
aee46736
JB
39/**
40 * Enumeration of pool events.
41 */
42export const PoolEvents = Object.freeze({
2431bdb4 43 ready: 'ready',
1f68cede 44 busy: 'busy',
ef3891a3 45 full: 'full',
8e8d9101 46 empty: 'empty',
ef3891a3 47 destroy: 'destroy',
91ee39ed 48 error: 'error',
671d5154
JB
49 taskError: 'taskError',
50 backPressure: 'backPressure'
aee46736
JB
51} as const)
52
53/**
54 * Pool event.
55 */
56export type PoolEvent = keyof typeof PoolEvents
57
6b27d407
JB
58/**
59 * Pool information.
60 */
61export interface PoolInfo {
4b628b48
JB
62 readonly version: string
63 readonly type: PoolType
64 readonly worker: WorkerType
47352846 65 readonly started: boolean
2431bdb4
JB
66 readonly ready: boolean
67 readonly strategy: WorkerChoiceStrategy
0e8587d2 68 readonly strategyRetries: number
4b628b48
JB
69 readonly minSize: number
70 readonly maxSize: number
aa9eede8 71 /** Pool utilization. */
4b628b48 72 readonly utilization?: number
01a59f3c 73 /** Pool total worker nodes. */
4b628b48 74 readonly workerNodes: number
5eb72b9e
JB
75 /** Pool stealing worker nodes. */
76 readonly stealingWorkerNodes?: number
01a59f3c 77 /** Pool idle worker nodes. */
4b628b48 78 readonly idleWorkerNodes: number
01a59f3c 79 /** Pool busy worker nodes. */
4b628b48
JB
80 readonly busyWorkerNodes: number
81 readonly executedTasks: number
82 readonly executingTasks: number
daf86646
JB
83 readonly queuedTasks?: number
84 readonly maxQueuedTasks?: number
a1763c54 85 readonly backPressure?: boolean
68cbdc84 86 readonly stolenTasks?: number
4b628b48
JB
87 readonly failedTasks: number
88 readonly runTime?: {
89 readonly minimum: number
90 readonly maximum: number
3baa0837 91 readonly average?: number
4b628b48 92 readonly median?: number
1dcf8b7b 93 }
4b628b48
JB
94 readonly waitTime?: {
95 readonly minimum: number
96 readonly maximum: number
3baa0837 97 readonly average?: number
4b628b48 98 readonly median?: number
1dcf8b7b 99 }
6b27d407
JB
100}
101
7171d33f 102/**
20c6f652 103 * Worker node tasks queue options.
7171d33f
JB
104 */
105export interface TasksQueueOptions {
106 /**
20c6f652
JB
107 * Maximum tasks queue size per worker node flagging it as back pressured.
108 *
109 * @defaultValue (pool maximum size)^2
110 */
ff3f866a 111 readonly size?: number
20c6f652
JB
112 /**
113 * Maximum number of tasks that can be executed concurrently on a worker node.
7171d33f
JB
114 *
115 * @defaultValue 1
116 */
eb7bf744 117 readonly concurrency?: number
47352846 118 /**
65542a35 119 * Whether to enable task stealing on idle.
47352846
JB
120 *
121 * @defaultValue true
122 */
dbd73092 123 readonly taskStealing?: boolean
47352846 124 /**
af98b972 125 * Whether to enable tasks stealing under back pressure.
47352846
JB
126 *
127 * @defaultValue true
128 */
129 readonly tasksStealingOnBackPressure?: boolean
32b141fd
JB
130 /**
131 * Queued tasks finished timeout in milliseconds at worker node termination.
132 *
653eba19 133 * @defaultValue 2000
32b141fd
JB
134 */
135 readonly tasksFinishedTimeout?: number
7171d33f
JB
136}
137
bdaf31cd
JB
138/**
139 * Options for a poolifier pool.
c319c66b 140 *
d480d708 141 * @typeParam Worker - Type of worker.
bdaf31cd 142 */
50e66724 143export interface PoolOptions<Worker extends IWorker> {
fd04474e
JB
144 /**
145 * A function that will listen for online event on each worker.
68f1f531
JB
146 *
147 * @defaultValue `() => {}`
fd04474e
JB
148 */
149 onlineHandler?: OnlineHandler<Worker>
bdaf31cd
JB
150 /**
151 * A function that will listen for message event on each worker.
68f1f531
JB
152 *
153 * @defaultValue `() => {}`
bdaf31cd
JB
154 */
155 messageHandler?: MessageHandler<Worker>
156 /**
157 * A function that will listen for error event on each worker.
68f1f531
JB
158 *
159 * @defaultValue `() => {}`
bdaf31cd
JB
160 */
161 errorHandler?: ErrorHandler<Worker>
bdaf31cd
JB
162 /**
163 * A function that will listen for exit event on each worker.
68f1f531
JB
164 *
165 * @defaultValue `() => {}`
bdaf31cd
JB
166 */
167 exitHandler?: ExitHandler<Worker>
47352846
JB
168 /**
169 * Whether to start the minimum number of workers at pool initialization.
170 *
8ff61e33 171 * @defaultValue true
47352846
JB
172 */
173 startWorkers?: boolean
bdaf31cd 174 /**
46e857ca 175 * The worker choice strategy to use in this pool.
d29bce7c 176 *
95ec6006 177 * @defaultValue WorkerChoiceStrategies.ROUND_ROBIN
bdaf31cd
JB
178 */
179 workerChoiceStrategy?: WorkerChoiceStrategy
da309861
JB
180 /**
181 * The worker choice strategy options.
182 */
183 workerChoiceStrategyOptions?: WorkerChoiceStrategyOptions
1f68cede
JB
184 /**
185 * Restart worker on error.
186 */
187 restartWorkerOnError?: boolean
bdaf31cd 188 /**
b5604034 189 * Pool events integrated with async resource emission.
bdaf31cd 190 *
38e795c1 191 * @defaultValue true
bdaf31cd
JB
192 */
193 enableEvents?: boolean
ff733df7 194 /**
20c6f652 195 * Pool worker node tasks queue.
ff733df7 196 *
ff733df7
JB
197 * @defaultValue false
198 */
199 enableTasksQueue?: boolean
7171d33f 200 /**
20c6f652 201 * Pool worker node tasks queue options.
7171d33f
JB
202 */
203 tasksQueueOptions?: TasksQueueOptions
c3719753
JB
204 /**
205 * Worker options.
206 *
207 * @see https://nodejs.org/api/worker_threads.html#new-workerfilename-options
208 */
209 workerOptions?: WorkerOptions
210 /**
211 * Key/value pairs to add to worker process environment.
212 *
213 * @see https://nodejs.org/api/cluster.html#cluster_cluster_fork_env
214 */
215 env?: Record<string, unknown>
216 /**
217 * Cluster settings.
218 *
219 * @see https://nodejs.org/api/cluster.html#cluster_cluster_settings
220 */
221 settings?: ClusterSettings
bdaf31cd 222}
a35560ba 223
729c563d
S
224/**
225 * Contract definition for a poolifier pool.
226 *
c4855468 227 * @typeParam Worker - Type of worker which manages this pool.
e102732c
JB
228 * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
229 * @typeParam Response - Type of execution response. This can only be structured-cloneable data.
729c563d 230 */
c4855468
JB
231export interface IPool<
232 Worker extends IWorker,
233 Data = unknown,
234 Response = unknown
235> {
08f3f44c 236 /**
6b27d407 237 * Pool information.
08f3f44c 238 */
6b27d407 239 readonly info: PoolInfo
c4855468
JB
240 /**
241 * Pool worker nodes.
9768f49f
JB
242 *
243 * @internal
c4855468 244 */
4b628b48 245 readonly workerNodes: Array<IWorkerNode<Worker, Data>>
b4904890 246 /**
d67bed32 247 * Pool event emitter integrated with async resource.
b5604034 248 * The async tracking tooling identifier is `poolifier:<PoolType>-<WorkerType>-pool`.
b4904890
JB
249 *
250 * Events that can currently be listened to:
251 *
8e8d9101 252 * - `'ready'`: Emitted when the number of workers created in the pool has reached the minimum size expected and are ready. If the pool is dynamic with a minimum number of workers is set to zero, this event is emitted when at least one dynamic worker is ready.
a9780ad2 253 * - `'busy'`: Emitted when the number of workers created in the pool has reached the maximum size expected and are executing concurrently their tasks quota.
ef3891a3 254 * - `'full'`: Emitted when the pool is dynamic and the number of workers created has reached the maximum size expected.
8e8d9101 255 * - `'empty'`: Emitted when the pool is dynamic with a minimum number of workers set to zero and the number of workers has reached the minimum size expected.
033f1776 256 * - `'destroy'`: Emitted when the pool is destroyed.
91ee39ed
JB
257 * - `'error'`: Emitted when an uncaught error occurs.
258 * - `'taskError'`: Emitted when an error occurs while executing a task.
d92f3ddf 259 * - `'backPressure'`: Emitted when all worker nodes have back pressure (i.e. their tasks queue is full: queue size \>= maximum queue size).
b4904890 260 */
f80125ca 261 readonly emitter?: EventEmitterAsyncResource
729c563d 262 /**
61aa11a6 263 * Executes the specified function in the worker constructor with the task data input parameter.
729c563d 264 *
7d91a8cd
JB
265 * @param data - The optional task input data for the specified task function. This can only be structured-cloneable data.
266 * @param name - The optional name of the task function to execute. If not specified, the default task function will be executed.
7379799c 267 * @param transferList - An optional array of transferable objects to transfer ownership of. Ownership of the transferred objects is given to the chosen pool's worker_threads worker and they should not be used in the main thread afterwards.
ef41a6e6 268 * @returns Promise that will be fulfilled when the task is completed.
729c563d 269 */
7d91a8cd
JB
270 readonly execute: (
271 data?: Data,
272 name?: string,
273 transferList?: TransferListItem[]
274 ) => Promise<Response>
47352846
JB
275 /**
276 * Starts the minimum number of workers in this pool.
277 */
278 readonly start: () => void
280c2a77 279 /**
aa9eede8 280 * Terminates all workers in this pool.
280c2a77 281 */
4b628b48 282 readonly destroy: () => Promise<void>
6703b9f4
JB
283 /**
284 * Whether the specified task function exists in this pool.
285 *
286 * @param name - The name of the task function.
287 * @returns `true` if the task function exists, `false` otherwise.
288 */
289 readonly hasTaskFunction: (name: string) => boolean
290 /**
291 * Adds a task function to this pool.
292 * If a task function with the same name already exists, it will be overwritten.
293 *
294 * @param name - The name of the task function.
3feeab69 295 * @param fn - The task function.
6703b9f4 296 * @returns `true` if the task function was added, `false` otherwise.
cf87987c
JB
297 * @throws {@link https://nodejs.org/api/errors.html#class-typeerror} If the `name` parameter is not a string or an empty string.
298 * @throws {@link https://nodejs.org/api/errors.html#class-typeerror} If the `fn` parameter is not a function.
6703b9f4
JB
299 */
300 readonly addTaskFunction: (
301 name: string,
3feeab69 302 fn: TaskFunction<Data, Response>
e81c38f2 303 ) => Promise<boolean>
6703b9f4
JB
304 /**
305 * Removes a task function from this pool.
306 *
307 * @param name - The name of the task function.
308 * @returns `true` if the task function was removed, `false` otherwise.
309 */
e81c38f2 310 readonly removeTaskFunction: (name: string) => Promise<boolean>
90d7d101
JB
311 /**
312 * Lists the names of task function available in this pool.
313 *
314 * @returns The names of task function available in this pool.
315 */
6703b9f4
JB
316 readonly listTaskFunctionNames: () => string[]
317 /**
318 * Sets the default task function in this pool.
319 *
320 * @param name - The name of the task function.
321 * @returns `true` if the default task function was set, `false` otherwise.
322 */
e81c38f2 323 readonly setDefaultTaskFunction: (name: string) => Promise<boolean>
a35560ba 324 /**
bdede008 325 * Sets the worker choice strategy in this pool.
a35560ba 326 *
38e795c1 327 * @param workerChoiceStrategy - The worker choice strategy.
59219cbb 328 * @param workerChoiceStrategyOptions - The worker choice strategy options.
a35560ba 329 */
4b628b48 330 readonly setWorkerChoiceStrategy: (
59219cbb
JB
331 workerChoiceStrategy: WorkerChoiceStrategy,
332 workerChoiceStrategyOptions?: WorkerChoiceStrategyOptions
333 ) => void
a20f0ba5
JB
334 /**
335 * Sets the worker choice strategy options in this pool.
336 *
337 * @param workerChoiceStrategyOptions - The worker choice strategy options.
338 */
4b628b48 339 readonly setWorkerChoiceStrategyOptions: (
a20f0ba5
JB
340 workerChoiceStrategyOptions: WorkerChoiceStrategyOptions
341 ) => void
342 /**
20c6f652 343 * Enables/disables the worker node tasks queue in this pool.
a20f0ba5 344 *
20c6f652
JB
345 * @param enable - Whether to enable or disable the worker node tasks queue.
346 * @param tasksQueueOptions - The worker node tasks queue options.
a20f0ba5 347 */
4b628b48 348 readonly enableTasksQueue: (
8f52842f
JB
349 enable: boolean,
350 tasksQueueOptions?: TasksQueueOptions
351 ) => void
a20f0ba5 352 /**
20c6f652 353 * Sets the worker node tasks queue options in this pool.
a20f0ba5 354 *
20c6f652 355 * @param tasksQueueOptions - The worker node tasks queue options.
a20f0ba5 356 */
4b628b48 357 readonly setTasksQueueOptions: (tasksQueueOptions: TasksQueueOptions) => void
c97c7edb 358}