compare-run.sh answers "how do we compare to MongoDB"; it says nothing
about whether a change made things better or worse than last week. Add a
harness that records each run and diffs it against the previous one.
bench-run.sh wraps compare-run.sh, adds a concurrent durable-write
comparison (concurrent.js: N clients each doing sequential insertOne with
{w:1, j:true}, exercising the group-commit path under real contention),
writes a versioned name<TAB>value report to results/bench-<timestamp>.txt,
and prints a diff of our numbers against results/bench-latest.txt.
Also:
- compare-run.sh polled with fixed sleeps, which are flaky once earlier
benchmark phases have warmed the machine; both servers now wait on a
real driver connection instead.
- a dispatch error only reached the client as a generic InternalError,
with nothing on the server side naming the failing command; log the
connection, command and error name before replacing the reply.
46 lines
2.2 KiB
JavaScript
46 lines
2.2 KiB
JavaScript
// Concurrent durable-write benchmark: N clients each do M sequential
|
|
// insertOne ({w:1, j:true} by default) into their own collection, reporting
|
|
// aggregate docs/s. Exercises the group-commit path under real contention.
|
|
//
|
|
// node tests/e2e/concurrent.js --url mongodb://127.0.0.1:27019 --label mongo-lite
|
|
// [--clients 8] [--per-client 2000] [--wc j|none]
|
|
//
|
|
// Output (stdout, tab-separated, one line):
|
|
// <label> clients=N <docs/s> (M docs in S s)
|
|
const { MongoClient, ObjectId } = require('mongodb');
|
|
|
|
let opt = { url: null, label: null, clients: 8, perClient: 2000, wc: 'j' };
|
|
for (let i = 2; i < process.argv.length; i++) {
|
|
const a = process.argv[i];
|
|
if (a === '--url') opt.url = process.argv[++i];
|
|
else if (a === '--label') opt.label = process.argv[++i];
|
|
else if (a === '--clients') opt.clients = Number(process.argv[++i]);
|
|
else if (a === '--per-client') opt.perClient = Number(process.argv[++i]);
|
|
else if (a === '--wc') opt.wc = process.argv[++i];
|
|
else { console.error(`unknown option ${a}`); process.exit(2); }
|
|
}
|
|
if (!opt.url) { console.error('--url required'); process.exit(2); }
|
|
opt.label = opt.label || opt.url.replace(/^mongodb:\/\//, '');
|
|
const WC = opt.wc === 'j' ? { writeConcern: { w: 1, j: true } } : {};
|
|
|
|
async function worker(i) {
|
|
const c = new MongoClient(opt.url, { maxPoolSize: 4, serverSelectionTimeoutMS: 15000 });
|
|
await c.connect();
|
|
// One collection per worker in a scratch db, so no cross-worker contention
|
|
// beyond the engine's own commit path.
|
|
const coll = c.db(`cc${Date.now() % 100000}`).collection(`w${i}`);
|
|
for (let j = 0; j < opt.perClient; j++) {
|
|
await coll.insertOne({ _id: new ObjectId(), k: j, payload: 'x'.repeat(256) }, WC);
|
|
}
|
|
await c.close();
|
|
}
|
|
|
|
(async () => {
|
|
const t0 = process.hrtime.bigint();
|
|
await Promise.all(Array.from({ length: opt.clients }, (_, i) => worker(i)));
|
|
const s = Number(process.hrtime.bigint() - t0) / 1e9;
|
|
const total = opt.clients * opt.perClient;
|
|
console.log(`${opt.label}\tclients=${opt.clients}\t${(total / s).toFixed(0)} docs/s\t(${total} docs in ${s.toFixed(2)} s)`);
|
|
process.exit(0);
|
|
})().catch((e) => { console.error('FAIL', e); process.exit(1); });
|