From 42688920872e39a0bb8c340399472b28cf342805 Mon Sep 17 00:00:00 2001 From: Alexander Date: Thu, 12 Oct 2023 17:54:31 +0400 Subject: [PATCH] refactor: add system config background rotation (#470) relates-to: #466 --- src/Config/CliBuilder.ts | 47 ++++++++++-------- ...ConfigReader.ts => SystemConfigManager.ts} | 48 ++++++++++++++++++- 2 files changed, 73 insertions(+), 22 deletions(-) rename src/Config/{SystemConfigReader.ts => SystemConfigManager.ts} (72%) diff --git a/src/Config/CliBuilder.ts b/src/Config/CliBuilder.ts index cc2d5463..2caa9b11 100644 --- a/src/Config/CliBuilder.ts +++ b/src/Config/CliBuilder.ts @@ -1,6 +1,6 @@ import { CliConfig, ConfigReader } from './ConfigReader'; import { ClusterArgs, Helpers, logger, LogLevel, Sentry } from '../Utils'; -import { SystemConfigReader } from './SystemConfigReader'; +import { SystemConfigManager } from './SystemConfigManager'; import { CliInfo } from './CliInfo'; import { Arguments, Argv, CommandModule } from 'yargs'; @@ -105,33 +105,40 @@ export class CliBuilder { const handler = command.handler.bind(command); command.handler = async (args: Arguments) => { - const systemConfigReader = new SystemConfigReader(args.api as string); - const systemConfig = await systemConfigReader.read(); - - Sentry.init({ - attachStacktrace: true, - dsn: systemConfig.sentryDsn, - release: process.env.VERSION, - beforeSend(event) { - if (event.contexts.args) { - event.contexts.args = { - ...event.contexts.args, - t: event.contexts.args.t && '[Filtered]', - token: event.contexts.args.token && '[Filtered]' - }; - } - - return event; - } - }); + const systemConfigManager = new SystemConfigManager(args.api as string); + const systemConfig = await systemConfigManager.read(); return Sentry.runWithAsyncContext(() => { + this.initSentry(systemConfig.sentryDsn); Sentry.setContext('args', args); + systemConfigManager.enableBackgroundRotation((rotatedSystemConfig) => { + this.initSentry(rotatedSystemConfig.sentryDsn); + }); + return handler(args); }); }; return command; } + + private initSentry(dsn: string) { + Sentry.init({ + attachStacktrace: true, + dsn, + release: process.env.VERSION, + beforeSend(event) { + if (event.contexts.args) { + event.contexts.args = { + ...event.contexts.args, + t: event.contexts.args.t && '[Filtered]', + token: event.contexts.args.token && '[Filtered]' + }; + } + + return event; + } + }); + } } diff --git a/src/Config/SystemConfigReader.ts b/src/Config/SystemConfigManager.ts similarity index 72% rename from src/Config/SystemConfigReader.ts rename to src/Config/SystemConfigManager.ts index e6e2c689..1581a0d3 100644 --- a/src/Config/SystemConfigReader.ts +++ b/src/Config/SystemConfigManager.ts @@ -14,10 +14,11 @@ interface SystemConfigFile { updatedAt: Date; } -export class SystemConfigReader { +export class SystemConfigManager { private readonly rotationInterval = 3600000; private readonly path = join(homedir(), '.brightclirc'); private readonly client: RequestPromiseAPI; + private backgroundRotationEnabled = false; constructor(baseUrl: string) { this.client = request.defaults({ @@ -37,6 +38,45 @@ export class SystemConfigReader { }; } + public enableBackgroundRotation(onRotation: (config: SystemConfig) => void) { + this.backgroundRotationEnabled = true; + + this.runBackgroundRotation(onRotation).catch((e) => { + logger.debug('An error occurred during background rotation', e); + }); + } + + public disableBackgroundRotation() { + this.backgroundRotationEnabled = false; + } + + private async runBackgroundRotation( + onRotation: (config: SystemConfig) => void + ) { + while (this.backgroundRotationEnabled) { + logger.debug('Performing background rotation of system config file'); + + const isRotated = await this.rotateIfNecessary(); + + if (isRotated) { + const configFile = await this.getConfigFile(); + + onRotation(configFile.data); + + logger.debug( + 'Background rotation is done, sleeping for %s ms', + this.rotationInterval + ); + } + + await this.sleep(this.rotationInterval); + } + } + + private sleep(ms: number) { + return new Promise((resolve) => setTimeout(resolve, ms).unref()); + } + private needsRotation(configFile: SystemConfigFile) { if (process.env.NODE_ENV !== 'production') { return; @@ -58,7 +98,7 @@ export class SystemConfigReader { configFile.updatedAt ); - return; + return false; } logger.debug( @@ -73,6 +113,8 @@ export class SystemConfigReader { data: newConfig, updatedAt: new Date() }); + + return true; } else { logger.debug('Rotation failed'); @@ -80,6 +122,8 @@ export class SystemConfigReader { ...configFile, updatedAt: new Date() }); + + return false; } }