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