neex 0.6.60 → 0.6.62
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.
|
@@ -90,29 +90,17 @@ function addStartCommands(program) {
|
|
|
90
90
|
const isDevelopment = options.watch || process.env.NODE_ENV === 'development';
|
|
91
91
|
const isProduction = !isDevelopment;
|
|
92
92
|
const cpuCount = os_1.default.cpus().length;
|
|
93
|
-
// Smart worker allocation
|
|
93
|
+
// Smart worker allocation
|
|
94
94
|
let workers = options.workers;
|
|
95
95
|
if (!workers) {
|
|
96
96
|
if (isDevelopment) {
|
|
97
|
-
workers = 1;
|
|
97
|
+
workers = 1;
|
|
98
98
|
}
|
|
99
99
|
else {
|
|
100
|
-
// For production,
|
|
101
|
-
|
|
102
|
-
workers = 1; // Single worker for small systems
|
|
103
|
-
}
|
|
104
|
-
else if (cpuCount <= 4) {
|
|
105
|
-
workers = 2; // Two workers for medium systems
|
|
106
|
-
}
|
|
107
|
-
else {
|
|
108
|
-
workers = Math.min(Math.floor(cpuCount / 2), 4); // Max 4 workers
|
|
109
|
-
}
|
|
100
|
+
// For production, use CPU count but cap at reasonable limit
|
|
101
|
+
workers = Math.min(cpuCount, 4); // Reduced from 8 to 4 for better resource management
|
|
110
102
|
}
|
|
111
103
|
}
|
|
112
|
-
// Force single worker for development or debugging
|
|
113
|
-
if (isDevelopment || options.inspect || options.inspectBrk) {
|
|
114
|
-
workers = 1;
|
|
115
|
-
}
|
|
116
104
|
const healthCheck = options.health !== false;
|
|
117
105
|
const defaultPort = parseInt(process.env.PORT || '8000');
|
|
118
106
|
const port = options.port || defaultPort;
|
|
@@ -130,26 +118,22 @@ function addStartCommands(program) {
|
|
|
130
118
|
logger_manager_js_1.loggerManager.printLine(`Environment: ${process.env.NODE_ENV}`);
|
|
131
119
|
logger_manager_js_1.loggerManager.printLine(`Port: ${port}`);
|
|
132
120
|
logger_manager_js_1.loggerManager.printLine(`Workers: ${workers}`);
|
|
133
|
-
logger_manager_js_1.loggerManager.printLine(`CPU Cores: ${cpuCount}`);
|
|
134
121
|
if (healthCheck) {
|
|
135
122
|
logger_manager_js_1.loggerManager.printLine(`Health Check: http://localhost:${options.healthPort}/health`);
|
|
136
123
|
}
|
|
137
124
|
}
|
|
138
|
-
// Optimize memory settings based on workers
|
|
139
|
-
const memoryPerWorker = workers > 1 ? Math.floor(512 / workers) : 512;
|
|
140
|
-
const maxMemoryPerWorker = workers > 1 ? Math.floor(1024 / workers) : 1024;
|
|
141
125
|
startManager = new start_manager_js_1.StartManager({
|
|
142
126
|
file: resolvedFile,
|
|
143
127
|
workingDir: options.dir,
|
|
144
128
|
envFile: options.env,
|
|
145
129
|
port,
|
|
146
130
|
workers,
|
|
147
|
-
memoryLimit: isProduction ?
|
|
131
|
+
memoryLimit: isProduction ? '512M' : undefined,
|
|
148
132
|
logLevel: options.verbose ? 'debug' : 'info',
|
|
149
133
|
color: process.stdout.isTTY,
|
|
150
134
|
verbose: options.verbose,
|
|
151
135
|
watch: options.watch,
|
|
152
|
-
maxMemory: options.maxMemory || (isProduction ?
|
|
136
|
+
maxMemory: options.maxMemory || (isProduction ? '1G' : undefined),
|
|
153
137
|
maxCrashes: isProduction ? 3 : 10,
|
|
154
138
|
restartDelay: isProduction ? 1000 : 500,
|
|
155
139
|
healthCheck,
|
package/dist/src/dev-manager.js
CHANGED
|
@@ -52,14 +52,14 @@ class DevManager {
|
|
|
52
52
|
return { command: parts[0], args: [...parts.slice(1), this.options.file] };
|
|
53
53
|
}
|
|
54
54
|
// Default to tsx for TypeScript files
|
|
55
|
-
const args = [this.options.file];
|
|
55
|
+
const args = ['--loader', 'tsx', this.options.file];
|
|
56
56
|
if (this.options.inspect) {
|
|
57
57
|
args.unshift('--inspect');
|
|
58
58
|
}
|
|
59
59
|
if (this.options.inspectBrk) {
|
|
60
60
|
args.unshift('--inspect-brk');
|
|
61
61
|
}
|
|
62
|
-
return { command: '
|
|
62
|
+
return { command: 'node', args };
|
|
63
63
|
}
|
|
64
64
|
clearConsole() {
|
|
65
65
|
if (this.options.clearConsole && process.stdout.isTTY) {
|
|
@@ -24,7 +24,6 @@ class StartManager {
|
|
|
24
24
|
this.totalRestarts = 0;
|
|
25
25
|
this.envLoaded = false;
|
|
26
26
|
this.masterProcess = null;
|
|
27
|
-
this.readyWorkers = 0;
|
|
28
27
|
this.options = options;
|
|
29
28
|
this.startTime = new Date();
|
|
30
29
|
this.debouncedRestart = (0, lodash_1.debounce)(this.restartAll.bind(this), options.restartDelay);
|
|
@@ -87,10 +86,10 @@ class StartManager {
|
|
|
87
86
|
args.push(`--max-old-space-size=${memoryMB}`);
|
|
88
87
|
}
|
|
89
88
|
}
|
|
90
|
-
if (this.options.inspect
|
|
89
|
+
if (this.options.inspect) {
|
|
91
90
|
args.push('--inspect');
|
|
92
91
|
}
|
|
93
|
-
if (this.options.inspectBrk
|
|
92
|
+
if (this.options.inspectBrk) {
|
|
94
93
|
args.push('--inspect-brk');
|
|
95
94
|
}
|
|
96
95
|
if (this.options.nodeArgs) {
|
|
@@ -99,7 +98,6 @@ class StartManager {
|
|
|
99
98
|
return args;
|
|
100
99
|
}
|
|
101
100
|
async startSingleProcess() {
|
|
102
|
-
var _a, _b;
|
|
103
101
|
const nodeArgs = this.getNodeArgs();
|
|
104
102
|
const port = this.options.port || 8000;
|
|
105
103
|
const env = {
|
|
@@ -107,31 +105,13 @@ class StartManager {
|
|
|
107
105
|
NODE_ENV: process.env.NODE_ENV || 'production',
|
|
108
106
|
PORT: port.toString(),
|
|
109
107
|
FORCE_COLOR: this.options.color ? '1' : '0',
|
|
110
|
-
NODE_OPTIONS: '--no-deprecation'
|
|
111
|
-
CLUSTER_WORKER: 'false',
|
|
112
|
-
MASTER_PROCESS: 'true'
|
|
108
|
+
NODE_OPTIONS: '--no-deprecation'
|
|
113
109
|
};
|
|
114
|
-
if (this.options.verbose) {
|
|
115
|
-
this.log(`Starting single process on port ${port}`);
|
|
116
|
-
}
|
|
117
110
|
this.masterProcess = (0, child_process_1.fork)(this.options.file, [], {
|
|
118
111
|
cwd: this.options.workingDir,
|
|
119
112
|
env,
|
|
120
113
|
execArgv: nodeArgs,
|
|
121
|
-
silent:
|
|
122
|
-
});
|
|
123
|
-
// Handle process output with filtering
|
|
124
|
-
(_a = this.masterProcess.stdout) === null || _a === void 0 ? void 0 : _a.on('data', (data) => {
|
|
125
|
-
const message = data.toString().trim();
|
|
126
|
-
if (message && !this.shouldFilterMessage(message)) {
|
|
127
|
-
console.log(message);
|
|
128
|
-
}
|
|
129
|
-
});
|
|
130
|
-
(_b = this.masterProcess.stderr) === null || _b === void 0 ? void 0 : _b.on('data', (data) => {
|
|
131
|
-
const message = data.toString().trim();
|
|
132
|
-
if (message && !this.shouldFilterMessage(message)) {
|
|
133
|
-
console.error(chalk_1.default.red(message));
|
|
134
|
-
}
|
|
114
|
+
silent: false // Let the process handle its own output
|
|
135
115
|
});
|
|
136
116
|
this.masterProcess.on('error', (error) => {
|
|
137
117
|
this.log(`Process error: ${error.message}`, 'error');
|
|
@@ -176,21 +156,9 @@ class StartManager {
|
|
|
176
156
|
});
|
|
177
157
|
});
|
|
178
158
|
if (this.options.verbose) {
|
|
179
|
-
this.log(`Process started (PID: ${this.masterProcess.pid})`);
|
|
159
|
+
this.log(`Process started (PID: ${this.masterProcess.pid}, Port: ${port})`);
|
|
180
160
|
}
|
|
181
161
|
}
|
|
182
|
-
shouldFilterMessage(message) {
|
|
183
|
-
const filters = [
|
|
184
|
-
'[dotenv@',
|
|
185
|
-
'injecting env',
|
|
186
|
-
'Express (',
|
|
187
|
-
'Local: http://localhost:',
|
|
188
|
-
'Health Check: http://localhost:',
|
|
189
|
-
'Environment: production',
|
|
190
|
-
'Environment: development'
|
|
191
|
-
];
|
|
192
|
-
return filters.some(filter => message.includes(filter));
|
|
193
|
-
}
|
|
194
162
|
async startWorker(workerId) {
|
|
195
163
|
var _a, _b;
|
|
196
164
|
const nodeArgs = this.getNodeArgs();
|
|
@@ -201,14 +169,9 @@ class StartManager {
|
|
|
201
169
|
WORKER_ID: workerId.toString(),
|
|
202
170
|
PORT: port.toString(),
|
|
203
171
|
CLUSTER_WORKER: 'true',
|
|
204
|
-
MASTER_PROCESS: 'false',
|
|
205
172
|
FORCE_COLOR: this.options.color ? '1' : '0',
|
|
206
|
-
NODE_OPTIONS: '--no-deprecation'
|
|
207
|
-
SUPPRESS_STARTUP_LOGS: 'true' // Signal to suppress duplicate logs
|
|
173
|
+
NODE_OPTIONS: '--no-deprecation'
|
|
208
174
|
};
|
|
209
|
-
if (this.options.verbose) {
|
|
210
|
-
this.log(`Starting worker ${workerId}`);
|
|
211
|
-
}
|
|
212
175
|
const workerProcess = (0, child_process_1.fork)(this.options.file, [], {
|
|
213
176
|
cwd: this.options.workingDir,
|
|
214
177
|
env,
|
|
@@ -221,14 +184,13 @@ class StartManager {
|
|
|
221
184
|
restarts: 0,
|
|
222
185
|
startTime: new Date(),
|
|
223
186
|
id: workerId,
|
|
224
|
-
port: port
|
|
225
|
-
ready: false
|
|
187
|
+
port: port
|
|
226
188
|
};
|
|
227
189
|
this.workers.set(workerId, workerInfo);
|
|
228
|
-
// Handle worker output
|
|
190
|
+
// Handle worker output
|
|
229
191
|
(_a = workerProcess.stdout) === null || _a === void 0 ? void 0 : _a.on('data', (data) => {
|
|
230
192
|
const message = data.toString().trim();
|
|
231
|
-
if (message && !
|
|
193
|
+
if (message && !message.includes('[dotenv@') && !message.includes('injecting env')) {
|
|
232
194
|
const prefix = this.options.verbose ?
|
|
233
195
|
chalk_1.default.dim(`[Worker ${workerId}] `) : '';
|
|
234
196
|
console.log(prefix + message);
|
|
@@ -236,7 +198,7 @@ class StartManager {
|
|
|
236
198
|
});
|
|
237
199
|
(_b = workerProcess.stderr) === null || _b === void 0 ? void 0 : _b.on('data', (data) => {
|
|
238
200
|
const message = data.toString().trim();
|
|
239
|
-
if (message && !
|
|
201
|
+
if (message && !message.includes('[dotenv@') && !message.includes('injecting env')) {
|
|
240
202
|
const prefix = this.options.verbose ?
|
|
241
203
|
chalk_1.default.dim(`[Worker ${workerId}] `) : '';
|
|
242
204
|
console.error(prefix + chalk_1.default.red(message));
|
|
@@ -255,15 +217,11 @@ class StartManager {
|
|
|
255
217
|
// Wait for worker to be ready
|
|
256
218
|
await new Promise((resolve, reject) => {
|
|
257
219
|
const timeout = setTimeout(() => {
|
|
258
|
-
workerInfo.ready = true;
|
|
259
|
-
this.readyWorkers++;
|
|
260
220
|
resolve(); // Don't reject, assume it's ready
|
|
261
221
|
}, 5000);
|
|
262
222
|
workerProcess.on('message', (message) => {
|
|
263
223
|
if (message && message.type === 'ready') {
|
|
264
224
|
clearTimeout(timeout);
|
|
265
|
-
workerInfo.ready = true;
|
|
266
|
-
this.readyWorkers++;
|
|
267
225
|
resolve();
|
|
268
226
|
}
|
|
269
227
|
});
|
|
@@ -327,11 +285,11 @@ class StartManager {
|
|
|
327
285
|
}
|
|
328
286
|
async startCluster() {
|
|
329
287
|
if (this.options.workers === 1) {
|
|
288
|
+
// Single process mode
|
|
330
289
|
await this.startSingleProcess();
|
|
331
290
|
return;
|
|
332
291
|
}
|
|
333
292
|
// Multi-worker mode
|
|
334
|
-
this.readyWorkers = 0;
|
|
335
293
|
const startPromises = [];
|
|
336
294
|
for (let i = 0; i < this.options.workers; i++) {
|
|
337
295
|
startPromises.push(this.startWorker(i + 1));
|
|
@@ -357,23 +315,16 @@ class StartManager {
|
|
|
357
315
|
return;
|
|
358
316
|
}
|
|
359
317
|
if (req.url === '/health') {
|
|
360
|
-
const activeWorkers = this.options.workers === 1 ?
|
|
361
|
-
(this.masterProcess ? 1 : 0) :
|
|
362
|
-
this.workers.size;
|
|
363
318
|
const stats = {
|
|
364
319
|
status: 'ok',
|
|
365
320
|
uptime: Date.now() - this.startTime.getTime(),
|
|
366
|
-
workers:
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
restarts: w.restarts,
|
|
374
|
-
uptime: Date.now() - w.startTime.getTime(),
|
|
375
|
-
ready: w.ready
|
|
376
|
-
})),
|
|
321
|
+
workers: this.workers.size,
|
|
322
|
+
activeWorkers: Array.from(this.workers.values()).map(w => ({
|
|
323
|
+
id: w.id,
|
|
324
|
+
pid: w.pid,
|
|
325
|
+
restarts: w.restarts,
|
|
326
|
+
uptime: Date.now() - w.startTime.getTime()
|
|
327
|
+
})),
|
|
377
328
|
totalRestarts: this.totalRestarts,
|
|
378
329
|
memory: process.memoryUsage(),
|
|
379
330
|
cpu: os_1.default.loadavg(),
|
|
@@ -428,6 +379,7 @@ class StartManager {
|
|
|
428
379
|
return;
|
|
429
380
|
this.log('Restarting due to file changes...');
|
|
430
381
|
if (this.options.workers === 1 && this.masterProcess) {
|
|
382
|
+
// Single process restart
|
|
431
383
|
try {
|
|
432
384
|
this.masterProcess.kill('SIGTERM');
|
|
433
385
|
await this.waitForProcessExit(this.masterProcess, 5000);
|
|
@@ -440,6 +392,7 @@ class StartManager {
|
|
|
440
392
|
}, this.options.restartDelay);
|
|
441
393
|
}
|
|
442
394
|
else {
|
|
395
|
+
// Multi-worker restart
|
|
443
396
|
const restartPromises = [];
|
|
444
397
|
for (const [workerId, workerInfo] of this.workers.entries()) {
|
|
445
398
|
restartPromises.push((async () => {
|
|
@@ -469,9 +422,8 @@ class StartManager {
|
|
|
469
422
|
await this.startCluster();
|
|
470
423
|
// Success message
|
|
471
424
|
const port = this.options.port || 8000;
|
|
472
|
-
const actualWorkers = this.options.workers === 1 ? 1 : this.workers.size;
|
|
473
425
|
const workerInfo = this.options.workers === 1 ?
|
|
474
|
-
'' : ` (${
|
|
426
|
+
'' : ` (${this.workers.size} workers)`;
|
|
475
427
|
logger_manager_js_1.loggerManager.printLine(`${chalk_1.default.green(figures_1.default.tick)} Server ready on port ${port}${workerInfo}`, 'info');
|
|
476
428
|
}
|
|
477
429
|
catch (error) {
|