build(deps-dev): apply updates
[poolifier.git] / src / pools / worker.ts
CommitLineData
e1c2dba7 1import type { EventEmitter } from 'node:events'
ded253e2
JB
2import type { MessageChannel, WorkerOptions } from 'node:worker_threads'
3
f12182ad 4import type { CircularBuffer } from '../circular-buffer.js'
31847469 5import type { Task, TaskFunctionProperties } from '../utility-types.js'
f06e48d8 6
671d5154
JB
7/**
8 * Callback invoked when the worker has started successfully.
09b75fef 9 * @typeParam Worker - Type of worker.
671d5154
JB
10 */
11export type OnlineHandler<Worker extends IWorker> = (this: Worker) => void
12
bdaf31cd
JB
13/**
14 * Callback invoked if the worker has received a message.
09b75fef 15 * @typeParam Worker - Type of worker.
bdaf31cd 16 */
50e66724
JB
17export type MessageHandler<Worker extends IWorker> = (
18 this: Worker,
e102732c 19 message: unknown
50e66724 20) => void
bdaf31cd
JB
21
22/**
23 * Callback invoked if the worker raised an error.
09b75fef 24 * @typeParam Worker - Type of worker.
bdaf31cd 25 */
50e66724
JB
26export type ErrorHandler<Worker extends IWorker> = (
27 this: Worker,
e102732c 28 error: Error
50e66724 29) => void
bdaf31cd 30
bdaf31cd
JB
31/**
32 * Callback invoked when the worker exits successfully.
09b75fef 33 * @typeParam Worker - Type of worker.
bdaf31cd 34 */
50e66724
JB
35export type ExitHandler<Worker extends IWorker> = (
36 this: Worker,
e102732c 37 exitCode: number
50e66724 38) => void
bdaf31cd 39
3bcbd4c5
JB
40/**
41 * Worker event handler.
3bcbd4c5
JB
42 * @typeParam Worker - Type of worker.
43 */
44export type EventHandler<Worker extends IWorker> =
45 | OnlineHandler<Worker>
46 | MessageHandler<Worker>
47 | ErrorHandler<Worker>
48 | ExitHandler<Worker>
49
f12182ad
JB
50/**
51 * Measurement history size.
52 */
53export const MeasurementHistorySize = 386
54
f06e48d8 55/**
cd4d348a 56 * Measurement statistics.
f9b4bbf8 57 * @internal
f06e48d8 58 */
cd4d348a 59export interface MeasurementStatistics {
02706357 60 /**
932fc8be 61 * Measurement aggregate.
02706357 62 */
71514351 63 aggregate?: number
f7510105
JB
64 /**
65 * Measurement minimum.
66 */
71514351 67 minimum?: number
f7510105
JB
68 /**
69 * Measurement maximum.
70 */
71514351 71 maximum?: number
02706357 72 /**
cd4d348a 73 * Measurement average.
02706357 74 */
71514351 75 average?: number
02706357 76 /**
cd4d348a 77 * Measurement median.
02706357 78 */
71514351 79 median?: number
02706357 80 /**
cd4d348a 81 * Measurement history.
02706357 82 */
0cd1f28c 83 readonly history: CircularBuffer
a4e07f72
JB
84}
85
5df69fab
JB
86/**
87 * Event loop utilization measurement statistics.
5df69fab
JB
88 * @internal
89 */
90export interface EventLoopUtilizationMeasurementStatistics {
eb7bf744
JB
91 readonly idle: MeasurementStatistics
92 readonly active: MeasurementStatistics
f7510105 93 utilization?: number
5df69fab
JB
94}
95
a4e07f72
JB
96/**
97 * Task statistics.
a4e07f72
JB
98 * @internal
99 */
a4e07f72 100export interface TaskStatistics {
02706357 101 /**
9a0613e9 102 * Number of executed tasks.
02706357 103 */
a4e07f72 104 executed: number
02706357 105 /**
9a0613e9 106 * Number of executing tasks.
02706357 107 */
a4e07f72 108 executing: number
0567595a 109 /**
9a0613e9 110 * Number of queued tasks.
0567595a 111 */
8604aaab 112 readonly queued: number
df593701
JB
113 /**
114 * Maximum number of queued tasks.
115 */
b25a42cd 116 readonly maxQueued?: number
463226a4
JB
117 /**
118 * Number of sequentially stolen tasks.
119 */
120 sequentiallyStolen: number
68cbdc84
JB
121 /**
122 * Number of stolen tasks.
123 */
124 stolen: number
0567595a 125 /**
9a0613e9 126 * Number of failed tasks.
0567595a 127 */
a4e07f72
JB
128 failed: number
129}
130
4b628b48
JB
131/**
132 * Enumeration of worker types.
133 */
3a502712 134export const WorkerTypes: Readonly<{ thread: 'thread'; cluster: 'cluster' }> =
59776ec5
JB
135 Object.freeze({
136 thread: 'thread',
3a502712 137 cluster: 'cluster',
59776ec5 138 } as const)
4b628b48
JB
139
140/**
141 * Worker type.
142 */
143export type WorkerType = keyof typeof WorkerTypes
144
f59e1027
JB
145/**
146 * Worker information.
f59e1027
JB
147 * @internal
148 */
149export interface WorkerInfo {
150 /**
83fa0a36 151 * Worker id.
f59e1027 152 */
eb7bf744 153 readonly id: number | undefined
4b628b48
JB
154 /**
155 * Worker type.
156 */
5b49e864 157 readonly type: WorkerType
8a1260a3
JB
158 /**
159 * Dynamic flag.
160 */
161 dynamic: boolean
f59e1027 162 /**
7c8381eb 163 * Ready flag.
f59e1027 164 */
7c8381eb 165 ready: boolean
5eb72b9e
JB
166 /**
167 * Stealing flag.
168 * This flag is set to `true` when worker node is stealing tasks from another worker node.
169 */
170 stealing: boolean
2eee7220
JB
171 /**
172 * Back pressure flag.
173 * This flag is set to `true` when worker node tasks queue has back pressure.
174 */
175 backPressure: boolean
b558f6b5 176 /**
31847469 177 * Task functions properties.
b558f6b5 178 */
31847469 179 taskFunctionsProperties?: TaskFunctionProperties[]
f59e1027
JB
180}
181
a4e07f72
JB
182/**
183 * Worker usage statistics.
a4e07f72
JB
184 * @internal
185 */
186export interface WorkerUsage {
0567595a 187 /**
a4e07f72 188 * Tasks statistics.
0567595a 189 */
eb7bf744 190 readonly tasks: TaskStatistics
0567595a 191 /**
a4e07f72 192 * Tasks runtime statistics.
0567595a 193 */
eb7bf744 194 readonly runTime: MeasurementStatistics
02706357 195 /**
a4e07f72 196 * Tasks wait time statistics.
02706357 197 */
eb7bf744 198 readonly waitTime: MeasurementStatistics
62c15a68 199 /**
5df69fab 200 * Tasks event loop utilization statistics.
62c15a68 201 */
eb7bf744 202 readonly elu: EventLoopUtilizationMeasurementStatistics
f06e48d8
JB
203}
204
f3a91bac 205/**
9df180cb 206 * Worker choice strategy data.
57a29f75 207 * @internal
f3a91bac
JB
208 */
209export interface StrategyData {
210 virtualTaskEndTimestamp?: number
211}
212
f06e48d8
JB
213/**
214 * Worker interface.
215 */
a4791fb1 216export interface IWorker extends EventEmitter {
f59e1027 217 /**
07e0c9e5 218 * Cluster worker id.
f59e1027 219 */
aecc6e48 220 readonly id?: number
07e0c9e5
JB
221 /**
222 * Worker thread worker id.
223 */
aecc6e48 224 readonly threadId?: number
bdaf31cd 225 /**
88af9bf1 226 * Registers an event handler.
38e795c1 227 * @param event - The event.
48ef9107 228 * @param handler - The event handler.
bdaf31cd 229 */
a4791fb1 230 readonly on: (event: string, handler: EventHandler<this>) => this
c3719753 231 /**
88af9bf1 232 * Registers once an event handler.
c3719753
JB
233 * @param event - The event.
234 * @param handler - The event handler.
bdaf31cd 235 */
a4791fb1 236 readonly once: (event: string, handler: EventHandler<this>) => this
d20cde84
JB
237 /**
238 * Calling `unref()` on a worker allows the thread to exit if this is the only
239 * active handle in the event system. If the worker is already `unref()`ed calling`unref()` again has no effect.
240 * @since v10.5.0
241 */
242 readonly unref?: () => void
07e0c9e5
JB
243 /**
244 * Stop all JavaScript execution in the worker thread as soon as possible.
245 * Returns a Promise for the exit code that is fulfilled when the `'exit' event` is emitted.
246 */
247 readonly terminate?: () => Promise<number>
248 /**
249 * Cluster worker disconnect.
250 */
251 readonly disconnect?: () => void
252 /**
253 * Cluster worker kill.
254 */
255 readonly kill?: (signal?: string) => void
bdaf31cd 256}
f06e48d8 257
5b49e864 258/**
c3719753 259 * Worker node options.
5b49e864
JB
260 * @internal
261 */
c3719753
JB
262export interface WorkerNodeOptions {
263 workerOptions?: WorkerOptions
264 env?: Record<string, unknown>
c63a35a0 265 tasksQueueBackPressureSize: number | undefined
95d1a734 266 tasksQueueBucketSize: number | undefined
fcfc3353 267 tasksQueuePriority: boolean | undefined
9f95d5eb 268}
ec287edf 269
f06e48d8
JB
270/**
271 * Worker node interface.
c319c66b 272 * @typeParam Worker - Type of worker.
e102732c 273 * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
c319c66b 274 * @internal
f06e48d8 275 */
9f95d5eb 276export interface IWorkerNode<Worker extends IWorker, Data = unknown>
e1c2dba7 277 extends EventEmitter {
c319c66b 278 /**
ccd73e07 279 * Worker.
c319c66b 280 */
02706357 281 readonly worker: Worker
f59e1027 282 /**
ccd73e07 283 * Worker info.
f59e1027 284 */
eb7bf744 285 readonly info: WorkerInfo
c319c66b 286 /**
ccd73e07 287 * Worker usage statistics.
c319c66b 288 */
5b49e864 289 readonly usage: WorkerUsage
f3a91bac 290 /**
9df180cb 291 * Worker choice strategy data.
ae3ab61d 292 * This is used to store data that are specific to the worker choice strategy.
f3a91bac
JB
293 */
294 strategyData?: StrategyData
26fb3c18 295 /**
07e0c9e5 296 * Message channel (worker thread only).
26fb3c18
JB
297 */
298 readonly messageChannel?: MessageChannel
20c6f652
JB
299 /**
300 * Tasks queue back pressure size.
301 * This is the number of tasks that can be enqueued before the worker node has back pressure.
302 */
303 tasksQueueBackPressureSize: number
fcfc3353
JB
304 /**
305 * Sets tasks queue priority.
fcfc3353
JB
306 * @param enablePriority - Whether to enable tasks queue priority.
307 */
308 readonly setTasksQueuePriority: (enablePriority: boolean) => void
c319c66b 309 /**
ccd73e07 310 * Tasks queue size.
4b628b48
JB
311 * @returns The tasks queue size.
312 */
313 readonly tasksQueueSize: () => number
314 /**
ccd73e07 315 * Enqueue task.
4b628b48 316 * @param task - The task to queue.
a1763c54 317 * @returns The tasks queue size.
4b628b48
JB
318 */
319 readonly enqueueTask: (task: Task<Data>) => number
320 /**
ccd73e07 321 * Dequeue task.
95d1a734 322 * @param bucket - The prioritized bucket to dequeue from. @defaultValue 0
4b628b48
JB
323 * @returns The dequeued task.
324 */
95d1a734 325 readonly dequeueTask: (bucket?: number) => Task<Data> | undefined
0d4e88b3 326 /**
2eee7220 327 * Dequeue last prioritized task.
0d4e88b3
JB
328 * @returns The dequeued task.
329 */
2eee7220 330 readonly dequeueLastPrioritizedTask: () => Task<Data> | undefined
4b628b48 331 /**
ccd73e07 332 * Clears tasks queue.
4b628b48
JB
333 */
334 readonly clearTasksQueue: () => void
671d5154 335 /**
e2b31e32 336 * Whether the worker node has back pressure (i.e. its tasks queue is full).
671d5154
JB
337 * @returns `true` if the worker node has back pressure, `false` otherwise.
338 */
339 readonly hasBackPressure: () => boolean
3f09ed9f 340 /**
07e0c9e5 341 * Terminates the worker node.
3f09ed9f 342 */
07e0c9e5 343 readonly terminate: () => Promise<void>
c3719753
JB
344 /**
345 * Registers a worker event handler.
c3719753 346 * @param event - The event.
88af9bf1 347 * @param handler - The event handler.
c3719753
JB
348 */
349 readonly registerWorkerEventHandler: (
350 event: string,
3bcbd4c5 351 handler: EventHandler<Worker>
c3719753
JB
352 ) => void
353 /**
354 * Registers once a worker event handler.
c3719753 355 * @param event - The event.
88af9bf1 356 * @param handler - The event handler.
c3719753
JB
357 */
358 readonly registerOnceWorkerEventHandler: (
359 event: string,
3bcbd4c5 360 handler: EventHandler<Worker>
c3719753 361 ) => void
ff128cc9 362 /**
2809112e 363 * Gets task function worker usage statistics.
2809112e
JB
364 * @param name - The task function name.
365 * @returns The task function worker usage statistics if the task function worker usage statistics are initialized, `undefined` otherwise.
ff128cc9 366 */
db0e38ee 367 readonly getTaskFunctionWorkerUsage: (name: string) => WorkerUsage | undefined
adee6053
JB
368 /**
369 * Deletes task function worker usage statistics.
adee6053
JB
370 * @param name - The task function name.
371 * @returns `true` if the task function worker usage statistics were deleted, `false` otherwise.
372 */
373 readonly deleteTaskFunctionWorkerUsage: (name: string) => boolean
f06e48d8 374}
c3719753
JB
375
376/**
377 * Worker node event detail.
c3719753
JB
378 * @internal
379 */
380export interface WorkerNodeEventDetail {
3a20a1a1 381 workerId?: number
c3719753
JB
382 workerNodeKey?: number
383}