@@ -10,6 +10,10 @@ import { AsyncResource } from 'node:async_hooks';
10
10
import { Subject } from 'rxjs' ;
11
11
import * as errors from './errors.js' ;
12
12
13
+ /**
14
+ * This defines a `WorkerTask` `AsyncResource` for tracking the life-cycle of a worker task
15
+ * It works with the `Node:Async_hooks` for tracking async resources.
16
+ */
13
17
class WorkerTask extends AsyncResource {
14
18
protected callback : TaskCallback ;
15
19
@@ -27,6 +31,12 @@ class WorkerTask extends AsyncResource {
27
31
const taskInfoSymbol = Symbol ( 'Task Info Symbol' ) ;
28
32
type PoolStatus = 'terminated' | 'idle' | 'working' | 'queued' ;
29
33
34
+ /**
35
+ * A WorkerPool class that manages a pool of worker threads for parallel processing.
36
+ * This class allows tasks to be distributed among a fixed number of workers, ensuring
37
+ * efficient utilization of resources. It provides mechanisms to queue tasks when all workers
38
+ * are occupied and handles error recovery and worker recreation.
39
+ */
30
40
class WorkerPool {
31
41
protected workerFactory : WorkerFactory ;
32
42
protected workers : Set < Worker > = new Set ( ) ;
@@ -45,6 +55,14 @@ class WorkerPool {
45
55
public $poolStatus = new Subject < PoolStatus > ( ) ;
46
56
public poolStatus : PoolStatus = 'idle' ;
47
57
58
+ /**
59
+ * Constructs an instance of the Worker Pool class and initializes the specified number of workers.
60
+ *
61
+ * @param workerNum - The number of workers to be created in the pool. Must be at least 1.
62
+ * @param workerFactory - A factory instance responsible for creating workers.
63
+ * @return A Worker Pool instance initialized with the specified workers and configurations.
64
+ * @throws {ErrorWorkerPoolInvalidWorkers } If the value of workerNum is less than 1.
65
+ */
48
66
constructor ( workerNum : number , workerFactory : WorkerFactory ) {
49
67
if ( workerNum < 1 ) throw new errors . ErrorWorkerPoolInvalidWorkers ( ) ;
50
68
this . workerFactory = workerFactory ;
@@ -71,6 +89,14 @@ class WorkerPool {
71
89
} ) ;
72
90
}
73
91
92
+ /**
93
+ * Adds a new worker to the worker pool by initializing its lifecycle handlers.
94
+ *
95
+ * This method creates a worker instance using the `workerFactory`, sets up its message and error event handlers,
96
+ * and handles worker initialization, error propagation, task completion, and cleanup when the worker exits.
97
+ * The initialized worker is stored in the list of free workers upon success.
98
+ *
99
+ */
74
100
protected addWorker ( ) {
75
101
const worker = this . workerFactory ( ) ;
76
102
let workerError : Error ;
@@ -133,6 +159,12 @@ class WorkerPool {
133
159
this . $workerCreated . next ( ) ;
134
160
}
135
161
162
+ /**
163
+ * Executes a task using an available worker. If no workers are free, the task is added to the queue.
164
+ *
165
+ * @param task - The task information to be executed by a worker, including type, data, and transfer list.
166
+ * @param callback - The callback function to handle the outcome of the executed task.
167
+ */
136
168
public runTask ( task : WorkerTaskInformation , callback : TaskCallback ) {
137
169
if ( this . terminatedError != null ) throw this . terminatedError ;
138
170
if ( this . freeWorkers . length === 0 ) {
@@ -151,6 +183,12 @@ class WorkerPool {
151
183
) ;
152
184
}
153
185
186
+ /**
187
+ * Terminates the worker pool by stopping all workers, preventing new tasks, and cleaning up resources.
188
+ *
189
+ * @param force - Determines whether to force termination immediately (true) or wait for existing tasks to complete (false).
190
+ * @return A promise that resolves when all workers are terminated and resources are cleaned up.
191
+ */
154
192
public async terminate ( force : boolean ) {
155
193
if ( this . terminatedError != null ) return ;
156
194
this . terminatedError = new errors . ErrorWorkerPoolWorkerTerminated ( ) ;
@@ -184,42 +222,59 @@ class WorkerPool {
184
222
}
185
223
186
224
/**
187
- * Returns a promise that will resolve once all tasks have been completed.
188
- * Will reject if a task failed.
225
+ * Returns a promise that resolves when the pool status becomes 'idle',
226
+ * or rejects if the pool status changes to 'terminated' or an error occurs.
227
+ *
228
+ * @return A promise that resolves when the pool is idle or rejects with an error.
189
229
*/
190
230
public completed ( ) : Promise < void > {
191
231
return new Promise < void > ( ( resolve , reject ) => {
192
- if ( this . poolStatus === 'idle' || this . poolStatus === 'terminated' ) {
193
- return resolve ( ) ;
232
+ if ( this . poolStatus === 'idle' ) return resolve ( ) ;
233
+ if ( this . poolStatus === 'terminated' ) {
234
+ return reject ( this . terminatedError ! ) ;
194
235
}
195
236
const errorSubscription = this . $workerError . subscribe ( ( e ) => {
196
237
errorSubscription . unsubscribe ( ) ;
197
238
stateSubscription . unsubscribe ( ) ;
198
239
reject ( e ) ;
199
240
} ) ;
200
241
const stateSubscription = this . $poolStatus . subscribe ( ( v ) => {
201
- if ( v === 'idle' || this . poolStatus === 'terminated' ) {
242
+ if ( v === 'idle' ) {
202
243
errorSubscription . unsubscribe ( ) ;
203
244
stateSubscription . unsubscribe ( ) ;
204
245
return resolve ( ) ;
205
246
}
247
+ if ( v === 'terminated' ) {
248
+ errorSubscription . unsubscribe ( ) ;
249
+ stateSubscription . unsubscribe ( ) ;
250
+ return reject ( this . terminatedError ! ) ;
251
+ }
206
252
} ) ;
207
253
} ) ;
208
254
}
209
255
210
256
/**
211
- * Returns a promise that will resolve once all tasks have been completed.
257
+ * Returns a promise that resolves when the pool status becomes 'idle',
258
+ * or rejects if the pool status becomes 'terminated'.
259
+ *
260
+ * @return A promise that resolves once the pool status is 'idle',
261
+ * or rejects if the pool status becomes 'terminated'.
212
262
*/
213
263
public settled ( ) : Promise < void > {
214
- return new Promise < void > ( ( resolve ) => {
215
- if ( this . poolStatus === 'idle' || this . poolStatus === 'terminated' ) {
216
- return resolve ( ) ;
264
+ return new Promise < void > ( ( resolve , reject ) => {
265
+ if ( this . poolStatus === 'idle' ) return resolve ( ) ;
266
+ if ( this . poolStatus === 'terminated' ) {
267
+ return reject ( this . terminatedError ! ) ;
217
268
}
218
269
const subscription = this . $poolStatus . subscribe ( ( v ) => {
219
- if ( v === 'idle' || this . poolStatus === 'terminated' ) {
270
+ if ( v === 'idle' ) {
220
271
subscription . unsubscribe ( ) ;
221
272
return resolve ( ) ;
222
273
}
274
+ if ( v === 'terminated' ) {
275
+ subscription . unsubscribe ( ) ;
276
+ return reject ( this . terminatedError ! ) ;
277
+ }
223
278
} ) ;
224
279
} ) ;
225
280
}
0 commit comments