@@ -2,6 +2,7 @@ import type { Schema } from 'mongodb-schema';
22import { isInternalFieldPath } from 'hadron-document' ;
33import type { Action , Reducer } from 'redux' ;
44import type { AggregateOptions } from 'mongodb' ;
5+ import type { QueryBarService } from '@mongodb-js/compass-query-bar' ;
56import { type AnalysisState } from '../constants/analysis-states' ;
67import {
78 ANALYSIS_STATE_ANALYZING ,
@@ -169,10 +170,58 @@ export const geoLayersDeleted = (
169170 } ;
170171} ;
171172
172- export const stopAnalysis = ( ) : SchemaThunkAction < void > => {
173+ // We track when the user cancels the analysis. We use the userCancelled
174+ // flag to indicate if we should track, as we also automatically stop
175+ // analysis when deactivating the plugin.
176+ const userCancelledAnalysisAbortReason = 'Cancelled analysis' ;
177+
178+ export const stopAnalysis = (
179+ userCancelled = false
180+ ) : SchemaThunkAction < void > => {
173181 return ( dispatch , getState , { abortControllerRef } ) => {
174182 if ( ! abortControllerRef . current ) return ;
175- abortControllerRef . current ?. abort ( ) ;
183+ abortControllerRef . current ?. abort (
184+ userCancelled ? userCancelledAnalysisAbortReason : undefined
185+ ) ;
186+ } ;
187+ } ;
188+
189+ const getSchemaAnalyzedEventPayload = ( {
190+ schema,
191+ query,
192+ analysisTime,
193+ } : {
194+ schema : Schema | null ;
195+ query : ReturnType < QueryBarService [ 'getLastAppliedQuery' ] > ;
196+ analysisTime : number ;
197+ } ) => {
198+ return async ( ) => {
199+ const {
200+ field_types,
201+ geo_data,
202+ optional_field_count,
203+ schema_depth,
204+ variable_type_count,
205+ } = schema
206+ ? await calculateSchemaMetadata ( schema )
207+ : {
208+ field_types : { } ,
209+ geo_data : false ,
210+ optional_field_count : 0 ,
211+ schema_depth : 0 ,
212+ variable_type_count : 0 ,
213+ } ;
214+
215+ return {
216+ with_filter : Object . entries ( query . filter ?? { } ) . length > 0 ,
217+ schema_width : schema ?. fields ?. length ?? 0 ,
218+ field_types,
219+ variable_type_count,
220+ optional_field_count,
221+ schema_depth,
222+ geo_data,
223+ analysis_time_ms : analysisTime ,
224+ } ;
176225 } ;
177226} ;
178227
@@ -223,12 +272,12 @@ export const startAnalysis = (): SchemaThunkAction<
223272 abortControllerRef . current = new AbortController ( ) ;
224273 const abortSignal = abortControllerRef . current . signal ;
225274
275+ const analysisStartTime = Date . now ( ) ;
226276 try {
227277 debug ( 'analysis started' ) ;
228278
229279 dispatch ( { type : SchemaAnalysisActions . analysisStarted } ) ;
230280
231- const analysisStartTime = Date . now ( ) ;
232281 const schemaAccessor = await analyzeSchema (
233282 dataService ,
234283 abortSignal ,
@@ -237,6 +286,11 @@ export const startAnalysis = (): SchemaThunkAction<
237286 driverOptions ,
238287 logger
239288 ) ;
289+
290+ if ( abortSignal ?. aborted ) {
291+ throw new Error ( abortSignal ?. reason || new Error ( 'Operation aborted' ) ) ;
292+ }
293+
240294 let schema : Schema | null = null ;
241295 if ( schemaAccessor ) {
242296 schema = await schemaAccessor . getInternalSchema ( ) ;
@@ -256,38 +310,33 @@ export const startAnalysis = (): SchemaThunkAction<
256310 schemaAccessor,
257311 } ) ;
258312
259- const trackEvent = async ( ) => {
260- const {
261- field_types,
262- geo_data,
263- optional_field_count,
264- schema_depth,
265- variable_type_count,
266- } = schema
267- ? await calculateSchemaMetadata ( schema )
268- : {
269- field_types : { } ,
270- geo_data : false ,
271- optional_field_count : 0 ,
272- schema_depth : 0 ,
273- variable_type_count : 0 ,
274- } ;
275-
276- return {
277- with_filter : Object . entries ( query . filter ?? { } ) . length > 0 ,
278- schema_width : schema ?. fields ?. length ?? 0 ,
279- field_types,
280- variable_type_count,
281- optional_field_count,
282- schema_depth,
283- geo_data,
284- analysis_time_ms : analysisTime ,
285- } ;
286- } ;
287- track ( 'Schema Analyzed' , trackEvent , connectionInfoRef . current ) ;
313+ track (
314+ 'Schema Analyzed' ,
315+ getSchemaAnalyzedEventPayload ( {
316+ schema,
317+ query,
318+ analysisTime,
319+ } ) ,
320+ connectionInfoRef . current
321+ ) ;
288322
289323 geoLayersRef . current = { } ;
290324 } catch ( err : any ) {
325+ if (
326+ abortSignal . aborted &&
327+ abortSignal . reason === userCancelledAnalysisAbortReason
328+ ) {
329+ const analysisTime = Date . now ( ) - analysisStartTime ;
330+ track (
331+ 'Schema Analysis Cancelled' ,
332+ {
333+ analysis_time_ms : analysisTime ,
334+ with_filter : Object . entries ( query . filter ?? { } ) . length > 0 ,
335+ } ,
336+ connectionInfoRef . current
337+ ) ;
338+ }
339+
291340 log . error (
292341 mongoLogId ( 1_001_000_188 ) ,
293342 'Schema analysis' ,
0 commit comments