feat: expand backend admin marketplace and scaling
فشلت بعض الفحوصات
/ deploy (push) Failing after 1m22s
فشلت بعض الفحوصات
/ deploy (push) Failing after 1m22s
هذا الالتزام موجود في:
150
scripts/startup-benchmark.js
Normal file
150
scripts/startup-benchmark.js
Normal file
@@ -0,0 +1,150 @@
|
||||
const { existsSync } = require('fs');
|
||||
const { spawn } = require('child_process');
|
||||
const { performance } = require('perf_hooks');
|
||||
|
||||
function parseArgs(argv) {
|
||||
const options = {
|
||||
entry: 'dist/main.js',
|
||||
port: 4100,
|
||||
timeout: 30000,
|
||||
path: '/api/v1/health',
|
||||
};
|
||||
|
||||
for (let index = 0; index < argv.length; index += 1) {
|
||||
const arg = argv[index];
|
||||
const next = argv[index + 1];
|
||||
|
||||
if (arg === '--entry' && next) {
|
||||
options.entry = next;
|
||||
index += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg === '--port' && next) {
|
||||
options.port = Number(next);
|
||||
index += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg === '--timeout' && next) {
|
||||
options.timeout = Number(next);
|
||||
index += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg === '--path' && next) {
|
||||
options.path = next.startsWith('/') ? next : `/${next}`;
|
||||
index += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!existsSync(options.entry)) {
|
||||
throw new Error(`Entry file not found: ${options.entry}. Run "npm run build" first.`);
|
||||
}
|
||||
|
||||
if (!Number.isInteger(options.port) || options.port <= 0) {
|
||||
throw new Error('port must be a positive integer');
|
||||
}
|
||||
|
||||
if (!Number.isFinite(options.timeout) || options.timeout <= 0) {
|
||||
throw new Error('timeout must be a positive number of milliseconds');
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
async function waitForHealth(url, timeoutMs) {
|
||||
const deadline = Date.now() + timeoutMs;
|
||||
let lastError = null;
|
||||
|
||||
while (Date.now() < deadline) {
|
||||
try {
|
||||
const response = await fetch(url, { method: 'GET' });
|
||||
if (response.ok) {
|
||||
const body = await response.text();
|
||||
return { status: response.status, body };
|
||||
}
|
||||
} catch (error) {
|
||||
lastError = error;
|
||||
}
|
||||
|
||||
await new Promise((resolve) => setTimeout(resolve, 250));
|
||||
}
|
||||
|
||||
if (lastError instanceof Error) {
|
||||
throw new Error(`Startup timeout. Last error: ${lastError.message}`);
|
||||
}
|
||||
|
||||
throw new Error('Startup timeout. Health endpoint did not become ready.');
|
||||
}
|
||||
|
||||
async function terminate(child) {
|
||||
if (child.exitCode !== null) {
|
||||
return;
|
||||
}
|
||||
|
||||
child.kill();
|
||||
await new Promise((resolve) => {
|
||||
child.once('exit', resolve);
|
||||
setTimeout(resolve, 5000);
|
||||
});
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const options = parseArgs(process.argv.slice(2));
|
||||
const url = `http://127.0.0.1:${options.port}${options.path}`;
|
||||
const stdoutLines = [];
|
||||
const stderrLines = [];
|
||||
|
||||
const startedAt = performance.now();
|
||||
const child = spawn(process.execPath, [options.entry], {
|
||||
cwd: process.cwd(),
|
||||
env: {
|
||||
...process.env,
|
||||
PORT: String(options.port),
|
||||
PUBLIC_BASE_URL: `http://127.0.0.1:${options.port}`,
|
||||
},
|
||||
stdio: ['ignore', 'pipe', 'pipe'],
|
||||
});
|
||||
|
||||
child.stdout.on('data', (chunk) => {
|
||||
stdoutLines.push(...String(chunk).split(/\r?\n/).filter(Boolean));
|
||||
if (stdoutLines.length > 20) {
|
||||
stdoutLines.splice(0, stdoutLines.length - 20);
|
||||
}
|
||||
});
|
||||
|
||||
child.stderr.on('data', (chunk) => {
|
||||
stderrLines.push(...String(chunk).split(/\r?\n/).filter(Boolean));
|
||||
if (stderrLines.length > 20) {
|
||||
stderrLines.splice(0, stderrLines.length - 20);
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
const healthResult = await waitForHealth(url, options.timeout);
|
||||
const readyMs = performance.now() - startedAt;
|
||||
|
||||
console.log(
|
||||
JSON.stringify(
|
||||
{
|
||||
entry: options.entry,
|
||||
url,
|
||||
startupMs: Number(readyMs.toFixed(2)),
|
||||
healthStatus: healthResult.status,
|
||||
recentStdout: stdoutLines,
|
||||
recentStderr: stderrLines,
|
||||
},
|
||||
null,
|
||||
2,
|
||||
),
|
||||
);
|
||||
} finally {
|
||||
await terminate(child);
|
||||
}
|
||||
}
|
||||
|
||||
main().catch((error) => {
|
||||
console.error(error instanceof Error ? error.message : String(error));
|
||||
process.exitCode = 1;
|
||||
});
|
||||
المرجع في مشكلة جديدة
حظر مستخدم