@coherentglobal/wasm-runner 0.0.103 → 0.1.19

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.
Files changed (54) hide show
  1. package/README.md +137 -222
  2. package/dist/CancellationToken.js.map +1 -1
  3. package/dist/browser/logger.js.map +1 -1
  4. package/dist/browser/template/main.template.js +1 -1
  5. package/dist/browser/template/main.template.js.map +1 -1
  6. package/dist/browser/template/runtime.template.js.map +1 -1
  7. package/dist/browser/template/worker.template.js +7 -4
  8. package/dist/browser/template/worker.template.js.map +1 -1
  9. package/dist/browser/template.js +1 -1
  10. package/dist/browser/template.js.map +1 -1
  11. package/dist/browser.d.ts +2 -2
  12. package/dist/browser.js +6 -6
  13. package/dist/browser.js.map +1 -1
  14. package/dist/constants.d.ts +5 -0
  15. package/dist/constants.js +14 -0
  16. package/dist/constants.js.map +1 -0
  17. package/dist/error.d.ts +5 -0
  18. package/dist/error.js +13 -3
  19. package/dist/error.js.map +1 -1
  20. package/dist/mockConstants.d.ts +5 -0
  21. package/dist/mockConstants.js +14 -0
  22. package/dist/mockConstants.js.map +1 -0
  23. package/dist/node/logger.d.ts +1 -4
  24. package/dist/node/logger.js +1 -1
  25. package/dist/node/logger.js.map +1 -1
  26. package/dist/node/logger.ts +1 -1
  27. package/dist/node/template/main.template.ejs +126 -86
  28. package/dist/node/threads/mockWorkerThread.d.ts +28 -0
  29. package/dist/node/threads/mockWorkerThread.js +89 -0
  30. package/dist/node/threads/mockWorkerThread.js.map +1 -0
  31. package/dist/node/threads/workerPool.d.ts +17 -0
  32. package/dist/node/threads/workerPool.js +27 -0
  33. package/dist/node/threads/workerPool.js.map +1 -0
  34. package/dist/node/threads/workerPool.ts +38 -0
  35. package/dist/node/threads/workerThread.d.ts +31 -0
  36. package/dist/node/threads/workerThread.js +91 -0
  37. package/dist/node/threads/workerThread.js.map +1 -0
  38. package/dist/node/threads/workerThread.ts +92 -0
  39. package/dist/node.d.ts +36 -26
  40. package/dist/node.js +334 -62
  41. package/dist/node.js.map +1 -1
  42. package/dist/responseTimeMetric.d.ts +16 -0
  43. package/dist/responseTimeMetric.js +56 -0
  44. package/dist/responseTimeMetric.js.map +1 -0
  45. package/dist/serializer/columnarSerializer.d.ts +3 -2
  46. package/dist/serializer/columnarSerializer.js +10 -1
  47. package/dist/serializer/columnarSerializer.js.map +1 -1
  48. package/dist/types.d.ts +41 -2
  49. package/dist/types.js +8 -0
  50. package/dist/types.js.map +1 -1
  51. package/dist/utils.d.ts +27 -0
  52. package/dist/utils.js +49 -13
  53. package/dist/utils.js.map +1 -1
  54. package/package.json +8 -5
@@ -3,17 +3,17 @@
3
3
  /* eslint-disable no-useless-catch */
4
4
  /* eslint-disable no-param-reassign */
5
5
  /* eslint-disable no-underscore-dangle */
6
- const { parentPort, workerData } = require('worker_threads');
6
+ const WorkerThread = require('<%= modules.workerThread %>').default;
7
+ const { threadId } = require('worker_threads');
7
8
  const model = require('<%= runtime %>');
8
- const externalResolver = require('<%= modules.externalResolver %>');
9
9
  const { logger } = require('<%= modules.logger %>');
10
10
  const metadata = <%- metadata %>;
11
11
  const formspec = <%- formspec %>;
12
-
13
- var events = require('events');
14
- var eventEmitter = new events.EventEmitter();
15
-
16
12
  const modelName = '<%= modelName %>';
13
+ const DISPATCH_TYPE = {
14
+ SPARK_SERVICE: 0,
15
+ EXTERNAL_API: 1,
16
+ };
17
17
 
18
18
  logger.debug({
19
19
  TimeStamp: Date.now(),
@@ -22,20 +22,24 @@ logger.debug({
22
22
 
23
23
  });
24
24
 
25
- let wasm;
26
25
  let wb;
27
-
28
26
  let isReady = false;
29
-
30
27
  let execute = () => { return Promise.resolve(false) };
31
28
  let _execute = () => { return Promise.resolve(false) };
32
-
33
29
  let modelIsBusy = false;
34
30
 
35
- const DISPATCH_TYPE = {
36
- SPARK_SERVICE: 0,
37
- EXTERNAL_API: 1,
38
- };
31
+ /**
32
+ * Place holder of the worker thread instance.
33
+ * Actual definition happens during Worker initialization.
34
+ */
35
+ let workerThreadInstance = null;
36
+
37
+ function sleep(ms) {
38
+ return new Promise(resolve => setTimeout(resolve, ms));
39
+ }
40
+
41
+ const start = Date.now();
42
+ let readyRes = undefined;
39
43
 
40
44
  try {
41
45
  logger.debug({
@@ -62,23 +66,20 @@ try {
62
66
  const resultData = new Uint8Array(
63
67
  instance.HEAPU8.subarray(argPtr, argPtr + argsOffSet)
64
68
  );
65
- const result = dnc.decode(resultData).slice();
66
69
 
70
+ const result = dnc.decode(resultData).slice();
67
71
  const requestData = JSON.parse(result);
68
72
 
69
73
  switch (service) {
70
74
  case DISPATCH_TYPE.SPARK_SERVICE: {
71
- const dispatchRes = await externalResolver.sparkService(requestData, ctx)
72
- return dispatchRes
73
- }
74
- case DISPATCH_TYPE.EXTERNAL_API: {
75
- // eslint-disable-next-line no-return-await
76
- return await externalResolver.externalApi(requestData, ctx);
75
+ const resultSparkService = await workerThreadInstance.requestMessage(requestData, ctx);
76
+ return resultSparkService;
77
77
  }
78
78
  default: {
79
79
  logger.error(
80
80
  `Not implemented for service ${service} data ${result}`
81
81
  );
82
+ return '';
82
83
  }
83
84
  }
84
85
  };
@@ -87,7 +88,7 @@ try {
87
88
  execute = function (req) {
88
89
  try {
89
90
  if (req === "isReady") {
90
- return Promise.resolve(isReady);
91
+ return Promise.resolve(readyRes);
91
92
  }
92
93
 
93
94
  if (req === "destroy") {
@@ -95,7 +96,7 @@ try {
95
96
  return Promise.resolve(true);
96
97
  }
97
98
 
98
- if(!req.request_data) req.request_data = {}
99
+ if (!req.request_data) req.request_data = {}
99
100
 
100
101
  let rawString = false;
101
102
  if (req.request_data._raw) {
@@ -115,7 +116,7 @@ try {
115
116
  }
116
117
  }
117
118
 
118
- if(!req.request_meta) req.request_meta = {}
119
+ if (!req.request_meta) req.request_meta = {}
119
120
 
120
121
  if (req.request_meta?._ctx?.correlationId) {
121
122
  ctx.correlationId = req.request_meta._ctx.correlationId;
@@ -149,22 +150,34 @@ try {
149
150
  delete req.request_meta._ctx.servicemap;
150
151
  }
151
152
 
152
- if(req.request_meta._ctx?.xcallChainId) {
153
+ if (req.request_meta._ctx?.xcallChainId) {
153
154
  ctx.xcallChainId = req.request_meta._ctx?.xcallChainId;
154
155
  delete req.request_meta._ctx.xcallChainId;
155
156
  }
156
157
 
157
- if(req.callid) {
158
+ if (req.request_meta._ctx?.callId) {
159
+ ctx.callid = req.request_meta._ctx.callId;
160
+ delete req.request_meta._ctx.callId;
161
+ } else if (req.callid) {
158
162
  ctx.callid = req.callid;
159
163
  delete req.callid;
160
164
  }
161
165
 
166
+ if (!req.request_meta?.allow_range_address) {
167
+ req.request_meta.allow_range_address = false;
168
+ }
169
+
170
+ if (req.request_meta?._ctx?.trace) {
171
+ ctx.trace = req.request_meta._ctx.trace;
172
+ delete req.request_meta._ctx.trace;
173
+ }
174
+
162
175
  const startTime = Date.now();
163
176
  logger.debug({
164
177
  TimeStamp: Date.now(),
165
178
  EventType: 'Runner.ModelThread.Execute',
166
- threadCallId: ctx.callid,
167
-
179
+ threadCallId: ctx.callid,
180
+ correlationId: ctx.correlationId,
168
181
  });
169
182
 
170
183
  const input = JSON.stringify(req);
@@ -191,21 +204,23 @@ try {
191
204
  [wb, inBuffer, encoded.length, outBuffer],
192
205
  { async: true }
193
206
  ).then((outPtr) => {
207
+
194
208
  var offset = instance.getValue(outBuffer, "i32");
195
209
  const resultData = new Uint8Array(instance.HEAPU8.subarray(outPtr, outPtr + offset));
196
210
  var result = dnc.decode(resultData).slice();
211
+
197
212
  instance._free(inBuffer);
198
213
  instance._free(outBuffer);
199
214
  instance._free(outPtr);
200
215
 
201
- if(isMetadataSubSvc) {
216
+ if (isMetadataSubSvc) {
202
217
  result = JSON.parse(result);
203
- if(!result.response_data) {
218
+ if (!result.response_data) {
204
219
  result.response_data = {}
205
220
  }
206
221
  const hasImageOutputs = metadata?.ImageOutputs ?? []
207
- const imageOutputs = hasImageOutputs ? hasImageOutputs.reduce( (prev, curr) => {
208
- if(!curr?.ImageName) return prev
222
+ const imageOutputs = hasImageOutputs ? hasImageOutputs.reduce((prev, curr) => {
223
+ if (!curr?.ImageName) return prev
209
224
  prev[curr.ImageName] = curr?.Base64Content || ""
210
225
  return prev
211
226
  }, {}) : {}
@@ -220,14 +235,14 @@ try {
220
235
  }
221
236
 
222
237
 
223
- if(isFormSpecSubSvc) {
238
+ if (isFormSpecSubSvc) {
224
239
  result = JSON.parse(result);
225
- if(!result.response_data) {
240
+ if (!result.response_data) {
226
241
  result.response_data = {}
227
242
  }
228
243
 
229
244
  // result.response_data.outputs = Object.assign({}, result.response_data.outputs, formspec);
230
- result.response_data.outputs = formspec;
245
+ result.response_data.outputs = formspec;
231
246
  return rawString ? JSON.stringify(result) : result;
232
247
  }
233
248
 
@@ -237,6 +252,7 @@ try {
237
252
  Message: `Complete execute model ${modelName}`,
238
253
  innerExecuteDuration: Date.now() - startTime,
239
254
  threadCallId: ctx.callid,
255
+ correlationId: ctx.correlationId,
240
256
  });
241
257
 
242
258
  return rawString ? result : JSON.parse(result);
@@ -257,14 +273,14 @@ try {
257
273
  instance._free(outBuffer);
258
274
  instance._free(outPtr);
259
275
 
260
- if(isMetadataSubSvc) {
276
+ if (isMetadataSubSvc) {
261
277
  result = JSON.parse(result);
262
- if(!result.response_data) {
278
+ if (!result.response_data) {
263
279
  result.response_data = {}
264
280
  }
265
281
  const hasImageOutputs = metadata?.ImageOutputs ?? []
266
- const imageOutputs = hasImageOutputs ? hasImageOutputs.reduce( (prev, curr) => {
267
- if(!curr?.ImageName) return prev
282
+ const imageOutputs = hasImageOutputs ? hasImageOutputs.reduce((prev, curr) => {
283
+ if (!curr?.ImageName) return prev
268
284
  prev[curr.ImageName] = curr?.Base64Content || ""
269
285
  return prev
270
286
  }, {}) : {}
@@ -273,17 +289,17 @@ try {
273
289
  ...metadata?.Outputs,
274
290
  ...imageOutputs,
275
291
  }
276
- result.response_data.outputs = Object.assign({}, metadataOutput);
292
+ result.response_data.outputs = Object.assign({}, metadataOutput);
277
293
  return rawString ? JSON.stringify(result) : result;
278
294
  }
279
295
 
280
- if(isFormSpecSubSvc) {
296
+ if (isFormSpecSubSvc) {
281
297
  result = JSON.parse(result);
282
- if(!result.response_data) {
298
+ if (!result.response_data) {
283
299
  result.response_data = {}
284
300
  }
285
301
 
286
- // result.response_data.outputs = Object.assign({}, result.response_data.outputs, formspec);
302
+ // result.response_data.outputs = Object.assign({}, result.response_data.outputs, formspec);
287
303
  result.response_data.outputs = formspec;
288
304
  return rawString ? JSON.stringify(result) : result;
289
305
  }
@@ -293,11 +309,11 @@ try {
293
309
  Message: `Complete execute model ${modelName}`,
294
310
  EventType: 'Runner.ModelThread.Execute',
295
311
  innerExecuteDuration: Date.now() - startTime,
296
- threadCallId: ctx.callid,
297
-
312
+ threadCallId: ctx.callid,
313
+ correlationId: ctx.correlationId,
298
314
  });
299
315
 
300
- return rawString ? result : JSON.parse(result);
316
+ return rawString ? result.concat('') : JSON.parse(result);
301
317
  });
302
318
  }
303
319
  } else {
@@ -316,14 +332,15 @@ try {
316
332
  instance._free(outBuffer);
317
333
  instance._free(outPtr);
318
334
 
319
- if(isMetadataSubSvc) {
335
+
336
+ if (isMetadataSubSvc) {
320
337
  result = JSON.parse(result);
321
- if(!result.response_data) {
338
+ if (!result.response_data) {
322
339
  result.response_data = {}
323
340
  }
324
341
  const hasImageOutputs = metadata?.ImageOutputs ?? []
325
- const imageOutputs = hasImageOutputs ? hasImageOutputs.reduce( (prev, curr) => {
326
- if(!curr?.ImageName) return prev
342
+ const imageOutputs = hasImageOutputs ? hasImageOutputs.reduce((prev, curr) => {
343
+ if (!curr?.ImageName) return prev
327
344
  prev[curr.ImageName] = curr?.Base64Content || null
328
345
  return prev
329
346
  }, {}) : {}
@@ -336,13 +353,13 @@ try {
336
353
  return rawString ? JSON.stringify(result) : result;
337
354
  }
338
355
 
339
- if(isFormSpecSubSvc) {
356
+ if (isFormSpecSubSvc) {
340
357
  result = JSON.parse(result);
341
- if(!result.response_data) {
358
+ if (!result.response_data) {
342
359
  result.response_data = {}
343
360
  }
344
361
 
345
- //result.response_data.outputs = Object.assign({}, result.response_data.outputs, formspec);
362
+ //result.response_data.outputs = Object.assign({}, result.response_data.outputs, formspec);
346
363
  result.response_data.outputs = formspec;
347
364
  return rawString ? JSON.stringify(result) : result;
348
365
  }
@@ -352,11 +369,11 @@ try {
352
369
  Message: `Complete execute model ${modelName}`,
353
370
  EventType: 'Runner.ModelThread.Execute',
354
371
  innerExecuteDuration: Date.now() - startTime,
355
- threadCallId: ctx.callid,
356
-
372
+ threadCallId: ctx.callid,
373
+ correlationId: ctx.correlationId,
357
374
  });
358
375
 
359
- return rawString ? result : JSON.parse(result);
376
+ return rawString ? result.concat('') : JSON.parse(result);
360
377
  });
361
378
  }
362
379
 
@@ -368,34 +385,33 @@ try {
368
385
  };
369
386
 
370
387
 
371
- _execute = function (req) {
372
- return new Promise((resolve, reject) => {
373
- if(!modelIsBusy) {
374
- logger.debug({
375
- TimeStamp: Date.now(),
376
- Message: `Execute ${modelName}`,
377
- EventType: 'Execute',
378
- })
388
+ _execute = async function (req) {
389
+ while (1) {
390
+ if (!modelIsBusy) {
379
391
  modelIsBusy = true;
380
- return _execute(req)
381
- .then((result) => {
382
- resolve(result);
383
- }).catch((err) => {
384
- reject(err);
385
- }).finally(() => {
386
- modelIsBusy = false
387
- });
392
+ const start = Date.now();
393
+
394
+ try {
395
+ return {
396
+ payload: await execute(req),
397
+ memoryUsage: process.memoryUsage().rss,
398
+ threadId,
399
+ time: Date.now() - start
400
+ }
401
+ } catch (err) {
402
+ return {
403
+ error: err,
404
+ memoryUsage: process.memoryUsage().rss,
405
+ threadId,
406
+ time: Date.now() - start
407
+ }
408
+ } finally {
409
+ modelIsBusy = false;
410
+ }
388
411
  } else {
389
- setTimeout(() => {
390
- logger.debug({
391
- TimeStamp: Date.now(),
392
- Message: `Execute.wait ${modelName}`,
393
- EventType: 'Execute.wait',
394
- });
395
- execute(req)
396
- }, 1)
412
+ await sleep(5)
397
413
  }
398
- });
414
+ }
399
415
  }
400
416
 
401
417
  logger.debug({
@@ -412,6 +428,13 @@ try {
412
428
  });
413
429
 
414
430
  isReady = true;
431
+ readyRes = {
432
+ memoryUsage: process.memoryUsage().rss,
433
+ threadId,
434
+ time: Date.now() - start,
435
+ readyTs: Date.now()
436
+ };
437
+
415
438
  return Promise.resolve();
416
439
  } catch (err) {
417
440
  instance = undefined
@@ -419,12 +442,29 @@ try {
419
442
  return Promise.reject(err);
420
443
  }
421
444
  })
422
- .catch((err) => logger.error('Instance Error: ', err));
445
+ .catch((err) => logger.error('Instance Error: ' + err.message, err));
423
446
  } catch (err) {
424
447
  logger.error('Error', err)
425
448
  }
426
449
 
427
- parentPort.on("message", (input) => {
450
+ /**
451
+ * Main worker function that triggers the `execute` logic which communicates to
452
+ * the WASM functions.
453
+ *
454
+ * @param {String|Object} input
455
+ * Can be 'isReady', JSON String or an Object.
456
+ *
457
+ * @returns {*}
458
+ */
459
+ async function main(input) {
460
+ // IMPORTANT: `postMessage` from parent also triggers this function, better not to pass `data` from parent
461
+ // and use `pool.execute()` instead.
462
+ if (!input) {
463
+ return;
464
+ }
465
+
466
+ // Private function init
467
+ workerThreadInstance = this;
428
468
 
429
469
  if (
430
470
  typeof input !== "string" &&
@@ -434,7 +474,7 @@ parentPort.on("message", (input) => {
434
474
  throw new Error("Param must be a json string or json object");
435
475
  }
436
476
 
437
- const promise = execute(input);
477
+ return _execute(input);
478
+ };
438
479
 
439
- return promise.then((result) => parentPort.postMessage(result));
440
- });
480
+ module.exports = new WorkerThread(main);
@@ -0,0 +1,28 @@
1
+ declare class WorkerThread extends ThreadWorker<any, any> {
2
+ constructor(taskFunctions: any, opts: any);
3
+ /**
4
+ * Sends message back to the main thread.
5
+ *
6
+ * @param {Object} message
7
+ */
8
+ postMessage(message: any): void;
9
+ /**
10
+ * Receives message from the main thread or other threads.
11
+ *
12
+ * @param {Function} callback
13
+ * Function to receive the message data.
14
+ */
15
+ onMessage(callback: Function): void;
16
+ /**
17
+ * Sends a request to the main thread and waits for a response.
18
+ *
19
+ * @param {Object} payload
20
+ * Object or details that needs to be passed to main thread as `payload`.
21
+ *
22
+ * @returns {Promise<Object>}
23
+ * Response from main thread.
24
+ */
25
+ requestMessage(payload: any, context: any): Promise<any>;
26
+ }
27
+ import { ThreadWorker } from "poolifier";
28
+ export { WorkerThread as default };
@@ -0,0 +1,89 @@
1
+ const events = require("events");
2
+ const { isMainThread, parentPort } = require("worker_threads");
3
+ const { createId } = require("@paralleldrive/cuid2");
4
+ const { ThreadWorker } = require("poolifier");
5
+ // eslint-disable-next-line import/no-unresolved, import/extensions
6
+ const { THREAD_EVENT_TYPES } = require("../../mockConstants");
7
+
8
+ class WorkerThread extends ThreadWorker {
9
+ // eslint-disable-next-line no-useless-constructor
10
+ constructor(taskFunctions, opts) {
11
+ super(taskFunctions, opts);
12
+ }
13
+
14
+ /**
15
+ * Sends message back to the main thread.
16
+ *
17
+ * @param {Object} message
18
+ */
19
+ postMessage(message) {
20
+ if (isMainThread) {
21
+ throw Error("Failed to post message using main thread.");
22
+ } else {
23
+ parentPort.postMessage(message);
24
+ }
25
+ }
26
+
27
+ /**
28
+ * Receives message from the main thread or other threads.
29
+ *
30
+ * @param {Function} callback
31
+ * Function to receive the message data.
32
+ */
33
+ onMessage(callback) {
34
+ if (isMainThread) {
35
+ throw Error("Failed to receive message using main thread.");
36
+ } else {
37
+ parentPort.on("message", callback);
38
+ }
39
+ }
40
+
41
+ /**
42
+ * Sends a request to the main thread and waits for a response.
43
+ *
44
+ * @param {Object} payload
45
+ * Object or details that needs to be passed to main thread as `payload`.
46
+ *
47
+ * @returns {Promise<Object>}
48
+ * Response from main thread.
49
+ */
50
+ async requestMessage(payload, context) {
51
+ return new Promise((resolve, reject) => {
52
+ const eventId = createId();
53
+ const eventEmitter = new events.EventEmitter();
54
+
55
+ // Prepare to process the response from parent
56
+ eventEmitter.once(eventId, (response) => {
57
+ eventEmitter.removeAllListeners(eventId);
58
+ if (response.type === THREAD_EVENT_TYPES.ERROR) {
59
+ reject(response?.payload);
60
+ } else {
61
+ resolve(response?.payload);
62
+ }
63
+ });
64
+
65
+ // Send the request to parent
66
+ this.postMessage({
67
+ payload,
68
+ context,
69
+ type: THREAD_EVENT_TYPES.REQUEST_EXECUTE,
70
+ eventId,
71
+ });
72
+
73
+ // Receive the response from parent once ready
74
+ this.onMessage((message) => {
75
+ if (
76
+ message.eventId === eventId &&
77
+ (message?.type === THREAD_EVENT_TYPES.RESPONSE ||
78
+ message?.type === THREAD_EVENT_TYPES.ERROR)
79
+ ) {
80
+ eventEmitter.emit(eventId, message);
81
+ }
82
+ });
83
+ });
84
+ }
85
+ }
86
+
87
+ module.exports = {
88
+ default: WorkerThread,
89
+ };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mockWorkerThread.js","sourceRoot":"","sources":["../../../src/node/threads/mockWorkerThread.js"],"names":[],"mappings":";;;;;;;;;AAAA,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;AACjC,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;AAC/D,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;AACrD,MAAM,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;AAC9C,mEAAmE;AACnE,MAAM,EAAE,kBAAkB,EAAE,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAAC;AAE9D,MAAM,YAAa,SAAQ,YAAY;IACrC,kDAAkD;IAClD,YAAY,aAAa,EAAE,IAAI;QAC7B,KAAK,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;IAC7B,CAAC;IAED;;;;OAIG;IACH,WAAW,CAAC,OAAO;QACjB,IAAI,YAAY,EAAE,CAAC;YACjB,MAAM,KAAK,CAAC,2CAA2C,CAAC,CAAC;QAC3D,CAAC;aAAM,CAAC;YACN,UAAU,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAED;;;;;OAKG;IACH,SAAS,CAAC,QAAQ;QAChB,IAAI,YAAY,EAAE,CAAC;YACjB,MAAM,KAAK,CAAC,8CAA8C,CAAC,CAAC;QAC9D,CAAC;aAAM,CAAC;YACN,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QACrC,CAAC;IACH,CAAC;IAED;;;;;;;;OAQG;IACG,cAAc,CAAC,OAAO,EAAE,OAAO;;YACnC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBACrC,MAAM,OAAO,GAAG,QAAQ,EAAE,CAAC;gBAC3B,MAAM,YAAY,GAAG,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;gBAE/C,8CAA8C;gBAC9C,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,EAAE;oBACtC,YAAY,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;oBACzC,IAAI,QAAQ,CAAC,IAAI,KAAK,kBAAkB,CAAC,KAAK,EAAE,CAAC;wBAC/C,MAAM,CAAC,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,OAAO,CAAC,CAAC;oBAC5B,CAAC;yBAAM,CAAC;wBACN,OAAO,CAAC,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,OAAO,CAAC,CAAC;oBAC7B,CAAC;gBACH,CAAC,CAAC,CAAC;gBAEH,6BAA6B;gBAC7B,IAAI,CAAC,WAAW,CAAC;oBACf,OAAO;oBACP,OAAO;oBACP,IAAI,EAAE,kBAAkB,CAAC,eAAe;oBACxC,OAAO;iBACR,CAAC,CAAC;gBAEH,8CAA8C;gBAC9C,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,EAAE;oBACzB,IACE,OAAO,CAAC,OAAO,KAAK,OAAO;wBAC3B,CAAC,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,IAAI,MAAK,kBAAkB,CAAC,QAAQ;4BAC5C,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,IAAI,MAAK,kBAAkB,CAAC,KAAK,CAAC,EAC7C,CAAC;wBACD,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;oBACtC,CAAC;gBACH,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;QACL,CAAC;KAAA;CACF;AAED,MAAM,CAAC,OAAO,GAAG;IACf,OAAO,EAAE,YAAY;CACtB,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { FixedThreadPool } from "poolifier";
2
+ import type { ThreadPoolOptions } from "poolifier";
3
+ import { EventResponseData } from "../../types";
4
+ declare class WorkerPool extends FixedThreadPool {
5
+ constructor(numberOfThreads: number, filePath: string, opts?: ThreadPoolOptions, maximumNumberOfThreads?: number);
6
+ /**
7
+ * Sends message to a specific worker thread or broadcasts the message
8
+ * to all running threads.
9
+ *
10
+ * @param message
11
+ * Any data that needs to passed to the worker.
12
+ *
13
+ */
14
+ postMessage(message: EventResponseData): void;
15
+ }
16
+ export default WorkerPool;
17
+ export type { FixedThreadPool };
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const poolifier_1 = require("poolifier");
4
+ class WorkerPool extends poolifier_1.FixedThreadPool {
5
+ constructor(numberOfThreads, filePath, opts, maximumNumberOfThreads) {
6
+ super(numberOfThreads, filePath, opts);
7
+ }
8
+ /**
9
+ * Sends message to a specific worker thread or broadcasts the message
10
+ * to all running threads.
11
+ *
12
+ * @param message
13
+ * Any data that needs to passed to the worker.
14
+ *
15
+ */
16
+ postMessage(message) {
17
+ let workerIndex = -1;
18
+ if (message.threadId) {
19
+ workerIndex = this.workerNodes.findIndex((w) => { var _a; return ((_a = w.info) === null || _a === void 0 ? void 0 : _a.id) === message.threadId; });
20
+ }
21
+ if (workerIndex > -1) {
22
+ this.workerNodes[workerIndex].worker.postMessage(message);
23
+ }
24
+ }
25
+ }
26
+ exports.default = WorkerPool;
27
+ //# sourceMappingURL=workerPool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workerPool.js","sourceRoot":"","sources":["../../../src/node/threads/workerPool.ts"],"names":[],"mappings":";;AAAA,yCAA4C;AAI5C,MAAM,UAAW,SAAQ,2BAAe;IACtC,YACE,eAAuB,EACvB,QAAgB,EAChB,IAAwB,EACxB,sBAA+B;QAE/B,KAAK,CAAC,eAAe,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;IACzC,CAAC;IAED;;;;;;;OAOG;IACH,WAAW,CAAC,OAA0B;QACpC,IAAI,WAAW,GAAG,CAAC,CAAC,CAAC;QACrB,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACrB,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,SAAS,CACtC,CAAC,CAAC,EAAE,EAAE,WAAC,OAAA,CAAA,MAAA,CAAC,CAAC,IAAI,0CAAE,EAAE,MAAK,OAAO,CAAC,QAAQ,CAAA,EAAA,CACvC,CAAC;QACJ,CAAC;QAED,IAAI,WAAW,GAAG,CAAC,CAAC,EAAE,CAAC;YACrB,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;CACF;AAED,kBAAe,UAAU,CAAC"}
@@ -0,0 +1,38 @@
1
+ import { FixedThreadPool } from "poolifier";
2
+ import type { ThreadPoolOptions } from "poolifier";
3
+ import { EventResponseData } from "../../types";
4
+
5
+ class WorkerPool extends FixedThreadPool {
6
+ constructor(
7
+ numberOfThreads: number,
8
+ filePath: string,
9
+ opts?: ThreadPoolOptions,
10
+ maximumNumberOfThreads?: number
11
+ ) {
12
+ super(numberOfThreads, filePath, opts);
13
+ }
14
+
15
+ /**
16
+ * Sends message to a specific worker thread or broadcasts the message
17
+ * to all running threads.
18
+ *
19
+ * @param message
20
+ * Any data that needs to passed to the worker.
21
+ *
22
+ */
23
+ postMessage(message: EventResponseData) {
24
+ let workerIndex = -1;
25
+ if (message.threadId) {
26
+ workerIndex = this.workerNodes.findIndex(
27
+ (w) => w.info?.id === message.threadId
28
+ );
29
+ }
30
+
31
+ if (workerIndex > -1) {
32
+ this.workerNodes[workerIndex].worker.postMessage(message);
33
+ }
34
+ }
35
+ }
36
+
37
+ export default WorkerPool;
38
+ export type { FixedThreadPool };
@@ -0,0 +1,31 @@
1
+ import { ThreadWorker } from "poolifier";
2
+ import type { TaskFunctions, TaskFunction, WorkerOptions } from "poolifier";
3
+ import type { EventRequestData } from "../../types";
4
+ declare class WorkerThread extends ThreadWorker {
5
+ constructor(taskFunctions: TaskFunction<unknown, Response> | TaskFunctions<unknown, Response>, opts?: WorkerOptions);
6
+ /**
7
+ * Sends message back to the main thread.
8
+ *
9
+ * @param {EventRequestData} message
10
+ */
11
+ postMessage(message: EventRequestData): void;
12
+ /**
13
+ * Receives message from the main thread or other threads.
14
+ *
15
+ * @param {Function} callback
16
+ * Function to receive the message data.
17
+ */
18
+ onMessage(callback: (value?: any) => void): void;
19
+ private cleanupListener;
20
+ /**
21
+ * Sends a request to the main thread and waits for a response.
22
+ *
23
+ * @param {Object} payload
24
+ * Object or details that needs to be passed to main thread as `payload`.
25
+ *
26
+ * @returns {Promise<Object>}
27
+ * Response from main thread.
28
+ */
29
+ requestMessage(payload: any, context: any): Promise<unknown>;
30
+ }
31
+ export default WorkerThread;