const path = require('path'); const { Client } = require('../../backend/node_modules/pg'); const { config, ensureDir, executeMeasured, getDbConfig, loadQueries, resultsDir, summarizeRows, writeCsv, writeJson } = require('./benchmark-lib'); const levels = String(process.env.BENCHMARK_CONCURRENCY_LEVELS || config.concurrencyLevels.join(',')) .split(',') .map((item) => Number.parseInt(item.trim(), 10)) .filter((item) => Number.isFinite(item) && item > 0); const requestsPerLevel = Number.parseInt( process.env.BENCHMARK_CONCURRENCY_REQUESTS || config.concurrencyRequestsPerLevel, 10 ); const runPool = async (items, workers, task) => { let index = 0; const worker = async () => { while (index < items.length) { const current = items[index]; index += 1; await task(current); } }; await Promise.all(Array.from({ length: Math.min(workers, items.length) }, () => worker())); }; const main = async () => { ensureDir(resultsDir); const queries = loadQueries(); const raw = []; for (const level of levels) { const work = Array.from({ length: requestsPerLevel }, (_, index) => ({ query: queries[index % queries.length], repetition: index + 1 })); await runPool(work, level, async ({ query, repetition }) => { const client = new Client(getDbConfig(level)); await client.connect(); try { const row = await executeMeasured(client, query, repetition, 'concurrency', level); raw.push(row); process.stdout.write(`concurrency=${level} ${query.id} ${repetition}/${requestsPerLevel} ${row.success ? 'ok' : 'fail'} ${row.endpoint_total_ms.toFixed(2)}ms\n`); } finally { await client.end(); } }); } raw.sort((a, b) => a.concurrency_level - b.concurrency_level || a.repetition - b.repetition); const summary = summarizeRows(raw, ['phase', 'concurrency_level', 'query_id', 'query_name', 'query_group']); const byLevel = summarizeRows(raw, ['phase', 'concurrency_level']); writeCsv(path.join(resultsDir, 'concurrency_raw.csv'), raw); writeCsv(path.join(resultsDir, 'concurrency_summary.csv'), summary.concat(byLevel)); writeJson(path.join(resultsDir, 'concurrency.json'), { generatedAt: new Date().toISOString(), levels, requestsPerLevel, expectedMeasuredOperations: levels.length * requestsPerLevel, measuredOperations: raw.length, summary, byLevel }); }; main().catch((error) => { console.error(error); process.exit(1); });