poolifier 2.1.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/lib/index.d.ts +773 -15
- package/lib/index.js +1 -1
- package/package.json +22 -22
- package/CHANGELOG.md +0 -107
- package/lib/pools/abstract-pool.d.ts +0 -245
- package/lib/pools/cluster/dynamic.d.ts +0 -30
- package/lib/pools/cluster/fixed.d.ts +0 -58
- package/lib/pools/pool-internal.d.ts +0 -74
- package/lib/pools/pool.d.ts +0 -26
- package/lib/pools/selection-strategies.d.ts +0 -58
- package/lib/pools/thread/dynamic.d.ts +0 -31
- package/lib/pools/thread/fixed.d.ts +0 -48
- package/lib/utility-types.d.ts +0 -58
- package/lib/utils.d.ts +0 -4
- package/lib/worker/abstract-worker.d.ts +0 -79
- package/lib/worker/cluster-worker.d.ts +0 -32
- package/lib/worker/thread-worker.d.ts +0 -30
- package/lib/worker/worker-options.d.ts +0 -61
package/lib/index.d.ts
CHANGED
|
@@ -1,15 +1,773 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { Worker } from "cluster";
|
|
3
|
+
import { MessagePort, MessageChannel } from "worker_threads";
|
|
4
|
+
import { Worker as Worker$0 } from "worker_threads";
|
|
5
|
+
import EventEmitter from "events";
|
|
6
|
+
import { AsyncResource } from "async_hooks";
|
|
7
|
+
/**
|
|
8
|
+
* Enumeration of kill behaviors.
|
|
9
|
+
*/
|
|
10
|
+
declare const KillBehaviors: Readonly<{
|
|
11
|
+
readonly SOFT: "SOFT";
|
|
12
|
+
readonly HARD: "HARD";
|
|
13
|
+
}>;
|
|
14
|
+
/**
|
|
15
|
+
* Kill behavior.
|
|
16
|
+
*/
|
|
17
|
+
type KillBehavior = keyof typeof KillBehaviors;
|
|
18
|
+
/**
|
|
19
|
+
* Options for workers.
|
|
20
|
+
*/
|
|
21
|
+
interface WorkerOptions {
|
|
22
|
+
/**
|
|
23
|
+
* Maximum waiting time in milliseconds for tasks.
|
|
24
|
+
*
|
|
25
|
+
* After this time, newly created workers will be terminated.
|
|
26
|
+
* The last active time of your worker unit will be updated when a task is submitted to a worker or when a worker terminate a task.
|
|
27
|
+
*
|
|
28
|
+
* - If `killBehavior` is set to `KillBehaviors.HARD` this value represents also the timeout for the tasks that you submit to the pool,
|
|
29
|
+
* when this timeout expires your tasks is interrupted and the worker is killed if is not part of the minimum size of the pool.
|
|
30
|
+
* - If `killBehavior` is set to `KillBehaviors.SOFT` your tasks have no timeout and your workers will not be terminated until your task is completed.
|
|
31
|
+
*
|
|
32
|
+
* @default 60.000 ms
|
|
33
|
+
*/
|
|
34
|
+
maxInactiveTime?: number;
|
|
35
|
+
/**
|
|
36
|
+
* Whether your worker will perform asynchronous or not.
|
|
37
|
+
*
|
|
38
|
+
* @default false
|
|
39
|
+
*/
|
|
40
|
+
async?: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* `killBehavior` dictates if your async unit (worker/process) will be deleted in case that a task is active on it.
|
|
43
|
+
*
|
|
44
|
+
* - SOFT: If `currentTime - lastActiveTime` is greater than `maxInactiveTime` but a task is still running, then the worker **won't** be deleted.
|
|
45
|
+
* - HARD: If `lastActiveTime` is greater than `maxInactiveTime` but a task is still running, then the worker will be deleted.
|
|
46
|
+
*
|
|
47
|
+
* This option only apply to the newly created workers.
|
|
48
|
+
*
|
|
49
|
+
* @default KillBehaviors.SOFT
|
|
50
|
+
*/
|
|
51
|
+
killBehavior?: KillBehavior;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Make all properties in T non-readonly.
|
|
55
|
+
*/
|
|
56
|
+
type Draft<T> = {
|
|
57
|
+
-readonly [P in keyof T]?: T[P];
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Message object that is passed between worker and main worker.
|
|
61
|
+
*/
|
|
62
|
+
interface MessageValue<Data = unknown, MainWorker extends Worker | MessagePort | unknown = unknown> {
|
|
63
|
+
/**
|
|
64
|
+
* Input data that will be passed to the worker.
|
|
65
|
+
*/
|
|
66
|
+
readonly data?: Data;
|
|
67
|
+
/**
|
|
68
|
+
* Id of the message.
|
|
69
|
+
*/
|
|
70
|
+
readonly id?: number;
|
|
71
|
+
/**
|
|
72
|
+
* Kill code.
|
|
73
|
+
*/
|
|
74
|
+
readonly kill?: KillBehavior | 1;
|
|
75
|
+
/**
|
|
76
|
+
* Error.
|
|
77
|
+
*/
|
|
78
|
+
readonly error?: string;
|
|
79
|
+
/**
|
|
80
|
+
* Reference to main worker.
|
|
81
|
+
*
|
|
82
|
+
* _Only for internal use_
|
|
83
|
+
*/
|
|
84
|
+
readonly parent?: MainWorker;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* An object holding the worker that will be used to resolve/rejects the promise later on.
|
|
88
|
+
*
|
|
89
|
+
* @template Worker Type of worker.
|
|
90
|
+
* @template Response Type of response of execution. This can only be serializable data.
|
|
91
|
+
*/
|
|
92
|
+
interface PromiseWorkerResponseWrapper<Worker extends IWorker, Response = unknown> {
|
|
93
|
+
/**
|
|
94
|
+
* Resolve callback to fulfill the promise.
|
|
95
|
+
*/
|
|
96
|
+
readonly resolve: (value: Response) => void;
|
|
97
|
+
/**
|
|
98
|
+
* Reject callback to reject the promise.
|
|
99
|
+
*/
|
|
100
|
+
readonly reject: (reason?: string) => void;
|
|
101
|
+
/**
|
|
102
|
+
* The worker that has the assigned task.
|
|
103
|
+
*/
|
|
104
|
+
readonly worker: Worker;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Enumeration of worker choice strategies.
|
|
108
|
+
*/
|
|
109
|
+
declare const WorkerChoiceStrategies: Readonly<{
|
|
110
|
+
readonly ROUND_ROBIN: "ROUND_ROBIN";
|
|
111
|
+
readonly LESS_RECENTLY_USED: "LESS_RECENTLY_USED";
|
|
112
|
+
}>;
|
|
113
|
+
/**
|
|
114
|
+
* Worker choice strategy.
|
|
115
|
+
*/
|
|
116
|
+
type WorkerChoiceStrategy = keyof typeof WorkerChoiceStrategies;
|
|
117
|
+
/**
|
|
118
|
+
* The worker choice strategy context.
|
|
119
|
+
*
|
|
120
|
+
* @template Worker Type of worker.
|
|
121
|
+
* @template Data Type of data sent to the worker. This can only be serializable data.
|
|
122
|
+
* @template Response Type of response of execution. This can only be serializable data.
|
|
123
|
+
*/
|
|
124
|
+
declare class WorkerChoiceStrategyContext<Worker extends IWorker, Data, Response> {
|
|
125
|
+
private readonly pool;
|
|
126
|
+
private createDynamicallyWorkerCallback;
|
|
127
|
+
// Will be set by setter in constructor
|
|
128
|
+
private workerChoiceStrategy;
|
|
129
|
+
/**
|
|
130
|
+
* Worker choice strategy context constructor.
|
|
131
|
+
*
|
|
132
|
+
* @param pool The pool instance.
|
|
133
|
+
* @param createDynamicallyWorkerCallback The worker creation callback for dynamic pool.
|
|
134
|
+
* @param workerChoiceStrategy The worker choice strategy.
|
|
135
|
+
*/
|
|
136
|
+
constructor(pool: IPoolInternal<Worker, Data, Response>, createDynamicallyWorkerCallback: () => Worker, workerChoiceStrategy?: WorkerChoiceStrategy);
|
|
137
|
+
/**
|
|
138
|
+
* Get the worker choice strategy instance specific to the pool type.
|
|
139
|
+
*
|
|
140
|
+
* @param workerChoiceStrategy The worker choice strategy.
|
|
141
|
+
* @returns The worker choice strategy instance for the pool type.
|
|
142
|
+
*/
|
|
143
|
+
private getPoolWorkerChoiceStrategy;
|
|
144
|
+
/**
|
|
145
|
+
* Set the worker choice strategy to use in the context.
|
|
146
|
+
*
|
|
147
|
+
* @param workerChoiceStrategy The worker choice strategy to set.
|
|
148
|
+
*/
|
|
149
|
+
setWorkerChoiceStrategy(workerChoiceStrategy: WorkerChoiceStrategy): void;
|
|
150
|
+
/**
|
|
151
|
+
* Choose a worker with the underlying selection strategy.
|
|
152
|
+
*
|
|
153
|
+
* @returns The chosen one.
|
|
154
|
+
*/
|
|
155
|
+
execute(): Worker;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Contract definition for a poolifier pool.
|
|
159
|
+
*
|
|
160
|
+
* @template Data Type of data sent to the worker. This can only be serializable data.
|
|
161
|
+
* @template Response Type of response of execution. This can only be serializable data.
|
|
162
|
+
*/
|
|
163
|
+
interface IPool<Data = unknown, Response = unknown> {
|
|
164
|
+
/**
|
|
165
|
+
* Perform the task specified in the constructor with the data parameter.
|
|
166
|
+
*
|
|
167
|
+
* @param data The input for the specified task. This can only be serializable data.
|
|
168
|
+
* @returns Promise that will be resolved when the task is successfully completed.
|
|
169
|
+
*/
|
|
170
|
+
execute(data: Data): Promise<Response>;
|
|
171
|
+
/**
|
|
172
|
+
* Shut down every current worker in this pool.
|
|
173
|
+
*/
|
|
174
|
+
destroy(): Promise<void>;
|
|
175
|
+
/**
|
|
176
|
+
* Set the worker choice strategy in this pool.
|
|
177
|
+
*
|
|
178
|
+
* @param workerChoiceStrategy The worker choice strategy.
|
|
179
|
+
*/
|
|
180
|
+
setWorkerChoiceStrategy(workerChoiceStrategy: WorkerChoiceStrategy): void;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Pool types.
|
|
184
|
+
*/
|
|
185
|
+
declare enum PoolType {
|
|
186
|
+
FIXED = "fixed",
|
|
187
|
+
DYNAMIC = "dynamic"
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Internal poolifier pool emitter.
|
|
191
|
+
*/
|
|
192
|
+
declare class PoolEmitter extends EventEmitter {
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Internal contract definition for a poolifier pool.
|
|
196
|
+
*
|
|
197
|
+
* @template Worker Type of worker which manages this pool.
|
|
198
|
+
* @template Data Type of data sent to the worker.
|
|
199
|
+
* @template Response Type of response of execution.
|
|
200
|
+
*/
|
|
201
|
+
interface IPoolInternal<Worker extends IWorker, Data = unknown, Response = unknown> extends IPool<Data, Response> {
|
|
202
|
+
/**
|
|
203
|
+
* List of currently available workers.
|
|
204
|
+
*/
|
|
205
|
+
readonly workers: Worker[];
|
|
206
|
+
/**
|
|
207
|
+
* The tasks map.
|
|
208
|
+
*
|
|
209
|
+
* - `key`: The `Worker`
|
|
210
|
+
* - `value`: Number of tasks currently in progress on the worker.
|
|
211
|
+
*/
|
|
212
|
+
readonly tasks: Map<Worker, number>;
|
|
213
|
+
/**
|
|
214
|
+
* Emitter on which events can be listened to.
|
|
215
|
+
*
|
|
216
|
+
* Events that can currently be listened to:
|
|
217
|
+
*
|
|
218
|
+
* - `'busy'`
|
|
219
|
+
*/
|
|
220
|
+
readonly emitter?: PoolEmitter;
|
|
221
|
+
/**
|
|
222
|
+
* Pool type.
|
|
223
|
+
*
|
|
224
|
+
* If it is `'dynamic'`, it provides the `max` property.
|
|
225
|
+
*/
|
|
226
|
+
readonly type: PoolType;
|
|
227
|
+
/**
|
|
228
|
+
* Maximum number of workers that can be created by this pool.
|
|
229
|
+
*/
|
|
230
|
+
readonly max?: number;
|
|
231
|
+
/**
|
|
232
|
+
* Whether the pool is busy or not.
|
|
233
|
+
*
|
|
234
|
+
* The pool busyness boolean status.
|
|
235
|
+
*/
|
|
236
|
+
readonly busy: boolean;
|
|
237
|
+
/**
|
|
238
|
+
* Number of tasks currently concurrently running.
|
|
239
|
+
*/
|
|
240
|
+
readonly numberOfRunningTasks: number;
|
|
241
|
+
/**
|
|
242
|
+
* Find a tasks map entry with a free worker based on the number of tasks the worker has applied.
|
|
243
|
+
*
|
|
244
|
+
* If an entry is found with a worker that has `0` tasks, it is detected as free.
|
|
245
|
+
*
|
|
246
|
+
* If no tasks map entry with a free worker was found, `false` will be returned.
|
|
247
|
+
*
|
|
248
|
+
* @returns A tasks map entry with a free worker if there was one, otherwise `false`.
|
|
249
|
+
*/
|
|
250
|
+
findFreeTasksMapEntry(): [
|
|
251
|
+
Worker,
|
|
252
|
+
number
|
|
253
|
+
] | false;
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Callback invoked if the worker has received a message.
|
|
257
|
+
*/
|
|
258
|
+
type MessageHandler<Worker> = (this: Worker, m: unknown) => void;
|
|
259
|
+
/**
|
|
260
|
+
* Callback invoked if the worker raised an error.
|
|
261
|
+
*/
|
|
262
|
+
type ErrorHandler<Worker> = (this: Worker, e: Error) => void;
|
|
263
|
+
/**
|
|
264
|
+
* Callback invoked when the worker has started successfully.
|
|
265
|
+
*/
|
|
266
|
+
type OnlineHandler<Worker> = (this: Worker) => void;
|
|
267
|
+
/**
|
|
268
|
+
* Callback invoked when the worker exits successfully.
|
|
269
|
+
*/
|
|
270
|
+
type ExitHandler<Worker> = (this: Worker, code: number) => void;
|
|
271
|
+
/**
|
|
272
|
+
* Basic interface that describes the minimum required implementation of listener events for a pool-worker.
|
|
273
|
+
*/
|
|
274
|
+
interface IWorker {
|
|
275
|
+
/**
|
|
276
|
+
* Register a listener to the message event.
|
|
277
|
+
*
|
|
278
|
+
* @param event `'message'`.
|
|
279
|
+
* @param handler The message handler.
|
|
280
|
+
*/
|
|
281
|
+
on(event: "message", handler: MessageHandler<this>): void;
|
|
282
|
+
/**
|
|
283
|
+
* Register a listener to the error event.
|
|
284
|
+
*
|
|
285
|
+
* @param event `'error'`.
|
|
286
|
+
* @param handler The error handler.
|
|
287
|
+
*/
|
|
288
|
+
on(event: "error", handler: ErrorHandler<this>): void;
|
|
289
|
+
/**
|
|
290
|
+
* Register a listener to the online event.
|
|
291
|
+
*
|
|
292
|
+
* @param event `'online'`.
|
|
293
|
+
* @param handler The online handler.
|
|
294
|
+
*/
|
|
295
|
+
on(event: "online", handler: OnlineHandler<this>): void;
|
|
296
|
+
/**
|
|
297
|
+
* Register a listener to the exit event.
|
|
298
|
+
*
|
|
299
|
+
* @param event `'exit'`.
|
|
300
|
+
* @param handler The exit handler.
|
|
301
|
+
*/
|
|
302
|
+
on(event: "exit", handler: ExitHandler<this>): void;
|
|
303
|
+
/**
|
|
304
|
+
* Register a listener to the exit event that will only performed once.
|
|
305
|
+
*
|
|
306
|
+
* @param event `'exit'`.
|
|
307
|
+
* @param handler The exit handler.
|
|
308
|
+
*/
|
|
309
|
+
once(event: "exit", handler: ExitHandler<this>): void;
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Options for a poolifier pool.
|
|
313
|
+
*/
|
|
314
|
+
interface PoolOptions<Worker> {
|
|
315
|
+
/**
|
|
316
|
+
* A function that will listen for message event on each worker.
|
|
317
|
+
*/
|
|
318
|
+
messageHandler?: MessageHandler<Worker>;
|
|
319
|
+
/**
|
|
320
|
+
* A function that will listen for error event on each worker.
|
|
321
|
+
*/
|
|
322
|
+
errorHandler?: ErrorHandler<Worker>;
|
|
323
|
+
/**
|
|
324
|
+
* A function that will listen for online event on each worker.
|
|
325
|
+
*/
|
|
326
|
+
onlineHandler?: OnlineHandler<Worker>;
|
|
327
|
+
/**
|
|
328
|
+
* A function that will listen for exit event on each worker.
|
|
329
|
+
*/
|
|
330
|
+
exitHandler?: ExitHandler<Worker>;
|
|
331
|
+
/**
|
|
332
|
+
* The work choice strategy to use in this pool.
|
|
333
|
+
*/
|
|
334
|
+
workerChoiceStrategy?: WorkerChoiceStrategy;
|
|
335
|
+
/**
|
|
336
|
+
* Pool events emission.
|
|
337
|
+
*
|
|
338
|
+
* @default true
|
|
339
|
+
*/
|
|
340
|
+
enableEvents?: boolean;
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Base class containing some shared logic for all poolifier pools.
|
|
344
|
+
*
|
|
345
|
+
* @template Worker Type of worker which manages this pool.
|
|
346
|
+
* @template Data Type of data sent to the worker. This can only be serializable data.
|
|
347
|
+
* @template Response Type of response of execution. This can only be serializable data.
|
|
348
|
+
*/
|
|
349
|
+
declare abstract class AbstractPool<Worker extends IWorker, Data = unknown, Response = unknown> implements IPoolInternal<Worker, Data, Response> {
|
|
350
|
+
readonly numberOfWorkers: number;
|
|
351
|
+
readonly filePath: string;
|
|
352
|
+
readonly opts: PoolOptions<Worker>;
|
|
353
|
+
/** @inheritdoc */
|
|
354
|
+
readonly workers: Worker[];
|
|
355
|
+
/** @inheritdoc */
|
|
356
|
+
readonly tasks: Map<Worker, number>;
|
|
357
|
+
/** @inheritdoc */
|
|
358
|
+
readonly emitter?: PoolEmitter;
|
|
359
|
+
/** @inheritdoc */
|
|
360
|
+
readonly max?: number;
|
|
361
|
+
/**
|
|
362
|
+
* The promise map.
|
|
363
|
+
*
|
|
364
|
+
* - `key`: This is the message Id of each submitted task.
|
|
365
|
+
* - `value`: An object that contains the worker, the resolve function and the reject function.
|
|
366
|
+
*
|
|
367
|
+
* When we receive a message from the worker we get a map entry and resolve/reject the promise based on the message.
|
|
368
|
+
*/
|
|
369
|
+
protected promiseMap: Map<number, PromiseWorkerResponseWrapper<Worker, Response>>;
|
|
370
|
+
/**
|
|
371
|
+
* Id of the next message.
|
|
372
|
+
*/
|
|
373
|
+
protected nextMessageId: number;
|
|
374
|
+
/**
|
|
375
|
+
* Worker choice strategy instance implementing the worker choice algorithm.
|
|
376
|
+
*
|
|
377
|
+
* Default to a strategy implementing a round robin algorithm.
|
|
378
|
+
*/
|
|
379
|
+
protected workerChoiceStrategyContext: WorkerChoiceStrategyContext<Worker, Data, Response>;
|
|
380
|
+
/**
|
|
381
|
+
* Constructs a new poolifier pool.
|
|
382
|
+
*
|
|
383
|
+
* @param numberOfWorkers Number of workers that this pool should manage.
|
|
384
|
+
* @param filePath Path to the worker-file.
|
|
385
|
+
* @param opts Options for the pool.
|
|
386
|
+
*/
|
|
387
|
+
constructor(numberOfWorkers: number, filePath: string, opts: PoolOptions<Worker>);
|
|
388
|
+
private checkFilePath;
|
|
389
|
+
private checkNumberOfWorkers;
|
|
390
|
+
private checkPoolOptions;
|
|
391
|
+
/** @inheritdoc */
|
|
392
|
+
abstract get type(): PoolType;
|
|
393
|
+
/** @inheritdoc */
|
|
394
|
+
get numberOfRunningTasks(): number;
|
|
395
|
+
/** @inheritdoc */
|
|
396
|
+
setWorkerChoiceStrategy(workerChoiceStrategy: WorkerChoiceStrategy): void;
|
|
397
|
+
/** @inheritdoc */
|
|
398
|
+
abstract get busy(): boolean;
|
|
399
|
+
protected internalGetBusyStatus(): boolean;
|
|
400
|
+
/** @inheritdoc */
|
|
401
|
+
findFreeTasksMapEntry(): [
|
|
402
|
+
Worker,
|
|
403
|
+
number
|
|
404
|
+
] | false;
|
|
405
|
+
/** @inheritdoc */
|
|
406
|
+
execute(data: Data): Promise<Response>;
|
|
407
|
+
/** @inheritdoc */
|
|
408
|
+
destroy(): Promise<void>;
|
|
409
|
+
/**
|
|
410
|
+
* Shut down given worker.
|
|
411
|
+
*
|
|
412
|
+
* @param worker A worker within `workers`.
|
|
413
|
+
*/
|
|
414
|
+
protected abstract destroyWorker(worker: Worker): void | Promise<void>;
|
|
415
|
+
/**
|
|
416
|
+
* Setup hook that can be overridden by a Poolifier pool implementation
|
|
417
|
+
* to run code before workers are created in the abstract constructor.
|
|
418
|
+
*/
|
|
419
|
+
protected setupHook(): void;
|
|
420
|
+
/**
|
|
421
|
+
* Should return whether the worker is the main worker or not.
|
|
422
|
+
*/
|
|
423
|
+
protected abstract isMain(): boolean;
|
|
424
|
+
/**
|
|
425
|
+
* Increase the number of tasks that the given worker has applied.
|
|
426
|
+
*
|
|
427
|
+
* @param worker Worker whose tasks are increased.
|
|
428
|
+
*/
|
|
429
|
+
protected increaseWorkersTask(worker: Worker): void;
|
|
430
|
+
/**
|
|
431
|
+
* Decrease the number of tasks that the given worker has applied.
|
|
432
|
+
*
|
|
433
|
+
* @param worker Worker whose tasks are decreased.
|
|
434
|
+
*/
|
|
435
|
+
protected decreaseWorkersTasks(worker: Worker): void;
|
|
436
|
+
/**
|
|
437
|
+
* Step the number of tasks that the given worker has applied.
|
|
438
|
+
*
|
|
439
|
+
* @param worker Worker whose tasks are set.
|
|
440
|
+
* @param step Worker number of tasks step.
|
|
441
|
+
*/
|
|
442
|
+
private stepWorkerNumberOfTasks;
|
|
443
|
+
/**
|
|
444
|
+
* Removes the given worker from the pool.
|
|
445
|
+
*
|
|
446
|
+
* @param worker Worker that will be removed.
|
|
447
|
+
*/
|
|
448
|
+
protected removeWorker(worker: Worker): void;
|
|
449
|
+
/**
|
|
450
|
+
* Choose a worker for the next task.
|
|
451
|
+
*
|
|
452
|
+
* The default implementation uses a round robin algorithm to distribute the load.
|
|
453
|
+
*
|
|
454
|
+
* @returns Worker.
|
|
455
|
+
*/
|
|
456
|
+
protected chooseWorker(): Worker;
|
|
457
|
+
/**
|
|
458
|
+
* Send a message to the given worker.
|
|
459
|
+
*
|
|
460
|
+
* @param worker The worker which should receive the message.
|
|
461
|
+
* @param message The message.
|
|
462
|
+
*/
|
|
463
|
+
protected abstract sendToWorker(worker: Worker, message: MessageValue<Data>): void;
|
|
464
|
+
/**
|
|
465
|
+
* Register a listener callback on a given worker.
|
|
466
|
+
*
|
|
467
|
+
* @param worker A worker.
|
|
468
|
+
* @param listener A message listener callback.
|
|
469
|
+
*/
|
|
470
|
+
protected abstract registerWorkerMessageListener<Message extends Data | Response>(worker: Worker, listener: (message: MessageValue<Message>) => void): void;
|
|
471
|
+
protected internalExecute(worker: Worker, messageId: number): Promise<Response>;
|
|
472
|
+
/**
|
|
473
|
+
* Returns a newly created worker.
|
|
474
|
+
*/
|
|
475
|
+
protected abstract createWorker(): Worker;
|
|
476
|
+
/**
|
|
477
|
+
* Function that can be hooked up when a worker has been newly created and moved to the workers registry.
|
|
478
|
+
*
|
|
479
|
+
* Can be used to update the `maxListeners` or binding the `main-worker`<->`worker` connection if not bind by default.
|
|
480
|
+
*
|
|
481
|
+
* @param worker The newly created worker.
|
|
482
|
+
*/
|
|
483
|
+
protected abstract afterWorkerSetup(worker: Worker): void;
|
|
484
|
+
/**
|
|
485
|
+
* Creates a new worker for this pool and sets it up completely.
|
|
486
|
+
*
|
|
487
|
+
* @returns New, completely set up worker.
|
|
488
|
+
*/
|
|
489
|
+
protected createAndSetupWorker(): Worker;
|
|
490
|
+
/**
|
|
491
|
+
* This function is the listener registered for each worker.
|
|
492
|
+
*
|
|
493
|
+
* @returns The listener function to execute when a message is sent from a worker.
|
|
494
|
+
*/
|
|
495
|
+
protected workerListener(): (message: MessageValue<Response>) => void;
|
|
496
|
+
private checkAndEmitBusy;
|
|
497
|
+
}
|
|
498
|
+
/**
|
|
499
|
+
* Options for a poolifier cluster pool.
|
|
500
|
+
*/
|
|
501
|
+
interface ClusterPoolOptions extends PoolOptions<Worker> {
|
|
502
|
+
/**
|
|
503
|
+
* Key/value pairs to add to worker process environment.
|
|
504
|
+
*
|
|
505
|
+
* @see https://nodejs.org/api/cluster.html#cluster_cluster_fork_env
|
|
506
|
+
*/
|
|
507
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
508
|
+
env?: any;
|
|
509
|
+
}
|
|
510
|
+
/**
|
|
511
|
+
* A cluster pool with a fixed number of workers.
|
|
512
|
+
*
|
|
513
|
+
* It is possible to perform tasks in sync or asynchronous mode as you prefer.
|
|
514
|
+
*
|
|
515
|
+
* This pool selects the workers in a round robin fashion.
|
|
516
|
+
*
|
|
517
|
+
* @template DataType of data sent to the worker. This can only be serializable data.
|
|
518
|
+
* @template ResponseType of response of execution. This can only be serializable data.
|
|
519
|
+
* @author [Christopher Quadflieg](https://github.com/Shinigami92)
|
|
520
|
+
* @since 2.0.0
|
|
521
|
+
*/
|
|
522
|
+
declare class FixedClusterPool<Data = unknown, Response = unknown> extends AbstractPool<Worker, Data, Response> {
|
|
523
|
+
readonly opts: ClusterPoolOptions;
|
|
524
|
+
/**
|
|
525
|
+
* Constructs a new poolifier fixed cluster pool.
|
|
526
|
+
*
|
|
527
|
+
* @param numberOfWorkers Number of workers for this pool.
|
|
528
|
+
* @param filePath Path to an implementation of a `ClusterWorker` file, which can be relative or absolute.
|
|
529
|
+
* @param [opts={}] Options for this fixed cluster pool.
|
|
530
|
+
*/
|
|
531
|
+
constructor(numberOfWorkers: number, filePath: string, opts?: ClusterPoolOptions);
|
|
532
|
+
/** @inheritdoc */
|
|
533
|
+
protected setupHook(): void;
|
|
534
|
+
/** @inheritdoc */
|
|
535
|
+
protected isMain(): boolean;
|
|
536
|
+
/** @inheritdoc */
|
|
537
|
+
destroyWorker(worker: Worker): void;
|
|
538
|
+
/** @inheritdoc */
|
|
539
|
+
protected sendToWorker(worker: Worker, message: MessageValue<Data>): void;
|
|
540
|
+
/** @inheritdoc */
|
|
541
|
+
registerWorkerMessageListener<Message extends Data | Response>(worker: Worker, listener: (message: MessageValue<Message>) => void): void;
|
|
542
|
+
/** @inheritdoc */
|
|
543
|
+
protected createWorker(): Worker;
|
|
544
|
+
/** @inheritdoc */
|
|
545
|
+
protected afterWorkerSetup(worker: Worker): void;
|
|
546
|
+
/** @inheritdoc */
|
|
547
|
+
get type(): PoolType;
|
|
548
|
+
/** @inheritdoc */
|
|
549
|
+
get busy(): boolean;
|
|
550
|
+
}
|
|
551
|
+
/**
|
|
552
|
+
* A cluster pool with a dynamic number of workers, but a guaranteed minimum number of workers.
|
|
553
|
+
*
|
|
554
|
+
* This cluster pool creates new workers when the others are busy, up to the maximum number of workers.
|
|
555
|
+
* When the maximum number of workers is reached, an event is emitted. If you want to listen to this event, use the pool's `emitter`.
|
|
556
|
+
*
|
|
557
|
+
* @template DataType of data sent to the worker. This can only be serializable data.
|
|
558
|
+
* @template ResponseType of response of execution. This can only be serializable data.
|
|
559
|
+
* @author [Christopher Quadflieg](https://github.com/Shinigami92)
|
|
560
|
+
* @since 2.0.0
|
|
561
|
+
*/
|
|
562
|
+
declare class DynamicClusterPool<Data = unknown, Response = unknown> extends FixedClusterPool<Data, Response> {
|
|
563
|
+
readonly max: number;
|
|
564
|
+
/**
|
|
565
|
+
* Constructs a new poolifier dynamic cluster pool.
|
|
566
|
+
*
|
|
567
|
+
* @param min Minimum number of workers which are always active.
|
|
568
|
+
* @param max Maximum number of workers that can be created by this pool.
|
|
569
|
+
* @param filePath Path to an implementation of a `ClusterWorker` file, which can be relative or absolute.
|
|
570
|
+
* @param [opts={}] Options for this dynamic cluster pool.
|
|
571
|
+
*/
|
|
572
|
+
constructor(min: number, max: number, filePath: string, opts?: ClusterPoolOptions);
|
|
573
|
+
/** @inheritdoc */
|
|
574
|
+
get type(): PoolType;
|
|
575
|
+
/** @inheritdoc */
|
|
576
|
+
get busy(): boolean;
|
|
577
|
+
}
|
|
578
|
+
/**
|
|
579
|
+
* A thread worker with message channels for communication between main thread and thread worker.
|
|
580
|
+
*/
|
|
581
|
+
type ThreadWorkerWithMessageChannel = Worker$0 & Draft<MessageChannel>;
|
|
582
|
+
/**
|
|
583
|
+
* A thread pool with a fixed number of threads.
|
|
584
|
+
*
|
|
585
|
+
* It is possible to perform tasks in sync or asynchronous mode as you prefer.
|
|
586
|
+
*
|
|
587
|
+
* This pool selects the threads in a round robin fashion.
|
|
588
|
+
*
|
|
589
|
+
* @template DataType of data sent to the worker. This can only be serializable data.
|
|
590
|
+
* @template ResponseType of response of execution. This can only be serializable data.
|
|
591
|
+
* @author [Alessandro Pio Ardizio](https://github.com/pioardi)
|
|
592
|
+
* @since 0.0.1
|
|
593
|
+
*/
|
|
594
|
+
declare class FixedThreadPool<Data = unknown, Response = unknown> extends AbstractPool<ThreadWorkerWithMessageChannel, Data, Response> {
|
|
595
|
+
/**
|
|
596
|
+
* Constructs a new poolifier fixed thread pool.
|
|
597
|
+
*
|
|
598
|
+
* @param numberOfThreads Number of threads for this pool.
|
|
599
|
+
* @param filePath Path to an implementation of a `ThreadWorker` file, which can be relative or absolute.
|
|
600
|
+
* @param [opts={}] Options for this fixed thread pool.
|
|
601
|
+
*/
|
|
602
|
+
constructor(numberOfThreads: number, filePath: string, opts?: PoolOptions<ThreadWorkerWithMessageChannel>);
|
|
603
|
+
/** @inheritdoc */
|
|
604
|
+
protected isMain(): boolean;
|
|
605
|
+
/** @inheritdoc */
|
|
606
|
+
destroyWorker(worker: ThreadWorkerWithMessageChannel): Promise<void>;
|
|
607
|
+
/** @inheritdoc */
|
|
608
|
+
protected sendToWorker(worker: ThreadWorkerWithMessageChannel, message: MessageValue<Data>): void;
|
|
609
|
+
/** @inheritdoc */
|
|
610
|
+
registerWorkerMessageListener<Message extends Data | Response>(messageChannel: ThreadWorkerWithMessageChannel, listener: (message: MessageValue<Message>) => void): void;
|
|
611
|
+
/** @inheritdoc */
|
|
612
|
+
protected createWorker(): ThreadWorkerWithMessageChannel;
|
|
613
|
+
/** @inheritdoc */
|
|
614
|
+
protected afterWorkerSetup(worker: ThreadWorkerWithMessageChannel): void;
|
|
615
|
+
/** @inheritdoc */
|
|
616
|
+
get type(): PoolType;
|
|
617
|
+
/** @inheritdoc */
|
|
618
|
+
get busy(): boolean;
|
|
619
|
+
}
|
|
620
|
+
/**
|
|
621
|
+
* A thread pool with a dynamic number of threads, but a guaranteed minimum number of threads.
|
|
622
|
+
*
|
|
623
|
+
* This thread pool creates new threads when the others are busy, up to the maximum number of threads.
|
|
624
|
+
* When the maximum number of threads is reached, an event is emitted. If you want to listen to this event, use the pool's `emitter`.
|
|
625
|
+
*
|
|
626
|
+
* @template DataType of data sent to the worker. This can only be serializable data.
|
|
627
|
+
* @template ResponseType of response of execution. This can only be serializable data.
|
|
628
|
+
* @author [Alessandro Pio Ardizio](https://github.com/pioardi)
|
|
629
|
+
* @since 0.0.1
|
|
630
|
+
*/
|
|
631
|
+
declare class DynamicThreadPool<Data = unknown, Response = unknown> extends FixedThreadPool<Data, Response> {
|
|
632
|
+
readonly max: number;
|
|
633
|
+
/**
|
|
634
|
+
* Constructs a new poolifier dynamic thread pool.
|
|
635
|
+
*
|
|
636
|
+
* @param min Minimum number of threads which are always active.
|
|
637
|
+
* @param max Maximum number of threads that can be created by this pool.
|
|
638
|
+
* @param filePath Path to an implementation of a `ThreadWorker` file, which can be relative or absolute.
|
|
639
|
+
* @param [opts={}] Options for this dynamic thread pool.
|
|
640
|
+
*/
|
|
641
|
+
constructor(min: number, max: number, filePath: string, opts?: PoolOptions<ThreadWorkerWithMessageChannel>);
|
|
642
|
+
/** @inheritdoc */
|
|
643
|
+
get type(): PoolType;
|
|
644
|
+
/** @inheritdoc */
|
|
645
|
+
get busy(): boolean;
|
|
646
|
+
}
|
|
647
|
+
/**
|
|
648
|
+
* Base class containing some shared logic for all poolifier workers.
|
|
649
|
+
*
|
|
650
|
+
* @template MainWorker Type of main worker.
|
|
651
|
+
* @template Data Type of data this worker receives from pool's execution. This can only be serializable data.
|
|
652
|
+
* @template Response Type of response the worker sends back to the main worker. This can only be serializable data.
|
|
653
|
+
*/
|
|
654
|
+
declare abstract class AbstractWorker<MainWorker extends Worker | MessagePort, Data = unknown, Response = unknown> extends AsyncResource {
|
|
655
|
+
protected mainWorker: MainWorker | undefined | null;
|
|
656
|
+
readonly opts: WorkerOptions;
|
|
657
|
+
/**
|
|
658
|
+
* Timestamp of the last task processed by this worker.
|
|
659
|
+
*/
|
|
660
|
+
protected lastTaskTimestamp: number;
|
|
661
|
+
/**
|
|
662
|
+
* Handler Id of the `aliveInterval` worker alive check.
|
|
663
|
+
*/
|
|
664
|
+
protected readonly aliveInterval?: NodeJS.Timeout;
|
|
665
|
+
/**
|
|
666
|
+
* Constructs a new poolifier worker.
|
|
667
|
+
*
|
|
668
|
+
* @param type The type of async event.
|
|
669
|
+
* @param isMain Whether this is the main worker or not.
|
|
670
|
+
* @param fn Function processed by the worker when the pool's `execution` function is invoked.
|
|
671
|
+
* @param mainWorker Reference to main worker.
|
|
672
|
+
* @param opts Options for the worker.
|
|
673
|
+
*/
|
|
674
|
+
constructor(type: string, isMain: boolean, fn: (data: Data) => Response, mainWorker: MainWorker | undefined | null, opts?: WorkerOptions);
|
|
675
|
+
private checkWorkerOptions;
|
|
676
|
+
/**
|
|
677
|
+
* Check if the `fn` parameter is passed to the constructor.
|
|
678
|
+
*
|
|
679
|
+
* @param fn The function that should be defined.
|
|
680
|
+
*/
|
|
681
|
+
private checkFunctionInput;
|
|
682
|
+
/**
|
|
683
|
+
* Returns the main worker.
|
|
684
|
+
*
|
|
685
|
+
* @returns Reference to the main worker.
|
|
686
|
+
*/
|
|
687
|
+
protected getMainWorker(): MainWorker;
|
|
688
|
+
/**
|
|
689
|
+
* Send a message to the main worker.
|
|
690
|
+
*
|
|
691
|
+
* @param message The response message.
|
|
692
|
+
*/
|
|
693
|
+
protected abstract sendToMainWorker(message: MessageValue<Response>): void;
|
|
694
|
+
/**
|
|
695
|
+
* Check to see if the worker should be terminated, because its living too long.
|
|
696
|
+
*/
|
|
697
|
+
protected checkAlive(): void;
|
|
698
|
+
/**
|
|
699
|
+
* Handle an error and convert it to a string so it can be sent back to the main worker.
|
|
700
|
+
*
|
|
701
|
+
* @param e The error raised by the worker.
|
|
702
|
+
* @returns Message of the error.
|
|
703
|
+
*/
|
|
704
|
+
protected handleError(e: Error | string): string;
|
|
705
|
+
/**
|
|
706
|
+
* Run the given function synchronously.
|
|
707
|
+
*
|
|
708
|
+
* @param fn Function that will be executed.
|
|
709
|
+
* @param value Input data for the given function.
|
|
710
|
+
*/
|
|
711
|
+
protected run(fn: (data?: Data) => Response, value: MessageValue<Data>): void;
|
|
712
|
+
/**
|
|
713
|
+
* Run the given function asynchronously.
|
|
714
|
+
*
|
|
715
|
+
* @param fn Function that will be executed.
|
|
716
|
+
* @param value Input data for the given function.
|
|
717
|
+
*/
|
|
718
|
+
protected runAsync(fn: (data?: Data) => Promise<Response>, value: MessageValue<Data>): void;
|
|
719
|
+
}
|
|
720
|
+
/**
|
|
721
|
+
* A cluster worker used by a poolifier `ClusterPool`.
|
|
722
|
+
*
|
|
723
|
+
* When this worker is inactive for more than the given `maxInactiveTime`,
|
|
724
|
+
* it will send a termination request to its main worker.
|
|
725
|
+
*
|
|
726
|
+
* If you use a `DynamicClusterPool` the extra workers that were created will be terminated,
|
|
727
|
+
* but the minimum number of workers will be guaranteed.
|
|
728
|
+
*
|
|
729
|
+
* @template DataType of data this worker receives from pool's execution. This can only be serializable data.
|
|
730
|
+
* @template ResponseType of response the worker sends back to the main worker. This can only be serializable data.
|
|
731
|
+
* @author [Christopher Quadflieg](https://github.com/Shinigami92)
|
|
732
|
+
* @since 2.0.0
|
|
733
|
+
*/
|
|
734
|
+
declare class ClusterWorker<Data = unknown, Response = unknown> extends AbstractWorker<Worker, Data, Response> {
|
|
735
|
+
/**
|
|
736
|
+
* Constructs a new poolifier cluster worker.
|
|
737
|
+
*
|
|
738
|
+
* @param fn Function processed by the worker when the pool's `execution` function is invoked.
|
|
739
|
+
* @param opts Options for the worker.
|
|
740
|
+
*/
|
|
741
|
+
constructor(fn: (data: Data) => Response, opts?: WorkerOptions);
|
|
742
|
+
/** @inheritdoc */
|
|
743
|
+
protected sendToMainWorker(message: MessageValue<Response>): void;
|
|
744
|
+
/** @inheritdoc */
|
|
745
|
+
protected handleError(e: Error | string): string;
|
|
746
|
+
}
|
|
747
|
+
/**
|
|
748
|
+
* A thread worker used by a poolifier `ThreadPool`.
|
|
749
|
+
*
|
|
750
|
+
* When this worker is inactive for more than the given `maxInactiveTime`,
|
|
751
|
+
* it will send a termination request to its main thread.
|
|
752
|
+
*
|
|
753
|
+
* If you use a `DynamicThreadPool` the extra workers that were created will be terminated,
|
|
754
|
+
* but the minimum number of workers will be guaranteed.
|
|
755
|
+
*
|
|
756
|
+
* @template DataType of data this worker receives from pool's execution. This can only be serializable data.
|
|
757
|
+
* @template ResponseType of response the worker sends back to the main thread. This can only be serializable data.
|
|
758
|
+
* @author [Alessandro Pio Ardizio](https://github.com/pioardi)
|
|
759
|
+
* @since 0.0.1
|
|
760
|
+
*/
|
|
761
|
+
declare class ThreadWorker<Data = unknown, Response = unknown> extends AbstractWorker<MessagePort, Data, Response> {
|
|
762
|
+
/**
|
|
763
|
+
* Constructs a new poolifier thread worker.
|
|
764
|
+
*
|
|
765
|
+
* @param fn Function processed by the worker when the pool's `execution` function is invoked.
|
|
766
|
+
* @param opts Options for the worker.
|
|
767
|
+
*/
|
|
768
|
+
constructor(fn: (data: Data) => Response, opts?: WorkerOptions);
|
|
769
|
+
/** @inheritdoc */
|
|
770
|
+
protected sendToMainWorker(message: MessageValue<Response>): void;
|
|
771
|
+
}
|
|
772
|
+
export type { ErrorHandler, ExitHandler, IWorker, OnlineHandler, PoolOptions, ClusterPoolOptions, IPool, WorkerChoiceStrategy, ThreadWorkerWithMessageChannel, KillBehavior, WorkerOptions };
|
|
773
|
+
export { DynamicClusterPool, FixedClusterPool, WorkerChoiceStrategies, DynamicThreadPool, FixedThreadPool, AbstractWorker, ClusterWorker, ThreadWorker, KillBehaviors };
|