@eggjs/cluster 4.0.0-beta.36 → 4.0.1-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.
package/dist/app_worker.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { AppProcessWorker } from "./utils/mode/impl/process/app.js";
|
|
2
2
|
import { AppThreadWorker } from "./utils/mode/impl/worker_threads/app.js";
|
|
3
3
|
import fs from "node:fs";
|
|
4
|
+
import os from "node:os";
|
|
4
5
|
import { debuglog } from "node:util";
|
|
5
6
|
import { EggConsoleLogger } from "egg-logger";
|
|
6
7
|
import { importModule } from "@eggjs/utils";
|
|
@@ -9,6 +10,12 @@ import { createServer as createServer$1 } from "node:https";
|
|
|
9
10
|
|
|
10
11
|
//#region src/app_worker.ts
|
|
11
12
|
const debug = debuglog("egg/cluster/app_worker");
|
|
13
|
+
const REUSE_PORT_SUPPORTED_PLATFORMS = [
|
|
14
|
+
"linux",
|
|
15
|
+
"freebsd",
|
|
16
|
+
"sunos",
|
|
17
|
+
"aix"
|
|
18
|
+
];
|
|
12
19
|
async function main() {
|
|
13
20
|
const options = JSON.parse(process.argv[2]);
|
|
14
21
|
if (options.require) for (const mod of options.require) await importModule(mod, { paths: [options.baseDir] });
|
|
@@ -50,7 +57,12 @@ async function main() {
|
|
|
50
57
|
const port = app.options.port = options.port || listenConfig.port;
|
|
51
58
|
const debugPort = options.debugPort;
|
|
52
59
|
const protocol = httpsOptions.key && httpsOptions.cert ? "https" : "http";
|
|
53
|
-
|
|
60
|
+
let reusePort = options.reusePort ?? listenConfig.reusePort ?? false;
|
|
61
|
+
if (reusePort && !REUSE_PORT_SUPPORTED_PLATFORMS.includes(os.platform())) {
|
|
62
|
+
reusePort = false;
|
|
63
|
+
debug("[app_worker:%s] platform %s is not supported for reusePort, set reusePort to false", process.pid, os.platform());
|
|
64
|
+
}
|
|
65
|
+
debug("[app_worker:%s] listenConfig: %j, real port: %o, protocol: %o, debugPort: %o, reusePort: %o", process.pid, listenConfig, port, protocol, debugPort, reusePort);
|
|
54
66
|
AppWorker.send({
|
|
55
67
|
to: "master",
|
|
56
68
|
action: "realport",
|
|
@@ -92,10 +104,20 @@ async function main() {
|
|
|
92
104
|
exitProcess();
|
|
93
105
|
return;
|
|
94
106
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
107
|
+
if (reusePort) {
|
|
108
|
+
const listenOptions = {
|
|
109
|
+
port,
|
|
110
|
+
reusePort
|
|
111
|
+
};
|
|
112
|
+
if (listenConfig.hostname) listenOptions.host = listenConfig.hostname;
|
|
113
|
+
debug("[app_worker:%s] listen with reusePort options %j", process.pid, listenOptions);
|
|
114
|
+
server.listen(listenOptions);
|
|
115
|
+
} else {
|
|
116
|
+
const args = [port];
|
|
117
|
+
if (listenConfig.hostname) args.push(listenConfig.hostname);
|
|
118
|
+
debug("listen options %j", args);
|
|
119
|
+
server.listen(...args);
|
|
120
|
+
}
|
|
99
121
|
}
|
|
100
122
|
if (debugPortServer) {
|
|
101
123
|
debug("listen on debug port: %s", debugPort);
|
|
@@ -108,14 +130,15 @@ async function main() {
|
|
|
108
130
|
address,
|
|
109
131
|
addressType: -1
|
|
110
132
|
};
|
|
111
|
-
debug("[app_worker:%s] listening at %j", process.pid, address);
|
|
133
|
+
debug("[app_worker:%s] listening at %j, reusePort: %o", process.pid, address, reusePort);
|
|
112
134
|
AppWorker.send({
|
|
113
135
|
to: "master",
|
|
114
136
|
action: "app-start",
|
|
115
137
|
data: {
|
|
116
138
|
address,
|
|
117
139
|
workerId: AppWorker.workerId
|
|
118
|
-
}
|
|
140
|
+
},
|
|
141
|
+
reusePort
|
|
119
142
|
});
|
|
120
143
|
});
|
|
121
144
|
}
|
|
@@ -14,6 +14,12 @@ interface MessageBody {
|
|
|
14
14
|
receiverPid?: string;
|
|
15
15
|
receiverWorkerId?: string;
|
|
16
16
|
senderWorkerId?: string;
|
|
17
|
+
/**
|
|
18
|
+
* Whether reusePort is enabled for server listen.
|
|
19
|
+
* When reusePort is true, cluster won't get `listening` event,
|
|
20
|
+
* so we need to use cluster `message` event instead.
|
|
21
|
+
*/
|
|
22
|
+
reusePort?: boolean;
|
|
17
23
|
}
|
|
18
24
|
/**
|
|
19
25
|
* master messenger, provide communication between parent, master, agent and app.
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { terminate } from "../../../terminate.js";
|
|
2
2
|
import { BaseAppUtils, BaseAppWorker } from "../../base/app.js";
|
|
3
|
+
import { debuglog } from "node:util";
|
|
3
4
|
import { graceful } from "graceful-process";
|
|
4
5
|
import { sendmessage } from "sendmessage";
|
|
5
6
|
import cluster from "node:cluster";
|
|
6
7
|
import { cfork } from "cfork";
|
|
7
8
|
|
|
8
9
|
//#region src/utils/mode/impl/process/app.ts
|
|
10
|
+
const debug = debuglog("egg/cluster/utils/mode/impl/process/app");
|
|
9
11
|
var AppProcessWorker = class extends BaseAppWorker {
|
|
10
12
|
get id() {
|
|
11
13
|
return this.instance.id;
|
|
@@ -33,6 +35,11 @@ var AppProcessWorker = class extends BaseAppWorker {
|
|
|
33
35
|
}
|
|
34
36
|
static send(message) {
|
|
35
37
|
message.senderWorkerId = String(process.pid);
|
|
38
|
+
if (message.action === "app-start" && message.reusePort) {
|
|
39
|
+
debug("send app-start message with reusePort, use cluster.worker.send()");
|
|
40
|
+
cluster.worker.send(message);
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
36
43
|
process.send(message);
|
|
37
44
|
}
|
|
38
45
|
static kill() {
|
|
@@ -103,15 +103,23 @@ var AppThreadUtils = class extends BaseAppUtils {
|
|
|
103
103
|
fork() {
|
|
104
104
|
this.startTime = Date.now();
|
|
105
105
|
this.startSuccessCount = 0;
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
this
|
|
114
|
-
|
|
106
|
+
if (this.options.reusePort) {
|
|
107
|
+
if (!this.options.port) throw new Error("options.port must be specified when reusePort is enabled");
|
|
108
|
+
for (let i = 0; i < this.options.workers; i++) {
|
|
109
|
+
const argv = [JSON.stringify(this.options)];
|
|
110
|
+
this.#forkSingle(this.getAppWorkerFile(), { argv }, i + 1);
|
|
111
|
+
}
|
|
112
|
+
} else {
|
|
113
|
+
const ports = this.options.ports ?? [];
|
|
114
|
+
if (!ports.length) ports.push(this.options.port);
|
|
115
|
+
this.options.workers = ports.length;
|
|
116
|
+
let i = 0;
|
|
117
|
+
do {
|
|
118
|
+
const options = Object.assign({}, this.options, { port: ports[i] });
|
|
119
|
+
const argv = [JSON.stringify(options)];
|
|
120
|
+
this.#forkSingle(this.getAppWorkerFile(), { argv }, ++i);
|
|
121
|
+
} while (i < ports.length);
|
|
122
|
+
}
|
|
115
123
|
return this;
|
|
116
124
|
}
|
|
117
125
|
async kill() {
|
package/dist/utils/options.d.ts
CHANGED
|
@@ -68,6 +68,12 @@ interface ClusterOptions {
|
|
|
68
68
|
* sticky mode server
|
|
69
69
|
*/
|
|
70
70
|
sticky?: boolean;
|
|
71
|
+
/**
|
|
72
|
+
* enable SO_REUSEPORT socket option for server listen, default is `false`.
|
|
73
|
+
* Only available on Linux 3.9+, DragonFlyBSD 3.6+, FreeBSD 12.0+, Solaris 11.4, and AIX 7.2.5+.
|
|
74
|
+
* @see https://nodejs.org/api/net.html#serverlistenoptions-callback
|
|
75
|
+
*/
|
|
76
|
+
reusePort?: boolean;
|
|
71
77
|
/** customized plugins, for unittest */
|
|
72
78
|
plugins?: object;
|
|
73
79
|
isDebug?: boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eggjs/cluster",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.1-beta.0",
|
|
4
4
|
"description": "cluster manager for egg",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cluster",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"sendmessage": "^3.0.1",
|
|
46
46
|
"terminal-link": "^5.0.0",
|
|
47
47
|
"utility": "^2.5.0",
|
|
48
|
-
"@eggjs/utils": "5.0.
|
|
48
|
+
"@eggjs/utils": "5.0.1-beta.0"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
51
51
|
"address": "2",
|
|
@@ -54,10 +54,10 @@
|
|
|
54
54
|
"typescript": "^5.9.3",
|
|
55
55
|
"urllib": "^4.8.2",
|
|
56
56
|
"vitest": "^4.0.15",
|
|
57
|
-
"@eggjs/
|
|
58
|
-
"@eggjs/
|
|
59
|
-
"@eggjs/supertest": "9.0.
|
|
60
|
-
"@eggjs/tsconfig": "3.1.
|
|
57
|
+
"@eggjs/errors": "3.0.1-beta.0",
|
|
58
|
+
"@eggjs/mock": "7.0.1-beta.0",
|
|
59
|
+
"@eggjs/supertest": "9.0.1-beta.0",
|
|
60
|
+
"@eggjs/tsconfig": "3.1.1-beta.0"
|
|
61
61
|
},
|
|
62
62
|
"engines": {
|
|
63
63
|
"node": ">=22.18.0"
|