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