-
Notifications
You must be signed in to change notification settings - Fork 247
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 10 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,14 @@ 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'; | ||
| import { TestName } from '@mongodb-js/compass-telemetry/provider'; | ||
|
|
||
| export type CollectionTabOptions = { | ||
| /** | ||
|
|
@@ -31,18 +39,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 +83,7 @@ export function activatePlugin( | |
| dataService, | ||
| workspaces, | ||
| localAppRegistry, | ||
| experimentationServices, | ||
| }) | ||
| ) | ||
| ); | ||
|
|
@@ -86,6 +106,25 @@ export function activatePlugin( | |
|
|
||
| void collectionModel.fetchMetadata({ dataService }).then((metadata) => { | ||
| store.dispatch(collectionMetadataFetched(metadata)); | ||
|
|
||
| // Assign experiment for Mock Data Generator | ||
| // Only assign when we're connected to Atlas and the org-level setting for AI features is enabled | ||
| if ( | ||
| connectionInfoRef.current?.atlasMetadata?.clusterName && // Ensures we only assign in Atlas | ||
|
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. We might want to check the
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. Thanks for the suggestion! I looked at the Seems like other checks for Atlas in the codebase just check for
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. But maybe we drop the clusterName check to match other patterns?
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. Got it! Up to you then!
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. 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(TestName.mockDataGenerator, { | ||
| team: 'Atlas Growth', | ||
| }) | ||
| .catch((error) => { | ||
| logger.debug('Mock Data Generator experiment assignment failed', { | ||
| experiment: TestName.mockDataGenerator, | ||
| namespace: namespace, | ||
| error: error instanceof Error ? error.message : String(error), | ||
| }); | ||
| }); | ||
| } | ||
| }); | ||
|
|
||
| return { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,4 @@ | ||
| export enum TestName { | ||
| earlyJourneyIndexesGuidance = 'EARLY_JOURNEY_INDEXES_GUIDANCE_20250328', | ||
| mockDataGenerator = 'MOCK_DATA_GENERATOR_20251001', | ||
| } |
| 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'; | ||
|
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. 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,22 @@ export function useTelemetry(): TrackFunction { | |
| return track; | ||
| } | ||
|
|
||
| export interface ExperimentationServices { | ||
| assignExperiment: ( | ||
| experimentName: TestName, | ||
| options?: types.AssignOptions<string> | ||
| ) => Promise<types.AsyncStatus | null>; | ||
| } | ||
|
|
||
| // Service locator for experimentation services (non-component access) | ||
| export const experimentationServiceLocator = createServiceLocator( | ||
| function useExperimentationServices(): ExperimentationServices { | ||
| 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.
TestName is a very generic name for this type, can we add experimentation to it to make it clearer what this refers to?