@eggjs/cluster 4.0.0-beta.19 → 4.0.0-beta.20
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.
- package/dist/agent-griHEaCW.js +246 -0
- package/dist/agent_worker.js +2 -2
- package/dist/app-5Was1vub.js +315 -0
- package/dist/app_worker.js +2 -2
- package/dist/index.d.ts +440 -5
- package/dist/index.js +692 -4
- package/dist/{utils/terminate.js → terminate-w3g0oQgq.js} +10 -1
- package/package.json +5 -5
- package/dist/dirname.js +0 -11
- package/dist/error/ClusterAgentWorkerError.d.ts +0 -13
- package/dist/error/ClusterAgentWorkerError.js +0 -22
- package/dist/error/ClusterWorkerExceptionError.d.ts +0 -10
- package/dist/error/ClusterWorkerExceptionError.js +0 -17
- package/dist/master.d.ts +0 -96
- package/dist/master.js +0 -426
- package/dist/utils/messenger.d.ts +0 -96
- package/dist/utils/messenger.js +0 -144
- package/dist/utils/mode/base/agent.d.ts +0 -45
- package/dist/utils/mode/base/agent.js +0 -63
- package/dist/utils/mode/base/app.d.ts +0 -56
- package/dist/utils/mode/base/app.js +0 -77
- package/dist/utils/mode/impl/process/agent.d.ts +0 -22
- package/dist/utils/mode/impl/process/agent.js +0 -93
- package/dist/utils/mode/impl/process/app.d.ts +0 -12
- package/dist/utils/mode/impl/process/app.js +0 -117
- package/dist/utils/mode/impl/worker_threads/agent.d.ts +0 -22
- package/dist/utils/mode/impl/worker_threads/agent.js +0 -79
- package/dist/utils/mode/impl/worker_threads/app.d.ts +0 -13
- package/dist/utils/mode/impl/worker_threads/app.js +0 -128
- package/dist/utils/options.d.ts +0 -83
- package/dist/utils/options.js +0 -56
- package/dist/utils/worker_manager.d.ts +0 -32
- package/dist/utils/worker_manager.js +0 -68
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
import { BaseAppUtils, BaseAppWorker } from "../../base/app.js";
|
|
2
|
-
import { terminate } from "../../../terminate.js";
|
|
3
|
-
import { sendmessage } from "sendmessage";
|
|
4
|
-
import { graceful } from "graceful-process";
|
|
5
|
-
import cluster from "node:cluster";
|
|
6
|
-
import { cfork } from "cfork";
|
|
7
|
-
|
|
8
|
-
//#region src/utils/mode/impl/process/app.ts
|
|
9
|
-
var AppProcessWorker = class extends BaseAppWorker {
|
|
10
|
-
get id() {
|
|
11
|
-
return this.instance.id;
|
|
12
|
-
}
|
|
13
|
-
get workerId() {
|
|
14
|
-
return this.instance.process.pid;
|
|
15
|
-
}
|
|
16
|
-
get exitedAfterDisconnect() {
|
|
17
|
-
return this.instance.exitedAfterDisconnect;
|
|
18
|
-
}
|
|
19
|
-
get exitCode() {
|
|
20
|
-
return this.instance.process.exitCode;
|
|
21
|
-
}
|
|
22
|
-
send(message) {
|
|
23
|
-
sendmessage(this.instance, message);
|
|
24
|
-
}
|
|
25
|
-
clean() {
|
|
26
|
-
this.instance.removeAllListeners();
|
|
27
|
-
}
|
|
28
|
-
static get workerId() {
|
|
29
|
-
return process.pid;
|
|
30
|
-
}
|
|
31
|
-
static on(event, listener) {
|
|
32
|
-
process.on(event, listener);
|
|
33
|
-
}
|
|
34
|
-
static send(message) {
|
|
35
|
-
message.senderWorkerId = String(process.pid);
|
|
36
|
-
process.send(message);
|
|
37
|
-
}
|
|
38
|
-
static kill() {
|
|
39
|
-
process.exitCode = 1;
|
|
40
|
-
process.kill(process.pid);
|
|
41
|
-
}
|
|
42
|
-
static gracefulExit(options) {
|
|
43
|
-
graceful(options);
|
|
44
|
-
}
|
|
45
|
-
};
|
|
46
|
-
var AppProcessUtils = class extends BaseAppUtils {
|
|
47
|
-
fork() {
|
|
48
|
-
this.startTime = Date.now();
|
|
49
|
-
this.startSuccessCount = 0;
|
|
50
|
-
const args = [JSON.stringify(this.options)];
|
|
51
|
-
this.log("[master] start appWorker with args %j (process)", args);
|
|
52
|
-
cfork({
|
|
53
|
-
exec: this.getAppWorkerFile(),
|
|
54
|
-
args,
|
|
55
|
-
silent: false,
|
|
56
|
-
count: this.options.workers,
|
|
57
|
-
refork: this.isProduction,
|
|
58
|
-
windowsHide: process.platform === "win32"
|
|
59
|
-
});
|
|
60
|
-
let debugPort = process.debugPort;
|
|
61
|
-
cluster.on("fork", (worker) => {
|
|
62
|
-
const appWorker = new AppProcessWorker(worker);
|
|
63
|
-
this.emit("worker_forked", appWorker);
|
|
64
|
-
appWorker.disableRefork = true;
|
|
65
|
-
worker.on("message", (msg) => {
|
|
66
|
-
if (typeof msg === "string") msg = {
|
|
67
|
-
action: msg,
|
|
68
|
-
data: msg
|
|
69
|
-
};
|
|
70
|
-
msg.from = "app";
|
|
71
|
-
this.messenger.send(msg);
|
|
72
|
-
});
|
|
73
|
-
this.log("[master] app_worker#%s:%s start, state: %s, current workers: %j", appWorker.id, appWorker.workerId, appWorker.state, Object.keys(cluster.workers));
|
|
74
|
-
if (this.options.isDebug) {
|
|
75
|
-
debugPort++;
|
|
76
|
-
this.messenger.send({
|
|
77
|
-
to: "parent",
|
|
78
|
-
from: "app",
|
|
79
|
-
action: "debug",
|
|
80
|
-
data: {
|
|
81
|
-
debugPort,
|
|
82
|
-
pid: appWorker.workerId,
|
|
83
|
-
workerId: appWorker.workerId
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
});
|
|
88
|
-
cluster.on("disconnect", (worker) => {
|
|
89
|
-
const appWorker = new AppProcessWorker(worker);
|
|
90
|
-
this.log("[master] app_worker#%s:%s disconnect, suicide: %s, state: %s, current workers: %j", appWorker.id, appWorker.workerId, appWorker.exitedAfterDisconnect, appWorker.state, Object.keys(cluster.workers));
|
|
91
|
-
});
|
|
92
|
-
cluster.on("exit", (worker, code, signal) => {
|
|
93
|
-
const appWorker = new AppProcessWorker(worker);
|
|
94
|
-
this.messenger.send({
|
|
95
|
-
action: "app-exit",
|
|
96
|
-
data: {
|
|
97
|
-
workerId: appWorker.workerId,
|
|
98
|
-
code,
|
|
99
|
-
signal
|
|
100
|
-
},
|
|
101
|
-
to: "master",
|
|
102
|
-
from: "app"
|
|
103
|
-
});
|
|
104
|
-
});
|
|
105
|
-
return this;
|
|
106
|
-
}
|
|
107
|
-
async kill(timeout) {
|
|
108
|
-
await Promise.all(Object.keys(cluster.workers).map((id) => {
|
|
109
|
-
const worker = cluster.workers[id];
|
|
110
|
-
Reflect.set(worker, "disableRefork", true);
|
|
111
|
-
return terminate(worker.process, timeout);
|
|
112
|
-
}));
|
|
113
|
-
}
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
//#endregion
|
|
117
|
-
export { AppProcessUtils, AppProcessWorker };
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { BaseAgentUtils, BaseAgentWorker } from "../../base/agent.js";
|
|
2
|
-
import { MessageBody } from "../../../messenger.js";
|
|
3
|
-
import { Worker } from "node:worker_threads";
|
|
4
|
-
import { Options } from "graceful-process";
|
|
5
|
-
|
|
6
|
-
//#region src/utils/mode/impl/worker_threads/agent.d.ts
|
|
7
|
-
declare class AgentThreadWorker extends BaseAgentWorker<Worker> {
|
|
8
|
-
get workerId(): number;
|
|
9
|
-
send(message: MessageBody): void;
|
|
10
|
-
static send(message: MessageBody): void;
|
|
11
|
-
static kill(): void;
|
|
12
|
-
static gracefulExit(options: Options): void;
|
|
13
|
-
}
|
|
14
|
-
declare class AgentThreadUtils extends BaseAgentUtils {
|
|
15
|
-
#private;
|
|
16
|
-
instance: AgentThreadWorker;
|
|
17
|
-
fork(): void;
|
|
18
|
-
clean(): void;
|
|
19
|
-
kill(): Promise<void>;
|
|
20
|
-
}
|
|
21
|
-
//#endregion
|
|
22
|
-
export { AgentThreadUtils };
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import { BaseAgentUtils, BaseAgentWorker } from "../../base/agent.js";
|
|
2
|
-
import { ClusterAgentWorkerError } from "../../../../error/ClusterAgentWorkerError.js";
|
|
3
|
-
import workerThreads from "node:worker_threads";
|
|
4
|
-
import "graceful-process";
|
|
5
|
-
|
|
6
|
-
//#region src/utils/mode/impl/worker_threads/agent.ts
|
|
7
|
-
var AgentThreadWorker = class extends BaseAgentWorker {
|
|
8
|
-
get workerId() {
|
|
9
|
-
return this.instance.threadId;
|
|
10
|
-
}
|
|
11
|
-
send(message) {
|
|
12
|
-
this.instance.postMessage(message);
|
|
13
|
-
}
|
|
14
|
-
static send(message) {
|
|
15
|
-
message.senderWorkerId = String(workerThreads.threadId);
|
|
16
|
-
workerThreads.parentPort.postMessage(message);
|
|
17
|
-
}
|
|
18
|
-
static kill() {
|
|
19
|
-
process.exit(1);
|
|
20
|
-
}
|
|
21
|
-
static gracefulExit(options) {
|
|
22
|
-
const { beforeExit } = options;
|
|
23
|
-
process.on("exit", async (code) => {
|
|
24
|
-
if (typeof beforeExit === "function") await beforeExit();
|
|
25
|
-
process.exit(code);
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
var AgentThreadUtils = class extends BaseAgentUtils {
|
|
30
|
-
#worker;
|
|
31
|
-
#id = 0;
|
|
32
|
-
instance;
|
|
33
|
-
fork() {
|
|
34
|
-
this.startTime = Date.now();
|
|
35
|
-
const argv = [JSON.stringify(this.options)];
|
|
36
|
-
const agentPath = this.getAgentWorkerFile();
|
|
37
|
-
const worker = this.#worker = new workerThreads.Worker(agentPath, { argv });
|
|
38
|
-
const agentWorker = this.instance = new AgentThreadWorker(worker);
|
|
39
|
-
this.emit("agent_forked", agentWorker);
|
|
40
|
-
agentWorker.status = "starting";
|
|
41
|
-
agentWorker.id = ++this.#id;
|
|
42
|
-
this.log("[master] agent_worker#%s:%s start with worker_threads", agentWorker.id, agentWorker.workerId);
|
|
43
|
-
worker.on("message", (msg) => {
|
|
44
|
-
if (typeof msg === "string") msg = {
|
|
45
|
-
action: msg,
|
|
46
|
-
data: msg
|
|
47
|
-
};
|
|
48
|
-
msg.from = "agent";
|
|
49
|
-
this.messenger.send(msg);
|
|
50
|
-
});
|
|
51
|
-
worker.on("error", (err) => {
|
|
52
|
-
this.logger.error(new ClusterAgentWorkerError(agentWorker.id, agentWorker.workerId, agentWorker.status, err));
|
|
53
|
-
});
|
|
54
|
-
worker.once("exit", (code, signal) => {
|
|
55
|
-
this.messenger.send({
|
|
56
|
-
action: "agent-exit",
|
|
57
|
-
data: {
|
|
58
|
-
code,
|
|
59
|
-
signal
|
|
60
|
-
},
|
|
61
|
-
to: "master",
|
|
62
|
-
from: "agent"
|
|
63
|
-
});
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
clean() {
|
|
67
|
-
this.#worker.removeAllListeners();
|
|
68
|
-
}
|
|
69
|
-
async kill() {
|
|
70
|
-
if (this.#worker) {
|
|
71
|
-
this.log(`[master] kill agent worker#${this.#id} (worker_threads) by worker.terminate()`);
|
|
72
|
-
this.clean();
|
|
73
|
-
await this.#worker.terminate();
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
//#endregion
|
|
79
|
-
export { AgentThreadUtils, AgentThreadWorker };
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { BaseAppUtils } from "../../base/app.js";
|
|
2
|
-
import { Worker } from "node:worker_threads";
|
|
3
|
-
import { Options } from "graceful-process";
|
|
4
|
-
|
|
5
|
-
//#region src/utils/mode/impl/worker_threads/app.d.ts
|
|
6
|
-
|
|
7
|
-
declare class AppThreadUtils extends BaseAppUtils {
|
|
8
|
-
#private;
|
|
9
|
-
fork(): this;
|
|
10
|
-
kill(): Promise<void>;
|
|
11
|
-
}
|
|
12
|
-
//#endregion
|
|
13
|
-
export { AppThreadUtils };
|
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
import { BaseAppUtils, BaseAppWorker } from "../../base/app.js";
|
|
2
|
-
import { Worker, parentPort, threadId } from "node:worker_threads";
|
|
3
|
-
import { setTimeout } from "node:timers/promises";
|
|
4
|
-
|
|
5
|
-
//#region src/utils/mode/impl/worker_threads/app.ts
|
|
6
|
-
var AppThreadWorker = class extends BaseAppWorker {
|
|
7
|
-
#state = "none";
|
|
8
|
-
#id;
|
|
9
|
-
constructor(instance, id) {
|
|
10
|
-
super(instance);
|
|
11
|
-
this.#id = id;
|
|
12
|
-
}
|
|
13
|
-
get id() {
|
|
14
|
-
return this.#id;
|
|
15
|
-
}
|
|
16
|
-
get workerId() {
|
|
17
|
-
return this.instance.threadId;
|
|
18
|
-
}
|
|
19
|
-
get state() {
|
|
20
|
-
return this.#state;
|
|
21
|
-
}
|
|
22
|
-
set state(val) {
|
|
23
|
-
this.#state = val;
|
|
24
|
-
}
|
|
25
|
-
get exitedAfterDisconnect() {
|
|
26
|
-
return true;
|
|
27
|
-
}
|
|
28
|
-
get exitCode() {
|
|
29
|
-
return 0;
|
|
30
|
-
}
|
|
31
|
-
send(message) {
|
|
32
|
-
this.instance.postMessage(message);
|
|
33
|
-
}
|
|
34
|
-
clean() {
|
|
35
|
-
this.instance.removeAllListeners();
|
|
36
|
-
}
|
|
37
|
-
static get workerId() {
|
|
38
|
-
return threadId;
|
|
39
|
-
}
|
|
40
|
-
static on(event, listener) {
|
|
41
|
-
parentPort.on(event, listener);
|
|
42
|
-
}
|
|
43
|
-
static send(message) {
|
|
44
|
-
message.senderWorkerId = String(threadId);
|
|
45
|
-
parentPort.postMessage(message);
|
|
46
|
-
}
|
|
47
|
-
static kill() {
|
|
48
|
-
process.exit(1);
|
|
49
|
-
}
|
|
50
|
-
static gracefulExit(options) {
|
|
51
|
-
process.on("exit", async (code) => {
|
|
52
|
-
if (typeof options.beforeExit === "function") await options.beforeExit();
|
|
53
|
-
process.exit(code);
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
};
|
|
57
|
-
var AppThreadUtils = class extends BaseAppUtils {
|
|
58
|
-
#workers = [];
|
|
59
|
-
#forkSingle(appPath, options, id) {
|
|
60
|
-
const worker = new Worker(appPath, options);
|
|
61
|
-
this.#workers.push(worker);
|
|
62
|
-
const appWorker = new AppThreadWorker(worker, id);
|
|
63
|
-
this.emit("worker_forked", appWorker);
|
|
64
|
-
appWorker.disableRefork = true;
|
|
65
|
-
worker.on("message", (msg) => {
|
|
66
|
-
if (typeof msg === "string") msg = {
|
|
67
|
-
action: msg,
|
|
68
|
-
data: msg
|
|
69
|
-
};
|
|
70
|
-
msg.from = "app";
|
|
71
|
-
this.messenger.send(msg);
|
|
72
|
-
});
|
|
73
|
-
this.log("[master] app_worker#%s (tid:%s) start", appWorker.id, appWorker.workerId);
|
|
74
|
-
let debugPort = process.debugPort;
|
|
75
|
-
if (this.options.isDebug) {
|
|
76
|
-
debugPort++;
|
|
77
|
-
this.messenger.send({
|
|
78
|
-
to: "parent",
|
|
79
|
-
from: "app",
|
|
80
|
-
action: "debug",
|
|
81
|
-
data: {
|
|
82
|
-
debugPort,
|
|
83
|
-
pid: appWorker.workerId,
|
|
84
|
-
workerId: appWorker.workerId
|
|
85
|
-
}
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
worker.on("exit", async (code) => {
|
|
89
|
-
appWorker.state = "dead";
|
|
90
|
-
this.messenger.send({
|
|
91
|
-
action: "app-exit",
|
|
92
|
-
data: {
|
|
93
|
-
workerId: appWorker.workerId,
|
|
94
|
-
code
|
|
95
|
-
},
|
|
96
|
-
to: "master",
|
|
97
|
-
from: "app"
|
|
98
|
-
});
|
|
99
|
-
await setTimeout(1e3);
|
|
100
|
-
this.#forkSingle(appPath, options, id);
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
fork() {
|
|
104
|
-
this.startTime = Date.now();
|
|
105
|
-
this.startSuccessCount = 0;
|
|
106
|
-
const ports = this.options.ports ?? [];
|
|
107
|
-
if (!ports.length) ports.push(this.options.port);
|
|
108
|
-
this.options.workers = ports.length;
|
|
109
|
-
let i = 0;
|
|
110
|
-
do {
|
|
111
|
-
const options = Object.assign({}, this.options, { port: ports[i] });
|
|
112
|
-
const argv = [JSON.stringify(options)];
|
|
113
|
-
this.#forkSingle(this.getAppWorkerFile(), { argv }, ++i);
|
|
114
|
-
} while (i < ports.length);
|
|
115
|
-
return this;
|
|
116
|
-
}
|
|
117
|
-
async kill() {
|
|
118
|
-
for (const worker of this.#workers) {
|
|
119
|
-
const id = Reflect.get(worker, "id");
|
|
120
|
-
this.log(`[master] kill app worker#${id} (worker_threads) by worker.terminate()`);
|
|
121
|
-
worker.removeAllListeners();
|
|
122
|
-
worker.terminate();
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
};
|
|
126
|
-
|
|
127
|
-
//#endregion
|
|
128
|
-
export { AppThreadUtils, AppThreadWorker };
|
package/dist/utils/options.d.ts
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import { SecureContextOptions } from "node:tls";
|
|
2
|
-
|
|
3
|
-
//#region src/utils/options.d.ts
|
|
4
|
-
interface ClusterHTTPSSecureOptions {
|
|
5
|
-
key: SecureContextOptions['key'];
|
|
6
|
-
cert: SecureContextOptions['cert'];
|
|
7
|
-
ca?: SecureContextOptions['ca'];
|
|
8
|
-
passphrase?: SecureContextOptions['passphrase'];
|
|
9
|
-
}
|
|
10
|
-
type ClusterStartMode = 'process' | 'worker_threads';
|
|
11
|
-
/** Cluster start options */
|
|
12
|
-
interface ClusterOptions {
|
|
13
|
-
/**
|
|
14
|
-
* specify framework that can be absolute path or npm package
|
|
15
|
-
*/
|
|
16
|
-
framework?: string;
|
|
17
|
-
/**
|
|
18
|
-
* @deprecated please use framework instead
|
|
19
|
-
*/
|
|
20
|
-
customEgg?: string;
|
|
21
|
-
/** directory of application, default to `process.cwd()` */
|
|
22
|
-
baseDir?: string;
|
|
23
|
-
/**
|
|
24
|
-
* numbers of app workers, default to `os.cpus().length`
|
|
25
|
-
*/
|
|
26
|
-
workers?: number | string;
|
|
27
|
-
/**
|
|
28
|
-
* listening port, default to `7001`(http) or `8443`(https)
|
|
29
|
-
*/
|
|
30
|
-
port?: number | string | null;
|
|
31
|
-
/**
|
|
32
|
-
* listening a debug port on http protocol
|
|
33
|
-
*/
|
|
34
|
-
debugPort?: number;
|
|
35
|
-
/**
|
|
36
|
-
* https options, { key, cert, ca }, full path
|
|
37
|
-
*/
|
|
38
|
-
https?: ClusterHTTPSSecureOptions | boolean;
|
|
39
|
-
/**
|
|
40
|
-
* @deprecated please use `options.https.key` instead
|
|
41
|
-
*/
|
|
42
|
-
key?: ClusterHTTPSSecureOptions['key'];
|
|
43
|
-
/**
|
|
44
|
-
* @deprecated please use `options.https.cert` instead
|
|
45
|
-
*/
|
|
46
|
-
cert?: ClusterHTTPSSecureOptions['cert'];
|
|
47
|
-
/**
|
|
48
|
-
* will inject into worker/agent process
|
|
49
|
-
*/
|
|
50
|
-
require?: string | string[];
|
|
51
|
-
/**
|
|
52
|
-
* will save master pid to this file
|
|
53
|
-
*/
|
|
54
|
-
pidFile?: string;
|
|
55
|
-
/**
|
|
56
|
-
* custom env, default is `process.env.EGG_SERVER_ENV`
|
|
57
|
-
*/
|
|
58
|
-
env?: string;
|
|
59
|
-
/**
|
|
60
|
-
* default is `'process'`, use `'worker_threads'` to start the app & agent worker by worker_threads
|
|
61
|
-
*/
|
|
62
|
-
startMode?: ClusterStartMode;
|
|
63
|
-
/**
|
|
64
|
-
* startup port of each app worker, such as: `[7001, 7002, 7003]`, only effects when the startMode is `'worker_threads'`
|
|
65
|
-
*/
|
|
66
|
-
ports?: number[];
|
|
67
|
-
/**
|
|
68
|
-
* sticky mode server
|
|
69
|
-
*/
|
|
70
|
-
sticky?: boolean;
|
|
71
|
-
/** customized plugins, for unittest */
|
|
72
|
-
plugins?: object;
|
|
73
|
-
isDebug?: boolean;
|
|
74
|
-
}
|
|
75
|
-
interface ParsedClusterOptions extends ClusterOptions {
|
|
76
|
-
port?: number;
|
|
77
|
-
baseDir: string;
|
|
78
|
-
workers: number;
|
|
79
|
-
framework: string;
|
|
80
|
-
startMode: ClusterStartMode;
|
|
81
|
-
}
|
|
82
|
-
//#endregion
|
|
83
|
-
export { ClusterHTTPSSecureOptions, ClusterOptions, ClusterStartMode, ParsedClusterOptions };
|
package/dist/utils/options.js
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import os from "node:os";
|
|
2
|
-
import { debuglog } from "node:util";
|
|
3
|
-
import path from "node:path";
|
|
4
|
-
import fs from "node:fs";
|
|
5
|
-
import assert from "node:assert";
|
|
6
|
-
import { getFrameworkPath, importModule } from "@eggjs/utils";
|
|
7
|
-
|
|
8
|
-
//#region src/utils/options.ts
|
|
9
|
-
const debug = debuglog("egg/cluster/utils/options");
|
|
10
|
-
async function parseOptions(options) {
|
|
11
|
-
options = {
|
|
12
|
-
baseDir: process.cwd(),
|
|
13
|
-
port: options?.https ? 8443 : void 0,
|
|
14
|
-
startMode: "process",
|
|
15
|
-
env: process.env.EGG_SERVER_ENV,
|
|
16
|
-
...options
|
|
17
|
-
};
|
|
18
|
-
const pkgPath = path.join(options.baseDir, "package.json");
|
|
19
|
-
assert(fs.existsSync(pkgPath), `${pkgPath} should exist`);
|
|
20
|
-
options.framework = getFrameworkPath({
|
|
21
|
-
baseDir: options.baseDir,
|
|
22
|
-
framework: options.framework ?? options.customEgg
|
|
23
|
-
});
|
|
24
|
-
debug("[parseOptions] %o", options);
|
|
25
|
-
const egg = await importModule(options.framework, { paths: [options.baseDir] });
|
|
26
|
-
assert(egg.Application, `should define Application in ${options.framework}`);
|
|
27
|
-
assert(egg.Agent, `should define Agent in ${options.framework}`);
|
|
28
|
-
if (options.https === true) {
|
|
29
|
-
console.warn("[@eggjs/cluster:deprecated] [master] Please use `https: { key, cert, ca }` instead of `https: true`");
|
|
30
|
-
options.https = {
|
|
31
|
-
key: options.key,
|
|
32
|
-
cert: options.cert
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
if (options.https) {
|
|
36
|
-
assert(options.https.key, "options.https.key should exists");
|
|
37
|
-
if (typeof options.https.key === "string") assert(fs.existsSync(options.https.key), "options.https.key file should exists");
|
|
38
|
-
assert(options.https.cert, "options.https.cert should exists");
|
|
39
|
-
if (typeof options.https.cert === "string") assert(fs.existsSync(options.https.cert), "options.https.cert file should exists");
|
|
40
|
-
if (typeof options.https.ca === "string") assert(fs.existsSync(options.https.ca), "options.https.ca file should exists");
|
|
41
|
-
}
|
|
42
|
-
if (options.port && typeof options.port === "string") options.port = parseInt(options.port);
|
|
43
|
-
if (options.port === null) options.port = void 0;
|
|
44
|
-
if (options.workers && typeof options.workers === "string") options.workers = parseInt(options.workers);
|
|
45
|
-
if (!options.workers) options.workers = os.cpus().length;
|
|
46
|
-
if (options.require) {
|
|
47
|
-
if (typeof options.require === "string") options.require = [options.require];
|
|
48
|
-
}
|
|
49
|
-
if (process.env.NODE_ENV === "production") process.env.NO_DEPRECATION = "*";
|
|
50
|
-
const isDebug = process.execArgv.some((argv) => argv.includes("--debug") || argv.includes("--inspect"));
|
|
51
|
-
if (isDebug) options.isDebug = isDebug;
|
|
52
|
-
return options;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
//#endregion
|
|
56
|
-
export { parseOptions };
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { BaseAgentWorker } from "./mode/base/agent.js";
|
|
2
|
-
import { BaseAppWorker } from "./mode/base/app.js";
|
|
3
|
-
import { EventEmitter } from "node:events";
|
|
4
|
-
import * as worker_threads0 from "worker_threads";
|
|
5
|
-
import * as cluster0 from "cluster";
|
|
6
|
-
import * as child_process0 from "child_process";
|
|
7
|
-
|
|
8
|
-
//#region src/utils/worker_manager.d.ts
|
|
9
|
-
declare class WorkerManager extends EventEmitter {
|
|
10
|
-
agent: BaseAgentWorker | null;
|
|
11
|
-
workers: Map<number, BaseAppWorker<worker_threads0.Worker | cluster0.Worker>>;
|
|
12
|
-
exception: number;
|
|
13
|
-
timer: NodeJS.Timeout;
|
|
14
|
-
constructor();
|
|
15
|
-
getWorkers(): number[];
|
|
16
|
-
setAgent(agent: BaseAgentWorker): void;
|
|
17
|
-
getAgent(): BaseAgentWorker<worker_threads0.Worker | child_process0.ChildProcess> | null;
|
|
18
|
-
deleteAgent(): void;
|
|
19
|
-
setWorker(worker: BaseAppWorker): void;
|
|
20
|
-
getWorker(workerId: number): BaseAppWorker<worker_threads0.Worker | cluster0.Worker> | undefined;
|
|
21
|
-
deleteWorker(workerId: number): void;
|
|
22
|
-
listWorkerIds(): number[];
|
|
23
|
-
listWorkers(): BaseAppWorker<worker_threads0.Worker | cluster0.Worker>[];
|
|
24
|
-
getListeningWorkerIds(): number[];
|
|
25
|
-
count(): {
|
|
26
|
-
agent: number;
|
|
27
|
-
worker: number;
|
|
28
|
-
};
|
|
29
|
-
startCheck(): void;
|
|
30
|
-
}
|
|
31
|
-
//#endregion
|
|
32
|
-
export { WorkerManager };
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import { EventEmitter } from "node:events";
|
|
2
|
-
|
|
3
|
-
//#region src/utils/worker_manager.ts
|
|
4
|
-
var WorkerManager = class extends EventEmitter {
|
|
5
|
-
agent;
|
|
6
|
-
workers = /* @__PURE__ */ new Map();
|
|
7
|
-
exception = 0;
|
|
8
|
-
timer;
|
|
9
|
-
constructor() {
|
|
10
|
-
super();
|
|
11
|
-
this.agent = null;
|
|
12
|
-
}
|
|
13
|
-
getWorkers() {
|
|
14
|
-
return Array.from(this.workers.keys());
|
|
15
|
-
}
|
|
16
|
-
setAgent(agent) {
|
|
17
|
-
this.agent = agent;
|
|
18
|
-
}
|
|
19
|
-
getAgent() {
|
|
20
|
-
return this.agent;
|
|
21
|
-
}
|
|
22
|
-
deleteAgent() {
|
|
23
|
-
this.agent = null;
|
|
24
|
-
}
|
|
25
|
-
setWorker(worker) {
|
|
26
|
-
this.workers.set(worker.workerId, worker);
|
|
27
|
-
}
|
|
28
|
-
getWorker(workerId) {
|
|
29
|
-
return this.workers.get(workerId);
|
|
30
|
-
}
|
|
31
|
-
deleteWorker(workerId) {
|
|
32
|
-
this.workers.delete(workerId);
|
|
33
|
-
}
|
|
34
|
-
listWorkerIds() {
|
|
35
|
-
return Array.from(this.workers.keys());
|
|
36
|
-
}
|
|
37
|
-
listWorkers() {
|
|
38
|
-
return Array.from(this.workers.values());
|
|
39
|
-
}
|
|
40
|
-
getListeningWorkerIds() {
|
|
41
|
-
const keys = [];
|
|
42
|
-
for (const [id, worker] of this.workers.entries()) if (worker.state === "listening") keys.push(id);
|
|
43
|
-
return keys;
|
|
44
|
-
}
|
|
45
|
-
count() {
|
|
46
|
-
return {
|
|
47
|
-
agent: this.agent?.status === "started" ? 1 : 0,
|
|
48
|
-
worker: this.listWorkerIds().length
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
startCheck() {
|
|
52
|
-
this.timer = setInterval(() => {
|
|
53
|
-
const count = this.count();
|
|
54
|
-
if (count.agent > 0 && count.worker > 0) {
|
|
55
|
-
this.exception = 0;
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
this.exception++;
|
|
59
|
-
if (this.exception >= 3) {
|
|
60
|
-
this.emit("exception", count);
|
|
61
|
-
clearInterval(this.timer);
|
|
62
|
-
}
|
|
63
|
-
}, 1e4);
|
|
64
|
-
}
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
//#endregion
|
|
68
|
-
export { WorkerManager };
|