@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,89 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.terminate = terminate;
4
+ const node_util_1 = require("node:util");
5
+ const promises_1 = require("node:timers/promises");
6
+ const node_events_1 = require("node:events");
7
+ const ps_tree_1 = require("@fengmk2/ps-tree");
8
+ const debug = (0, node_util_1.debuglog)('@eggjs/cluster/utils/terminate');
9
+ async function terminate(subProcess, timeout) {
10
+ const pid = subProcess.process?.pid ?? subProcess.pid;
11
+ const childPids = await getChildPids(pid);
12
+ await Promise.all([
13
+ killProcess(subProcess, timeout),
14
+ killChildren(childPids, timeout),
15
+ ]);
16
+ }
17
+ // kill process, if SIGTERM not work, try SIGKILL
18
+ async function killProcess(subProcess, timeout) {
19
+ // https://github.com/nodejs/node/pull/34312
20
+ (subProcess.process ?? subProcess).kill('SIGTERM');
21
+ await Promise.race([
22
+ (0, node_events_1.once)(subProcess, 'exit'),
23
+ (0, promises_1.setTimeout)(timeout),
24
+ ]);
25
+ if (subProcess.killed) {
26
+ return;
27
+ }
28
+ // SIGKILL: http://man7.org/linux/man-pages/man7/signal.7.html
29
+ // worker: https://github.com/nodejs/node/blob/master/lib/internal/cluster/worker.js#L22
30
+ // subProcess.kill is wrapped to subProcess.destroy, it will wait to disconnected.
31
+ (subProcess.process ?? subProcess).kill('SIGKILL');
32
+ }
33
+ // kill all children processes, if SIGTERM not work, try SIGKILL
34
+ async function killChildren(childrenPids, timeout) {
35
+ if (childrenPids.length === 0) {
36
+ return;
37
+ }
38
+ kill(childrenPids, 'SIGTERM');
39
+ const start = Date.now();
40
+ // if timeout is 1000, it will check twice.
41
+ const checkInterval = 400;
42
+ let unterminated = [];
43
+ while (Date.now() - start < timeout - checkInterval) {
44
+ await (0, promises_1.setTimeout)(checkInterval);
45
+ unterminated = getUnterminatedProcesses(childrenPids);
46
+ if (unterminated.length === 0) {
47
+ return;
48
+ }
49
+ }
50
+ kill(unterminated, 'SIGKILL');
51
+ }
52
+ async function getChildPids(pid) {
53
+ let childrenPids = [];
54
+ try {
55
+ const children = await (0, ps_tree_1.pstree)(pid);
56
+ childrenPids = children.map(c => parseInt(c.PID));
57
+ }
58
+ catch (err) {
59
+ // if get children error, just ignore it
60
+ debug('pstree %s error: %s, ignore it', pid, err);
61
+ }
62
+ return childrenPids;
63
+ }
64
+ function kill(pids, signal) {
65
+ for (const pid of pids) {
66
+ try {
67
+ process.kill(pid, signal);
68
+ }
69
+ catch (err) {
70
+ // ignore
71
+ debug('kill %s error: %s, signal: %s, ignore it', pid, err, signal);
72
+ }
73
+ }
74
+ }
75
+ function getUnterminatedProcesses(pids) {
76
+ return pids.filter(pid => {
77
+ try {
78
+ // success means it's still alive
79
+ process.kill(pid, 0);
80
+ return true;
81
+ }
82
+ catch (err) {
83
+ // error means it's dead
84
+ debug('kill %s error: %s, it still alive', pid, err);
85
+ return false;
86
+ }
87
+ });
88
+ }
89
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVybWluYXRlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3V0aWxzL3Rlcm1pbmF0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQVlBLDhCQU9DO0FBbkJELHlDQUFxQztBQUNyQyxtREFBMkQ7QUFDM0QsNkNBQW1DO0FBRW5DLDhDQUEwQztBQUUxQyxNQUFNLEtBQUssR0FBRyxJQUFBLG9CQUFRLEVBQUMsZ0NBQWdDLENBQUMsQ0FBQztBQU1sRCxLQUFLLFVBQVUsU0FBUyxDQUFDLFVBQXNCLEVBQUUsT0FBZTtJQUNyRSxNQUFNLEdBQUcsR0FBRyxVQUFVLENBQUMsT0FBTyxFQUFFLEdBQUcsSUFBSSxVQUFVLENBQUMsR0FBRyxDQUFDO0lBQ3RELE1BQU0sU0FBUyxHQUFHLE1BQU0sWUFBWSxDQUFDLEdBQUksQ0FBQyxDQUFDO0lBQzNDLE1BQU0sT0FBTyxDQUFDLEdBQUcsQ0FBQztRQUNoQixXQUFXLENBQUMsVUFBVSxFQUFFLE9BQU8sQ0FBQztRQUNoQyxZQUFZLENBQUMsU0FBUyxFQUFFLE9BQU8sQ0FBQztLQUNqQyxDQUFDLENBQUM7QUFDTCxDQUFDO0FBRUQsaURBQWlEO0FBQ2pELEtBQUssVUFBVSxXQUFXLENBQUMsVUFBc0IsRUFBRSxPQUFlO0lBQ2hFLDRDQUE0QztJQUM1QyxDQUFDLFVBQVUsQ0FBQyxPQUFPLElBQUksVUFBVSxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ25ELE1BQU0sT0FBTyxDQUFDLElBQUksQ0FBQztRQUNqQixJQUFBLGtCQUFJLEVBQUMsVUFBVSxFQUFFLE1BQU0sQ0FBQztRQUN4QixJQUFBLHFCQUFLLEVBQUMsT0FBTyxDQUFDO0tBQ2YsQ0FBQyxDQUFDO0lBQ0gsSUFBSSxVQUFVLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDdEIsT0FBTztJQUNULENBQUM7SUFDRCw4REFBOEQ7SUFDOUQsd0ZBQXdGO0lBQ3hGLGtGQUFrRjtJQUNsRixDQUFDLFVBQVUs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
@@ -0,0 +1,25 @@
1
+ import { EventEmitter } from 'node:events';
2
+ import { BaseAgentWorker } from './mode/base/agent.js';
3
+ import { BaseAppWorker } from './mode/base/app.js';
4
+ export declare class WorkerManager extends EventEmitter {
5
+ agent: BaseAgentWorker | null;
6
+ workers: Map<number, BaseAppWorker<import("worker_threads").Worker | import("cluster").Worker>>;
7
+ exception: number;
8
+ timer: NodeJS.Timeout;
9
+ constructor();
10
+ getWorkers(): number[];
11
+ setAgent(agent: BaseAgentWorker): void;
12
+ getAgent(): BaseAgentWorker<import("child_process").ChildProcess | import("worker_threads").Worker> | null;
13
+ deleteAgent(): void;
14
+ setWorker(worker: BaseAppWorker): void;
15
+ getWorker(workerId: number): BaseAppWorker<import("worker_threads").Worker | import("cluster").Worker> | undefined;
16
+ deleteWorker(workerId: number): void;
17
+ listWorkerIds(): number[];
18
+ listWorkers(): BaseAppWorker<import("worker_threads").Worker | import("cluster").Worker>[];
19
+ getListeningWorkerIds(): number[];
20
+ count(): {
21
+ agent: number;
22
+ worker: number;
23
+ };
24
+ startCheck(): void;
25
+ }
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WorkerManager = void 0;
4
+ const node_events_1 = require("node:events");
5
+ // worker manager to record agent and worker forked by egg-cluster
6
+ // can do some check stuff here to monitor the healthy
7
+ class WorkerManager extends node_events_1.EventEmitter {
8
+ agent;
9
+ workers = new Map();
10
+ exception = 0;
11
+ timer;
12
+ constructor() {
13
+ super();
14
+ this.agent = null;
15
+ }
16
+ getWorkers() {
17
+ return Array.from(this.workers.keys());
18
+ }
19
+ setAgent(agent) {
20
+ this.agent = agent;
21
+ }
22
+ getAgent() {
23
+ return this.agent;
24
+ }
25
+ deleteAgent() {
26
+ this.agent = null;
27
+ }
28
+ setWorker(worker) {
29
+ this.workers.set(worker.workerId, worker);
30
+ }
31
+ getWorker(workerId) {
32
+ return this.workers.get(workerId);
33
+ }
34
+ deleteWorker(workerId) {
35
+ this.workers.delete(workerId);
36
+ }
37
+ listWorkerIds() {
38
+ return Array.from(this.workers.keys());
39
+ }
40
+ listWorkers() {
41
+ return Array.from(this.workers.values());
42
+ }
43
+ getListeningWorkerIds() {
44
+ const keys = [];
45
+ for (const [id, worker] of this.workers.entries()) {
46
+ if (worker.state === 'listening') {
47
+ keys.push(id);
48
+ }
49
+ }
50
+ return keys;
51
+ }
52
+ count() {
53
+ return {
54
+ agent: this.agent?.status === 'started' ? 1 : 0,
55
+ worker: this.listWorkerIds().length,
56
+ };
57
+ }
58
+ // check agent and worker must both alive
59
+ // if exception appear 3 times, emit an exception event
60
+ startCheck() {
61
+ this.timer = setInterval(() => {
62
+ const count = this.count();
63
+ if (count.agent > 0 && count.worker > 0) {
64
+ this.exception = 0;
65
+ return;
66
+ }
67
+ this.exception++;
68
+ if (this.exception >= 3) {
69
+ this.emit('exception', count);
70
+ clearInterval(this.timer);
71
+ }
72
+ }, 10000);
73
+ }
74
+ }
75
+ exports.WorkerManager = WorkerManager;
76
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid29ya2VyX21hbmFnZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdXRpbHMvd29ya2VyX21hbmFnZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsNkNBQTJDO0FBSTNDLGtFQUFrRTtBQUNsRSxzREFBc0Q7QUFDdEQsTUFBYSxhQUFjLFNBQVEsMEJBQVk7SUFDN0MsS0FBSyxDQUF5QjtJQUM5QixPQUFPLEdBQUcsSUFBSSxHQUFHLEVBQXlCLENBQUM7SUFDM0MsU0FBUyxHQUFHLENBQUMsQ0FBQztJQUNkLEtBQUssQ0FBaUI7SUFFdEI7UUFDRSxLQUFLLEVBQUUsQ0FBQztRQUNSLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDO0lBQ3BCLENBQUM7SUFFRCxVQUFVO1FBQ1IsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRUQsUUFBUSxDQUFDLEtBQXNCO1FBQzdCLElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO0lBQ3JCLENBQUM7SUFFRCxRQUFRO1FBQ04sT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDO0lBQ3BCLENBQUM7SUFFRCxXQUFXO1FBQ1QsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7SUFDcEIsQ0FBQztJQUVELFNBQVMsQ0FBQyxNQUFxQjtRQUM3QixJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQzVDLENBQUM7SUFFRCxTQUFTLENBQUMsUUFBZ0I7UUFDeEIsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUNwQyxDQUFDO0lBRUQsWUFBWSxDQUFDLFFBQWdCO1FBQzNCLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ2hDLENBQUM7SUFFRCxhQUFhO1FBQ1gsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRUQsV0FBVztRQUNULE9BQU8sS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7SUFDM0MsQ0FBQztJQUVELHFCQUFxQjtRQUNuQixNQUFNLElBQUksR0FBRyxFQUFFLENBQUM7UUFDaEIsS0FBSyxNQUFNLENBQUUsRUFBRSxFQUFFLE1BQU0sQ0FBRSxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQztZQUNwRCxJQUFJLE1BQU0sQ0FBQyxLQUFLLEtBQUssV0FBVyxFQUFFLENBQUM7Z0JBQ2pDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDaEIsQ0FBQztRQUNILENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxLQUFLO1FBQ0gsT0FBTztZQUNMLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxFQUFFLE1BQU0sS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUMvQyxNQUFNLEVBQUUsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDLE1BQU07U0FDcEMsQ0FBQztJQUNKLENBQUM7SUFFRCx5Q0FBeUM7SUFDekMsdURBQXVEO0lBQ3ZELFVBQVU7UUFDUixJQUFJLENBQUMsS0FBSyxHQUFHLFdBQVcsQ0FBQyxHQUFHLEVBQUU7WUFDNUIsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQzNCLElBQUksS0FBSyxDQUFDLEtBQUssR0FBRyxDQUFDLElBQUksS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDeEMsSUFBSSxDQUFDLFNBQVMsR0FBRyxDQUFDLENBQUM7Z0JBQ25CLE9BQU87WUFDVCxDQUFDO1lBQ0QsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ2pCLElBQUksSUFBSSxDQUFDLFNBQVMsSUFBSSxDQUFDLEVBQUUsQ0FBQztnQkFDeEIsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsS0FBSyxDQUFDLENBQUM7Z0JBQzlCLGFBQWEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDNUIsQ0FBQztRQUNILENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQztJQUNaLENBQUM7Q0FDRjtBQWhGRCxzQ0FnRkMifQ==
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,63 @@
1
+ import { debuglog } from 'node:util';
2
+ import { EggConsoleLogger as ConsoleLogger } from 'egg-logger';
3
+ import { importModule } from '@eggjs/utils';
4
+ import { AgentThreadWorker } from './utils/mode/impl/worker_threads/agent.js';
5
+ import { AgentProcessWorker } from './utils/mode/impl/process/agent.js';
6
+ const debug = debuglog('@eggjs/cluster/agent_worker');
7
+ /**
8
+ * agent worker is child_process forked by master.
9
+ *
10
+ * agent worker only exit in two cases:
11
+ * - receive signal SIGTERM, exit code 0 (exit gracefully)
12
+ * - receive disconnect event, exit code 110 (maybe master exit in accident)
13
+ */
14
+ async function main() {
15
+ // $ node agent_worker.js options
16
+ const options = JSON.parse(process.argv[2]);
17
+ if (options.require) {
18
+ // inject
19
+ options.require.forEach(mod => {
20
+ require(mod);
21
+ });
22
+ }
23
+ let AgentWorker;
24
+ if (options.startMode === 'worker_threads') {
25
+ AgentWorker = AgentThreadWorker;
26
+ }
27
+ else {
28
+ AgentWorker = AgentProcessWorker;
29
+ }
30
+ const consoleLogger = new ConsoleLogger({ level: process.env.EGG_AGENT_WORKER_LOGGER_LEVEL });
31
+ const { Agent } = await importModule(options.framework);
32
+ debug('new Agent with options %j', options);
33
+ let agent;
34
+ try {
35
+ agent = new Agent(options);
36
+ }
37
+ catch (err) {
38
+ consoleLogger.error(err);
39
+ throw err;
40
+ }
41
+ function startErrorHandler(err) {
42
+ consoleLogger.error(err);
43
+ consoleLogger.error('[agent_worker] start error, exiting with code:1');
44
+ AgentWorker.kill();
45
+ }
46
+ agent.ready((err) => {
47
+ // don't send started message to master when start error
48
+ if (err) {
49
+ return;
50
+ }
51
+ agent.removeListener('error', startErrorHandler);
52
+ AgentWorker.send({ action: 'agent-start', to: 'master' });
53
+ });
54
+ // exit if agent start error
55
+ agent.once('error', startErrorHandler);
56
+ AgentWorker.gracefulExit({
57
+ logger: consoleLogger,
58
+ label: 'agent_worker',
59
+ beforeExit: () => agent.close(),
60
+ });
61
+ }
62
+ main();
63
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWdlbnRfd29ya2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FnZW50X3dvcmtlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ3JDLE9BQU8sRUFBRSxnQkFBZ0IsSUFBSSxhQUFhLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDL0QsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUU1QyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSwyQ0FBMkMsQ0FBQztBQUM5RSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUV4RSxNQUFNLEtBQUssR0FBRyxRQUFRLENBQUMsNkJBQTZCLENBQUMsQ0FBQztBQUV0RDs7Ozs7O0dBTUc7QUFDSCxLQUFLLFVBQVUsSUFBSTtJQUNqQixpQ0FBaUM7SUFDakMsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUl6QyxDQUFDO0lBQ0YsSUFBSSxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDcEIsU0FBUztRQUNULE9BQU8sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxFQUFFO1lBQzVCLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNmLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELElBQUksV0FBbUMsQ0FBQztJQUN4QyxJQUFJLE9BQU8sQ0FBQyxTQUFTLEtBQUssZ0JBQWdCLEVBQUUsQ0FBQztRQUMzQyxXQUFXLEdBQUcsaUJBQXdCLENBQUM7SUFDekMsQ0FBQztTQUFNLENBQUM7UUFDTixXQUFXLEdBQUcsa0JBQXlCLENBQUM7SUFDMUMsQ0FBQztJQUVELE1BQU0sYUFBYSxHQUFHLElBQUksYUFBYSxDQUFDLEVBQUUsS0FBSyxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsNkJBQTZCLEVBQUUsQ0FBQyxDQUFDO0lBQzlGLE1BQU0sRUFBRSxLQUFLLEVBQUUsR0FBRyxNQUFNLFlBQVksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDeEQsS0FBSyxDQUFDLDJCQUEyQixFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQzVDLElBQUksS0FBVSxDQUFDO0lBQ2YsSUFBSSxDQUFDO1FBQ0gsS0FBSyxHQUFHLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQzdCLENBQUM7SUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO1FBQ2IsYUFBYSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN6QixNQUFNLEdBQUcsQ0FBQztJQUNaLENBQUM7SUFFRCxTQUFTLGlCQUFpQixDQUFDLEdBQVU7UUFDbkMsYUFBYSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN6QixhQUFhLENBQUMsS0FBSyxDQUFDLGlEQUFpRCxDQUFDLENBQUM7UUFDdkUsV0FBVyxDQUFDLElBQUksRUFBRSxDQUFDO0lBQ3JCLENBQUM7SUFFRCxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBVyxFQUFFLEVBQUU7UUFDMUIsd0RBQXdEO1FBQ3hELElBQUksR0FBRyxFQUFFLENBQUM7WUFDUixPQUFPO1FBQ1QsQ0FBQztRQUVELEtBQUssQ0FBQyxjQUFjLENBQUMsT0FBTyxFQUFFLGlCQUFpQixDQUFDLENBQUM7UUFDakQsV0FBVyxDQUFDLElBQUksQ0FBQyxFQUFFLE1BQU0sRUFBRSxhQUFhLEVBQUUsRUFBRSxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUM7SUFDNUQsQ0FBQyxDQUFDLENBQUM7SUFFSCw0QkFBNEI7SUFDNUIsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztJQUV2QyxXQUFXLENBQUMsWUFBWSxDQUFDO1FBQ3ZCLE1BQU0sRUFBRSxhQUFhO1FBQ3JCLEtBQUssRUFBRSxjQUFjO1FBQ3JCLFVBQVUsRUFBRSxHQUFHLEVBQUUsQ0FBQyxLQUFLLENBQUMsS0FBSyxFQUFFO0tBQ2hDLENBQUMsQ0FBQztBQUNMLENBQUM7QUFFRCxJQUFJLEVBQUUsQ0FBQyJ9
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,146 @@
1
+ import fs from 'node:fs';
2
+ import { createServer as createHttpServer } from 'node:http';
3
+ import { createServer as createHttpsServer } from 'node:https';
4
+ import { debuglog } from 'node:util';
5
+ import { EggConsoleLogger as ConsoleLogger } from 'egg-logger';
6
+ import { importModule } from '@eggjs/utils';
7
+ import { AppThreadWorker } from './utils/mode/impl/worker_threads/app.js';
8
+ import { AppProcessWorker } from './utils/mode/impl/process/app.js';
9
+ const debug = debuglog('@eggjs/cluster/app_worker');
10
+ async function main() {
11
+ // $ node app_worker.js options-json-string
12
+ const options = JSON.parse(process.argv[2]);
13
+ if (options.require) {
14
+ // inject
15
+ for (const mod of options.require) {
16
+ await importModule(mod);
17
+ }
18
+ }
19
+ let AppWorker;
20
+ if (options.startMode === 'worker_threads') {
21
+ AppWorker = AppThreadWorker;
22
+ }
23
+ else {
24
+ AppWorker = AppProcessWorker;
25
+ }
26
+ const consoleLogger = new ConsoleLogger({
27
+ level: process.env.EGG_APP_WORKER_LOGGER_LEVEL,
28
+ });
29
+ const { Application } = await importModule(options.framework);
30
+ debug('new Application with options %j', options);
31
+ let app;
32
+ try {
33
+ app = new Application(options);
34
+ }
35
+ catch (err) {
36
+ consoleLogger.error(err);
37
+ throw err;
38
+ }
39
+ app.ready(startServer);
40
+ function exitProcess() {
41
+ // Use SIGTERM kill process, ensure trigger the gracefulExit
42
+ AppWorker.kill();
43
+ }
44
+ // exit if worker start timeout
45
+ app.once('startTimeout', startTimeoutHandler);
46
+ function startTimeoutHandler() {
47
+ consoleLogger.error('[app_worker] start timeout, exiting with code:1');
48
+ exitProcess();
49
+ }
50
+ function startServer(err) {
51
+ if (err) {
52
+ consoleLogger.error(err);
53
+ consoleLogger.error('[app_worker] start error, exiting with code:1');
54
+ exitProcess();
55
+ return;
56
+ }
57
+ const clusterConfig = app.config.cluster ?? {};
58
+ const listenConfig = clusterConfig.listen ?? {};
59
+ const httpsOptions = {
60
+ ...clusterConfig.https,
61
+ ...options.https,
62
+ };
63
+ const port = options.port = options.port ?? listenConfig.port;
64
+ const debugPort = options.debugPort;
65
+ const protocol = (httpsOptions.key && httpsOptions.cert) ? 'https' : 'http';
66
+ AppWorker.send({
67
+ to: 'master',
68
+ action: 'realport',
69
+ data: {
70
+ port,
71
+ protocol,
72
+ },
73
+ });
74
+ app.removeListener('startTimeout', startTimeoutHandler);
75
+ let server;
76
+ let debugPortServer;
77
+ // https config
78
+ if (protocol === 'https') {
79
+ httpsOptions.key = fs.readFileSync(httpsOptions.key);
80
+ httpsOptions.cert = fs.readFileSync(httpsOptions.cert);
81
+ httpsOptions.ca = httpsOptions.ca && fs.readFileSync(httpsOptions.ca);
82
+ server = createHttpsServer(httpsOptions, app.callback());
83
+ if (debugPort) {
84
+ debugPortServer = createHttpServer(app.callback());
85
+ }
86
+ }
87
+ else {
88
+ server = createHttpServer(app.callback());
89
+ if (debugPort) {
90
+ debugPortServer = server;
91
+ }
92
+ }
93
+ server.once('error', (err) => {
94
+ consoleLogger.error('[app_worker] server got error: %s, code: %s', err.message, err.code);
95
+ exitProcess();
96
+ });
97
+ // emit `server` event in app
98
+ app.emit('server', server);
99
+ if (options.sticky && options.stickyWorkerPort) {
100
+ server.listen(options.stickyWorkerPort, '127.0.0.1');
101
+ // Listen to messages was sent from the master. Ignore everything else.
102
+ AppWorker.on('message', (message, connection) => {
103
+ if (message !== 'sticky-session:connection') {
104
+ return;
105
+ }
106
+ // Emulate a connection event on the server by emitting the
107
+ // event with the connection the master sent us.
108
+ server.emit('connection', connection);
109
+ connection.resume();
110
+ });
111
+ }
112
+ else {
113
+ if (listenConfig.path) {
114
+ server.listen(listenConfig.path);
115
+ }
116
+ else {
117
+ if (typeof port !== 'number') {
118
+ consoleLogger.error('[app_worker] port should be number, but got %s(%s)', port, typeof port);
119
+ exitProcess();
120
+ return;
121
+ }
122
+ const args = [port];
123
+ if (listenConfig.hostname)
124
+ args.push(listenConfig.hostname);
125
+ debug('listen options %s', args);
126
+ server.listen(...args);
127
+ }
128
+ if (debugPortServer) {
129
+ debug('listen on debug port: %s', debugPort);
130
+ debugPortServer.listen(debugPort);
131
+ }
132
+ }
133
+ AppWorker.send({
134
+ to: 'master',
135
+ action: 'listening',
136
+ data: server.address() || { port },
137
+ });
138
+ }
139
+ AppWorker.gracefulExit({
140
+ logger: consoleLogger,
141
+ label: 'app_worker',
142
+ beforeExit: () => app.close(),
143
+ });
144
+ }
145
+ main();
146
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwX3dvcmtlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hcHBfd29ya2VyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUN6QixPQUFPLEVBQUUsWUFBWSxJQUFJLGdCQUFnQixFQUFlLE1BQU0sV0FBVyxDQUFDO0FBQzFFLE9BQU8sRUFBRSxZQUFZLElBQUksaUJBQWlCLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFFL0QsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUNyQyxPQUFPLEVBQUUsZ0JBQWdCLElBQUksYUFBYSxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQy9ELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFFNUMsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHlDQUF5QyxDQUFDO0FBQzFFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBRXBFLE1BQU0sS0FBSyxHQUFHLFFBQVEsQ0FBQywyQkFBMkIsQ0FBQyxDQUFDO0FBRXBELEtBQUssVUFBVSxJQUFJO0lBQ2pCLDJDQUEyQztJQUMzQyxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBU3pDLENBQUM7SUFDRixJQUFJLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNwQixTQUFTO1FBQ1QsS0FBSyxNQUFNLEdBQUcsSUFBSSxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDbEMsTUFBTSxZQUFZLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDMUIsQ0FBQztJQUNILENBQUM7SUFFRCxJQUFJLFNBQStCLENBQUM7SUFDcEMsSUFBSSxPQUFPLENBQUMsU0FBUyxLQUFLLGdCQUFnQixFQUFFLENBQUM7UUFDM0MsU0FBUyxHQUFHLGVBQXNCLENBQUM7SUFDckMsQ0FBQztTQUFN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
@@ -0,0 +1 @@
1
+ export declare function getSrcDirname(): string;
@@ -0,0 +1,11 @@
1
+ import { fileURLToPath } from 'node:url';
2
+ import path from 'node:path';
3
+ export function getSrcDirname() {
4
+ if (typeof __dirname !== 'undefined') {
5
+ return __dirname;
6
+ }
7
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
8
+ // @ts-ignore
9
+ return path.dirname(fileURLToPath(import.meta.url));
10
+ }
11
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlybmFtZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9kaXJuYW1lLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDekMsT0FBTyxJQUFJLE1BQU0sV0FBVyxDQUFDO0FBRTdCLE1BQU0sVUFBVSxhQUFhO0lBQzNCLElBQUksT0FBTyxTQUFTLEtBQUssV0FBVyxFQUFFLENBQUM7UUFDckMsT0FBTyxTQUFTLENBQUM7SUFDbkIsQ0FBQztJQUNELDZEQUE2RDtJQUM3RCxhQUFhO0lBQ2IsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7QUFDdEQsQ0FBQyJ9
@@ -0,0 +1,10 @@
1
+ export declare class ClusterAgentWorkerError extends Error {
2
+ id: number;
3
+ /**
4
+ * pid in process mode
5
+ * tid in worker_threads mode
6
+ */
7
+ workerId: number;
8
+ status: string;
9
+ constructor(id: number, workerId: number, status: string, error: Error);
10
+ }
@@ -0,0 +1,19 @@
1
+ export class ClusterAgentWorkerError extends Error {
2
+ id;
3
+ /**
4
+ * pid in process mode
5
+ * tid in worker_threads mode
6
+ */
7
+ workerId;
8
+ status;
9
+ constructor(id, workerId, status, error) {
10
+ const message = `Got agent worker error: ${error.message}`;
11
+ super(message, { cause: error });
12
+ this.name = this.constructor.name;
13
+ this.id = id;
14
+ this.workerId = workerId;
15
+ this.status = status;
16
+ Error.captureStackTrace(this, this.constructor);
17
+ }
18
+ }
19
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ2x1c3RlckFnZW50V29ya2VyRXJyb3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZXJyb3IvQ2x1c3RlckFnZW50V29ya2VyRXJyb3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsTUFBTSxPQUFPLHVCQUF3QixTQUFRLEtBQUs7SUFDaEQsRUFBRSxDQUFTO0lBQ1g7OztPQUdHO0lBQ0gsUUFBUSxDQUFTO0lBQ2pCLE1BQU0sQ0FBUztJQUVmLFlBQVksRUFBVSxFQUFFLFFBQWdCLEVBQUUsTUFBYyxFQUFFLEtBQVk7UUFDcEUsTUFBTSxPQUFPLEdBQUcsMkJBQTJCLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUMzRCxLQUFLLENBQUMsT0FBTyxFQUFFLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUM7UUFDakMsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQztRQUNsQyxJQUFJLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQztRQUNiLElBQUksQ0FBQyxRQUFRLEdBQUcsUUFBUSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO1FBQ3JCLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQ2xELENBQUM7Q0FDRiJ9
@@ -0,0 +1,7 @@
1
+ export declare class ClusterWorkerExceptionError extends Error {
2
+ count: {
3
+ agent: number;
4
+ worker: number;
5
+ };
6
+ constructor(agent: number, worker: number);
7
+ }
@@ -0,0 +1,14 @@
1
+ export class ClusterWorkerExceptionError extends Error {
2
+ count;
3
+ constructor(agent, worker) {
4
+ const message = `[master] ${agent} agent and ${worker} worker(s) alive, exit to avoid unknown state`;
5
+ super(message);
6
+ this.name = this.constructor.name;
7
+ this.count = {
8
+ agent,
9
+ worker,
10
+ };
11
+ Error.captureStackTrace(this, this.constructor);
12
+ }
13
+ }
14
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ2x1c3RlcldvcmtlckV4Y2VwdGlvbkVycm9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2Vycm9yL0NsdXN0ZXJXb3JrZXJFeGNlcHRpb25FcnJvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxNQUFNLE9BQU8sMkJBQTRCLFNBQVEsS0FBSztJQUNwRCxLQUFLLENBR0g7SUFFRixZQUFZLEtBQWEsRUFBRSxNQUFjO1FBQ3ZDLE1BQU0sT0FBTyxHQUFHLFlBQVksS0FBSyxjQUFjLE1BQU0sK0NBQStDLENBQUM7UUFDckcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2YsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQztRQUNsQyxJQUFJLENBQUMsS0FBSyxHQUFHO1lBQ1gsS0FBSztZQUNMLE1BQU07U0FDUCxDQUFDO1FBQ0YsS0FBSyxDQUFDLGlCQUFpQixDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDbEQsQ0FBQztDQUNGIn0=
@@ -0,0 +1,2 @@
1
+ export * from './ClusterAgentWorkerError.js';
2
+ export * from './ClusterWorkerExceptionError.js';
@@ -0,0 +1,3 @@
1
+ export * from './ClusterAgentWorkerError.js';
2
+ export * from './ClusterWorkerExceptionError.js';
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZXJyb3IvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYyw4QkFBOEIsQ0FBQztBQUM3QyxjQUFjLGtDQUFrQyxDQUFDIn0=
@@ -0,0 +1,17 @@
1
+ import { Master, MasterOptions } from './master.js';
2
+ import { ClusterOptions, ClusterHTTPSSecureOptions, ClusterStartMode } from './utils/options.js';
3
+ /**
4
+ * cluster start flow:
5
+ *
6
+ * [startCluster] -> master -> agent_worker -> new [Agent] -> agentWorkerLoader
7
+ * `-> app_worker -> new [Application] -> appWorkerLoader
8
+ *
9
+ */
10
+ /**
11
+ * start egg app
12
+ * @function Egg#startCluster
13
+ * @param {Object} options {@link Master}
14
+ */
15
+ export declare function startCluster(options: ClusterOptions): Promise<void>;
16
+ export { Master, MasterOptions, ClusterOptions, ClusterHTTPSSecureOptions, ClusterStartMode, };
17
+ export * from './error/index.js';
@@ -0,0 +1,19 @@
1
+ import { Master } from './master.js';
2
+ /**
3
+ * cluster start flow:
4
+ *
5
+ * [startCluster] -> master -> agent_worker -> new [Agent] -> agentWorkerLoader
6
+ * `-> app_worker -> new [Application] -> appWorkerLoader
7
+ *
8
+ */
9
+ /**
10
+ * start egg app
11
+ * @function Egg#startCluster
12
+ * @param {Object} options {@link Master}
13
+ */
14
+ export async function startCluster(options) {
15
+ await new Master(options).ready();
16
+ }
17
+ export { Master, };
18
+ export * from './error/index.js';
19
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBaUIsTUFBTSxhQUFhLENBQUM7QUFHcEQ7Ozs7OztHQU1HO0FBRUg7Ozs7R0FJRztBQUNILE1BQU0sQ0FBQyxLQUFLLFVBQVUsWUFBWSxDQUFDLE9BQXVCO0lBQ3hELE1BQU0sSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUM7QUFDcEMsQ0FBQztBQUVELE9BQU8sRUFDTCxNQUFNLEdBRVAsQ0FBQztBQUVGLGNBQWMsa0JBQWtCLENBQUMifQ==
@@ -0,0 +1,90 @@
1
+ import { ReadyEventEmitter } from 'get-ready';
2
+ import { EggConsoleLogger as ConsoleLogger } from 'egg-logger';
3
+ import { ClusterOptions, ParsedClusterOptions } from './utils/options.js';
4
+ import { WorkerManager } from './utils/worker_manager.js';
5
+ import { Messenger } from './utils/messenger.js';
6
+ import { AgentProcessUtils as ProcessAgentWorker } from './utils/mode/impl/process/agent.js';
7
+ import { AppProcessUtils as ProcessAppWorker } from './utils/mode/impl/process/app.js';
8
+ import { AgentThreadUtils as WorkerThreadsAgentWorker } from './utils/mode/impl/worker_threads/agent.js';
9
+ import { AppThreadUtils as WorkerThreadsAppWorker } from './utils/mode/impl/worker_threads/app.js';
10
+ export interface MasterOptions extends ParsedClusterOptions {
11
+ clusterPort?: number;
12
+ stickyWorkerPort?: number;
13
+ }
14
+ export declare class Master extends ReadyEventEmitter {
15
+ #private;
16
+ options: MasterOptions;
17
+ isStarted: boolean;
18
+ workerManager: WorkerManager;
19
+ messenger: Messenger;
20
+ isProduction: boolean;
21
+ agentWorkerIndex: number;
22
+ closed: boolean;
23
+ logger: ConsoleLogger;
24
+ agentWorker: ProcessAgentWorker | WorkerThreadsAgentWorker;
25
+ appWorker: ProcessAppWorker | WorkerThreadsAppWorker;
26
+ constructor(options?: ClusterOptions);
27
+ startByProcess(): void;
28
+ startByWorkerThreads(): void;
29
+ detectPorts(): Promise<void>;
30
+ log(msg: string, ...args: any[]): void;
31
+ startMasterSocketServer(cb: (err?: Error) => void): void;
32
+ stickyWorker(ip: string): import("./utils/mode/base/app.js").BaseAppWorker<import("worker_threads").Worker | import("cluster").Worker>;
33
+ forkAgentWorker(): void;
34
+ forkAppWorkers(): void;
35
+ /**
36
+ * close agent worker, App Worker will closed by cluster
37
+ *
38
+ * https://www.exratione.com/2013/05/die-child-process-die/
39
+ * make sure Agent Worker exit before master exit
40
+ *
41
+ * @param {number} timeout - kill agent timeout
42
+ * @return {Promise} -
43
+ */
44
+ killAgentWorker(timeout: number): Promise<void>;
45
+ killAppWorkers(timeout: number): Promise<void>;
46
+ /**
47
+ * Agent Worker exit handler
48
+ * Will exit during startup, and refork during running.
49
+ */
50
+ onAgentExit(data: {
51
+ /** exit code */
52
+ code: number;
53
+ /** received signal */
54
+ signal: string;
55
+ }): void;
56
+ onAgentStart(): void;
57
+ /**
58
+ * App Worker exit handler
59
+ */
60
+ onAppExit(data: {
61
+ workerId: number;
62
+ code: number;
63
+ signal: string;
64
+ }): void;
65
+ /**
66
+ * after app worker
67
+ */
68
+ onAppStart(data: {
69
+ workerId: number;
70
+ address: ListeningAddress;
71
+ }): void;
72
+ /**
73
+ * master exit handler
74
+ */
75
+ onExit(code: number): void;
76
+ onSignal(signal: string): void;
77
+ /**
78
+ * reload workers, for develop purpose
79
+ */
80
+ onReload(): void;
81
+ close(): Promise<void>;
82
+ _doClose(): Promise<void>;
83
+ }
84
+ interface ListeningAddress {
85
+ port: number;
86
+ protocol: string;
87
+ address?: string;
88
+ addressType?: number;
89
+ }
90
+ export {};