UNPKG

3.63 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, '__esModule', {
4 value: true
5});
6exports.default = void 0;
7
8function _stream() {
9 const data = require('stream');
10
11 _stream = function () {
12 return data;
13 };
14
15 return data;
16}
17
18var _types = require('../types');
19
20/**
21 * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
22 *
23 * This source code is licensed under the MIT license found in the
24 * LICENSE file in the root directory of this source tree.
25 */
26class WorkerAbstract extends _stream().EventEmitter {
27 /**
28 * DO NOT WRITE TO THIS DIRECTLY.
29 * Use this.state getter/setters so events are emitted correctly.
30 */
31 #state = _types.WorkerStates.STARTING;
32 _fakeStream = null;
33 _exitPromise;
34 _resolveExitPromise;
35 _workerReadyPromise;
36 _resolveWorkerReady;
37
38 get state() {
39 return this.#state;
40 }
41
42 set state(value) {
43 if (this.#state !== value) {
44 const oldState = this.#state;
45 this.#state = value;
46 this.emit(_types.WorkerEvents.STATE_CHANGE, value, oldState);
47 }
48 }
49
50 constructor(options) {
51 super();
52
53 if (typeof options.on === 'object') {
54 for (const [event, handlers] of Object.entries(options.on)) {
55 // Can't do Array.isArray on a ReadonlyArray<T>.
56 // https://github.com/microsoft/TypeScript/issues/17002
57 if (typeof handlers === 'function') {
58 super.on(event, handlers);
59 } else {
60 for (const handler of handlers) {
61 super.on(event, handler);
62 }
63 }
64 }
65 }
66
67 this._exitPromise = new Promise(resolve => {
68 this._resolveExitPromise = resolve;
69 });
70
71 this._exitPromise.then(() => {
72 this.state = _types.WorkerStates.SHUT_DOWN;
73 });
74 }
75 /**
76 * Wait for the worker child process to be ready to handle requests.
77 *
78 * @returns Promise which resolves when ready.
79 */
80
81 waitForWorkerReady() {
82 if (!this._workerReadyPromise) {
83 this._workerReadyPromise = new Promise((resolve, reject) => {
84 let settled = false;
85 let to;
86
87 switch (this.state) {
88 case _types.WorkerStates.OUT_OF_MEMORY:
89 case _types.WorkerStates.SHUTTING_DOWN:
90 case _types.WorkerStates.SHUT_DOWN:
91 settled = true;
92 reject(
93 new Error(
94 `Worker state means it will never be ready: ${this.state}`
95 )
96 );
97 break;
98
99 case _types.WorkerStates.STARTING:
100 case _types.WorkerStates.RESTARTING:
101 this._resolveWorkerReady = () => {
102 settled = true;
103 resolve();
104
105 if (to) {
106 clearTimeout(to);
107 }
108 };
109
110 break;
111
112 case _types.WorkerStates.OK:
113 settled = true;
114 resolve();
115 break;
116 }
117
118 if (!settled) {
119 to = setTimeout(() => {
120 if (!settled) {
121 reject(new Error('Timeout starting worker'));
122 }
123 }, 500);
124 }
125 });
126 }
127
128 return this._workerReadyPromise;
129 }
130 /**
131 * Used to shut down the current working instance once the children have been
132 * killed off.
133 */
134
135 _shutdown() {
136 this.state === _types.WorkerStates.SHUT_DOWN; // End the permanent stream so the merged stream end too
137
138 if (this._fakeStream) {
139 this._fakeStream.end();
140
141 this._fakeStream = null;
142 }
143
144 this._resolveExitPromise();
145 }
146
147 _getFakeStream() {
148 if (!this._fakeStream) {
149 this._fakeStream = new (_stream().PassThrough)();
150 }
151
152 return this._fakeStream;
153 }
154}
155
156exports.default = WorkerAbstract;