-
Notifications
You must be signed in to change notification settings - Fork 246
chore(data-service, connections): make sure that instance info is only fetched once on initial connection COMPASS-9549 COMPASS-7675 #7089
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
Changes from all commits
626c999
d00eb2d
7ecdc82
a8f551c
980508f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Original file line | Diff line number | Diff line change |
|---|---|---|---|
|
|
@@ -16,6 +16,7 @@ import type { | ||
| ConnectionAttempt, | ConnectionAttempt, | ||
| ConnectionOptions, | ConnectionOptions, | ||
| DataService, | DataService, | ||
| InstanceDetails, | |||
| } from 'mongodb-data-service'; | } from 'mongodb-data-service'; | ||
| import { createConnectionAttempt } from 'mongodb-data-service'; | import { createConnectionAttempt } from 'mongodb-data-service'; | ||
| import { UUID } from 'bson'; | import { UUID } from 'bson'; | ||
|
|
@@ -43,7 +44,8 @@ import type { ImportConnectionOptions } from '@mongodb-js/connection-storage/pro | ||
| export type ConnectionsEventMap = { | export type ConnectionsEventMap = { | ||
| connected: ( | connected: ( | ||
| connectionId: ConnectionId, | connectionId: ConnectionId, | ||
| connectionInfo: ConnectionInfo | connectionInfo: ConnectionInfo, | ||
| instanceInfo: InstanceDetails | |||
| ) => void; | ) => void; | ||
| disconnected: ( | disconnected: ( | ||
| connectionId: ConnectionId, | connectionId: ConnectionId, | ||
|
|
@@ -1658,6 +1660,14 @@ const connectWithOptions = ( | ||
| return; | return; | ||
| } | } | ||
|
|
|
||
| // We're trying to optimise the initial Compass loading times here: to | |||
| // make sure that the driver connection pool doesn't immediately get | |||
| // overwhelmed with requests, we fetch instance info only once and then | |||
|
Comment on lines
+1663
to
+1665
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yea, in fact it doesn't really matter what we set our pool size to, browsers do not permit more than 6 parallel connections to be creating at the same time. It obviously matters for our total count in the long run, but at least at boot that's our bottleneck.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We still have multiplexing in the plans, right? Just wondering |
|||
| // pass it down to telemetry and instance model. This is a relatively | |||
| // expensive dataService operation so we're trying to keep the usage | |||
| // very limited | |||
| const instanceInfo = await dataService.instance(); | |||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is somewhat a breaking change in Compass behavior as described in COMPASS-7675 but I think it's probably okay to do so as we were already discussing doing this. Basically the main change in the behavior here is that some connection related errors that would show up in this weird state where you connected, but we didn't even manage to get to the listing database part of the logic before now will start showing up as part of the connection flow, this doesn't sound too bad to me, but I also asked Betsy to confirm in the ticket |
|||
|
|
|||
| let showedNonRetryableErrorToast = false; | let showedNonRetryableErrorToast = false; | ||
| // Listen for non-retry-able errors on failed server heartbeats. | // Listen for non-retry-able errors on failed server heartbeats. | ||
| // These can happen on compass web when: | // These can happen on compass web when: | ||
|
|
@@ -1762,13 +1772,17 @@ const connectWithOptions = ( | ||
| track( | track( | ||
| 'New Connection', | 'New Connection', | ||
| async () => { | async () => { | ||
| const [ | const { | ||
| { dataLake, genuineMongoDB, host, build, isAtlas, isLocalAtlas }, | dataLake, | ||
| [extraInfo, resolvedHostname], | genuineMongoDB, | ||
| ] = await Promise.all([ | host, | ||
| dataService.instance(), | build, | ||
| getExtraConnectionData(connectionInfo), | isAtlas, | ||
| ]); | isLocalAtlas, | ||
| } = instanceInfo; | |||
| const [extraInfo, resolvedHostname] = await getExtraConnectionData( | |||
| connectionInfo | |||
| ); | |||
|
|
|
||
| const connections = getState().connections; | const connections = getState().connections; | ||
| // Counting all connections, we need to filter out any connections currently being created | // Counting all connections, we need to filter out any connections currently being created | ||
|
|
@@ -1811,45 +1825,34 @@ const connectWithOptions = ( | ||
| connectionsEventEmitter.emit( | connectionsEventEmitter.emit( | ||
| 'connected', | 'connected', | ||
| connectionInfo.id, | connectionInfo.id, | ||
| connectionInfo | connectionInfo, | ||
| instanceInfo | |||
| ); | ); | ||
|
|
|
||
| dispatch({ | dispatch({ | ||
| type: ActionTypes.ConnectionAttemptSuccess, | type: ActionTypes.ConnectionAttemptSuccess, | ||
| connectionId: connectionInfo.id, | connectionId: connectionInfo.id, | ||
| }); | }); | ||
|
|
|
||
| const { networkTraffic, showEndOfLifeConnectionModal } = | |||
| preferences.getPreferences(); | |||
|
|
|||
| if ( | if ( | ||
| getGenuineMongoDB(connectionInfo.connectionOptions.connectionString) | getGenuineMongoDB(connectionInfo.connectionOptions.connectionString) | ||
| .isGenuine === false | .isGenuine === false | ||
| ) { | ) { | ||
| dispatch(showNonGenuineMongoDBWarningModal(connectionInfo.id)); | dispatch(showNonGenuineMongoDBWarningModal(connectionInfo.id)); | ||
| } else if (showEndOfLifeConnectionModal) { | } else if ( | ||
| void dataService | await shouldShowEndOfLifeWarning( | ||
| .instance() | instanceInfo.build.version, | ||
| .then(async (instance) => { | preferences, | ||
| const { version } = instance.build; | debug | ||
| const latestEndOfLifeServerVersion = | ) | ||
| await getLatestEndOfLifeServerVersion(networkTraffic); | ) { | ||
| if (isEndOfLifeVersion(version, latestEndOfLifeServerVersion)) { | |||
| dispatch( | dispatch( | ||
| showEndOfLifeMongoDBWarningModal( | showEndOfLifeMongoDBWarningModal( | ||
| connectionInfo.id, | connectionInfo.id, | ||
| instance.build.version | instanceInfo.build.version | ||
| ) | ) | ||
| ); | ); | ||
| } | } | ||
| }) | |||
| .catch((err) => { | |||
| debug( | |||
| 'failed to get instance details to determine if the server version is end-of-life', | |||
| err | |||
| ); | |||
| }); | |||
| } | |||
| } catch (err) { | } catch (err) { | ||
| dispatch(connectionAttemptError(connectionInfo, err)); | dispatch(connectionAttemptError(connectionInfo, err)); | ||
| } finally { | } finally { | ||
|
|
@@ -2173,6 +2176,30 @@ export const showNonGenuineMongoDBWarningModal = ( | ||
| }; | }; | ||
| }; | }; | ||
|
|
|
||
| async function shouldShowEndOfLifeWarning( | |||
| serverVersion: string, | |||
| preferences: PreferencesAccess, | |||
| debug: Logger['debug'] | |||
| ) { | |||
| try { | |||
| const { showEndOfLifeConnectionModal, networkTraffic } = | |||
| preferences.getPreferences(); | |||
| if (!showEndOfLifeConnectionModal) { | |||
| return; | |||
| } | |||
| const latestEndOfLifeServerVersion = await getLatestEndOfLifeServerVersion( | |||
| networkTraffic | |||
| ); | |||
| return isEndOfLifeVersion(serverVersion, latestEndOfLifeServerVersion); | |||
| } catch (err) { | |||
| debug( | |||
| 'failed to get instance details to determine if the server version is end-of-life', | |||
| err | |||
| ); | |||
| return false; | |||
| } | |||
| } | |||
|
|
|||
| export const showEndOfLifeMongoDBWarningModal = ( | export const showEndOfLifeMongoDBWarningModal = ( | ||
| connectionId: string, | connectionId: string, | ||
| version: string | version: string | ||
|
|
|||
| Original file line number | Original file line | Diff line number | Diff line change |
|---|---|---|---|
|
|
@@ -310,6 +310,8 @@ export interface DataService { | ||
|
|
|
||
| /** | /** | ||
| * Get the current instance details. | * Get the current instance details. | ||
| * | |||
| * @deprecated avoid using `instance` directly and use `InstanceModel` instead | |||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Literally everywhere except for those initial / inside models fetches we should be using models instead, so I'm adding this marking to make IDEs highlight the method usage |
|||
| */ | */ | ||
| instance(): Promise<InstanceDetails>; | instance(): Promise<InstanceDetails>; | ||
|
|
|
||
|
|
@@ -340,6 +342,9 @@ export interface DataService { | ||
|
|
|
||
| /** | /** | ||
| * List all collections for a database. | * List all collections for a database. | ||
| * | |||
| * @deprecated avoid using `listCollections` directly and use | |||
| * `CollectionModel` instead | |||
| */ | */ | ||
| listCollections( | listCollections( | ||
| databaseName: string, | databaseName: string, | ||
|
|
@@ -448,6 +453,9 @@ export interface DataService { | ||
|
|
|
||
| /** | /** | ||
| * List all databases on the currently connected instance. | * List all databases on the currently connected instance. | ||
| * | |||
| * @deprecated avoid using `listDatabases` directly and use `DatabaseModel` | |||
| * instead | |||
| */ | */ | ||
| listDatabases(options?: { | listDatabases(options?: { | ||
| nameOnly?: true; | nameOnly?: true; | ||
|
|
|||
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're now tacking on more positional arguments. Wouldn't one object where you can just pick what you want from it start to make more sense? Or do we have too many things using this and that would involve lots of changes? Or is there some other reason I can't immediately spot why we can't change it?
Uh oh!
There was an error while loading. Please reload this page.
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'll take a closer look at the usage, adding a positional was just the easiest for me, but generally speaking yes, we can probably pack it all into one object (also
instanceConnectionIdis justconnectionInfo.id, so I'll just drop it I think)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 went back and forth on this and decided not to change this, I started moving them to an object of properties, but then
disconnectevent is different and wanted to keep them consistent, but thenconnectionIdis like the only used argument indisconnectand having it inside an object was weird, so I was trying different combinations, like maybe keepingconnectionIdas an argument, but moving everything else into an object in a second argument, and this also didn't look right, then I thought I'm overthinking it and it was cleaner to just keep it as is. Hope that's okay