Merge branch 'master' of github.com:poolifier/poolifier
[poolifier.git] / src / pools / worker.ts
1 import type { CircularArray } from '../circular-array'
2 import type { Task } from '../utility-types'
3
4 /**
5 * Callback invoked if the worker has received a message.
6 */
7 export type MessageHandler<Worker extends IWorker> = (
8 this: Worker,
9 message: unknown
10 ) => void
11
12 /**
13 * Callback invoked if the worker raised an error.
14 */
15 export type ErrorHandler<Worker extends IWorker> = (
16 this: Worker,
17 error: Error
18 ) => void
19
20 /**
21 * Callback invoked when the worker has started successfully.
22 */
23 export type OnlineHandler<Worker extends IWorker> = (this: Worker) => void
24
25 /**
26 * Callback invoked when the worker exits successfully.
27 */
28 export type ExitHandler<Worker extends IWorker> = (
29 this: Worker,
30 exitCode: number
31 ) => void
32
33 /**
34 * Measurement statistics.
35 *
36 * @internal
37 */
38 export interface MeasurementStatistics {
39 /**
40 * Measurement aggregate.
41 */
42 aggregate?: number
43 /**
44 * Measurement minimum.
45 */
46 minimum?: number
47 /**
48 * Measurement maximum.
49 */
50 maximum?: number
51 /**
52 * Measurement average.
53 */
54 average?: number
55 /**
56 * Measurement median.
57 */
58 median?: number
59 /**
60 * Measurement history.
61 */
62 readonly history: CircularArray<number>
63 }
64
65 /**
66 * Event loop utilization measurement statistics.
67 *
68 * @internal
69 */
70 export interface EventLoopUtilizationMeasurementStatistics {
71 readonly idle: MeasurementStatistics
72 readonly active: MeasurementStatistics
73 utilization?: number
74 }
75
76 /**
77 * Task statistics.
78 *
79 * @internal
80 */
81 export interface TaskStatistics {
82 /**
83 * Number of executed tasks.
84 */
85 executed: number
86 /**
87 * Number of executing tasks.
88 */
89 executing: number
90 /**
91 * Number of queued tasks.
92 */
93 readonly queued: number
94 /**
95 * Maximum number of queued tasks.
96 */
97 readonly maxQueued?: number
98 /**
99 * Number of failed tasks.
100 */
101 failed: number
102 }
103
104 /**
105 * Enumeration of worker types.
106 */
107 export const WorkerTypes = Object.freeze({
108 cluster: 'cluster',
109 thread: 'thread'
110 } as const)
111
112 /**
113 * Worker type.
114 */
115 export type WorkerType = keyof typeof WorkerTypes
116
117 /**
118 * Worker information.
119 *
120 * @internal
121 */
122 export interface WorkerInfo {
123 /**
124 * Worker id.
125 */
126 readonly id: number | undefined
127 /**
128 * Worker type.
129 */
130 type: WorkerType
131 /**
132 * Dynamic flag.
133 */
134 dynamic: boolean
135 /**
136 * Ready flag.
137 */
138 ready: boolean
139 }
140
141 /**
142 * Worker usage statistics.
143 *
144 * @internal
145 */
146 export interface WorkerUsage {
147 /**
148 * Tasks statistics.
149 */
150 readonly tasks: TaskStatistics
151 /**
152 * Tasks runtime statistics.
153 */
154 readonly runTime: MeasurementStatistics
155 /**
156 * Tasks wait time statistics.
157 */
158 readonly waitTime: MeasurementStatistics
159 /**
160 * Tasks event loop utilization statistics.
161 */
162 readonly elu: EventLoopUtilizationMeasurementStatistics
163 }
164
165 /**
166 * Worker interface.
167 */
168 export interface IWorker {
169 /**
170 * Worker id.
171 */
172 readonly id?: number
173 readonly threadId?: number
174 /**
175 * Registers an event listener.
176 *
177 * @param event - The event.
178 * @param handler - The event handler.
179 */
180 readonly on: ((event: 'message', handler: MessageHandler<this>) => void) &
181 ((event: 'error', handler: ErrorHandler<this>) => void) &
182 ((event: 'online', handler: OnlineHandler<this>) => void) &
183 ((event: 'exit', handler: ExitHandler<this>) => void)
184 /**
185 * Registers a listener to the exit event that will only be performed once.
186 *
187 * @param event - `'exit'`.
188 * @param handler - The exit handler.
189 */
190 readonly once: (event: 'exit', handler: ExitHandler<this>) => void
191 }
192
193 /**
194 * Worker node interface.
195 *
196 * @typeParam Worker - Type of worker.
197 * @typeParam Data - Type of data sent to the worker. This can only be structured-cloneable data.
198 * @internal
199 */
200 export interface IWorkerNode<Worker extends IWorker, Data = unknown> {
201 /**
202 * Worker.
203 */
204 readonly worker: Worker
205 /**
206 * Worker info.
207 */
208 readonly info: WorkerInfo
209 /**
210 * Worker usage statistics.
211 */
212 usage: WorkerUsage
213 /**
214 * Tasks queue size.
215 *
216 * @returns The tasks queue size.
217 */
218 readonly tasksQueueSize: () => number
219 /**
220 * Enqueue task.
221 *
222 * @param task - The task to queue.
223 * @returns The task queue size.
224 */
225 readonly enqueueTask: (task: Task<Data>) => number
226 /**
227 * Dequeue task.
228 *
229 * @returns The dequeued task.
230 */
231 readonly dequeueTask: () => Task<Data> | undefined
232 /**
233 * Clears tasks queue.
234 */
235 readonly clearTasksQueue: () => void
236 /**
237 * Resets usage statistics .
238 */
239 readonly resetUsage: () => void
240 /**
241 * Gets task usage statistics.
242 */
243 readonly getTaskWorkerUsage: (name: string) => WorkerUsage | undefined
244 }