child-pool.js 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.ChildPool = void 0;
  4. const path = require("path");
  5. const child_1 = require("./child");
  6. const CHILD_KILL_TIMEOUT = 30000;
  7. const supportCJS = () => {
  8. return (typeof require === 'function' &&
  9. typeof module === 'object' &&
  10. typeof module.exports === 'object');
  11. };
  12. class ChildPool {
  13. constructor({ mainFile = supportCJS()
  14. ? path.join(process.cwd(), 'dist/cjs/classes/main.js')
  15. : path.join(process.cwd(), 'dist/esm/classes/main.js'), useWorkerThreads, workerForkOptions, workerThreadsOptions, }) {
  16. this.retained = {};
  17. this.free = {};
  18. this.opts = {
  19. mainFile,
  20. useWorkerThreads,
  21. workerForkOptions,
  22. workerThreadsOptions,
  23. };
  24. }
  25. async retain(processFile) {
  26. let child = this.getFree(processFile).pop();
  27. if (child) {
  28. this.retained[child.pid] = child;
  29. return child;
  30. }
  31. child = new child_1.Child(this.opts.mainFile, processFile, {
  32. useWorkerThreads: this.opts.useWorkerThreads,
  33. workerForkOptions: this.opts.workerForkOptions,
  34. workerThreadsOptions: this.opts.workerThreadsOptions,
  35. });
  36. child.on('exit', this.remove.bind(this, child));
  37. try {
  38. await child.init();
  39. // Check status here as well, in case the child exited before we could
  40. // retain it.
  41. if (child.exitCode !== null || child.signalCode !== null) {
  42. throw new Error('Child exited before it could be retained');
  43. }
  44. this.retained[child.pid] = child;
  45. return child;
  46. }
  47. catch (err) {
  48. console.error(err);
  49. this.release(child);
  50. throw err;
  51. }
  52. }
  53. release(child) {
  54. delete this.retained[child.pid];
  55. this.getFree(child.processFile).push(child);
  56. }
  57. remove(child) {
  58. delete this.retained[child.pid];
  59. const free = this.getFree(child.processFile);
  60. const childIndex = free.indexOf(child);
  61. if (childIndex > -1) {
  62. free.splice(childIndex, 1);
  63. }
  64. }
  65. async kill(child, signal = 'SIGKILL') {
  66. this.remove(child);
  67. return child.kill(signal, CHILD_KILL_TIMEOUT);
  68. }
  69. async clean() {
  70. const children = Object.values(this.retained).concat(this.getAllFree());
  71. this.retained = {};
  72. this.free = {};
  73. await Promise.all(children.map(c => this.kill(c, 'SIGTERM')));
  74. }
  75. getFree(id) {
  76. return (this.free[id] = this.free[id] || []);
  77. }
  78. getAllFree() {
  79. return Object.values(this.free).reduce((first, second) => first.concat(second), []);
  80. }
  81. }
  82. exports.ChildPool = ChildPool;
  83. //# sourceMappingURL=child-pool.js.map