@eggjs/cluster 3.0.0-beta.0

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 (96) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +92 -0
  3. package/dist/commonjs/agent_worker.d.ts +1 -0
  4. package/dist/commonjs/agent_worker.js +65 -0
  5. package/dist/commonjs/app_worker.d.ts +1 -0
  6. package/dist/commonjs/app_worker.js +151 -0
  7. package/dist/commonjs/dirname.d.ts +1 -0
  8. package/dist/commonjs/dirname.js +17 -0
  9. package/dist/commonjs/error/ClusterAgentWorkerError.d.ts +10 -0
  10. package/dist/commonjs/error/ClusterAgentWorkerError.js +23 -0
  11. package/dist/commonjs/error/ClusterWorkerExceptionError.d.ts +7 -0
  12. package/dist/commonjs/error/ClusterWorkerExceptionError.js +18 -0
  13. package/dist/commonjs/error/index.d.ts +2 -0
  14. package/dist/commonjs/error/index.js +19 -0
  15. package/dist/commonjs/index.d.ts +17 -0
  16. package/dist/commonjs/index.js +37 -0
  17. package/dist/commonjs/master.d.ts +90 -0
  18. package/dist/commonjs/master.js +544 -0
  19. package/dist/commonjs/package.json +3 -0
  20. package/dist/commonjs/utils/messenger.d.ts +87 -0
  21. package/dist/commonjs/utils/messenger.js +183 -0
  22. package/dist/commonjs/utils/mode/base/agent.d.ts +38 -0
  23. package/dist/commonjs/utils/mode/base/agent.js +68 -0
  24. package/dist/commonjs/utils/mode/base/app.d.ts +48 -0
  25. package/dist/commonjs/utils/mode/base/app.js +81 -0
  26. package/dist/commonjs/utils/mode/impl/process/agent.d.ts +18 -0
  27. package/dist/commonjs/utils/mode/impl/process/agent.js +107 -0
  28. package/dist/commonjs/utils/mode/impl/process/app.d.ts +20 -0
  29. package/dist/commonjs/utils/mode/impl/process/app.js +134 -0
  30. package/dist/commonjs/utils/mode/impl/worker_threads/agent.d.ts +18 -0
  31. package/dist/commonjs/utils/mode/impl/worker_threads/agent.js +90 -0
  32. package/dist/commonjs/utils/mode/impl/worker_threads/app.d.ts +25 -0
  33. package/dist/commonjs/utils/mode/impl/worker_threads/app.js +156 -0
  34. package/dist/commonjs/utils/options.d.ts +80 -0
  35. package/dist/commonjs/utils/options.js +81 -0
  36. package/dist/commonjs/utils/terminate.d.ts +6 -0
  37. package/dist/commonjs/utils/terminate.js +89 -0
  38. package/dist/commonjs/utils/worker_manager.d.ts +25 -0
  39. package/dist/commonjs/utils/worker_manager.js +76 -0
  40. package/dist/esm/agent_worker.d.ts +1 -0
  41. package/dist/esm/agent_worker.js +63 -0
  42. package/dist/esm/app_worker.d.ts +1 -0
  43. package/dist/esm/app_worker.js +146 -0
  44. package/dist/esm/dirname.d.ts +1 -0
  45. package/dist/esm/dirname.js +11 -0
  46. package/dist/esm/error/ClusterAgentWorkerError.d.ts +10 -0
  47. package/dist/esm/error/ClusterAgentWorkerError.js +19 -0
  48. package/dist/esm/error/ClusterWorkerExceptionError.d.ts +7 -0
  49. package/dist/esm/error/ClusterWorkerExceptionError.js +14 -0
  50. package/dist/esm/error/index.d.ts +2 -0
  51. package/dist/esm/error/index.js +3 -0
  52. package/dist/esm/index.d.ts +17 -0
  53. package/dist/esm/index.js +19 -0
  54. package/dist/esm/master.d.ts +90 -0
  55. package/dist/esm/master.js +537 -0
  56. package/dist/esm/package.json +3 -0
  57. package/dist/esm/utils/messenger.d.ts +87 -0
  58. package/dist/esm/utils/messenger.js +176 -0
  59. package/dist/esm/utils/mode/base/agent.d.ts +38 -0
  60. package/dist/esm/utils/mode/base/agent.js +60 -0
  61. package/dist/esm/utils/mode/base/app.d.ts +48 -0
  62. package/dist/esm/utils/mode/base/app.js +73 -0
  63. package/dist/esm/utils/mode/impl/process/agent.d.ts +18 -0
  64. package/dist/esm/utils/mode/impl/process/agent.js +102 -0
  65. package/dist/esm/utils/mode/impl/process/app.d.ts +20 -0
  66. package/dist/esm/utils/mode/impl/process/app.js +126 -0
  67. package/dist/esm/utils/mode/impl/worker_threads/agent.d.ts +18 -0
  68. package/dist/esm/utils/mode/impl/worker_threads/agent.js +82 -0
  69. package/dist/esm/utils/mode/impl/worker_threads/app.d.ts +25 -0
  70. package/dist/esm/utils/mode/impl/worker_threads/app.js +151 -0
  71. package/dist/esm/utils/options.d.ts +80 -0
  72. package/dist/esm/utils/options.js +75 -0
  73. package/dist/esm/utils/terminate.d.ts +6 -0
  74. package/dist/esm/utils/terminate.js +86 -0
  75. package/dist/esm/utils/worker_manager.d.ts +25 -0
  76. package/dist/esm/utils/worker_manager.js +72 -0
  77. package/dist/package.json +4 -0
  78. package/package.json +94 -0
  79. package/src/agent_worker.ts +75 -0
  80. package/src/app_worker.ts +170 -0
  81. package/src/dirname.ts +11 -0
  82. package/src/error/ClusterAgentWorkerError.ts +19 -0
  83. package/src/error/ClusterWorkerExceptionError.ts +17 -0
  84. package/src/error/index.ts +2 -0
  85. package/src/index.ts +26 -0
  86. package/src/master.ts +641 -0
  87. package/src/utils/messenger.ts +199 -0
  88. package/src/utils/mode/base/agent.ts +90 -0
  89. package/src/utils/mode/base/app.ts +115 -0
  90. package/src/utils/mode/impl/process/agent.ts +118 -0
  91. package/src/utils/mode/impl/process/app.ts +146 -0
  92. package/src/utils/mode/impl/worker_threads/agent.ts +98 -0
  93. package/src/utils/mode/impl/worker_threads/app.ts +180 -0
  94. package/src/utils/options.ts +169 -0
  95. package/src/utils/terminate.ts +97 -0
  96. package/src/utils/worker_manager.ts +87 -0
@@ -0,0 +1,544 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.Master = void 0;
7
+ const node_os_1 = __importDefault(require("node:os"));
8
+ const node_v8_1 = __importDefault(require("node:v8"));
9
+ const node_util_1 = __importDefault(require("node:util"));
10
+ const node_path_1 = __importDefault(require("node:path"));
11
+ const node_fs_1 = __importDefault(require("node:fs"));
12
+ const node_net_1 = __importDefault(require("node:net"));
13
+ const get_ready_1 = require("get-ready");
14
+ const detect_port_1 = require("detect-port");
15
+ const cluster_reload_1 = require("cluster-reload");
16
+ const egg_logger_1 = require("egg-logger");
17
+ const utility_1 = require("utility");
18
+ const terminal_link_1 = __importDefault(require("terminal-link"));
19
+ const options_js_1 = require("./utils/options.js");
20
+ const worker_manager_js_1 = require("./utils/worker_manager.js");
21
+ const messenger_js_1 = require("./utils/messenger.js");
22
+ const agent_js_1 = require("./utils/mode/impl/process/agent.js");
23
+ const app_js_1 = require("./utils/mode/impl/process/app.js");
24
+ const agent_js_2 = require("./utils/mode/impl/worker_threads/agent.js");
25
+ const app_js_2 = require("./utils/mode/impl/worker_threads/app.js");
26
+ const ClusterWorkerExceptionError_js_1 = require("./error/ClusterWorkerExceptionError.js");
27
+ class Master extends get_ready_1.ReadyEventEmitter {
28
+ options;
29
+ isStarted = false;
30
+ workerManager;
31
+ messenger;
32
+ isProduction;
33
+ agentWorkerIndex = 0;
34
+ closed = false;
35
+ logger;
36
+ agentWorker;
37
+ appWorker;
38
+ #logMethod;
39
+ #realPort;
40
+ #protocol;
41
+ #appAddress;
42
+ constructor(options) {
43
+ super();
44
+ this.#start(options)
45
+ .catch(err => {
46
+ this.ready(err);
47
+ });
48
+ }
49
+ async #start(options) {
50
+ this.options = await (0, options_js_1.parseOptions)(options);
51
+ this.workerManager = new worker_manager_js_1.WorkerManager();
52
+ this.messenger = new messenger_js_1.Messenger(this, this.workerManager);
53
+ this.isProduction = isProduction(this.options);
54
+ this.#realPort = this.options.port;
55
+ this.#protocol = this.options.https ? 'https' : 'http';
56
+ // app started or not
57
+ this.isStarted = false;
58
+ this.logger = new egg_logger_1.EggConsoleLogger({ level: process.env.EGG_MASTER_LOGGER_LEVEL ?? 'INFO' });
59
+ this.#logMethod = 'info';
60
+ if (this.options.env === 'local' || process.env.NODE_ENV === 'development') {
61
+ this.#logMethod = 'debug';
62
+ }
63
+ // get the real framework info
64
+ const frameworkPath = this.options.framework;
65
+ const frameworkPkg = (0, utility_1.readJSONSync)(node_path_1.default.join(frameworkPath, 'package.json'));
66
+ // set app & agent worker impl
67
+ if (this.options.startMode === 'worker_threads') {
68
+ this.startByWorkerThreads();
69
+ }
70
+ else {
71
+ this.startByProcess();
72
+ }
73
+ this.log(`[master] =================== ${frameworkPkg.name} start =====================`);
74
+ this.logger.info(`[master] node version ${process.version}`);
75
+ /* istanbul ignore next */
76
+ if ('alinode' in process) {
77
+ this.logger.info(`[master] alinode version ${process.alinode}`);
78
+ }
79
+ this.logger.info(`[master] ${frameworkPkg.name} version ${frameworkPkg.version}`);
80
+ if (this.isProduction) {
81
+ this.logger.info('[master] start with options:%s%s', node_os_1.default.EOL, JSON.stringify(this.options, null, 2));
82
+ }
83
+ else {
84
+ this.log('[master] start with options: %j', this.options);
85
+ }
86
+ this.log('[master] start with env: isProduction: %s, EGG_SERVER_ENV: %s, NODE_ENV: %s', this.isProduction, this.options.env, process.env.NODE_ENV);
87
+ const startTime = Date.now();
88
+ this.ready(() => {
89
+ this.isStarted = true;
90
+ const stickyMsg = this.options.sticky ? ' with STICKY MODE!' : '';
91
+ const startedURL = (0, terminal_link_1.default)(this.#appAddress, this.#appAddress, { fallback: false });
92
+ this.logger.info('[master] %s started on %s (%sms)%s', frameworkPkg.name, startedURL, Date.now() - startTime, stickyMsg);
93
+ if (this.options.debugPort) {
94
+ const url = getAddress({
95
+ port: this.options.debugPort,
96
+ protocol: 'http',
97
+ });
98
+ const debugPortURL = (0, terminal_link_1.default)(url, url, { fallback: false });
99
+ this.logger.info('[master] %s started debug port on %s', frameworkPkg.name, debugPortURL);
100
+ }
101
+ const action = 'egg-ready';
102
+ this.messenger.send({
103
+ action,
104
+ to: 'parent',
105
+ data: {
106
+ port: this.#realPort,
107
+ debugPort: this.options.debugPort,
108
+ address: this.#appAddress,
109
+ protocol: this.#protocol,
110
+ },
111
+ });
112
+ this.messenger.send({
113
+ action,
114
+ to: 'app',
115
+ data: this.options,
116
+ });
117
+ this.messenger.send({
118
+ action,
119
+ to: 'agent',
120
+ data: this.options,
121
+ });
122
+ // start check agent and worker status
123
+ if (this.isProduction) {
124
+ this.workerManager.startCheck();
125
+ }
126
+ });
127
+ this.on('agent-exit', this.onAgentExit.bind(this));
128
+ this.on('agent-start', this.onAgentStart.bind(this));
129
+ this.on('app-exit', this.onAppExit.bind(this));
130
+ this.on('app-start', this.onAppStart.bind(this));
131
+ this.on('reload-worker', this.onReload.bind(this));
132
+ // fork app workers after agent started
133
+ this.once('agent-start', this.forkAppWorkers.bind(this));
134
+ // get the real port from options and app.config
135
+ // app worker will send after loading
136
+ this.on('realport', ({ port, protocol }) => {
137
+ if (port) {
138
+ this.#realPort = port;
139
+ }
140
+ if (protocol) {
141
+ this.#protocol = protocol;
142
+ }
143
+ });
144
+ // https://nodejs.org/api/process.html#process_signal_events
145
+ // https://en.wikipedia.org/wiki/Unix_signal
146
+ // kill(2) Ctrl-C
147
+ process.once('SIGINT', this.onSignal.bind(this, 'SIGINT'));
148
+ // kill(3) Ctrl-\
149
+ process.once('SIGQUIT', this.onSignal.bind(this, 'SIGQUIT'));
150
+ // kill(15) default
151
+ process.once('SIGTERM', this.onSignal.bind(this, 'SIGTERM'));
152
+ process.once('exit', this.onExit.bind(this));
153
+ // write pid to file if provided
154
+ if (this.options.pidFile) {
155
+ node_fs_1.default.mkdirSync(node_path_1.default.dirname(this.options.pidFile), { recursive: true });
156
+ node_fs_1.default.writeFileSync(this.options.pidFile, process.pid.toString(), 'utf-8');
157
+ }
158
+ this.detectPorts()
159
+ .then(() => {
160
+ this.forkAgentWorker();
161
+ });
162
+ // exit when agent or worker exception
163
+ this.workerManager.on('exception', (count) => {
164
+ const err = new ClusterWorkerExceptionError_js_1.ClusterWorkerExceptionError(count.agent, count.worker);
165
+ this.logger.error(err);
166
+ process.exit(1);
167
+ });
168
+ }
169
+ startByProcess() {
170
+ this.agentWorker = new agent_js_1.AgentProcessUtils(this.options, {
171
+ log: this.log.bind(this),
172
+ logger: this.logger,
173
+ messenger: this.messenger,
174
+ });
175
+ this.appWorker = new app_js_1.AppProcessUtils(this.options, {
176
+ log: this.log.bind(this),
177
+ logger: this.logger,
178
+ messenger: this.messenger,
179
+ isProduction: this.isProduction,
180
+ });
181
+ }
182
+ startByWorkerThreads() {
183
+ this.agentWorker = new agent_js_2.AgentThreadUtils(this.options, {
184
+ log: this.log.bind(this),
185
+ logger: this.logger,
186
+ messenger: this.messenger,
187
+ });
188
+ this.appWorker = new app_js_2.AppThreadUtils(this.options, {
189
+ log: this.log.bind(this),
190
+ logger: this.logger,
191
+ messenger: this.messenger,
192
+ isProduction: this.isProduction,
193
+ });
194
+ }
195
+ async detectPorts() {
196
+ // Detect cluster client port
197
+ try {
198
+ const clusterPort = await (0, detect_port_1.detectPort)();
199
+ this.options.clusterPort = clusterPort;
200
+ // If sticky mode, detect worker port
201
+ if (this.options.sticky) {
202
+ const stickyWorkerPort = await (0, detect_port_1.detectPort)();
203
+ this.options.stickyWorkerPort = stickyWorkerPort;
204
+ }
205
+ }
206
+ catch (err) {
207
+ this.logger.error(err);
208
+ process.exit(1);
209
+ }
210
+ }
211
+ log(msg, ...args) {
212
+ this.logger[this.#logMethod](msg, ...args);
213
+ }
214
+ startMasterSocketServer(cb) {
215
+ // Create the outside facing server listening on our port.
216
+ node_net_1.default.createServer({
217
+ pauseOnConnect: true,
218
+ }, connection => {
219
+ // We received a connection and need to pass it to the appropriate
220
+ // worker. Get the worker for this connection's source IP and pass
221
+ // it the connection.
222
+ /* istanbul ignore next */
223
+ if (!connection.remoteAddress) {
224
+ // This will happen when a client sends an RST(which is set to 1) right
225
+ // after the three-way handshake to the server.
226
+ // Read https://en.wikipedia.org/wiki/TCP_reset_attack for more details.
227
+ connection.destroy();
228
+ }
229
+ else {
230
+ const worker = this.stickyWorker(connection.remoteAddress);
231
+ worker.instance.send('sticky-session:connection', connection);
232
+ }
233
+ }).listen(this.#realPort, cb);
234
+ }
235
+ stickyWorker(ip) {
236
+ const workerNumbers = this.options.workers;
237
+ const ws = this.workerManager.listWorkerIds();
238
+ let s = '';
239
+ for (let i = 0; i < ip.length; i++) {
240
+ if (!isNaN(parseInt(ip[i]))) {
241
+ s += ip[i];
242
+ }
243
+ }
244
+ const pid = ws[Number(s) % workerNumbers];
245
+ return this.workerManager.getWorker(pid);
246
+ }
247
+ forkAgentWorker() {
248
+ this.agentWorker.on('agent_forked', (agent) => {
249
+ this.workerManager.setAgent(agent);
250
+ });
251
+ this.agentWorker.fork();
252
+ }
253
+ forkAppWorkers() {
254
+ this.appWorker.on('worker_forked', (worker) => {
255
+ this.workerManager.setWorker(worker);
256
+ });
257
+ this.appWorker.fork();
258
+ }
259
+ /**
260
+ * close agent worker, App Worker will closed by cluster
261
+ *
262
+ * https://www.exratione.com/2013/05/die-child-process-die/
263
+ * make sure Agent Worker exit before master exit
264
+ *
265
+ * @param {number} timeout - kill agent timeout
266
+ * @return {Promise} -
267
+ */
268
+ async killAgentWorker(timeout) {
269
+ await this.agentWorker.kill(timeout);
270
+ }
271
+ async killAppWorkers(timeout) {
272
+ await this.appWorker.kill(timeout);
273
+ }
274
+ /**
275
+ * Agent Worker exit handler
276
+ * Will exit during startup, and refork during running.
277
+ */
278
+ onAgentExit(data) {
279
+ if (this.closed)
280
+ return;
281
+ this.messenger.send({
282
+ action: 'egg-pids',
283
+ to: 'app',
284
+ data: [],
285
+ });
286
+ const agentWorker = this.agentWorker;
287
+ this.workerManager.deleteAgent();
288
+ const err = new Error(node_util_1.default.format('[master] agent_worker#%s:%s died (code: %s, signal: %s)', agentWorker.instance.id, agentWorker.instance.workerId, data.code, data.signal));
289
+ err.name = 'AgentWorkerDiedError';
290
+ this.logger.error(err);
291
+ // remove all listeners to avoid memory leak
292
+ agentWorker.clean();
293
+ if (this.isStarted) {
294
+ this.log('[master] try to start a new agent_worker after 1s ...');
295
+ setTimeout(() => {
296
+ this.logger.info('[master] new agent_worker starting...');
297
+ this.forkAgentWorker();
298
+ }, 1000);
299
+ this.messenger.send({
300
+ action: 'agent-worker-died',
301
+ to: 'parent',
302
+ });
303
+ }
304
+ else {
305
+ this.logger.error('[master] agent_worker#%s:%s start fail, exiting with code:1', agentWorker.instance.id, agentWorker.instance.workerId);
306
+ process.exit(1);
307
+ }
308
+ }
309
+ onAgentStart() {
310
+ this.agentWorker.instance.status = 'started';
311
+ // Send egg-ready when agent is started after launched
312
+ if (this.appWorker.isAllWorkerStarted) {
313
+ this.messenger.send({
314
+ action: 'egg-ready',
315
+ to: 'agent',
316
+ data: this.options,
317
+ });
318
+ }
319
+ this.messenger.send({
320
+ action: 'egg-pids',
321
+ to: 'app',
322
+ data: [this.agentWorker.instance.workerId],
323
+ });
324
+ // should send current worker pids when agent restart
325
+ if (this.isStarted) {
326
+ this.messenger.send({
327
+ action: 'egg-pids',
328
+ to: 'agent',
329
+ data: this.workerManager.getListeningWorkerIds(),
330
+ });
331
+ }
332
+ this.messenger.send({
333
+ action: 'agent-start',
334
+ to: 'app',
335
+ });
336
+ this.logger.info('[master] agent_worker#%s:%s started (%sms)', this.agentWorker.instance.id, this.agentWorker.instance.workerId, Date.now() - this.agentWorker.startTime);
337
+ }
338
+ /**
339
+ * App Worker exit handler
340
+ */
341
+ onAppExit(data) {
342
+ if (this.closed)
343
+ return;
344
+ const worker = this.workerManager.getWorker(data.workerId);
345
+ if (!worker.isDevReload) {
346
+ const signal = data.signal;
347
+ const message = node_util_1.default.format('[master] app_worker#%s:%s died (code: %s, signal: %s, suicide: %s, state: %s), current workers: %j', worker.id, worker.workerId, worker.exitCode, signal, worker.exitedAfterDisconnect, worker.state, this.workerManager.listWorkerIds());
348
+ if (this.options.isDebug && signal === 'SIGKILL') {
349
+ // exit if died during debug
350
+ this.logger.error(message);
351
+ this.logger.error('[master] worker kill by debugger, exiting...');
352
+ setTimeout(() => this.close(), 10);
353
+ }
354
+ else {
355
+ const err = new Error(message);
356
+ err.name = 'AppWorkerDiedError';
357
+ this.logger.error(err);
358
+ }
359
+ }
360
+ // remove all listeners to avoid memory leak
361
+ worker.clean();
362
+ this.workerManager.deleteWorker(data.workerId);
363
+ // send message to agent with alive workers
364
+ this.messenger.send({
365
+ action: 'egg-pids',
366
+ to: 'agent',
367
+ data: this.workerManager.getListeningWorkerIds(),
368
+ });
369
+ if (this.appWorker.isAllWorkerStarted) {
370
+ // cfork will only refork at production mode
371
+ this.messenger.send({
372
+ action: 'app-worker-died',
373
+ to: 'parent',
374
+ });
375
+ }
376
+ else {
377
+ // exit if died during startup
378
+ this.logger.error('[master] app_worker#%s:%s start fail, exiting with code:1', worker.id, worker.workerId);
379
+ process.exit(1);
380
+ }
381
+ }
382
+ /**
383
+ * after app worker
384
+ */
385
+ onAppStart(data) {
386
+ const address = data.address;
387
+ // worker should listen stickyWorkerPort when sticky mode
388
+ if (this.options.sticky) {
389
+ if (String(address.port) !== String(this.options.stickyWorkerPort)) {
390
+ return;
391
+ }
392
+ // worker should listen REALPORT when not sticky mode
393
+ }
394
+ else if (this.options.startMode !== 'worker_threads' &&
395
+ !isUnixSock(address) &&
396
+ (String(address.port) !== String(this.#realPort))) {
397
+ return;
398
+ }
399
+ // send message to agent with alive workers
400
+ this.messenger.send({
401
+ action: 'egg-pids',
402
+ to: 'agent',
403
+ data: this.workerManager.getListeningWorkerIds(),
404
+ });
405
+ this.appWorker.startSuccessCount++;
406
+ const worker = this.workerManager.getWorker(data.workerId);
407
+ const remain = this.appWorker.isAllWorkerStarted ? 0 : this.options.workers - this.appWorker.startSuccessCount;
408
+ this.log('[master] app_worker#%s:%s started at %s, remain %s (%sms)', worker.id, worker.workerId, address.port, remain, Date.now() - this.appWorker.startTime);
409
+ // Send egg-ready when app is started after launched
410
+ if (this.appWorker.isAllWorkerStarted) {
411
+ this.messenger.send({
412
+ action: 'egg-ready',
413
+ to: 'app',
414
+ data: this.options,
415
+ });
416
+ }
417
+ // if app is started, it should enable this worker
418
+ if (this.appWorker.isAllWorkerStarted) {
419
+ worker.disableRefork = false;
420
+ }
421
+ if (this.appWorker.isAllWorkerStarted || this.appWorker.startSuccessCount < this.options.workers) {
422
+ return;
423
+ }
424
+ this.appWorker.isAllWorkerStarted = true;
425
+ // enable all workers when app started
426
+ for (const worker of this.workerManager.listWorkers()) {
427
+ worker.disableRefork = false;
428
+ }
429
+ address.protocol = this.#protocol;
430
+ address.port = this.options.sticky ? this.#realPort : address.port;
431
+ this.#appAddress = getAddress(address);
432
+ if (this.options.sticky) {
433
+ this.startMasterSocketServer(err => {
434
+ if (err) {
435
+ return this.ready(err);
436
+ }
437
+ this.ready(true);
438
+ });
439
+ }
440
+ else {
441
+ this.ready(true);
442
+ }
443
+ }
444
+ /**
445
+ * master exit handler
446
+ */
447
+ onExit(code) {
448
+ if (this.options.pidFile && node_fs_1.default.existsSync(this.options.pidFile)) {
449
+ try {
450
+ node_fs_1.default.unlinkSync(this.options.pidFile);
451
+ }
452
+ catch (err) {
453
+ /* istanbul ignore next */
454
+ this.logger.error('[master] delete pidFile %s fail with %s', this.options.pidFile, err.message);
455
+ }
456
+ }
457
+ // istanbul can't cover here
458
+ // https://github.com/gotwarlost/istanbul/issues/567
459
+ const level = code === 0 ? 'info' : 'error';
460
+ this.logger[level]('[master] exit with code:%s', code);
461
+ }
462
+ onSignal(signal) {
463
+ if (this.closed)
464
+ return;
465
+ this.logger.info('[master] master is killed by signal %s, closing', signal);
466
+ // logger more info
467
+ const { used_heap_size, heap_size_limit } = node_v8_1.default.getHeapStatistics();
468
+ this.logger.info('[master] system memory: total %s, free %s', node_os_1.default.totalmem(), node_os_1.default.freemem());
469
+ this.logger.info('[master] process info: heap_limit %s, heap_used %s', heap_size_limit, used_heap_size);
470
+ this.close();
471
+ }
472
+ /**
473
+ * reload workers, for develop purpose
474
+ */
475
+ onReload() {
476
+ this.log('[master] reload %s workers...', this.options.workers);
477
+ for (const worker of this.workerManager.listWorkers()) {
478
+ worker.isDevReload = true;
479
+ }
480
+ (0, cluster_reload_1.reload)(this.options.workers);
481
+ }
482
+ async close() {
483
+ this.closed = true;
484
+ try {
485
+ await this._doClose();
486
+ this.log('[master] close done, exiting with code:0');
487
+ process.exit(0);
488
+ }
489
+ catch (e) {
490
+ this.logger.error('[master] close with error: ', e);
491
+ process.exit(1);
492
+ }
493
+ }
494
+ async _doClose() {
495
+ // kill app workers
496
+ // kill agent worker
497
+ // exit itself
498
+ const legacyTimeout = process.env.EGG_MASTER_CLOSE_TIMEOUT || '5000';
499
+ const appTimeout = parseInt(process.env.EGG_APP_CLOSE_TIMEOUT || legacyTimeout);
500
+ const agentTimeout = parseInt(process.env.EGG_AGENT_CLOSE_TIMEOUT || legacyTimeout);
501
+ this.logger.info('[master] send kill SIGTERM to app workers, will exit with code:0 after %sms', appTimeout);
502
+ this.logger.info('[master] wait %sms', appTimeout);
503
+ try {
504
+ await this.killAppWorkers(appTimeout);
505
+ }
506
+ catch (e) {
507
+ this.logger.error('[master] app workers exit error: ', e);
508
+ }
509
+ this.logger.info('[master] send kill SIGTERM to agent worker, will exit with code:0 after %sms', agentTimeout);
510
+ this.logger.info('[master] wait %sms', agentTimeout);
511
+ try {
512
+ await this.killAgentWorker(agentTimeout);
513
+ }
514
+ catch (e) /* istanbul ignore next */ {
515
+ this.logger.error('[master] agent worker exit error: ', e);
516
+ }
517
+ }
518
+ }
519
+ exports.Master = Master;
520
+ function isProduction(options) {
521
+ if (options.env) {
522
+ return options.env !== 'local' && options.env !== 'unittest';
523
+ }
524
+ return process.env.NODE_ENV === 'production';
525
+ }
526
+ function getAddress({ addressType, address, port, protocol, }) {
527
+ // unix sock
528
+ // https://nodejs.org/api/cluster.html#cluster_event_listening_1
529
+ if (addressType === -1) {
530
+ return address;
531
+ }
532
+ let hostname = address;
533
+ if (!hostname && process.env.HOST && process.env.HOST !== '0.0.0.0') {
534
+ hostname = process.env.HOST;
535
+ }
536
+ if (!hostname) {
537
+ hostname = '127.0.0.1';
538
+ }
539
+ return `${protocol}://${hostname}:${port}`;
540
+ }
541
+ function isUnixSock(address) {
542
+ return address.addressType === -1;
543
+ }
544
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFzdGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL21hc3Rlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSxzREFBeUI7QUFDekIsc0RBQXlCO0FBQ3pCLDBEQUE2QjtBQUM3QiwwREFBNkI7QUFDN0Isc0RBQXlCO0FBQ3pCLHdEQUEyQjtBQUMzQix5Q0FBOEM7QUFDOUMsNkNBQXlDO0FBQ3pDLG1EQUF3QztBQUN4QywyQ0FBK0Q7QUFDL0QscUNBQXVDO0FBQ3ZDLGtFQUF5QztBQUN6QyxtREFBd0Y7QUFDeEYsaUVBQTBEO0FBQzFELHVEQUFpRDtBQUNqRCxpRUFFNEM7QUFDNUMsNkRBQXlHO0FBQ3pHLHdFQUVtRDtBQUNuRCxvRUFBb0g7QUFDcEgsMkZBQXFGO0FBT3JGLE1BQWEsTUFBTyxTQUFRLDZCQUFpQjtJQUMzQyxPQUFPLENBQWdCO0lBQ3ZCLFNBQVMsR0FBRyxLQUFLLENBQUM7SUFDbEIsYUFBYSxDQUFnQjtJQUM3QixTQUFTLENBQVk7SUFDckIsWUFBWSxDQUFVO0lBQ3RCLGdCQUFnQixHQUFHLENBQUMsQ0FBQztJQUNyQixNQUFNLEdBQUcsS0FBSyxDQUFDO0lBQ2YsTUFBTSxDQUFnQjtJQUN0QixXQUFXLENBQWdEO0lBQzNELFNBQVMsQ0FBNEM7SUFDckQsVUFBVSxDQUFtQjtJQUM3QixTQUFTLENBQVU7SUFDbkIsU0FBUyxDQUFTO0lBQ2xCLFdBQVcsQ0FBUztJQUVwQixZQUFZLE9BQXdCO1FBQ2xDLEtBQUssRUFBRSxDQUFDO1FBQ1IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUM7YUFDakIsS0FBSyxDQUFDLEdBQUcsQ0FBQyxFQUFFO1lBQ1gsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNsQixDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFRCxLQUFLLENBQUMsTUFBTSxDQUFDLE9BQXdCO1FBQ25DLElBQUksQ0FBQyxPQUFPLEdBQUcsTUFBTSxJQUFB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
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "commonjs"
3
+ }
@@ -0,0 +1,87 @@
1
+ import type { Master } from '../master.js';
2
+ import type { WorkerManager } from './worker_manager.js';
3
+ export type MessageCharacter = 'agent' | 'app' | 'master' | 'parent';
4
+ export interface MessageBody {
5
+ action: string;
6
+ data?: unknown;
7
+ to?: MessageCharacter;
8
+ from?: MessageCharacter;
9
+ receiverPid?: string;
10
+ }
11
+ /**
12
+ * master messenger, provide communication between parent, master, agent and app.
13
+ *
14
+ * ┌────────┐
15
+ * │ parent │
16
+ * /└────────┘\
17
+ * / | \
18
+ * / ┌────────┐ \
19
+ * / │ master │ \
20
+ * / └────────┘ \
21
+ * / / \ \
22
+ * ┌───────┐ ┌───────┐
23
+ * │ agent │ ------- │ app │
24
+ * └───────┘ └───────┘
25
+ *
26
+ *
27
+ * in app worker
28
+ *
29
+ * ```js
30
+ * process.send({
31
+ * action: 'xxx',
32
+ * data: '',
33
+ * to: 'agent/master/parent', // default to agent
34
+ * });
35
+ * ```
36
+ *
37
+ * in agent worker
38
+ *
39
+ * ```js
40
+ * process.send({
41
+ * action: 'xxx',
42
+ * data: '',
43
+ * to: 'app/master/parent', // default to app
44
+ * });
45
+ * ```
46
+ *
47
+ * in parent
48
+ *
49
+ * ```js
50
+ * process.send({
51
+ * action: 'xxx',
52
+ * data: '',
53
+ * to: 'app/agent/master', // default to master
54
+ * });
55
+ * ```
56
+ */
57
+ export declare class Messenger {
58
+ #private;
59
+ constructor(master: Master, workerManager: WorkerManager);
60
+ /**
61
+ * send message
62
+ * @param {Object} data message body
63
+ * - {String} from from who
64
+ * - {String} to to who
65
+ */
66
+ send(data: MessageBody): void;
67
+ /**
68
+ * send message to master self
69
+ * @param {Object} data message body
70
+ */
71
+ sendToMaster(data: MessageBody): void;
72
+ /**
73
+ * send message to parent process
74
+ * @param {Object} data message body
75
+ */
76
+ sendToParent(data: MessageBody): void;
77
+ /**
78
+ * send message to app worker
79
+ * @param {Object} data message body
80
+ */
81
+ sendToAppWorker(data: MessageBody): void;
82
+ /**
83
+ * send message to agent worker
84
+ * @param {Object} data message body
85
+ */
86
+ sendToAgentWorker(data: MessageBody): void;
87
+ }