@@ -140,8 +140,11 @@ export abstract class CommandModule<T extends {} = {}> implements CommandModuleI
140
140
141
141
// Gather and report analytics.
142
142
const analytics = await this . getAnalytics ( ) ;
143
+ let stopPeriodicFlushes : ( ( ) => Promise < void > ) | undefined ;
144
+
143
145
if ( this . shouldReportAnalytics ) {
144
146
await this . reportAnalytics ( camelCasedOptions ) ;
147
+ stopPeriodicFlushes = this . periodicAnalyticsFlush ( analytics ) ;
145
148
}
146
149
147
150
let exitCode : number | void | undefined ;
@@ -151,7 +154,6 @@ export abstract class CommandModule<T extends {} = {}> implements CommandModuleI
151
154
exitCode = await this . run ( camelCasedOptions as Options < T > & OtherOptions ) ;
152
155
const endTime = Date . now ( ) ;
153
156
analytics . timing ( this . commandName , 'duration' , endTime - startTime ) ;
154
- await analytics . flush ( ) ;
155
157
} catch ( e ) {
156
158
if ( e instanceof schema . SchemaValidationException ) {
157
159
this . context . logger . fatal ( `Error: ${ e . message } ` ) ;
@@ -160,6 +162,8 @@ export abstract class CommandModule<T extends {} = {}> implements CommandModuleI
160
162
throw e ;
161
163
}
162
164
} finally {
165
+ await stopPeriodicFlushes ?.( ) ;
166
+
163
167
if ( typeof exitCode === 'number' && exitCode > 0 ) {
164
168
process . exitCode = exitCode ;
165
169
}
@@ -170,6 +174,7 @@ export abstract class CommandModule<T extends {} = {}> implements CommandModuleI
170
174
options : ( Options < T > & OtherOptions ) | OtherOptions ,
171
175
paths : string [ ] = [ ] ,
172
176
dimensions : ( boolean | number | string ) [ ] = [ ] ,
177
+ title ?: string ,
173
178
) : Promise < void > {
174
179
for ( const [ name , ua ] of this . optionsWithAnalytics ) {
175
180
const value = options [ name ] ;
@@ -183,6 +188,7 @@ export abstract class CommandModule<T extends {} = {}> implements CommandModuleI
183
188
analytics . pageview ( '/command/' + [ this . commandName , ...paths ] . join ( '/' ) , {
184
189
dimensions,
185
190
metrics : [ ] ,
191
+ title,
186
192
} ) ;
187
193
}
188
194
@@ -275,6 +281,26 @@ export abstract class CommandModule<T extends {} = {}> implements CommandModuleI
275
281
276
282
return workspace ;
277
283
}
284
+
285
+ /**
286
+ * Flush on an interval (if the event loop is waiting).
287
+ *
288
+ * @returns a method that when called will terminate the periodic
289
+ * flush and call flush one last time.
290
+ */
291
+ private periodicAnalyticsFlush ( analytics : analytics . Analytics ) : ( ) => Promise < void > {
292
+ let analyticsFlushPromise = Promise . resolve ( ) ;
293
+ const analyticsFlushInterval = setInterval ( ( ) => {
294
+ analyticsFlushPromise = analyticsFlushPromise . then ( ( ) => analytics . flush ( ) ) ;
295
+ } , 2000 ) ;
296
+
297
+ return ( ) => {
298
+ clearInterval ( analyticsFlushInterval ) ;
299
+
300
+ // Flush one last time.
301
+ return analyticsFlushPromise . then ( ( ) => analytics . flush ( ) ) ;
302
+ } ;
303
+ }
278
304
}
279
305
280
306
/**
0 commit comments