From 6febfb1a0e8c9dd669dbba4915c0e581a4e9d040 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Fern=C3=A1ndez=20Haro?= Date: Tue, 6 Oct 2020 12:45:58 +0100 Subject: [PATCH] [Telemetry] Synchronous `setup` and `start` methods (#79457) # Conflicts: # src/plugins/telemetry/server/plugin.ts --- src/plugins/telemetry/server/fetcher.ts | 13 +++++----- src/plugins/telemetry/server/plugin.ts | 33 +++++++++++++++++++------ 2 files changed, 32 insertions(+), 14 deletions(-) diff --git a/src/plugins/telemetry/server/fetcher.ts b/src/plugins/telemetry/server/fetcher.ts index 75cfac721bcd3..2c5237bc736f7 100644 --- a/src/plugins/telemetry/server/fetcher.ts +++ b/src/plugins/telemetry/server/fetcher.ts @@ -18,7 +18,7 @@ */ import moment from 'moment'; -import { Observable } from 'rxjs'; +import { Observable, Subscription, timer } from 'rxjs'; import { take } from 'rxjs/operators'; // @ts-ignore import fetch from 'node-fetch'; @@ -58,7 +58,7 @@ export class FetcherTask { private readonly config$: Observable; private readonly currentKibanaVersion: string; private readonly logger: Logger; - private intervalId?: NodeJS.Timeout; + private intervalId?: Subscription; private lastReported?: number; private isSending = false; private internalRepository?: SavedObjectsClientContract; @@ -79,15 +79,14 @@ export class FetcherTask { this.telemetryCollectionManager = telemetryCollectionManager; this.elasticsearchClient = elasticsearch.legacy.createClient('telemetry-fetcher'); - setTimeout(() => { - this.sendIfDue(); - this.intervalId = setInterval(() => this.sendIfDue(), this.checkIntervalMs); - }, this.initialCheckDelayMs); + this.intervalId = timer(this.initialCheckDelayMs, this.checkIntervalMs).subscribe(() => + this.sendIfDue() + ); } public stop() { if (this.intervalId) { - clearInterval(this.intervalId); + this.intervalId.unsubscribe(); } if (this.elasticsearchClient) { this.elasticsearchClient.close(); diff --git a/src/plugins/telemetry/server/plugin.ts b/src/plugins/telemetry/server/plugin.ts index bd7a2a8c1a8ca..c586b3b784438 100644 --- a/src/plugins/telemetry/server/plugin.ts +++ b/src/plugins/telemetry/server/plugin.ts @@ -17,21 +17,22 @@ * under the License. */ -import { Observable } from 'rxjs'; +import { AsyncSubject, Observable } from 'rxjs'; import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; import { TelemetryCollectionManagerPluginSetup, TelemetryCollectionManagerPluginStart, } from 'src/plugins/telemetry_collection_manager/server'; +import { take } from 'rxjs/operators'; import { CoreSetup, PluginInitializerContext, ISavedObjectsRepository, CoreStart, - IUiSettingsClient, SavedObjectsClient, Plugin, Logger, + UiSettingsServiceStart, } from '../../../core/server'; import { registerRoutes } from './routes'; import { registerCollection } from './telemetry_collection'; @@ -60,8 +61,11 @@ export class TelemetryPlugin implements Plugin { private readonly config$: Observable; private readonly isDev: boolean; private readonly fetcherTask: FetcherTask; + /** + * @private Used to mark the completion of the old UI Settings migration + */ + private readonly oldUiSettingsHandled$ = new AsyncSubject(); private savedObjectsClient?: ISavedObjectsRepository; - private uiSettingsClient?: IUiSettingsClient; constructor(initializerContext: PluginInitializerContext) { this.logger = initializerContext.logger.get(); @@ -74,7 +78,7 @@ export class TelemetryPlugin implements Plugin { }); } - public async setup( + public setup( { elasticsearch, http, savedObjects }: CoreSetup, { usageCollection, telemetryCollectionManager }: TelemetryPluginsSetup ) { @@ -101,15 +105,30 @@ export class TelemetryPlugin implements Plugin { public async start(core: CoreStart, { telemetryCollectionManager }: TelemetryPluginsStart) { const { savedObjects, uiSettings } = core; this.savedObjectsClient = savedObjects.createInternalRepository(); - const savedObjectsClient = new SavedObjectsClient(this.savedObjectsClient); - this.uiSettingsClient = uiSettings.asScopedToClient(savedObjectsClient); + + // Not catching nor awaiting these promises because they should never reject + this.handleOldUiSettings(uiSettings); + this.startFetcherWhenOldSettingsAreHandled(core, telemetryCollectionManager); + } + + private async handleOldUiSettings(uiSettings: UiSettingsServiceStart) { + const savedObjectsClient = new SavedObjectsClient(this.savedObjectsClient!); + const uiSettingsClient = uiSettings.asScopedToClient(savedObjectsClient); try { - await handleOldSettings(savedObjectsClient, this.uiSettingsClient); + await handleOldSettings(savedObjectsClient, uiSettingsClient); } catch (error) { this.logger.warn('Unable to update legacy telemetry configs.'); } + // Set the mark in the AsyncSubject as complete so all the methods that require this method to be completed before working, can move on + this.oldUiSettingsHandled$.complete(); + } + private async startFetcherWhenOldSettingsAreHandled( + core: CoreStart, + telemetryCollectionManager: TelemetryCollectionManagerPluginStart + ) { + await this.oldUiSettingsHandled$.pipe(take(1)).toPromise(); // Wait for the old settings to be handled this.fetcherTask.start(core, { telemetryCollectionManager }); }