From b8d9563276b2af6419358b60869c847cc1c785dc Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Wed, 20 Nov 2024 18:16:35 -0500 Subject: [PATCH 01/10] wip --- src/cmap/connect.ts | 10 ++- test/benchmarks/driverBench/index.js | 36 ++++----- .../mongoBench/suites/parallelBench.js | 78 +++++++++---------- 3 files changed, 65 insertions(+), 59 deletions(-) diff --git a/src/cmap/connect.ts b/src/cmap/connect.ts index 938b524e082..8c549d42bd2 100644 --- a/src/cmap/connect.ts +++ b/src/cmap/connect.ts @@ -387,10 +387,18 @@ export async function makeSocket(options: MakeConnectionOptions): Promise resolve(socket)) .once('error', error => reject(connectionFailureError('error', error))) - .once('timeout', () => reject(connectionFailureError('timeout'))) + .once('timeout', () => { + const end = performance.now(); + return reject( + new MongoNetworkTimeoutError( + `socket.connect() timed out! connectTimeoutMS=${connectTimeoutMS}ms, socket.setTimeout fired after ${end - start}ms.` + ) + ); + }) .once('close', () => reject(connectionFailureError('close'))); if (options.cancellationToken != null) { diff --git a/test/benchmarks/driverBench/index.js b/test/benchmarks/driverBench/index.js index 3e2ecf30ae2..9245b65eb7c 100644 --- a/test/benchmarks/driverBench/index.js +++ b/test/benchmarks/driverBench/index.js @@ -10,7 +10,9 @@ let bsonType = 'js-bson'; // TODO(NODE-4606): test against different driver configurations in CI const { writeFile } = require('fs/promises'); -const { makeParallelBenchmarks, makeSingleBench, makeMultiBench } = require('../mongoBench/suites'); +const { + makeParallelBenchmarks /* makeSingleBench, makeMultiBench*/ +} = require('../mongoBench/suites'); const { MONGODB_CLIENT_OPTIONS } = require('./common'); const hw = os.cpus(); @@ -33,27 +35,23 @@ function average(arr) { } const benchmarkRunner = new Runner() - .suite('singleBench', suite => makeSingleBench(suite)) - .suite('multiBench', suite => makeMultiBench(suite)) + // .suite('singleBench', suite => makeSingleBench(suite)) + // .suite('multiBench', suite => makeMultiBench(suite)) .suite('parallel', suite => makeParallelBenchmarks(suite)); benchmarkRunner .run() .then(microBench => { - const singleBench = average([ - microBench.singleBench.findOne, - microBench.singleBench.smallDocInsertOne, - microBench.singleBench.largeDocInsertOne - ]); - const multiBench = average(Object.values(microBench.multiBench)); - - // ldjsonMultiFileUpload and ldjsonMultiFileExport cause connection errors. - // While we investigate, we will use the last known good values: - // https://spruce.mongodb.com/task/mongo_node_driver_next_performance_tests_run_spec_benchmark_tests_node_server_4bc3e500b6f0e8ab01f052c4a1bfb782d6a29b4e_f168e1328f821bbda265e024cc91ae54_24_11_18_15_37_24/logs?execution=0 + // const singleBench = average([ + // microBench.singleBench.findOne, + // microBench.singleBench.smallDocInsertOne, + // microBench.singleBench.largeDocInsertOne + // ]); + // const multiBench = average(Object.values(microBench.multiBench)); const parallelBench = average([ - microBench.parallel.ldjsonMultiFileUpload ?? 44.02343490518617, - microBench.parallel.ldjsonMultiFileExport ?? 31.83182984813926, + microBench.parallel.ldjsonMultiFileUpload, + microBench.parallel.ldjsonMultiFileExport, microBench.parallel.gridfsMultiFileUpload, microBench.parallel.gridfsMultiFileDownload ]); @@ -63,7 +61,7 @@ benchmarkRunner microBench.multiBench.findManyAndEmptyCursor, microBench.multiBench.gridFsDownload, microBench.parallel.gridfsMultiFileDownload, - microBench.parallel.ldjsonMultiFileExport ?? 31.83182984813926 + microBench.parallel.ldjsonMultiFileExport ]); const writeBench = average([ microBench.singleBench.smallDocInsertOne, @@ -71,15 +69,15 @@ benchmarkRunner microBench.multiBench.smallDocBulkInsert, microBench.multiBench.largeDocBulkInsert, microBench.multiBench.gridFsUpload, - microBench.parallel.ldjsonMultiFileUpload ?? 44.02343490518617, + microBench.parallel.ldjsonMultiFileUpload, microBench.parallel.gridfsMultiFileUpload ]); const driverBench = average([readBench, writeBench]); const benchmarkResults = { - singleBench, - multiBench, + // singleBench, + // multiBench, parallelBench, readBench, writeBench, diff --git a/test/benchmarks/mongoBench/suites/parallelBench.js b/test/benchmarks/mongoBench/suites/parallelBench.js index 197646e3958..b011603b75d 100644 --- a/test/benchmarks/mongoBench/suites/parallelBench.js +++ b/test/benchmarks/mongoBench/suites/parallelBench.js @@ -13,7 +13,9 @@ const { dropBucket, initCollection, initDb, - connectClient + connectClient, + dropCollection, + createCollection } = require('../../driverBench/common'); const { pipeline } = require('stream/promises'); const { EJSON } = require('bson'); @@ -34,7 +36,6 @@ async function clearTemporaryDirectory() { await Promise.all(files.map(file => rm(file))); } -// eslint-disable-next-line no-unused-vars async function ldjsonMultiUpload() { const directory = resolve(benchmarkFileDirectory, 'ldjson_multi'); const files = await readdir(directory); @@ -63,7 +64,6 @@ async function ldjsonMultiUpload() { await Promise.all(uploads); } -// eslint-disable-next-line no-unused-vars async function ldjsonMultiExport() { const skips = Array.from({ length: 100 }, (_, index) => index * 5000); @@ -113,43 +113,43 @@ async function gridfsMultiFileDownload() { * @returns Benchmark */ function makeParallelBenchmarks(suite) { - // .benchmark('ldjsonMultiFileUpload', benchmark => - // // https://github.com/mongodb/specifications/blob/master/source/benchmarking/benchmarking.rst#ldjson-multi-file-import - // benchmark - // .taskSize(565) - // .setup(makeClient) - // .setup(connectClient) - // .setup(initDb) - // .setup(dropDb) - // .beforeTask(initCollection) - // .beforeTask(dropCollection) - // .beforeTask(createCollection) - // .task(ldjsonMultiUpload) - // .teardown(dropDb) - // .teardown(disconnectClient) - // ) - // .benchmark('ldjsonMultiFileExport', benchmark => - // // https://github.com/mongodb/specifications/blob/master/source/benchmarking/benchmarking.rst#ldjson-multi-file-export - // benchmark - // .taskSize(565) - // .setup(makeClient) - // .setup(connectClient) - // .setup(initDb) - // .setup(dropDb) - // .beforeTask(initCollection) - // .beforeTask(dropCollection) - // .beforeTask(createCollection) - // .beforeTask(ldjsonMultiUpload) - // .beforeTask(initTemporaryDirectory) - // .task(ldjsonMultiExport) - // .afterTask(clearTemporaryDirectory) - // .teardown(dropDb) - // .teardown(async function () { - // await rm(this.temporaryDirectory, { recursive: true, force: true }); - // }) - // .teardown(disconnectClient) - // ) return suite + .benchmark('ldjsonMultiFileUpload', benchmark => + // https://github.com/mongodb/specifications/blob/master/source/benchmarking/benchmarking.rst#ldjson-multi-file-import + benchmark + .taskSize(565) + .setup(makeClient) + .setup(connectClient) + .setup(initDb) + .setup(dropDb) + .beforeTask(initCollection) + .beforeTask(dropCollection) + .beforeTask(createCollection) + .task(ldjsonMultiUpload) + .teardown(dropDb) + .teardown(disconnectClient) + ) + .benchmark('ldjsonMultiFileExport', benchmark => + // https://github.com/mongodb/specifications/blob/master/source/benchmarking/benchmarking.rst#ldjson-multi-file-export + benchmark + .taskSize(565) + .setup(makeClient) + .setup(connectClient) + .setup(initDb) + .setup(dropDb) + .beforeTask(initCollection) + .beforeTask(dropCollection) + .beforeTask(createCollection) + .beforeTask(ldjsonMultiUpload) + .beforeTask(initTemporaryDirectory) + .task(ldjsonMultiExport) + .afterTask(clearTemporaryDirectory) + .teardown(dropDb) + .teardown(async function () { + await rm(this.temporaryDirectory, { recursive: true, force: true }); + }) + .teardown(disconnectClient) + ) .benchmark('gridfsMultiFileUpload', benchmark => // https://github.com/mongodb/specifications/blob/master/source/benchmarking/benchmarking.rst#gridfs-multi-file-upload benchmark From 57cdffcf444b3a15862129119c6a6e95b02a4ad7 Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Thu, 21 Nov 2024 16:29:55 -0500 Subject: [PATCH 02/10] chore: test isolation and info --- src/cmap/connect.ts | 7 ++-- test/benchmarks/driverBench/common.js | 56 ++++++++++++++++++++++++--- test/benchmarks/driverBench/index.js | 36 +++++++++++------ 3 files changed, 78 insertions(+), 21 deletions(-) diff --git a/src/cmap/connect.ts b/src/cmap/connect.ts index 8c549d42bd2..e36829b72e8 100644 --- a/src/cmap/connect.ts +++ b/src/cmap/connect.ts @@ -386,16 +386,15 @@ export async function makeSocket(options: MakeConnectionOptions): Promise resolve(socket)) .once('error', error => reject(connectionFailureError('error', error))) .once('timeout', () => { - const end = performance.now(); - return reject( + reject( new MongoNetworkTimeoutError( - `socket.connect() timed out! connectTimeoutMS=${connectTimeoutMS}ms, socket.setTimeout fired after ${end - start}ms.` + `Socket '${connectEvent}' timed out after ${(performance.now() - start) | 0}ms (connectTimeoutMS: ${connectTimeoutMS})` ) ); }) diff --git a/test/benchmarks/driverBench/common.js b/test/benchmarks/driverBench/common.js index d4abaac5e63..576201113f8 100644 --- a/test/benchmarks/driverBench/common.js +++ b/test/benchmarks/driverBench/common.js @@ -4,10 +4,50 @@ const fs = require('fs'); const path = require('path'); const { Readable } = require('stream'); const { pipeline } = require('stream/promises'); -const { MongoClient } = require('../../..'); -const { GridFSBucket } = require('../../..'); -// eslint-disable-next-line no-restricted-modules -const { MONGODB_ERROR_CODES } = require('../../../lib/error'); +const child_process = require('child_process'); + +const MONGODB_DRIVER_PATH = (() => { + let driverPath = process.env.MONGODB_DRIVER_PATH; + if (!driverPath?.length) { + driverPath = path.resolve(__dirname, '../../..'); + } + return driverPath; +})(); + +const { MongoClient, GridFSBucket } = require(MONGODB_DRIVER_PATH); + +const { version: MONGODB_DRIVER_VERSION } = require(path.join(MONGODB_DRIVER_PATH, 'package.json')); + +const MONGODB_DRIVER_REVISION = (() => { + try { + return child_process + .execSync('git rev-parse --short HEAD', { + cwd: MONGODB_DRIVER_PATH, + encoding: 'utf8' + }) + .trim(); + } catch { + return 'unknown revision'; + } +})(); + +const MONGODB_BSON_PATH = path.join(MONGODB_DRIVER_PATH, 'node_modules', 'bson'); +const { version: MONGODB_BSON_VERSION } = require(path.join(MONGODB_BSON_PATH, 'package.json')); +const MONGODB_BSON_REVISION = (() => { + if (!fs.existsSync(path.join(MONGODB_BSON_PATH, '.git'))) { + return 'installed from npm'; + } + try { + return child_process + .execSync('git rev-parse --short HEAD', { + cwd: path.join(MONGODB_BSON_PATH), + encoding: 'utf8' + }) + .trim(); + } catch { + return 'unknown revision'; + } +})(); const DB_NAME = 'perftest'; const COLLECTION_NAME = 'corpus'; @@ -67,7 +107,7 @@ function initCollection() { function dropCollection() { return this.collection.drop().catch(e => { - if (e.code !== MONGODB_ERROR_CODES.NamespaceNotFound) { + if (e.code !== 26 /* NamespaceNotFound */) { throw e; } }); @@ -117,6 +157,12 @@ async function writeSingleByteFileToBucket() { module.exports = { MONGODB_URI, MONGODB_CLIENT_OPTIONS, + MONGODB_DRIVER_PATH, + MONGODB_DRIVER_VERSION, + MONGODB_DRIVER_REVISION, + MONGODB_BSON_PATH, + MONGODB_BSON_VERSION, + MONGODB_BSON_REVISION, makeClient, connectClient, disconnectClient, diff --git a/test/benchmarks/driverBench/index.js b/test/benchmarks/driverBench/index.js index 9245b65eb7c..054f96aa408 100644 --- a/test/benchmarks/driverBench/index.js +++ b/test/benchmarks/driverBench/index.js @@ -2,6 +2,7 @@ const MongoBench = require('../mongoBench'); const os = require('node:os'); +const util = require('node:util'); const process = require('node:process'); const Runner = MongoBench.Runner; @@ -11,9 +12,17 @@ let bsonType = 'js-bson'; const { writeFile } = require('fs/promises'); const { - makeParallelBenchmarks /* makeSingleBench, makeMultiBench*/ + makeParallelBenchmarks /* makeSingleBench, makeMultiBench */ } = require('../mongoBench/suites'); -const { MONGODB_CLIENT_OPTIONS } = require('./common'); +const { + MONGODB_CLIENT_OPTIONS, + MONGODB_DRIVER_PATH, + MONGODB_DRIVER_VERSION, + MONGODB_DRIVER_REVISION, + MONGODB_BSON_PATH, + MONGODB_BSON_VERSION, + MONGODB_BSON_REVISION +} = require('./common'); const hw = os.cpus(); const ram = os.totalmem() / 1024 ** 3; @@ -26,7 +35,10 @@ const systemInfo = () => `- arch: ${os.arch()}`, `- os: ${process.platform} (${os.release()})`, `- ram: ${platform.ram}`, - `- node: ${process.version}\n` + `- node: ${process.version}`, + `- driver: ${MONGODB_DRIVER_VERSION} (${MONGODB_DRIVER_REVISION}): ${MONGODB_DRIVER_PATH}`, + ` - options ${util.inspect(MONGODB_CLIENT_OPTIONS)}`, + `- bson: ${MONGODB_BSON_VERSION} (${MONGODB_BSON_REVISION}): (${MONGODB_BSON_PATH})\n` ].join('\n'); console.log(systemInfo()); @@ -57,18 +69,18 @@ benchmarkRunner ]); const readBench = average([ - microBench.singleBench.findOne, - microBench.multiBench.findManyAndEmptyCursor, - microBench.multiBench.gridFsDownload, + // microBench.singleBench.findOne, + // microBench.multiBench.findManyAndEmptyCursor, + // microBench.multiBench.gridFsDownload, microBench.parallel.gridfsMultiFileDownload, microBench.parallel.ldjsonMultiFileExport ]); const writeBench = average([ - microBench.singleBench.smallDocInsertOne, - microBench.singleBench.largeDocInsertOne, - microBench.multiBench.smallDocBulkInsert, - microBench.multiBench.largeDocBulkInsert, - microBench.multiBench.gridFsUpload, + // microBench.singleBench.smallDocInsertOne, + // microBench.singleBench.largeDocInsertOne, + // microBench.multiBench.smallDocBulkInsert, + // microBench.multiBench.largeDocBulkInsert, + // microBench.multiBench.gridFsUpload, microBench.parallel.ldjsonMultiFileUpload, microBench.parallel.gridfsMultiFileUpload ]); @@ -111,6 +123,6 @@ benchmarkRunner return writeFile('results.json', results); }) .catch(err => { - console.error('failure: ', err.name, err.message); + console.error('failure: ', err.name, err.message, err.stack); process.exit(1); }); From 50fc112de0b3a821d9de2a669e4bd91216825f78 Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Mon, 25 Nov 2024 11:54:53 -0500 Subject: [PATCH 03/10] chore: prepare for BSON fix --- src/cmap/connect.ts | 58 +++++++++++-------------- test/benchmarks/driverBench/common.js | 22 ++++++++++ test/benchmarks/driverBench/index.js | 62 +++++++++++---------------- 3 files changed, 73 insertions(+), 69 deletions(-) diff --git a/src/cmap/connect.ts b/src/cmap/connect.ts index e36829b72e8..9efe2461070 100644 --- a/src/cmap/connect.ts +++ b/src/cmap/connect.ts @@ -390,7 +390,9 @@ export async function makeSocket(options: MakeConnectionOptions): Promise resolve(socket)) - .once('error', error => reject(connectionFailureError('error', error))) + .once('error', cause => + reject(new MongoNetworkError(MongoError.buildErrorMessage(cause), { cause })) + ) .once('timeout', () => { reject( new MongoNetworkTimeoutError( @@ -398,10 +400,21 @@ export async function makeSocket(options: MakeConnectionOptions): Promise reject(connectionFailureError('close'))); + .once('close', () => + reject( + new MongoNetworkError( + `Socket closed after ${(performance.now() - start) | 0} during connection establishment` + ) + ) + ); if (options.cancellationToken != null) { - cancellationHandler = () => reject(connectionFailureError('cancel')); + cancellationHandler = () => + reject( + new MongoNetworkError( + `Socket connection establishment was cancelled after ${(performance.now() - start) | 0}` + ) + ); options.cancellationToken.once('cancel', cancellationHandler); } } @@ -454,9 +467,11 @@ async function makeSocks5Connection(options: MakeConnectionOptions): Promise { let driverPath = process.env.MONGODB_DRIVER_PATH; if (!driverPath?.length) { @@ -16,8 +21,13 @@ const MONGODB_DRIVER_PATH = (() => { const { MongoClient, GridFSBucket } = require(MONGODB_DRIVER_PATH); +/** Grab the version from the package.json */ const { version: MONGODB_DRIVER_VERSION } = require(path.join(MONGODB_DRIVER_PATH, 'package.json')); +/** + * Use git to optionally determine the git revision, + * but the benchmarks could be run against an npm installed version so this should be allowed to fail + */ const MONGODB_DRIVER_REVISION = (() => { try { return child_process @@ -31,8 +41,20 @@ const MONGODB_DRIVER_REVISION = (() => { } })(); +/** + * Find the BSON dependency inside the driver PATH given and grab the version from the package.json. + */ const MONGODB_BSON_PATH = path.join(MONGODB_DRIVER_PATH, 'node_modules', 'bson'); const { version: MONGODB_BSON_VERSION } = require(path.join(MONGODB_BSON_PATH, 'package.json')); + +/** + * If you need to test BSON changes, you should clone, checkout and build BSON. + * run: `npm link` with no arguments to register the link. + * Then in the driver you are testing run `npm link bson` to use your local build. + * + * This will symlink the BSON into the driver's node_modules directory. So here + * we can find the revision of the BSON we are testing against if .git exists. + */ const MONGODB_BSON_REVISION = (() => { if (!fs.existsSync(path.join(MONGODB_BSON_PATH, '.git'))) { return 'installed from npm'; diff --git a/test/benchmarks/driverBench/index.js b/test/benchmarks/driverBench/index.js index 054f96aa408..34e10206a4b 100644 --- a/test/benchmarks/driverBench/index.js +++ b/test/benchmarks/driverBench/index.js @@ -2,7 +2,6 @@ const MongoBench = require('../mongoBench'); const os = require('node:os'); -const util = require('node:util'); const process = require('node:process'); const Runner = MongoBench.Runner; @@ -11,18 +10,8 @@ let bsonType = 'js-bson'; // TODO(NODE-4606): test against different driver configurations in CI const { writeFile } = require('fs/promises'); -const { - makeParallelBenchmarks /* makeSingleBench, makeMultiBench */ -} = require('../mongoBench/suites'); -const { - MONGODB_CLIENT_OPTIONS, - MONGODB_DRIVER_PATH, - MONGODB_DRIVER_VERSION, - MONGODB_DRIVER_REVISION, - MONGODB_BSON_PATH, - MONGODB_BSON_VERSION, - MONGODB_BSON_REVISION -} = require('./common'); +const { makeParallelBenchmarks, makeSingleBench, makeMultiBench } = require('../mongoBench/suites'); +const { MONGODB_CLIENT_OPTIONS } = require('./common'); const hw = os.cpus(); const ram = os.totalmem() / 1024 ** 3; @@ -35,10 +24,7 @@ const systemInfo = () => `- arch: ${os.arch()}`, `- os: ${process.platform} (${os.release()})`, `- ram: ${platform.ram}`, - `- node: ${process.version}`, - `- driver: ${MONGODB_DRIVER_VERSION} (${MONGODB_DRIVER_REVISION}): ${MONGODB_DRIVER_PATH}`, - ` - options ${util.inspect(MONGODB_CLIENT_OPTIONS)}`, - `- bson: ${MONGODB_BSON_VERSION} (${MONGODB_BSON_REVISION}): (${MONGODB_BSON_PATH})\n` + `- node: ${process.version}\n` ].join('\n'); console.log(systemInfo()); @@ -47,19 +33,23 @@ function average(arr) { } const benchmarkRunner = new Runner() - // .suite('singleBench', suite => makeSingleBench(suite)) - // .suite('multiBench', suite => makeMultiBench(suite)) + .suite('singleBench', suite => makeSingleBench(suite)) + .suite('multiBench', suite => makeMultiBench(suite)) .suite('parallel', suite => makeParallelBenchmarks(suite)); benchmarkRunner .run() .then(microBench => { - // const singleBench = average([ - // microBench.singleBench.findOne, - // microBench.singleBench.smallDocInsertOne, - // microBench.singleBench.largeDocInsertOne - // ]); - // const multiBench = average(Object.values(microBench.multiBench)); + const singleBench = average([ + microBench.singleBench.findOne, + microBench.singleBench.smallDocInsertOne, + microBench.singleBench.largeDocInsertOne + ]); + const multiBench = average(Object.values(microBench.multiBench)); + + // ldjsonMultiFileUpload and ldjsonMultiFileExport cause connection errors. + // While we investigate, we will use the last known good values: + // https://spruce.mongodb.com/task/mongo_node_driver_next_performance_tests_run_spec_benchmark_tests_node_server_4bc3e500b6f0e8ab01f052c4a1bfb782d6a29b4e_f168e1328f821bbda265e024cc91ae54_24_11_18_15_37_24/logs?execution=0 const parallelBench = average([ microBench.parallel.ldjsonMultiFileUpload, @@ -69,18 +59,18 @@ benchmarkRunner ]); const readBench = average([ - // microBench.singleBench.findOne, - // microBench.multiBench.findManyAndEmptyCursor, - // microBench.multiBench.gridFsDownload, + microBench.singleBench.findOne, + microBench.multiBench.findManyAndEmptyCursor, + microBench.multiBench.gridFsDownload, microBench.parallel.gridfsMultiFileDownload, microBench.parallel.ldjsonMultiFileExport ]); const writeBench = average([ - // microBench.singleBench.smallDocInsertOne, - // microBench.singleBench.largeDocInsertOne, - // microBench.multiBench.smallDocBulkInsert, - // microBench.multiBench.largeDocBulkInsert, - // microBench.multiBench.gridFsUpload, + microBench.singleBench.smallDocInsertOne, + microBench.singleBench.largeDocInsertOne, + microBench.multiBench.smallDocBulkInsert, + microBench.multiBench.largeDocBulkInsert, + microBench.multiBench.gridFsUpload, microBench.parallel.ldjsonMultiFileUpload, microBench.parallel.gridfsMultiFileUpload ]); @@ -88,8 +78,8 @@ benchmarkRunner const driverBench = average([readBench, writeBench]); const benchmarkResults = { - // singleBench, - // multiBench, + singleBench, + multiBench, parallelBench, readBench, writeBench, @@ -123,6 +113,6 @@ benchmarkRunner return writeFile('results.json', results); }) .catch(err => { - console.error('failure: ', err.name, err.message, err.stack); + console.error('failure: ', err.name, err.message); process.exit(1); }); From 679a05c8c4b4d8fa79c9c48d12c39aa92c2ae9b8 Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Wed, 27 Nov 2024 12:40:19 -0500 Subject: [PATCH 04/10] test: latest bson --- package-lock.json | 5 ++--- package.json | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index b4d5e414602..42a3f940c5a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "license": "Apache-2.0", "dependencies": { "@mongodb-js/saslprep": "^1.1.9", - "bson": "^6.10.0", + "bson": "github:mongodb/js-bson#main", "mongodb-connection-string-url": "^3.0.0" }, "devDependencies": { @@ -3662,8 +3662,7 @@ }, "node_modules/bson": { "version": "6.10.0", - "resolved": "https://registry.npmjs.org/bson/-/bson-6.10.0.tgz", - "integrity": "sha512-ROchNosXMJD2cbQGm84KoP7vOGPO6/bOAW0veMMbzhXLqoZptcaYRVLitwvuhwhjjpU1qP4YZRWLhgETdgqUQw==", + "resolved": "git+ssh://git@github.com/mongodb/js-bson.git#3ede13e4ff551785af3d459d62c854605fe8b154", "license": "Apache-2.0", "engines": { "node": ">=16.20.1" diff --git a/package.json b/package.json index dbfa1afc6f8..ce5bdd6713e 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ }, "dependencies": { "@mongodb-js/saslprep": "^1.1.9", - "bson": "^6.10.0", + "bson": "github:mongodb/js-bson#main", "mongodb-connection-string-url": "^3.0.0" }, "peerDependencies": { From c81f0fa4366bdfba0f6a6bcdd65456e23f306986 Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Wed, 27 Nov 2024 12:48:43 -0500 Subject: [PATCH 05/10] chore: fix how I test bson main --- .evergreen/install-dependencies.sh | 1 + package-lock.json | 5 +++-- package.json | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.evergreen/install-dependencies.sh b/.evergreen/install-dependencies.sh index ef56c295fb7..23c4410e59d 100644 --- a/.evergreen/install-dependencies.sh +++ b/.evergreen/install-dependencies.sh @@ -19,5 +19,6 @@ fi source $DRIVERS_TOOLS/.evergreen/install-node.sh npm install "${NPM_OPTIONS}" +npm install mongodb/js-bson#main source $DRIVERS_TOOLS/.evergreen/init-node-and-npm-env.sh diff --git a/package-lock.json b/package-lock.json index 42a3f940c5a..b4d5e414602 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "license": "Apache-2.0", "dependencies": { "@mongodb-js/saslprep": "^1.1.9", - "bson": "github:mongodb/js-bson#main", + "bson": "^6.10.0", "mongodb-connection-string-url": "^3.0.0" }, "devDependencies": { @@ -3662,7 +3662,8 @@ }, "node_modules/bson": { "version": "6.10.0", - "resolved": "git+ssh://git@github.com/mongodb/js-bson.git#3ede13e4ff551785af3d459d62c854605fe8b154", + "resolved": "https://registry.npmjs.org/bson/-/bson-6.10.0.tgz", + "integrity": "sha512-ROchNosXMJD2cbQGm84KoP7vOGPO6/bOAW0veMMbzhXLqoZptcaYRVLitwvuhwhjjpU1qP4YZRWLhgETdgqUQw==", "license": "Apache-2.0", "engines": { "node": ">=16.20.1" diff --git a/package.json b/package.json index ce5bdd6713e..dbfa1afc6f8 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ }, "dependencies": { "@mongodb-js/saslprep": "^1.1.9", - "bson": "github:mongodb/js-bson#main", + "bson": "^6.10.0", "mongodb-connection-string-url": "^3.0.0" }, "peerDependencies": { From e6409c77c4d7c8c1b3f1af1e005aff0f1351604f Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Tue, 3 Dec 2024 16:14:52 -0500 Subject: [PATCH 06/10] fix: bump bson --- .evergreen/install-dependencies.sh | 1 - package-lock.json | 8 ++++---- package.json | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/.evergreen/install-dependencies.sh b/.evergreen/install-dependencies.sh index 23c4410e59d..ef56c295fb7 100644 --- a/.evergreen/install-dependencies.sh +++ b/.evergreen/install-dependencies.sh @@ -19,6 +19,5 @@ fi source $DRIVERS_TOOLS/.evergreen/install-node.sh npm install "${NPM_OPTIONS}" -npm install mongodb/js-bson#main source $DRIVERS_TOOLS/.evergreen/init-node-and-npm-env.sh diff --git a/package-lock.json b/package-lock.json index b4d5e414602..cc1128f0704 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "license": "Apache-2.0", "dependencies": { "@mongodb-js/saslprep": "^1.1.9", - "bson": "^6.10.0", + "bson": "^6.10.1", "mongodb-connection-string-url": "^3.0.0" }, "devDependencies": { @@ -3661,9 +3661,9 @@ } }, "node_modules/bson": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/bson/-/bson-6.10.0.tgz", - "integrity": "sha512-ROchNosXMJD2cbQGm84KoP7vOGPO6/bOAW0veMMbzhXLqoZptcaYRVLitwvuhwhjjpU1qP4YZRWLhgETdgqUQw==", + "version": "6.10.1", + "resolved": "https://registry.npmjs.org/bson/-/bson-6.10.1.tgz", + "integrity": "sha512-P92xmHDQjSKPLHqFxefqMxASNq/aWJMEZugpCjf+AF/pgcUpMMQCg7t7+ewko0/u8AapvF3luf/FoehddEK+sA==", "license": "Apache-2.0", "engines": { "node": ">=16.20.1" diff --git a/package.json b/package.json index dbfa1afc6f8..b15eb562eaa 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ }, "dependencies": { "@mongodb-js/saslprep": "^1.1.9", - "bson": "^6.10.0", + "bson": "^6.10.1", "mongodb-connection-string-url": "^3.0.0" }, "peerDependencies": { From ef7ef02d31585ebe09cc0c9e60d2c317b8107764 Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Wed, 4 Dec 2024 10:27:28 -0500 Subject: [PATCH 07/10] chore: undo src changes --- src/cmap/connect.ts | 67 +++++++++++++++++++++++---------------------- 1 file changed, 34 insertions(+), 33 deletions(-) diff --git a/src/cmap/connect.ts b/src/cmap/connect.ts index 9efe2461070..938b524e082 100644 --- a/src/cmap/connect.ts +++ b/src/cmap/connect.ts @@ -386,35 +386,15 @@ export async function makeSocket(options: MakeConnectionOptions): Promise resolve(socket)) - .once('error', cause => - reject(new MongoNetworkError(MongoError.buildErrorMessage(cause), { cause })) - ) - .once('timeout', () => { - reject( - new MongoNetworkTimeoutError( - `Socket '${connectEvent}' timed out after ${(performance.now() - start) | 0}ms (connectTimeoutMS: ${connectTimeoutMS})` - ) - ); - }) - .once('close', () => - reject( - new MongoNetworkError( - `Socket closed after ${(performance.now() - start) | 0} during connection establishment` - ) - ) - ); + .once('error', error => reject(connectionFailureError('error', error))) + .once('timeout', () => reject(connectionFailureError('timeout'))) + .once('close', () => reject(connectionFailureError('close'))); if (options.cancellationToken != null) { - cancellationHandler = () => - reject( - new MongoNetworkError( - `Socket connection establishment was cancelled after ${(performance.now() - start) | 0}` - ) - ); + cancellationHandler = () => reject(connectionFailureError('cancel')); options.cancellationToken.once('cancel', cancellationHandler); } } @@ -467,11 +447,9 @@ async function makeSocks5Connection(options: MakeConnectionOptions): Promise Date: Wed, 4 Dec 2024 15:02:32 -0500 Subject: [PATCH 08/10] chore: add readme and prints --- test/benchmarks/driverBench/index.js | 16 +++++++++-- test/readme.md | 42 ++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/test/benchmarks/driverBench/index.js b/test/benchmarks/driverBench/index.js index 34e10206a4b..8bdc35c7f8d 100644 --- a/test/benchmarks/driverBench/index.js +++ b/test/benchmarks/driverBench/index.js @@ -2,6 +2,7 @@ const MongoBench = require('../mongoBench'); const os = require('node:os'); +const util = require('node:util'); const process = require('node:process'); const Runner = MongoBench.Runner; @@ -11,7 +12,15 @@ let bsonType = 'js-bson'; const { writeFile } = require('fs/promises'); const { makeParallelBenchmarks, makeSingleBench, makeMultiBench } = require('../mongoBench/suites'); -const { MONGODB_CLIENT_OPTIONS } = require('./common'); +const { + MONGODB_CLIENT_OPTIONS, + MONGODB_DRIVER_PATH, + MONGODB_DRIVER_VERSION, + MONGODB_DRIVER_REVISION, + MONGODB_BSON_PATH, + MONGODB_BSON_VERSION, + MONGODB_BSON_REVISION +} = require('./common'); const hw = os.cpus(); const ram = os.totalmem() / 1024 ** 3; @@ -24,7 +33,10 @@ const systemInfo = () => `- arch: ${os.arch()}`, `- os: ${process.platform} (${os.release()})`, `- ram: ${platform.ram}`, - `- node: ${process.version}\n` + `- node: ${process.version}`, + `- driver: ${MONGODB_DRIVER_VERSION} (${MONGODB_DRIVER_REVISION}): ${MONGODB_DRIVER_PATH}`, + ` - options ${util.inspect(MONGODB_CLIENT_OPTIONS)}`, + `- bson: ${MONGODB_BSON_VERSION} (${MONGODB_BSON_REVISION}): (${MONGODB_BSON_PATH})\n` ].join('\n'); console.log(systemInfo()); diff --git a/test/readme.md b/test/readme.md index deae82a2deb..62a20448f58 100644 --- a/test/readme.md +++ b/test/readme.md @@ -241,6 +241,48 @@ beforeEach(() => { }); ``` +## Running Benchmarks + +Refer to the `run-spec-benchmark-tests-node-server` task for Node.js version, MongoDB server version, and platform that we run benchmarks against in CI. + +The server is run in standalone mode and the server versions are aliased by this script: https://github.com/mongodb-labs/drivers-evergreen-tools/blob/5048cca80e9ca62642409de2d401058bbd7057fa/.evergreen/mongodl.py#L58 check the latest version to see what alias the driver is running against. + +The host used is described here: https://spruce.mongodb.com/distro/rhel90-dbx-perf-large/settings/general (Auth required to view) + +It is best to try reproductions against as similar a deployment as possible to isolate regressions. + +### Configuration + +The benchmarks can be directed to test different settings and driver versions. + +The following are environment variables and how the benchmark runner uses them: + +- `MONGODB_DRIVER_PATH` - if set MUST be set to the directory a driver version is in, usually another clone of the driver checked out to a different revision. +- `MONGODB_CLIENT_OPTIONS` - if set MUST be a JSON string that will be parsed and passed as the second argument to the MongoClient constructor. +- `MONGODB_URI` - if set MUST be a valid MongoDB connection string and it will be used as the host the benchmarks will run against. + +It may be desirable to test how changes to `BSON` impact the driver's performance. + +To do this: +- clone the changed version of BSON + - run the build script for that repo (usually done by `npm install` for you) +- run `npm link` +- over in the driver repo run `npm link bson` + +When you run the benchmarks verify that the BSON version has been picked by the version references that are printed out: + +```md +- cpu: Apple M1 Max +- cores: 10 +- arch: arm64 +- os: darwin (23.6.0) +- ram: 32GB +- node: v22.6.0 +- driver: 6.11.0 (df3ea32a9): .../mongodb + - options {} +- bson: 6.10.1 (installed from npm): (.../mongodb/node_modules/bson) +``` + ## Testing with Special Environments In order to test some features, you will need to generate and set a specialized group of environment variables. The subsections below will walk you through how to generate and set the environment variables for these features. From 545665ba297356e8bd272aaa4007fa5e6dfaabe5 Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Wed, 4 Dec 2024 15:06:10 -0500 Subject: [PATCH 09/10] chore: add command --- test/readme.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/readme.md b/test/readme.md index 62a20448f58..9b288c6b9f5 100644 --- a/test/readme.md +++ b/test/readme.md @@ -243,6 +243,10 @@ beforeEach(() => { ## Running Benchmarks +```sh +npm run check:bench +``` + Refer to the `run-spec-benchmark-tests-node-server` task for Node.js version, MongoDB server version, and platform that we run benchmarks against in CI. The server is run in standalone mode and the server versions are aliased by this script: https://github.com/mongodb-labs/drivers-evergreen-tools/blob/5048cca80e9ca62642409de2d401058bbd7057fa/.evergreen/mongodl.py#L58 check the latest version to see what alias the driver is running against. From b383cc8c015c363a30fbf2b581318caa9baff606 Mon Sep 17 00:00:00 2001 From: Neal Beeken Date: Wed, 4 Dec 2024 16:14:48 -0500 Subject: [PATCH 10/10] chore: add defaults and host description --- test/readme.md | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/test/readme.md b/test/readme.md index 9b288c6b9f5..bce66e7c070 100644 --- a/test/readme.md +++ b/test/readme.md @@ -251,7 +251,15 @@ Refer to the `run-spec-benchmark-tests-node-server` task for Node.js version, Mo The server is run in standalone mode and the server versions are aliased by this script: https://github.com/mongodb-labs/drivers-evergreen-tools/blob/5048cca80e9ca62642409de2d401058bbd7057fa/.evergreen/mongodl.py#L58 check the latest version to see what alias the driver is running against. -The host used is described here: https://spruce.mongodb.com/distro/rhel90-dbx-perf-large/settings/general (Auth required to view) +The host used is described in detail here: https://spruce.mongodb.com/distro/rhel90-dbx-perf-large/settings/general (Auth required to view) + +Here is a rough list of the key configurations: + +- cpu: Intel(R) Xeon(R) Platinum 8259CL CPU @ 2.50GHz +- cores: 16 +- arch: x64 +- os: RHEL 9.0 linux (5.14.0-70.75.1.el9_0.x86_64) +- ram: 64 GB It is best to try reproductions against as similar a deployment as possible to isolate regressions. @@ -261,9 +269,9 @@ The benchmarks can be directed to test different settings and driver versions. The following are environment variables and how the benchmark runner uses them: -- `MONGODB_DRIVER_PATH` - if set MUST be set to the directory a driver version is in, usually another clone of the driver checked out to a different revision. -- `MONGODB_CLIENT_OPTIONS` - if set MUST be a JSON string that will be parsed and passed as the second argument to the MongoClient constructor. -- `MONGODB_URI` - if set MUST be a valid MongoDB connection string and it will be used as the host the benchmarks will run against. +- `MONGODB_DRIVER_PATH` - (default: current working driver) if set MUST be set to the directory a driver version is in, usually another clone of the driver checked out to a different revision. +- `MONGODB_CLIENT_OPTIONS` - (default: empty object) if set MUST be a JSON string that will be parsed and passed as the second argument to the MongoClient constructor. +- `MONGODB_URI` - (default: `mongodb://127.0.0.1:27017`) if set MUST be a valid MongoDB connection string and it will be used as the host the benchmarks will run against. It may be desirable to test how changes to `BSON` impact the driver's performance.