Skip to content

Commit 626c999

Browse files
committed
chore(data-service, connections): make sure that instance info is only fetched once on initial connection
1 parent 79a6f24 commit 626c999

File tree

3 files changed

+116
-77
lines changed

3 files changed

+116
-77
lines changed

packages/compass-app-stores/src/stores/instance-store.ts

Lines changed: 62 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type { MongoDBInstanceProps } from 'mongodb-instance-model';
22
import { MongoDBInstance } from 'mongodb-instance-model';
33
import toNS from 'mongodb-ns';
44
import type {
5+
ConnectionInfo,
56
ConnectionsService,
67
DataService,
78
} from '@mongodb-js/compass-connections/provider';
@@ -14,6 +15,8 @@ import { openToast } from '@mongodb-js/compass-components';
1415
import { MongoDBInstancesManager } from '../instances-manager';
1516
import type { PreferencesAccess } from 'compass-preferences-model';
1617

18+
type InstanceDetails = Awaited<ReturnType<DataService['instance']>>;
19+
1720
function serversArray(
1821
serversMap: NonNullable<
1922
ReturnType<DataService['getLastSeenTopology']>
@@ -305,55 +308,68 @@ export function createInstancesStore(
305308
instancesManager.removeMongoDBInstanceForConnection(connectionInfoId);
306309
});
307310

308-
on(connections, 'connected', function (instanceConnectionId: string) {
309-
const dataService =
310-
connections.getDataServiceForConnection(instanceConnectionId);
311-
const connectionString = dataService.getConnectionString();
312-
const firstHost = connectionString.hosts[0] || '';
313-
const [hostname, port] = firstHost.split(':');
314-
315-
const initialInstanceProps: Partial<MongoDBInstanceProps> = {
316-
_id: firstHost,
317-
hostname: hostname,
318-
port: port ? +port : undefined,
319-
topologyDescription: getTopologyDescription(
320-
dataService.getLastSeenTopology()
321-
),
322-
preferences,
323-
};
324-
const instance = instancesManager.createMongoDBInstanceForConnection(
325-
instanceConnectionId,
326-
initialInstanceProps as MongoDBInstanceProps
327-
);
311+
on(
312+
connections,
313+
'connected',
314+
function (
315+
instanceConnectionId: string,
316+
_connectionInfo: ConnectionInfo,
317+
instanceInfo: InstanceDetails
318+
) {
319+
const dataService =
320+
connections.getDataServiceForConnection(instanceConnectionId);
321+
const connectionString = dataService.getConnectionString();
322+
const firstHost = connectionString.hosts[0] || '';
323+
const [hostname, port] = firstHost.split(':');
324+
325+
const initialInstanceProps: Partial<MongoDBInstanceProps> = {
326+
_id: firstHost,
327+
hostname: hostname,
328+
port: port ? +port : undefined,
329+
topologyDescription: getTopologyDescription(
330+
dataService.getLastSeenTopology()
331+
),
332+
preferences,
333+
};
334+
const instance = instancesManager.createMongoDBInstanceForConnection(
335+
instanceConnectionId,
336+
initialInstanceProps as MongoDBInstanceProps
337+
);
338+
instance.set({
339+
status: 'ready',
340+
statusError: null,
341+
...(instanceInfo as Partial<MongoDBInstanceProps>),
342+
});
328343

329-
addCleanup(() => {
330-
instance.removeAllListeners();
331-
});
344+
addCleanup(() => {
345+
instance.removeAllListeners();
346+
});
332347

333-
void refreshInstance(
334-
{
335-
fetchDatabases: true,
336-
fetchDbStats: true,
337-
},
338-
{
339-
connectionId: instanceConnectionId,
340-
}
341-
);
348+
void refreshInstance(
349+
{
350+
fetchDatabases: true,
351+
fetchDbStats: true,
352+
},
353+
{
354+
connectionId: instanceConnectionId,
355+
}
356+
);
342357

343-
on(
344-
dataService,
345-
'topologyDescriptionChanged',
346-
({
347-
newDescription,
348-
}: {
349-
newDescription: ReturnType<DataService['getLastSeenTopology']>;
350-
}) => {
351-
instance.set({
352-
topologyDescription: getTopologyDescription(newDescription),
353-
});
354-
}
355-
);
356-
});
358+
on(
359+
dataService,
360+
'topologyDescriptionChanged',
361+
({
362+
newDescription,
363+
}: {
364+
newDescription: ReturnType<DataService['getLastSeenTopology']>;
365+
}) => {
366+
instance.set({
367+
topologyDescription: getTopologyDescription(newDescription),
368+
});
369+
}
370+
);
371+
}
372+
);
357373

358374
on(
359375
globalAppRegistry,

packages/compass-connections/src/stores/connections-store-redux.ts

Lines changed: 46 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import type {
1616
ConnectionAttempt,
1717
ConnectionOptions,
1818
DataService,
19+
InstanceDetails,
1920
} from 'mongodb-data-service';
2021
import { createConnectionAttempt } from 'mongodb-data-service';
2122
import { UUID } from 'bson';
@@ -42,7 +43,8 @@ import {
4243
export type ConnectionsEventMap = {
4344
connected: (
4445
connectionId: ConnectionId,
45-
connectionInfo: ConnectionInfo
46+
connectionInfo: ConnectionInfo,
47+
instanceInfo: InstanceDetails
4648
) => void;
4749
disconnected: (
4850
connectionId: ConnectionId,
@@ -1657,6 +1659,14 @@ const connectWithOptions = (
16571659
return;
16581660
}
16591661

1662+
// We're trying to optimise the initial Compass loading times here: to
1663+
// make sure that the driver connection pool doesn't immediately get
1664+
// overwhelmed with requests, we fetch instance info only once and then
1665+
// pass it down to telemetry and instance model. This is a relatively
1666+
// expensive dataService operation so we're trying to keep the usage
1667+
// very limited
1668+
const instanceInfo = await dataService.instance();
1669+
16601670
let showedNonRetryableErrorToast = false;
16611671
// Listen for non-retry-able errors on failed server heartbeats.
16621672
// These can happen on compass web when:
@@ -1765,7 +1775,7 @@ const connectWithOptions = (
17651775
{ dataLake, genuineMongoDB, host, build, isAtlas, isLocalAtlas },
17661776
[extraInfo, resolvedHostname],
17671777
] = await Promise.all([
1768-
dataService.instance(),
1778+
instanceInfo,
17691779
getExtraConnectionData(connectionInfo),
17701780
]);
17711781

@@ -1810,44 +1820,29 @@ const connectWithOptions = (
18101820
connectionsEventEmitter.emit(
18111821
'connected',
18121822
connectionInfo.id,
1813-
connectionInfo
1823+
connectionInfo,
1824+
instanceInfo
18141825
);
18151826

18161827
dispatch({
18171828
type: ActionTypes.ConnectionAttemptSuccess,
18181829
connectionId: connectionInfo.id,
18191830
});
18201831

1821-
const { networkTraffic, showEndOfLifeConnectionModal } =
1822-
preferences.getPreferences();
1832+
const { showEndOfLifeConnectionModal } = preferences.getPreferences();
18231833

18241834
if (
18251835
getGenuineMongoDB(connectionInfo.connectionOptions.connectionString)
18261836
.isGenuine === false
18271837
) {
18281838
dispatch(showNonGenuineMongoDBWarningModal(connectionInfo.id));
18291839
} else if (showEndOfLifeConnectionModal) {
1830-
void dataService
1831-
.instance()
1832-
.then(async (instance) => {
1833-
const { version } = instance.build;
1834-
const latestEndOfLifeServerVersion =
1835-
await getLatestEndOfLifeServerVersion(networkTraffic);
1836-
if (isEndOfLifeVersion(version, latestEndOfLifeServerVersion)) {
1837-
dispatch(
1838-
showEndOfLifeMongoDBWarningModal(
1839-
connectionInfo.id,
1840-
instance.build.version
1841-
)
1842-
);
1843-
}
1844-
})
1845-
.catch((err) => {
1846-
debug(
1847-
'failed to get instance details to determine if the server version is end-of-life',
1848-
err
1849-
);
1850-
});
1840+
void dispatch(
1841+
showEndOfLifeMongoDBWarningModal(
1842+
connectionInfo.id,
1843+
instanceInfo.build.version
1844+
)
1845+
);
18511846
}
18521847
} catch (err) {
18531848
dispatch(connectionAttemptError(connectionInfo, err));
@@ -2175,11 +2170,31 @@ export const showNonGenuineMongoDBWarningModal = (
21752170
export const showEndOfLifeMongoDBWarningModal = (
21762171
connectionId: string,
21772172
version: string
2178-
): ConnectionsThunkAction<void> => {
2179-
return (_dispatch, getState, { track }) => {
2180-
const connectionInfo = getCurrentConnectionInfo(getState(), connectionId);
2181-
track('Screen', { name: 'end_of_life_mongodb_modal' }, connectionInfo);
2182-
void _showEndOfLifeMongoDBWarningModal(connectionInfo, version);
2173+
): ConnectionsThunkAction<Promise<void>> => {
2174+
return async (
2175+
_dispatch,
2176+
getState,
2177+
{ track, logger: { debug }, preferences }
2178+
) => {
2179+
try {
2180+
const latestEndOfLifeServerVersion =
2181+
await getLatestEndOfLifeServerVersion(
2182+
preferences.getPreferences().networkTraffic
2183+
);
2184+
if (isEndOfLifeVersion(version, latestEndOfLifeServerVersion)) {
2185+
const connectionInfo = getCurrentConnectionInfo(
2186+
getState(),
2187+
connectionId
2188+
);
2189+
track('Screen', { name: 'end_of_life_mongodb_modal' }, connectionInfo);
2190+
void _showEndOfLifeMongoDBWarningModal(connectionInfo, version);
2191+
}
2192+
} catch (err) {
2193+
debug(
2194+
'failed to get instance details to determine if the server version is end-of-life',
2195+
err
2196+
);
2197+
}
21832198
};
21842199
};
21852200

packages/data-service/src/data-service.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,8 @@ export interface DataService {
310310

311311
/**
312312
* Get the current instance details.
313+
*
314+
* @deprecated avoid using `instance` directly and use `InstanceModel` instead
313315
*/
314316
instance(): Promise<InstanceDetails>;
315317

@@ -340,6 +342,9 @@ export interface DataService {
340342

341343
/**
342344
* List all collections for a database.
345+
*
346+
* @deprecated avoid using `listCollections` directly and use
347+
* `CollectionModel` instead
343348
*/
344349
listCollections(
345350
databaseName: string,
@@ -448,6 +453,9 @@ export interface DataService {
448453

449454
/**
450455
* List all databases on the currently connected instance.
456+
*
457+
* @deprecated avoid using `listDatabases` directly and use `DatabaseModel`
458+
* instead
451459
*/
452460
listDatabases(options?: {
453461
nameOnly?: true;

0 commit comments

Comments
 (0)