mirror of
https://github.com/dromara/hertzbeat.git
synced 2026-10-02 14:09:07 +00:00
101 lines
2.5 KiB
JavaScript
101 lines
2.5 KiB
JavaScript
import { spawn } from 'node:child_process';
|
|
import { existsSync } from 'node:fs';
|
|
import path from 'node:path';
|
|
import process from 'node:process';
|
|
|
|
export function sleep(ms) {
|
|
return new Promise(resolve => {
|
|
setTimeout(resolve, ms);
|
|
});
|
|
}
|
|
|
|
export async function waitForServer(baseUrl, readyPath = '/overview') {
|
|
let lastError = null;
|
|
for (let attempt = 0; attempt < 120; attempt += 1) {
|
|
try {
|
|
const response = await fetch(`${baseUrl}${readyPath}`);
|
|
if (response.ok) {
|
|
return;
|
|
}
|
|
lastError = new Error(`received ${response.status}`);
|
|
} catch (error) {
|
|
lastError = error;
|
|
}
|
|
await sleep(500);
|
|
}
|
|
throw new Error(
|
|
`release-shell server did not become ready at ${baseUrl}${readyPath}: ${
|
|
lastError instanceof Error ? lastError.message : String(lastError)
|
|
}`
|
|
);
|
|
}
|
|
|
|
export async function startLocalReleaseServer({
|
|
port,
|
|
readyPath = '/overview',
|
|
distDir = process.env.NEXT_DIST_DIR || '.next'
|
|
}) {
|
|
const buildIdPath = path.join(process.cwd(), distDir, 'BUILD_ID');
|
|
const nextBinPath = path.join(process.cwd(), 'node_modules', 'next', 'dist', 'bin', 'next');
|
|
const command = existsSync(buildIdPath) ? 'start' : 'dev';
|
|
const child = spawn(process.execPath, [nextBinPath, command, '--hostname', '127.0.0.1', '--port', String(port)], {
|
|
cwd: process.cwd(),
|
|
env: { ...process.env, PORT: String(port) },
|
|
stdio: ['ignore', 'pipe', 'pipe']
|
|
});
|
|
|
|
child.stdout.on('data', chunk => {
|
|
process.stdout.write(chunk);
|
|
});
|
|
child.stderr.on('data', chunk => {
|
|
process.stderr.write(chunk);
|
|
});
|
|
|
|
const stop = () => {
|
|
if (!child.killed) {
|
|
child.kill('SIGTERM');
|
|
}
|
|
};
|
|
|
|
process.on('exit', stop);
|
|
process.on('SIGINT', () => {
|
|
stop();
|
|
process.exit(130);
|
|
});
|
|
process.on('SIGTERM', () => {
|
|
stop();
|
|
process.exit(143);
|
|
});
|
|
|
|
const baseUrl = `http://127.0.0.1:${port}`;
|
|
let ready = false;
|
|
const exitBeforeReady = new Promise((_, reject) => {
|
|
child.once('error', error => {
|
|
if (!ready) {
|
|
reject(error);
|
|
}
|
|
});
|
|
child.once('exit', (code, signal) => {
|
|
if (!ready) {
|
|
reject(
|
|
new Error(
|
|
`release-shell server exited before ready (code=${code ?? 'null'}, signal=${signal ?? 'null'}, baseUrl=${baseUrl})`
|
|
)
|
|
);
|
|
}
|
|
});
|
|
});
|
|
|
|
await Promise.race([
|
|
waitForServer(baseUrl, readyPath).then(() => {
|
|
ready = true;
|
|
}),
|
|
exitBeforeReady
|
|
]);
|
|
|
|
return {
|
|
baseUrl,
|
|
stop
|
|
};
|
|
}
|