Commit | Line | Data |
---|---|---|
06b0522e CQ |
1 | declare module "poolifier" { |
2 | import { AsyncResource } from "async_hooks"; | |
3 | import { EventEmitter } from "events"; | |
4 | import { Worker } from "worker_threads"; | |
5 | ||
6 | export interface FixedThreadPoolOptions { | |
7 | /** | |
8 | * A function that will listen for error event on each worker thread. | |
9 | */ | |
10 | errorHandler?: (this: Worker, e: Error) => void; | |
11 | /** | |
12 | * A function that will listen for online event on each worker thread. | |
13 | */ | |
14 | onlineHandler?: (this: Worker) => void; | |
15 | /** | |
16 | * A function that will listen for exit event on each worker thread. | |
17 | */ | |
18 | exitHandler?: (this: Worker, code: number) => void; | |
19 | /** | |
20 | * This is just to avoid not useful warnings message, is used to set `maxListeners` on event emitters (workers are event emitters). | |
21 | * | |
22 | * @default 1000 | |
23 | */ | |
24 | maxTasks?: number; | |
25 | } | |
26 | ||
27 | /** | |
28 | * A thread pool with a static number of threads, is possible to execute tasks in sync or async mode as you prefer. | |
29 | * | |
30 | * This pool will select the worker thread in a round robin fashion. | |
31 | * | |
32 | * @author [Alessandro Pio Ardizio](https://github.com/pioardi) | |
33 | * @since 0.0.1 | |
34 | */ | |
35 | export class FixedThreadPool<Data = any, Response = any> { | |
36 | /** | |
37 | * Num of threads for this worker pool. | |
38 | */ | |
39 | numThreads: number; | |
40 | workers: Worker[]; | |
41 | nextWorker: number; | |
42 | opts: FixedThreadPoolOptions; | |
43 | filePath: string; | |
44 | tasks: Map<Worker, number>; | |
45 | ||
46 | _id: number; | |
47 | ||
48 | /** | |
49 | * @param numThreads Num of threads for this worker pool. | |
50 | * @param filePath A file path with implementation of `ThreadWorker` class, relative path is fine. | |
51 | * @param opts An object with possible options for example `errorHandler`, `onlineHandler`. Default: `{ maxTasks: 1000 }` | |
52 | */ | |
53 | constructor( | |
54 | numThreads: number, | |
55 | filePath: string, | |
56 | opts?: FixedThreadPoolOptions | |
57 | ); | |
58 | ||
59 | destroy(): Promise<void>; | |
60 | ||
61 | /** | |
62 | * Execute the task specified into the constructor with the data parameter. | |
63 | * | |
64 | * @param data The input for the task specified. | |
65 | * @returns Promise that is resolved when the task is done. | |
66 | */ | |
67 | execute(data: Data): Promise<Response>; | |
68 | ||
69 | _execute(worker: Worker, id: number): Promise<unknown>; | |
70 | _chooseWorker(): Worker; | |
71 | _newWorker(): Worker; | |
72 | } | |
73 | ||
74 | export type DynamicThreadPoolOptions = FixedThreadPoolOptions; | |
75 | ||
76 | class MyEmitter extends EventEmitter {} | |
77 | ||
78 | /** | |
79 | * A thread pool with a min/max number of threads, is possible to execute tasks in sync or async mode as you prefer. | |
80 | * | |
81 | * This thread pool will create new workers when the other ones are busy, until the max number of threads, | |
82 | * when the max number of threads is reached, an event will be emitted, if you want to listen this event use the emitter method. | |
83 | * | |
84 | * @author [Alessandro Pio Ardizio](https://github.com/pioardi) | |
85 | * @since 0.0.1 | |
86 | */ | |
87 | export class DynamicThreadPool< | |
88 | Data = any, | |
89 | Response = any | |
90 | > extends FixedThreadPool<Data, Response> { | |
91 | max: number; | |
92 | emitter: MyEmitter; | |
93 | ||
94 | /** | |
95 | * @param min Min number of threads that will be always active | |
96 | * @param max Max number of threads that will be active | |
97 | * @param filename A file path with implementation of `ThreadWorker` class, relative path is fine. | |
98 | * @param opts An object with possible options for example `errorHandler`, `onlineHandler`. Default: `{ maxTasks: 1000 }` | |
99 | */ | |
100 | constructor( | |
101 | min: number, | |
102 | max: number, | |
103 | filename: string, | |
104 | opts?: DynamicThreadPoolOptions | |
105 | ); | |
106 | } | |
107 | ||
108 | export interface ThreadWorkerOptions { | |
109 | /** | |
110 | * Max time to wait tasks to work on (in ms), after this period the new worker threads will die. | |
111 | * | |
112 | * @default 60.000 ms | |
113 | */ | |
114 | maxInactiveTime?: number; | |
115 | /** | |
116 | * `true` if your function contains async pieces, else `false`. | |
117 | * | |
118 | * @default false | |
119 | */ | |
120 | async?: boolean; | |
121 | } | |
122 | ||
123 | /** | |
124 | * An example worker that will be always alive, you just need to **extend** this class if you want a static pool. | |
125 | * | |
126 | * When this worker is inactive for more than 1 minute, it will send this info to the main thread, | |
127 | * if you are using DynamicThreadPool, the workers created after will be killed, the min num of thread will be guaranteed. | |
128 | * | |
129 | * @author [Alessandro Pio Ardizio](https://github.com/pioardi) | |
130 | * @since 0.0.1 | |
131 | */ | |
132 | export class ThreadWorker<Data = any, Response = any> extends AsyncResource { | |
133 | opts: ThreadWorkerOptions; | |
134 | maxInactiveTime: number; | |
135 | async: boolean; | |
136 | lastTask: number; | |
137 | interval: number; | |
138 | parent: Worker; | |
139 | ||
140 | constructor(fn: (data: Data) => Response, opts?: ThreadWorkerOptions); | |
141 | ||
142 | _checkAlive(): boolean; | |
143 | _run(fn: (data: Data) => Response, value: { data: Data }): void; | |
144 | _runAsync( | |
145 | fn: (data: Data) => Promise<Response>, | |
146 | value: { data: Data } | |
147 | ): void; | |
148 | } | |
149 | } |