feat: add statistics accounting to ELU fields
[poolifier.git] / src / pools / worker.ts
1 import type { CircularArray } from '../circular-array'
2 import type { Queue } from '../queue'
3
4 /**
5 * Callback invoked if the worker has received a message.
6 */
7 export type MessageHandler<Worker extends IWorker> = (
8 this: Worker,
9 m: 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 e: 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 code: number
31 ) => void
32
33 /**
34 * Message object that is passed as a task between main worker and worker.
35 *
36 * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
37 * @internal
38 */
39 export interface Task<Data = unknown> {
40 /**
41 * Task name.
42 */
43 readonly name?: string
44 /**
45 * Task input data that will be passed to the worker.
46 */
47 readonly data?: Data
48 /**
49 * Timestamp.
50 */
51 readonly timestamp?: number
52 /**
53 * Message UUID.
54 */
55 readonly id?: string
56 }
57
58 /**
59 * Measurement statistics.
60 *
61 * @internal
62 */
63 export interface MeasurementStatistics {
64 /**
65 * Measurement aggregate.
66 */
67 aggregate: number
68 /**
69 * Measurement average.
70 */
71 average: number
72 /**
73 * Measurement median.
74 */
75 median: number
76 /**
77 * Measurement history.
78 */
79 history: CircularArray<number>
80 }
81
82 /**
83 * Event loop utilization measurement statistics.
84 *
85 * @internal
86 */
87 export interface EventLoopUtilizationMeasurementStatistics {
88 idle: MeasurementStatistics
89 active: MeasurementStatistics
90 utilization: number
91 }
92
93 /**
94 * Task statistics.
95 *
96 * @internal
97 */
98 export interface TaskStatistics {
99 /**
100 * Number of executed tasks.
101 */
102 executed: number
103 /**
104 * Number of executing tasks.
105 */
106 executing: number
107 /**
108 * Number of queued tasks.
109 */
110 readonly queued: number
111 /**
112 * Number of failed tasks.
113 */
114 failed: number
115 }
116
117 /**
118 * Worker usage statistics.
119 *
120 * @internal
121 */
122 export interface WorkerUsage {
123 /**
124 * Tasks statistics.
125 */
126 tasks: TaskStatistics
127 /**
128 * Tasks runtime statistics.
129 */
130 runTime: MeasurementStatistics
131 /**
132 * Tasks wait time statistics.
133 */
134 waitTime: MeasurementStatistics
135 /**
136 * Tasks event loop utilization statistics.
137 */
138 elu: EventLoopUtilizationMeasurementStatistics
139 }
140
141 /**
142 * Worker interface.
143 */
144 export interface IWorker {
145 /**
146 * Register an event listener.
147 *
148 * @param event - The event.
149 * @param handler - The event handler.
150 */
151 on: ((event: 'message', handler: MessageHandler<this>) => void) &
152 ((event: 'error', handler: ErrorHandler<this>) => void) &
153 ((event: 'online', handler: OnlineHandler<this>) => void) &
154 ((event: 'exit', handler: ExitHandler<this>) => void)
155 /**
156 * Register a listener to the exit event that will only be performed once.
157 *
158 * @param event - `'exit'`.
159 * @param handler - The exit handler.
160 */
161 once: (event: 'exit', handler: ExitHandler<this>) => void
162 }
163
164 /**
165 * Worker node interface.
166 *
167 * @typeParam Worker - Type of worker.
168 * @typeParam Data - Type of data sent to the worker. This can only be serializable data.
169 * @internal
170 */
171 export interface WorkerNode<Worker extends IWorker, Data = unknown> {
172 /**
173 * Worker node worker.
174 */
175 readonly worker: Worker
176 /**
177 * Worker node worker usage statistics.
178 */
179 workerUsage: WorkerUsage
180 /**
181 * Worker node tasks queue.
182 */
183 readonly tasksQueue: Queue<Task<Data>>
184 }