From 935d650805848ebe61659a0219b5231c9671e38a Mon Sep 17 00:00:00 2001 From: Guilherme Gazzo Date: Fri, 17 Nov 2023 19:39:11 -0300 Subject: [PATCH] chore: improve license sync (#31011) --- apps/meteor/ee/app/license/server/startup.ts | 37 ++++++++++++++++---- ee/packages/license/src/definition/events.ts | 1 + ee/packages/license/src/license.ts | 5 +-- 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/apps/meteor/ee/app/license/server/startup.ts b/apps/meteor/ee/app/license/server/startup.ts index 2862f8cf5e9f..e0dd567da392 100644 --- a/apps/meteor/ee/app/license/server/startup.ts +++ b/apps/meteor/ee/app/license/server/startup.ts @@ -42,7 +42,29 @@ const applyLicense = async (license: string, isNewLicense: boolean): Promise { +/** + * This is a debounced function that will sync the workspace data to the cloud. + * it caches the context, waits for a second and then syncs the data. + */ + +const syncByTriggerDebounced = (() => { + let timeout: NodeJS.Timeout | undefined; + const contexts: Set = new Set(); + return async (context: string) => { + contexts.add(context); + if (timeout) { + clearTimeout(timeout); + } + + timeout = setTimeout(() => { + timeout = undefined; + void syncByTrigger([...contexts]); + contexts.clear(); + }, 1000); + }; +})(); + +const syncByTrigger = async (contexts: string[]) => { if (!License.encryptedLicense) { return; } @@ -60,16 +82,19 @@ const syncByTrigger = async (context: string) => { const [, , signed] = License.encryptedLicense.split('.'); // Check if this sync has already been done. Based on License, behavior. - if (existingData.signed === signed && existingData[context] === period) { + + if ([...contexts.values()].every((context) => existingData.signed === signed && existingData[context] === period)) { return; } + const obj = Object.fromEntries(contexts.map((context) => [context, period])); + await Settings.updateValueById( 'Enterprise_License_Data', JSON.stringify({ ...(existingData.signed === signed && existingData), ...existingData, - [context]: period, + ...obj, signed, }), ); @@ -91,11 +116,11 @@ settings.onReady(async () => { callbacks.add('workspaceLicenseChanged', async (updatedLicense) => applyLicense(updatedLicense, true)); - License.onBehaviorTriggered('prevent_action', (context) => syncByTrigger(`prevent_action_${context.limit}`)); + License.onBehaviorTriggered('prevent_action', (context) => syncByTriggerDebounced(`prevent_action_${context.limit}`)); - License.onBehaviorTriggered('start_fair_policy', async (context) => syncByTrigger(`start_fair_policy_${context.limit}`)); + License.onBehaviorTriggered('start_fair_policy', async (context) => syncByTriggerDebounced(`start_fair_policy_${context.limit}`)); - License.onBehaviorTriggered('disable_modules', async (context) => syncByTrigger(`disable_modules_${context.limit}`)); + License.onBehaviorTriggered('disable_modules', async (context) => syncByTriggerDebounced(`disable_modules_${context.limit}`)); License.onChange(() => api.broadcast('license.sync')); diff --git a/ee/packages/license/src/definition/events.ts b/ee/packages/license/src/definition/events.ts index b9d211da9b7a..f19dc13cc82e 100644 --- a/ee/packages/license/src/definition/events.ts +++ b/ee/packages/license/src/definition/events.ts @@ -15,6 +15,7 @@ export type LicenseEvents = ModuleValidation & BehaviorTriggeredToggled & BehaviorTriggered & LimitReached & { + installed: undefined; validate: undefined; invalidate: undefined; module: { module: LicenseModule; valid: boolean }; diff --git a/ee/packages/license/src/license.ts b/ee/packages/license/src/license.ts index 0faa22f4e22d..a75b187d045b 100644 --- a/ee/packages/license/src/license.ts +++ b/ee/packages/license/src/license.ts @@ -56,8 +56,7 @@ export class LicenseManager extends Emitter { constructor() { super(); - - this.on('validate', () => showLicense.call(this, this._license, this._valid)); + this.on('installed', () => showLicense.call(this, this._license, this._valid)); } public get license(): ILicenseV3 | undefined { @@ -268,6 +267,8 @@ export class LicenseManager extends Emitter { } await this.setLicenseV3(decrypted, encryptedLicense, decrypted, isNewLicense); + this.emit('installed'); + return true; } catch (e) { logger.error('Invalid license');