-
Couldn't load subscription status.
- Fork 240
feat(compass-collection): Collection Plugin Experimentation Assignment Integration – CLOUDP-333845 #7165
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
feat(compass-collection): Collection Plugin Experimentation Assignment Integration – CLOUDP-333845 #7165
Changes from 3 commits
e0d6e74
57c2bb5
1a32e51
4a75007
29ce148
41957c6
66413a0
a16f2c9
73a6ea8
36817d3
b725084
97a3614
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,6 +9,13 @@ import reducer, { | |
| import type { Collection } from '@mongodb-js/compass-app-stores/provider'; | ||
| import type { ActivateHelpers } from '@mongodb-js/compass-app-registry'; | ||
| import type { workspacesServiceLocator } from '@mongodb-js/compass-workspaces/provider'; | ||
| import type { experimentationServiceLocator } from '@mongodb-js/compass-telemetry'; | ||
| import type { connectionInfoRefLocator } from '@mongodb-js/compass-connections/provider'; | ||
| import type { Logger } from '@mongodb-js/compass-logging/provider'; | ||
| import { | ||
| isAIFeatureEnabled, | ||
| type PreferencesAccess, | ||
| } from 'compass-preferences-model/provider'; | ||
|
|
||
| export type CollectionTabOptions = { | ||
| /** | ||
|
|
@@ -31,18 +38,29 @@ export type CollectionTabServices = { | |
| collection: Collection; | ||
| localAppRegistry: AppRegistry; | ||
| workspaces: ReturnType<typeof workspacesServiceLocator>; | ||
| experimentationServices: ReturnType<typeof experimentationServiceLocator>; | ||
| connectionInfoRef: ReturnType<typeof connectionInfoRefLocator>; | ||
| logger: Logger; | ||
| preferences: PreferencesAccess; | ||
| }; | ||
|
|
||
| export function activatePlugin( | ||
| { namespace, editViewName, tabId }: CollectionTabOptions, | ||
| services: CollectionTabServices, | ||
| { on, cleanup }: ActivateHelpers | ||
| ) { | ||
| ): { | ||
| store: ReturnType<typeof createStore>; | ||
| deactivate: () => void; | ||
| } { | ||
| const { | ||
| dataService, | ||
| collection: collectionModel, | ||
| localAppRegistry, | ||
| workspaces, | ||
| experimentationServices, | ||
| connectionInfoRef, | ||
| logger, | ||
| preferences, | ||
| } = services; | ||
|
|
||
| if (!collectionModel) { | ||
|
|
@@ -64,6 +82,7 @@ export function activatePlugin( | |
| dataService, | ||
| workspaces, | ||
| localAppRegistry, | ||
| experimentationServices, | ||
| }) | ||
| ) | ||
| ); | ||
|
|
@@ -86,6 +105,28 @@ export function activatePlugin( | |
|
|
||
| void collectionModel.fetchMetadata({ dataService }).then((metadata) => { | ||
| store.dispatch(collectionMetadataFetched(metadata)); | ||
|
|
||
| // Assign experiment for Mock Data Generator: | ||
| // Only assign when experimentationServices.assignExperiment is initialized, | ||
| // we're connected to Atlas, | ||
| // and the org-level setting for AI features is enabled | ||
| if ( | ||
| experimentationServices?.assignExperiment && // Ensures experimentation services are available | ||
| connectionInfoRef.current?.atlasMetadata?.clusterName && // Ensures we only assign in Atlas | ||
|
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 might want to check the 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. Thanks for the suggestion! I looked at the Seems like other checks for Atlas in the codebase just check for 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. But maybe we drop the clusterName check to match other patterns? 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. Got it! Up to you then! 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. You can't connect to clusters and get to this screen if clusters are not in connectable states, there's no reason to check for specific states here |
||
| isAIFeatureEnabled(preferences.getPreferences()) // Ensures org-level AI features setting is enabled | ||
| ) { | ||
| void experimentationServices | ||
| .assignExperiment('mock-data-generator', { | ||
| team: 'Atlas Growth', | ||
| }) | ||
| .catch((error) => { | ||
| logger.debug('Mock Data Generator experiment assignment failed', { | ||
| experiment: 'MOCK_DATA_GENERATOR', | ||
| namespace: namespace, | ||
| error: error.message, | ||
| }); | ||
| }); | ||
| } | ||
| }); | ||
|
|
||
| return { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,3 +7,4 @@ export type { | |
| } from './types'; | ||
|
|
||
| export { CompassExperimentationProvider } from './experimentation-provider'; | ||
| export { experimentationServiceLocator } from './provider'; | ||
|
Comment on lines
9
to
+10
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 should be exported from the /provider named export, not from the index 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. @jcobis as I mentioned above, locators and hooks shouldn't be exported from the index export, only from provider, please remove this export 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. Sorry I missed this somehow! Removed it here |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,11 @@ | ||
| import React, { useRef } from 'react'; | ||
| import React, { useRef, useContext } from 'react'; | ||
| import { createServiceLocator } from '@mongodb-js/compass-app-registry'; | ||
| import { createTrack, type TelemetryServiceOptions } from './generic-track'; | ||
| import { useLogger } from '@mongodb-js/compass-logging/provider'; | ||
| import type { TrackFunction } from './types'; | ||
| import { TestName } from './growth-experiments'; | ||
| import { ExperimentationContext } from './experimentation-provider'; | ||
| import type { types } from '@mongodb-js/mdb-experiment-js'; | ||
|
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. Really just a small note and not a request for changes in this PR, but when I've seen packages which have exports with highly generic names, they are typically being accessed through a generic import; e.g. import type * as exp from '@mongodb-js/mdb-experiment-js';
// ...
Promise<exp.types.AsyncStatus | null>not a big deal but in larger files this can keep one from jiggling around many unrelated concepts in the single "global namespace" of a given file, obviously for this one this is totally fine |
||
|
|
||
| const noop = () => { | ||
| // noop | ||
|
|
@@ -47,6 +49,20 @@ export function useTelemetry(): TrackFunction { | |
| return track; | ||
| } | ||
|
|
||
| // Service locator for experimentation services (non-component access) | ||
| export const experimentationServiceLocator = createServiceLocator( | ||
| function useExperimentationServices(): { | ||
| assignExperiment: ( | ||
| experimentName: string, | ||
| options?: types.AssignOptions<string> | ||
| ) => Promise<types.AsyncStatus | null>; | ||
| } { | ||
| const { assignExperiment } = useContext(ExperimentationContext); | ||
| return { assignExperiment }; | ||
| }, | ||
| 'experimentationServiceLocator' | ||
| ); | ||
|
|
||
| type FirstArgument<F> = F extends (...args: [infer A, ...any]) => any | ||
| ? A | ||
| : F extends { new (...args: [infer A, ...any]): any } | ||
|
|
||
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.
As you are providing default context value, in what case are they not available?