Skip to content

Conversation

baileympearson
Copy link
Contributor

@baileympearson baileympearson commented Oct 7, 2025

Description

Summary of Changes

This PR makes all metadata properties in the driver internal. Additionally, it removes some unnecessary properties (additionalDriverInfo, extendedMetadata) in favor of metadata.

I also took this opportunity to clean up the client metadata module. Specifically:

  • addContainerMetadata is now internal to the module and called by makeClientMetadata. The only reason we exported this function and called it separate from makeClientMetadata was that MongoClient.options.metadata was public, which meant that we could not change the type from ClientMetadata -> Promise<ClientMetadata>.
  • Now that interface ClientMetadata is internal, I updated it so that it matches the specification.
Notes for Reviewers

What is the motivation for this change?

Release Highlight

Internal ClientMetadata properties have been removed

Previous versions of the driver unintentionally made properties used when constructing client metadata public. These properties have now been made internal. The full list of properties is:

MongoClient.options.additionalDriverInfo
MongoClient.options.metadata
MongoClient.options.extendedMetadata
MongoOptions.additionalDriverInfo
MongoOptions.metadata
MongoOptions.extendedMetadata
ConnectionOptions.metadata
ConnectionOptions.extendedMetadata

Double check the following

  • Lint is passing (npm run check:lint)
  • Self-review completed using the steps outlined here
  • PR title follows the correct format: type(NODE-xxxx)[!]: description
    • Example: feat(NODE-1234)!: rewriting everything in coffeescript
  • Changes are covered by tests
  • New TODOs have a related JIRA ticket

Comment on lines 49 to 58
env?: {
name: 'aws.lambda' | 'gcp.func' | 'azure.func' | 'vercel';
name?: 'aws.lambda' | 'gcp.func' | 'azure.func' | 'vercel';
timeout_sec?: Int32;
memory_mb?: Int32;
region?: string;
url?: string;
container?: {
runtime?: string;
orchestrator?: string;
};
};
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes here align this interface with the specification.

if (typeof callback === 'function') callback(undefined, true);
}

get clientMetadata(): ClientMetadata {
Copy link
Contributor Author

@baileympearson baileympearson Oct 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Happy to put this back, although we'd have to change it to return a promise. This is dead code in src/, although I did find a few usages in tests (which I worked around by checking for the metadata on the options object instead).

// make metadata = 507 bytes, so it takes up entire LimitedSizeDocument
// make a metadata object that, with just the name and appName, is already at capacity.
const longAppName = 's'.repeat(493);
const metadata = makeClientMetadata(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes like this one in this file are a result of making addContainerMetadata internal to the client metadata module.

makeClientMetadata truncates the appname, so creating a long appName isn't sufficient to make the metadata exceed the handshake's max size anymore.


import {
type Collection,
type CommandFailedEvent,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two tests related to the appName in this file broke with the changes in this PR. I decided to just refactor this file to async-await while I was working in it.

writeConcern: { w: 1, wtimeoutMS: 1000, fsync: true, j: true },
readPreference: 'nearest',
readPreferenceTags: { loc: 'ny' },
readPreferenceTags: [{ loc: 'ny' }],
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

drive-by: this is the correct way to specify readpreferencetags

'Invalid scheme, expected connection string to start with "mongodb://" or "mongodb+srv://"'
);
}
it('Should fail due to wrong uri user:password@localhost', function () {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this test can run everywhere.


client.connect(function (err) {
expect(err).to.exist;
it('correctly error out when no socket available on MongoClient `connect`', async function () {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this test can run everywhere.

metadata: {
requires: {
topology: ['single']
it('Should correctly pass through socketTimeoutMS and connectTimeoutMS', async function () {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this test can run everywhere.

}
});
// TODO(NODE-7219): remove unnecessary test
// it('should open a new MongoClient connection', {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we have plenty of coverage for this test elsewhere

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I understand what's left for the TODO if this is intentionally commented out here – would it be about removing the comments?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To aid in reviewing the test refactors that Sergey and Pavel are doing, we've decided to comment out unnecessary tests instead of deleting them. Otherwise, the diff gets shifted and harder to read.

}
);
}
it('should error on unexpected options', async function () {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this test can run everywhere.

@baileympearson baileympearson marked this pull request as ready for review October 8, 2025 14:55
@baileympearson baileympearson requested a review from a team as a code owner October 8, 2025 14:55
@durran durran self-assigned this Oct 8, 2025
@durran durran added the Primary Review In Review with primary reviewer, not yet ready for team's eyes label Oct 8, 2025
}
});
// TODO(NODE-7219): remove unnecessary test
// it('should open a new MongoClient connection', {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure I understand what's left for the TODO if this is intentionally commented out here – would it be about removing the comments?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Primary Review In Review with primary reviewer, not yet ready for team's eyes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants