Commit | Line | Data |
---|---|---|
e1c2dba7 | 1 | import type { EventEmitter } from 'node:events' |
ded253e2 JB |
2 | import type { MessageChannel, WorkerOptions } from 'node:worker_threads' |
3 | ||
f12182ad | 4 | import type { CircularBuffer } from '../circular-buffer.js' |
31847469 | 5 | import 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 | */ |
11 | export 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 |
17 | export 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 |
26 | export 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 |
35 | export 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 | */ | |
44 | export 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 | */ | |
53 | export const MeasurementHistorySize = 386 | |
54 | ||
f06e48d8 | 55 | /** |
cd4d348a | 56 | * Measurement statistics. |
f9b4bbf8 | 57 | * @internal |
f06e48d8 | 58 | */ |
cd4d348a | 59 | export 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 | */ | |
90 | export 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 | 100 | export 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 | 134 | export 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 | */ | |
143 | export type WorkerType = keyof typeof WorkerTypes | |
144 | ||
f59e1027 JB |
145 | /** |
146 | * Worker information. | |
f59e1027 JB |
147 | * @internal |
148 | */ | |
149 | export 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 | */ | |
186 | export 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 | */ |
209 | export interface StrategyData { | |
210 | virtualTaskEndTimestamp?: number | |
211 | } | |
212 | ||
f06e48d8 JB |
213 | /** |
214 | * Worker interface. | |
215 | */ | |
a4791fb1 | 216 | export 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 |
262 | export 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 | 276 | export 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 | */ | |
380 | export interface WorkerNodeEventDetail { | |
3a20a1a1 | 381 | workerId?: number |
c3719753 JB |
382 | workerNodeKey?: number |
383 | } |