From 67bccd37112fada34e0130ff950b3e615318c5e5 Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Fri, 2 Jun 2023 15:26:47 +0200 Subject: [PATCH] disable dynamic debounce values when running out of source or when developing an extension (#184159) re https://github.com/microsoft/vscode/issues/144541 --- .../services/languageFeatureDebounce.ts | 46 +++++++++++++++---- .../test/browser/outlineModel.test.ts | 14 +++++- .../browser/documentSemanticTokens.test.ts | 8 +++- .../test/browser/stickyScroll.test.ts | 5 ++ src/vs/editor/test/browser/testCodeEditor.ts | 7 +++ src/vs/editor/test/common/testTextModel.ts | 6 +++ .../test/browser/extHostApiCommands.test.ts | 5 ++ 7 files changed, 78 insertions(+), 13 deletions(-) diff --git a/src/vs/editor/common/services/languageFeatureDebounce.ts b/src/vs/editor/common/services/languageFeatureDebounce.ts index 417a2d9dc08..e0d2cb832f3 100644 --- a/src/vs/editor/common/services/languageFeatureDebounce.ts +++ b/src/vs/editor/common/services/languageFeatureDebounce.ts @@ -8,6 +8,7 @@ import { LRUCache } from 'vs/base/common/map'; import { clamp, MovingAverage, SlidingWindowAverage } from 'vs/base/common/numbers'; import { LanguageFeatureRegistry } from 'vs/editor/common/languageFeatureRegistry'; import { ITextModel } from 'vs/editor/common/model'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { ILogService } from 'vs/platform/log/common/log'; @@ -42,6 +43,21 @@ namespace IdentityHash { } } +class NullDebounceInformation implements IFeatureDebounceInformation { + + constructor(private readonly _default: number) { } + + get(_model: ITextModel): number { + return this._default; + } + update(_model: ITextModel, _value: number): number { + return this._default; + } + default(): number { + return this._default; + } +} + class FeatureDebounceInformation implements IFeatureDebounceInformation { private readonly _cache = new LRUCache(50, 0.7); @@ -100,10 +116,15 @@ export class LanguageFeatureDebounceService implements ILanguageFeatureDebounceS declare _serviceBrand: undefined; - private readonly _data = new Map(); + private readonly _data = new Map(); + private readonly _isDev: boolean; - constructor(@ILogService private readonly _logService: ILogService) { + constructor( + @ILogService private readonly _logService: ILogService, + @IEnvironmentService envService: IEnvironmentService, + ) { + this._isDev = envService.isExtensionDevelopment || !envService.isBuilt; } for(feature: LanguageFeatureRegistry, name: string, config?: { min?: number; max?: number; key?: string }): IFeatureDebounceInformation { @@ -113,14 +134,19 @@ export class LanguageFeatureDebounceService implements ILanguageFeatureDebounceS const key = `${IdentityHash.of(feature)},${min}${extra ? ',' + extra : ''}`; let info = this._data.get(key); if (!info) { - info = new FeatureDebounceInformation( - this._logService, - name, - feature, - (this._overallAverage() | 0) || (min * 1.5), // default is overall default or derived from min-value - min, - max - ); + if (!this._isDev) { + this._logService.debug(`[DEBOUNCE: ${name}] is disabled in developed mode`); + info = new NullDebounceInformation(min * 1.5); + } else { + info = new FeatureDebounceInformation( + this._logService, + name, + feature, + (this._overallAverage() | 0) || (min * 1.5), // default is overall default or derived from min-value + min, + max + ); + } this._data.set(key, info); } return info; diff --git a/src/vs/editor/contrib/documentSymbols/test/browser/outlineModel.test.ts b/src/vs/editor/contrib/documentSymbols/test/browser/outlineModel.test.ts index 04220e19b6e..2249c107004 100644 --- a/src/vs/editor/contrib/documentSymbols/test/browser/outlineModel.test.ts +++ b/src/vs/editor/contrib/documentSymbols/test/browser/outlineModel.test.ts @@ -16,6 +16,8 @@ import { createModelServices, createTextModel } from 'vs/editor/test/common/test import { NullLogService } from 'vs/platform/log/common/log'; import { IMarker, MarkerSeverity } from 'vs/platform/markers/common/markers'; import { OutlineElement, OutlineGroup, OutlineModel, OutlineModelService } from '../../browser/outlineModel'; +import { mock } from 'vs/base/test/common/mock'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; suite('OutlineModel', function () { @@ -30,7 +32,11 @@ suite('OutlineModel', function () { const insta = createModelServices(disposables); const modelService = insta.get(IModelService); - const service = new OutlineModelService(languageFeaturesService, new LanguageFeatureDebounceService(new NullLogService()), modelService); + const envService = new class extends mock() { + override isBuilt: boolean = true; + override isExtensionDevelopment: boolean = false; + }; + const service = new OutlineModelService(languageFeaturesService, new LanguageFeatureDebounceService(new NullLogService(), envService), modelService); const model = createTextModel('foo', undefined, undefined, URI.file('/fome/path.foo')); let count = 0; @@ -61,7 +67,11 @@ suite('OutlineModel', function () { const insta = createModelServices(disposables); const modelService = insta.get(IModelService); - const service = new OutlineModelService(languageFeaturesService, new LanguageFeatureDebounceService(new NullLogService()), modelService); + const envService = new class extends mock() { + override isBuilt: boolean = true; + override isExtensionDevelopment: boolean = false; + }; + const service = new OutlineModelService(languageFeaturesService, new LanguageFeatureDebounceService(new NullLogService(), envService), modelService); const model = createTextModel('foo', undefined, undefined, URI.file('/fome/path.foo')); let isCancelled = false; diff --git a/src/vs/editor/contrib/semanticTokens/test/browser/documentSemanticTokens.test.ts b/src/vs/editor/contrib/semanticTokens/test/browser/documentSemanticTokens.test.ts index 33ad9d64b49..85cda9b2e53 100644 --- a/src/vs/editor/contrib/semanticTokens/test/browser/documentSemanticTokens.test.ts +++ b/src/vs/editor/contrib/semanticTokens/test/browser/documentSemanticTokens.test.ts @@ -31,6 +31,8 @@ import { LanguageFeaturesService } from 'vs/editor/common/services/languageFeatu import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; import { SemanticTokensStylingService } from 'vs/editor/common/services/semanticTokensStylingService'; import { DocumentSemanticTokensFeature } from 'vs/editor/contrib/semanticTokens/browser/documentSemanticTokens'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { mock } from 'vs/base/test/common/mock'; suite('ModelSemanticColoring', () => { @@ -54,7 +56,11 @@ suite('ModelSemanticColoring', () => { languageService, new TestLanguageConfigurationService(), )); - disposables.add(new DocumentSemanticTokensFeature(semanticTokensStylingService, modelService, themeService, configService, new LanguageFeatureDebounceService(logService), languageFeaturesService)); + const envService = new class extends mock() { + override isBuilt: boolean = true; + override isExtensionDevelopment: boolean = false; + }; + disposables.add(new DocumentSemanticTokensFeature(semanticTokensStylingService, modelService, themeService, configService, new LanguageFeatureDebounceService(logService, envService), languageFeaturesService)); }); teardown(() => { diff --git a/src/vs/editor/contrib/stickyScroll/test/browser/stickyScroll.test.ts b/src/vs/editor/contrib/stickyScroll/test/browser/stickyScroll.test.ts index d3ee356d8d6..909bddf9801 100644 --- a/src/vs/editor/contrib/stickyScroll/test/browser/stickyScroll.test.ts +++ b/src/vs/editor/contrib/stickyScroll/test/browser/stickyScroll.test.ts @@ -20,6 +20,7 @@ import { ILanguageFeatureDebounceService, LanguageFeatureDebounceService } from import { TestLanguageConfigurationService } from 'vs/editor/test/common/modes/testLanguageConfigurationService'; import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { runWithFakedTimers } from 'vs/base/test/common/timeTravelScheduler'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; suite('Sticky Scroll Tests', () => { @@ -28,6 +29,10 @@ suite('Sticky Scroll Tests', () => { [ILogService, new NullLogService()], [IContextMenuService, new class extends mock() { }], [ILanguageConfigurationService, new TestLanguageConfigurationService()], + [IEnvironmentService, new class extends mock() { + override isBuilt: boolean = true; + override isExtensionDevelopment: boolean = false; + }], [ILanguageFeatureDebounceService, new SyncDescriptor(LanguageFeatureDebounceService)], ); diff --git a/src/vs/editor/test/browser/testCodeEditor.ts b/src/vs/editor/test/browser/testCodeEditor.ts index b9f488595a2..957920ebe67 100644 --- a/src/vs/editor/test/browser/testCodeEditor.ts +++ b/src/vs/editor/test/browser/testCodeEditor.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { mock } from 'vs/base/test/common/mock'; import { EditorConfiguration, IEditorConstructionOptions } from 'vs/editor/browser/config/editorConfiguration'; import { IActiveCodeEditor, ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; @@ -39,6 +40,7 @@ import { TestConfigurationService } from 'vs/platform/configuration/test/common/ import { IContextKeyService, IContextKeyServiceTarget } from 'vs/platform/contextkey/common/contextkey'; import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { TestDialogService } from 'vs/platform/dialogs/test/common/testDialogService'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { BrandedService, IInstantiationService, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection'; @@ -191,6 +193,11 @@ export function createCodeEditorServices(disposables: DisposableStore, services: define(IContextKeyService, MockContextKeyService); define(ICommandService, TestCommandService); define(ITelemetryService, NullTelemetryServiceShape); + define(IEnvironmentService, class extends mock() { + declare readonly _serviceBrand: undefined; + override isBuilt: boolean = true; + override isExtensionDevelopment: boolean = false; + }); define(ILanguageFeatureDebounceService, LanguageFeatureDebounceService); define(ILanguageFeaturesService, LanguageFeaturesService); diff --git a/src/vs/editor/test/common/testTextModel.ts b/src/vs/editor/test/common/testTextModel.ts index f513fa490ca..cdab452aa9c 100644 --- a/src/vs/editor/test/common/testTextModel.ts +++ b/src/vs/editor/test/common/testTextModel.ts @@ -32,6 +32,8 @@ import { PLAINTEXT_LANGUAGE_ID } from 'vs/editor/common/languages/modesRegistry' import { ILanguageFeatureDebounceService, LanguageFeatureDebounceService } from 'vs/editor/common/services/languageFeatureDebounce'; import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures'; import { LanguageFeaturesService } from 'vs/editor/common/services/languageFeaturesService'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { mock } from 'vs/base/test/common/mock'; class TestTextModel extends TextModel { public registerDisposable(disposable: IDisposable): void { @@ -96,6 +98,10 @@ export function createModelServices(disposables: DisposableStore, services: Serv [ITextResourcePropertiesService, TestTextResourcePropertiesService], [IThemeService, TestThemeService], [ILogService, NullLogService], + [IEnvironmentService, new class extends mock() { + override isBuilt: boolean = true; + override isExtensionDevelopment: boolean = false; + }], [ILanguageFeatureDebounceService, LanguageFeatureDebounceService], [ILanguageFeaturesService, LanguageFeaturesService], [IModelService, ModelService], diff --git a/src/vs/workbench/api/test/browser/extHostApiCommands.test.ts b/src/vs/workbench/api/test/browser/extHostApiCommands.test.ts index 13748c699e2..ab55eb49740 100644 --- a/src/vs/workbench/api/test/browser/extHostApiCommands.test.ts +++ b/src/vs/workbench/api/test/browser/extHostApiCommands.test.ts @@ -61,6 +61,7 @@ import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity' import { IExtHostTelemetry } from 'vs/workbench/api/common/extHostTelemetry'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; +import { IEnvironmentService } from 'vs/platform/environment/common/environment'; function assertRejects(fn: () => Promise, message: string = 'Expected rejection') { return fn().then(() => assert.ok(false, message), _err => assert.ok(true)); @@ -124,6 +125,10 @@ suite('ExtHostLanguageFeatureCommands', function () { return Promise.resolve(insta.invokeFunction(handler, ...args)); } })); + services.set(IEnvironmentService, new class extends mock() { + override isBuilt: boolean = true; + override isExtensionDevelopment: boolean = false; + }); services.set(IMarkerService, new MarkerService()); services.set(ILogService, new SyncDescriptor(NullLogService)); services.set(ILanguageFeatureDebounceService, new SyncDescriptor(LanguageFeatureDebounceService));