Merge dependabot/npm_and_yarn/examples/typescript/http-client-pool/types/node-20...
[poolifier.git] / src / pools / worker.ts
1 import type { MessageChannel } from 'node:worker_threads'
2 import type { CircularArray } from '../circular-array'
3 import type { Task } from '../utility-types'
4
5 /**
6 * Callback invoked when the worker has started successfully.
7 *
8 * @typeParam Worker - Type of worker.
9 */
10 export type OnlineHandler<Worker extends IWorker> = (this: Worker) => void
11
12 /**
13 * Callback invoked if the worker has received a message.
14 *
15 * @typeParam Worker - Type of worker.
16 */
17 export type MessageHandler<Worker extends IWorker> = (
18 this: Worker,
19 message: unknown
20 ) => void
21
22 /**
23 * Callback invoked if the worker raised an error.
24 *
25 * @typeParam Worker - Type of worker.
26 */
27 export type ErrorHandler<Worker extends IWorker> = (
28 this: Worker,
29 error: Error
30 ) => void
31
32 /**
33 * Callback invoked when the worker exits successfully.
34 *
35 * @typeParam Worker - Type of worker.
36 */
37 export type ExitHandler<Worker extends IWorker> = (
38 this: Worker,
39 exitCode: number
40 ) => void
41
42 /**
43 * Measurement statistics.
44 *
45 * @internal
46 */
47 export interface MeasurementStatistics {
48 /**
49 * Measurement aggregate.
50 */
51 aggregate?: number
52 /**
53 * Measurement minimum.
54 */
55 minimum?: number
56 /**
57 * Measurement maximum.
58 */
59 maximum?: number
60 /**
61 * Measurement average.
62 */
63 average?: number
64 /**
65 * Measurement median.
66 */
67 median?: number
68 /**
69 * Measurement history.
70 */
71 readonly history: CircularArray<number>
72 }
73
74 /**
75 * Event loop utilization measurement statistics.
76 *
77 * @internal
78 */
79 export interface EventLoopUtilizationMeasurementStatistics {
80 readonly idle: MeasurementStatistics
81 readonly active: MeasurementStatistics
82 utilization?: number
83 }
84
85 /**
86 * Task statistics.
87 *
88 * @internal
89 */
90 export interface TaskStatistics {
91 /**
92 * Number of executed tasks.
93 */
94 executed: number
95 /**
96 * Number of executing tasks.
97 */
98 executing: number
99 /**
100 * Number of queued tasks.
101 */
102 readonly queued: number
103 /**
104 * Maximum number of queued tasks.
105 */
106 readonly maxQueued?: number
107 /**
108 * Number of stolen tasks.
109 */
110 stolen: number
111 /**
112 * Number of failed tasks.
113 */
114 failed: number
115 }
116
117 /**
118 * Enumeration of worker types.
119 */
120 export const WorkerTypes = Object.freeze({
121 thread: 'thread',
122 cluster: 'cluster'
123 } as const)
124
125 /**
126 * Worker type.
127 */
128 export type WorkerType = keyof typeof WorkerTypes
129
130 /**
131 * Worker information.
132 *
133 * @internal
134 */
135 export interface WorkerInfo {
136 /**
137 * Worker id.
138 */
139 readonly id: number | undefined
140 /**
141 * Worker type.
142 */
143 readonly type: WorkerType
144 /**
145 * Dynamic flag.
146 */
147 dynamic: boolean
148 /**
149 * Ready flag.
150 */
151 ready: boolean
152 /**
153 * Task function names.
154 */
155 taskFunctionNames?: string[]
156 }
157
158 /**
159 * Worker usage statistics.
160 *
161 * @internal
162 */
163 export interface WorkerUsage {
164 /**
165 * Tasks statistics.
166 */
167 readonly tasks: TaskStatistics
168 /**
169 * Tasks runtime statistics.
170 */
171 readonly runTime: MeasurementStatistics
172 /**
173 * Tasks wait time statistics.
174 */
175 readonly waitTime: MeasurementStatistics
176 /**
177 * Tasks event loop utilization statistics.
178 */
179 readonly elu: EventLoopUtilizationMeasurementStatistics
180 }
181
182 /**
183 * Worker choice strategy data.
184 *
185 * @internal
186 */
187 export interface StrategyData {
188 virtualTaskEndTimestamp?: number
189 }
190
191 /**
192 * Worker interface.
193 */
194 export interface IWorker {
195 /**
196 * Worker id.
197 */
198 readonly id?: number
199 readonly threadId?: number
200 /**
201 * Registers an event listener.
202 *
203 * @param event - The event.
204 * @param handler - The event handler.
205 */
206 readonly on: ((event: 'online', handler: OnlineHandler<this>) => void) &
207 ((event: 'message', handler: MessageHandler<this>) => void) &
208 ((event: 'error', handler: ErrorHandler<this>) => void) &
209 ((event: 'exit', handler: ExitHandler<this>) => void)
210 /**
211 * Registers a listener to the exit event that will only be performed once.
212 *
213 * @param event - The `'exit'` event.
214 * @param handler - The exit handler.
215 */
216 readonly once: (event: 'exit', handler: ExitHandler<this>) => void
217 }
218
219 /**
220 * Worker node event detail.
221 *
222 * @internal
223 */
224 export interface WorkerNodeEventDetail {
225 workerId: number
226 }
227
228 /**
229 * Worker node interface.
230 *
231 * @typeParam Worker - Type of worker.
232 * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
233 * @internal
234 */
235 export interface IWorkerNode<Worker extends IWorker, Data = unknown>
236 extends EventTarget {
237 /**
238 * Worker.
239 */
240 readonly worker: Worker
241 /**
242 * Worker info.
243 */
244 readonly info: WorkerInfo
245 /**
246 * Worker usage statistics.
247 */
248 readonly usage: WorkerUsage
249 /**
250 * Worker choice strategy data.
251 * This is used to store data that are specific to the worker choice strategy.
252 */
253 strategyData?: StrategyData
254 /**
255 * Message channel (worker_threads only).
256 */
257 readonly messageChannel?: MessageChannel
258 /**
259 * Tasks queue back pressure size.
260 * This is the number of tasks that can be enqueued before the worker node has back pressure.
261 */
262 tasksQueueBackPressureSize: number
263 /**
264 * Tasks queue size.
265 *
266 * @returns The tasks queue size.
267 */
268 readonly tasksQueueSize: () => number
269 /**
270 * Enqueue task.
271 *
272 * @param task - The task to queue.
273 * @returns The tasks queue size.
274 */
275 readonly enqueueTask: (task: Task<Data>) => number
276 /**
277 * Prepends a task to the tasks queue.
278 *
279 * @param task - The task to prepend.
280 * @returns The tasks queue size.
281 */
282 readonly unshiftTask: (task: Task<Data>) => number
283 /**
284 * Dequeue task.
285 *
286 * @returns The dequeued task.
287 */
288 readonly dequeueTask: () => Task<Data> | undefined
289 /**
290 * Pops a task from the tasks queue.
291 *
292 * @returns The popped task.
293 */
294 readonly popTask: () => Task<Data> | undefined
295 /**
296 * Clears tasks queue.
297 */
298 readonly clearTasksQueue: () => void
299 /**
300 * Whether the worker node has back pressure (i.e. its tasks queue is full).
301 *
302 * @returns `true` if the worker node has back pressure, `false` otherwise.
303 */
304 readonly hasBackPressure: () => boolean
305 /**
306 * Resets usage statistics.
307 */
308 readonly resetUsage: () => void
309 /**
310 * Closes communication channel.
311 */
312 readonly closeChannel: () => void
313 /**
314 * Gets task function worker usage statistics.
315 *
316 * @param name - The task function name.
317 * @returns The task function worker usage statistics if the task function worker usage statistics are initialized, `undefined` otherwise.
318 */
319 readonly getTaskFunctionWorkerUsage: (name: string) => WorkerUsage | undefined
320 /**
321 * Deletes task function worker usage statistics.
322 *
323 * @param name - The task function name.
324 * @returns `true` if the task function worker usage statistics were deleted, `false` otherwise.
325 */
326 readonly deleteTaskFunctionWorkerUsage: (name: string) => boolean
327 }