-
Notifications
You must be signed in to change notification settings - Fork 89
feat: update connectionString appName param - [MCP-68] #406
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Pull Request Test Coverage Report for Build 16673953200Details
💛 - Coveralls |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
} | ||
|
||
// Build the extended appName format: appName--deviceId--clientName | ||
const extendedAppName = `${components.appName}--${deviceId}--${clientName}`; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[q] what if components.appName
is empty? should it be unknown
like the others?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see the code we are getting packageInfo
stuff, should we not make it a parameter and get package info straight away?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the previous behaviour is that we would set it to appName:
${packageInfo.mcpServerName} ${packageInfo.version},
if it's not defined, so we always send it. I could move that logic here, is that what you mean with the packageInfo question?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how would appName be defined? is it really a parameter? is there an env var?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
components.appName
seems to be fixed as ${packageInfo.mcpServerName} ${packageInfo.version}
always
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR refactors telemetry device ID handling by extracting device ID generation logic into a centralized utility and extending the MongoDB connection string appName parameter format to include device ID and client name components.
- Centralizes device ID retrieval logic into a reusable helper utility
- Extends appName format from simple name to
appName--deviceId--clientName
structure - Updates telemetry and connection handling to use the new centralized approach
Reviewed Changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 1 comment.
Show a summary per file
File | Description |
---|---|
src/helpers/deviceId.ts | New centralized utility for device ID generation with error handling |
src/helpers/connectionOptions.ts | Enhanced appName parameter setting with extended format support |
src/common/session.ts | Updated to use extended appName format with client name |
src/telemetry/telemetry.ts | Refactored to use centralized device ID utility |
src/tools/atlas/connect/connectCluster.ts | Updated Atlas connection to use extended appName format |
tests/ | Comprehensive test coverage for new functionality |
Comments suppressed due to low confidence (2)
tests/unit/helpers/connectionOptions.test.ts:34
- The test comment mentions URL normalization but doesn't verify the exact appName value. Consider adding an assertion that explicitly checks the appName parameter value to ensure it remains 'ExistingApp' and hasn't been modified.
// The ConnectionString library normalizes URLs, so we need to check the content rather than exact equality
tests/unit/helpers/deviceId.test.ts:109
- This test uses fake timers but doesn't actually test timeout behavior since the mock immediately calls the onError callback. Consider creating a test that truly exercises the timeout mechanism by having the getDeviceId promise not resolve within the timeout period.
vi.useFakeTimers();
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
src/helpers/deviceId.ts
Outdated
*/ | ||
export async function getDeviceIdForConnection(): Promise<string> { | ||
const controller = new AbortController(); | ||
const timeoutId = setTimeout(() => controller.abort(), DEVICE_ID_TIMEOUT); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do we need timeout? getDeviceId
has a timeout builtin
}); | ||
|
||
it("should timeout if machine ID resolution takes too long", async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why are we removing the timeout test? I think it is useful to have
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
didn't remove, moved it to deviceId unit tests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah saw this now, nevermind, ty!
|
||
private constructor( | ||
private readonly session: Session, | ||
private readonly userConfig: UserConfig, | ||
private readonly commonProperties: CommonProperties, | ||
{ eventCache, getRawMachineId }: { eventCache: EventCache; getRawMachineId: () => Promise<string> } | ||
{ eventCache }: { eventCache: EventCache } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I think it'd still be good to pass getDeviceIdForConnection
for explicit DI. It also helps us avoid mocking the file which is a bit of JavaScript magic
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's important in my opinion to avoid double device ID resolution
} | ||
|
||
const deviceId = components.deviceId || (await getDeviceIdForConnection()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we shouldn't end up awaiting device ID a second time, can we organize it so this device ID gets passed from one point of entry and we never fallback to this function? deviceId
doesn't get passed in connectToMongoDB
right now.
if (!searchParams.has("appName") && defaultAppName !== undefined) { | ||
searchParams.set("appName", defaultAppName); | ||
// Only set appName if it's not already present | ||
if (searchParams.has("appName")) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In Compass / mongosh we only pass the device ID if it's an Atlas host to minimize visibility of this, can we also do this here?
Proposed changes
appName--deviceId--clientName
Checklist