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