Skip to content

Commit

Permalink
[Telemetry] Synchronous setup and start methods (#79457)
Browse files Browse the repository at this point in the history
  • Loading branch information
afharo authored Oct 6, 2020
1 parent d8b4472 commit 4ed1cb3
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 25 deletions.
13 changes: 6 additions & 7 deletions src/plugins/telemetry/server/fetcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -61,7 +61,7 @@ export class FetcherTask {
private readonly config$: Observable<TelemetryConfigType>;
private readonly currentKibanaVersion: string;
private readonly logger: Logger;
private intervalId?: NodeJS.Timeout;
private intervalId?: Subscription;
private lastReported?: number;
private isSending = false;
private internalRepository?: SavedObjectsClientContract;
Expand All @@ -82,15 +82,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();
Expand Down
56 changes: 38 additions & 18 deletions src/plugins/telemetry/server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
*/

import { URL } from 'url';
import { Observable } from 'rxjs';
import { AsyncSubject, Observable } from 'rxjs';
import { UsageCollectionSetup } from 'src/plugins/usage_collection/server';
import {
TelemetryCollectionManagerPluginSetup,
Expand All @@ -30,11 +30,11 @@ import {
PluginInitializerContext,
ISavedObjectsRepository,
CoreStart,
IUiSettingsClient,
SavedObjectsClient,
Plugin,
Logger,
IClusterClient,
UiSettingsServiceStart,
} from '../../../core/server';
import { registerRoutes } from './routes';
import { registerCollection } from './telemetry_collection';
Expand Down Expand Up @@ -82,8 +82,11 @@ export class TelemetryPlugin implements Plugin<TelemetryPluginSetup, TelemetryPl
private readonly config$: Observable<TelemetryConfigType>;
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;
private elasticsearchClient?: IClusterClient;

constructor(initializerContext: PluginInitializerContext<TelemetryConfigType>) {
Expand All @@ -97,10 +100,10 @@ export class TelemetryPlugin implements Plugin<TelemetryPluginSetup, TelemetryPl
});
}

public async setup(
public setup(
{ elasticsearch, http, savedObjects }: CoreSetup,
{ usageCollection, telemetryCollectionManager }: TelemetryPluginsDepsSetup
): Promise<TelemetryPluginSetup> {
): TelemetryPluginSetup {
const currentKibanaVersion = this.currentKibanaVersion;
const config$ = this.config$;
const isDev = this.isDev;
Expand Down Expand Up @@ -131,25 +134,21 @@ export class TelemetryPlugin implements Plugin<TelemetryPluginSetup, TelemetryPl
};
}

public async start(core: CoreStart, { telemetryCollectionManager }: TelemetryPluginsDepsStart) {
public start(core: CoreStart, { telemetryCollectionManager }: TelemetryPluginsDepsStart) {
const { savedObjects, uiSettings, elasticsearch } = core;
this.savedObjectsClient = savedObjects.createInternalRepository();
const savedObjectsClient = new SavedObjectsClient(this.savedObjectsClient);
this.uiSettingsClient = uiSettings.asScopedToClient(savedObjectsClient);
const savedObjectsInternalRepository = savedObjects.createInternalRepository();
this.savedObjectsClient = savedObjectsInternalRepository;
this.elasticsearchClient = elasticsearch.client;

try {
await handleOldSettings(savedObjectsClient, this.uiSettingsClient);
} catch (error) {
this.logger.warn('Unable to update legacy telemetry configs.');
}

this.fetcherTask.start(core, { telemetryCollectionManager });
// Not catching nor awaiting these promises because they should never reject
this.handleOldUiSettings(uiSettings);
this.startFetcherWhenOldSettingsAreHandled(core, telemetryCollectionManager);

return {
getIsOptedIn: async () => {
const internalRepository = new SavedObjectsClient(savedObjects.createInternalRepository());
const telemetrySavedObject = await getTelemetrySavedObject(internalRepository!);
await this.oldUiSettingsHandled$.pipe(take(1)).toPromise(); // Wait for the old settings to be handled
const internalRepository = new SavedObjectsClient(savedObjectsInternalRepository);
const telemetrySavedObject = await getTelemetrySavedObject(internalRepository);
const config = await this.config$.pipe(take(1)).toPromise();
const allowChangingOptInStatus = config.allowChangingOptInStatus;
const configTelemetryOptIn = typeof config.optIn === 'undefined' ? null : config.optIn;
Expand All @@ -166,6 +165,27 @@ export class TelemetryPlugin implements Plugin<TelemetryPluginSetup, TelemetryPl
};
}

private async handleOldUiSettings(uiSettings: UiSettingsServiceStart) {
const savedObjectsClient = new SavedObjectsClient(this.savedObjectsClient!);
const uiSettingsClient = uiSettings.asScopedToClient(savedObjectsClient);

try {
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 });
}

private registerMappings(registerType: SavedObjectsRegisterType) {
registerType({
name: 'telemetry',
Expand Down

0 comments on commit 4ed1cb3

Please sign in to comment.