mirror of
https://github.com/whyour/qinglong.git
synced 2026-09-19 14:59:43 +08:00
perf: reduce resident dependencies and duplicate WebSocket authentication (#3071)
* perf: load HTTP dependencies only in the HTTP worker * docs: record 30-minute idle resource comparison * perf: isolate database initialization from the cluster primary * docs: record isolated database startup resource comparison * perf: avoid an extra shell child in Docker health probes * perf: load notification dependencies only when needed * perf: retain queue cleanup after notification loading comparison * fix: stop page polling after unmount and avoid duplicate fetches * perf: share WebSocket session polling across connections * docs: measure real WebSocket container CPU and memory * perf: reuse JWT validation within each WebSocket session check * perf: bound login IP lookup allocations with an address cache * refactor: limit resource optimization PR to three core changes * docs: benchmark the three core optimizations against develop * chore: remove documentation and benchmark artifacts from PR
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
import { fork } from 'child_process';
|
||||
|
||||
// Keep one-off startup dependencies out of the long-lived cluster primary.
|
||||
export function runStartupProcess(entrypoint: string): Promise<void> {
|
||||
return new Promise((resolve, reject) => {
|
||||
const child = fork(entrypoint, [], { stdio: 'inherit' });
|
||||
let interrupted: NodeJS.Signals | undefined;
|
||||
let killTimer: NodeJS.Timeout | undefined;
|
||||
|
||||
const terminate = (signal: NodeJS.Signals) => {
|
||||
if (interrupted) return;
|
||||
interrupted = signal;
|
||||
child.kill(signal);
|
||||
killTimer = setTimeout(() => child.kill('SIGKILL'), 8000);
|
||||
killTimer.unref();
|
||||
};
|
||||
const onSigterm = () => terminate('SIGTERM');
|
||||
const onSigint = () => terminate('SIGINT');
|
||||
const onExit = () => child.kill('SIGKILL');
|
||||
const cleanup = () => {
|
||||
if (killTimer) clearTimeout(killTimer);
|
||||
process.removeListener('SIGTERM', onSigterm);
|
||||
process.removeListener('SIGINT', onSigint);
|
||||
process.removeListener('exit', onExit);
|
||||
};
|
||||
|
||||
process.once('SIGTERM', onSigterm);
|
||||
process.once('SIGINT', onSigint);
|
||||
process.once('exit', onExit);
|
||||
child.once('error', (error) => {
|
||||
cleanup();
|
||||
reject(error);
|
||||
});
|
||||
child.once('close', (code, signal) => {
|
||||
cleanup();
|
||||
if (code === 0 && !interrupted) {
|
||||
resolve();
|
||||
} else {
|
||||
reject(
|
||||
new Error(
|
||||
`Startup process failed (${interrupted || signal || code})`,
|
||||
),
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user