diff --git a/src/vs/platform/configuration/node/configurationService.ts b/src/vs/platform/configuration/node/configurationService.ts index a0254f8aa61..d647c5e3987 100644 --- a/src/vs/platform/configuration/node/configurationService.ts +++ b/src/vs/platform/configuration/node/configurationService.ts @@ -15,6 +15,7 @@ import { IConfigurationService, IConfigurationServiceEvent, IConfigurationValue, import Event, { Emitter } from 'vs/base/common/event'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; +import { RunOnceScheduler } from 'vs/base/common/async'; export class ConfigurationService implements IConfigurationService, IDisposable { @@ -25,6 +26,8 @@ export class ConfigurationService implements IConfigurationService, IDisposab private rawConfig: ConfigWatcher; private cache: T; + private onConfigurationChangeDelayer: RunOnceScheduler; + private _onDidUpdateConfiguration: Emitter; private _telemetryService: ITelemetryService; @@ -40,14 +43,26 @@ export class ConfigurationService implements IConfigurationService, IDisposab this.rawConfig = new ConfigWatcher(environmentService.appSettingsPath, { changeBufferDelay: 300, defaultConfig: Object.create(null) }); this.disposables.push(toDisposable(() => this.rawConfig.dispose())); - // Listeners + this.onConfigurationChangeDelayer = new RunOnceScheduler(() => this.onConfigurationChange(), 0); + this.disposables.push(this.onConfigurationChangeDelayer); + + this.registerListeners(); + } + + private registerListeners(): void { + + // Emit config change event when the raw config notifies us about a change this.disposables.push(this.rawConfig.onDidUpdateConfiguration(event => { this.onConfigurationChange(); if (this._telemetryService) { this._telemetryService.publicLog('updateUserConfiguration', { userConfigurationKeys: Object.keys(event.config) }); } })); - this.disposables.push(Registry.as(Extensions.Configuration).onDidRegisterConfiguration(() => this.onConfigurationChange())); + + // Expect many calls to the registry (e.g. from extensions). So we buffer this event to not + // spam listeners with too many configuration change events + const configurationRegistry = Registry.as(Extensions.Configuration); + this.disposables.push(configurationRegistry.onDidRegisterConfiguration(() => this.onConfigurationChangeDelayer.schedule())); } private onConfigurationChange(): void {