Skip to content

Commit 89b8a94

Browse files
authored
perf: avoid filewatchers if enableCodeLenses=false #3445
Problem: `aws.samcli.enableCodeLenses` setting was added in 136a67b #1681 as a cosmetic feature, it didn't actually disable initialization of the codelense filewatchers(!). Solution: - Split the codelense setup logic for "sam template.yaml files" from "code files". - Only initialize "code file" codelenses and filewatchers if: 1 . `aws.samcli.enableCodeLenses` setting is enabled (at startup _or_ dynamically at runtime) 2 . user invokes "Add SAM Debug Configuration"
1 parent 36c0b1f commit 89b8a94

File tree

2 files changed

+113
-75
lines changed

2 files changed

+113
-75
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"type": "Feature",
3+
"description": "Faster startup and less filesystem usage when the `aws.samcli.enableCodeLenses` setting is disabled"
4+
}

src/shared/sam/activation.ts

Lines changed: 109 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ import { SamTemplateCodeLensProvider } from '../codelens/samTemplateCodeLensProv
2626
import * as jsLensProvider from '../codelens/typescriptCodeLensProvider'
2727
import { ExtContext, VSCODE_EXTENSION_ID } from '../extensions'
2828
import { getIdeProperties, getIdeType, IDE, isCloud9 } from '../extensionUtilities'
29-
import { getLogger } from '../logger/logger'
30-
import { TelemetryService } from '../telemetry/telemetryService'
29+
import { PerfLog, getLogger } from '../logger/logger'
3130
import { NoopWatcher } from '../fs/watchedFiles'
3231
import { detectSamCli } from './cli/samCliDetection'
3332
import { CodelensRootRegistry } from '../fs/codelensRootRegistry'
@@ -43,20 +42,41 @@ import { registerSync } from './sync'
4342

4443
const sharedDetectSamCli = shared(detectSamCli)
4544

45+
const supportedLanguages: {
46+
[language: string]: codelensUtils.OverridableCodeLensProvider
47+
} = {}
48+
4649
/**
4750
* Activate SAM-related functionality.
4851
*/
4952
export async function activate(ctx: ExtContext): Promise<void> {
53+
let didActivateCodeLensProviders = false
5054
await createYamlExtensionPrompt()
5155
const config = SamCliSettings.instance
5256

53-
ctx.extensionContext.subscriptions.push(
54-
...(await activateCodeLensProviders(ctx, config, ctx.outputChannel, ctx.telemetryService))
55-
)
57+
// Do this "on-demand" because it is slow.
58+
async function activateSlowCodeLensesOnce(): Promise<void> {
59+
if (!didActivateCodeLensProviders) {
60+
didActivateCodeLensProviders = true
61+
const disposeable = await activateCodefileOverlays(ctx, config)
62+
ctx.extensionContext.subscriptions.push(...disposeable)
63+
}
64+
}
65+
66+
if (config.get('enableCodeLenses', false)) {
67+
activateSlowCodeLensesOnce()
68+
}
5669

57-
await registerServerlessCommands(ctx, config)
70+
await registerCommands(ctx, config)
71+
Commands.register('aws.addSamDebugConfig', async () => {
72+
if (!didActivateCodeLensProviders) {
73+
await activateSlowCodeLensesOnce()
74+
await samDebugConfigCmd()
75+
}
76+
})
5877

5978
ctx.extensionContext.subscriptions.push(
79+
activateSamYamlOverlays(),
6080
vscode.debug.registerDebugConfigurationProvider(AWS_SAM_DEBUG_TYPE, new SamDebugConfigProvider(ctx))
6181
)
6282

@@ -72,10 +92,19 @@ export async function activate(ctx: ExtContext): Promise<void> {
7292
)
7393
)
7494

75-
config.onDidChange(event => {
76-
if (event.key === 'location') {
77-
// This only shows a message (passive=true), does not set anything.
78-
sharedDetectSamCli({ passive: true, showMessage: true })
95+
config.onDidChange(async event => {
96+
switch (event.key) {
97+
case 'location':
98+
// This only shows a message (passive=true), does not set anything.
99+
sharedDetectSamCli({ passive: true, showMessage: true })
100+
break
101+
case 'enableCodeLenses':
102+
if (config.get(event.key, false) && !didActivateCodeLensProviders) {
103+
await activateSlowCodeLensesOnce()
104+
}
105+
break
106+
default:
107+
break
79108
}
80109
})
81110

@@ -88,7 +117,7 @@ export async function activate(ctx: ExtContext): Promise<void> {
88117
registerSync()
89118
}
90119

91-
async function registerServerlessCommands(ctx: ExtContext, settings: SamCliSettings): Promise<void> {
120+
async function registerCommands(ctx: ExtContext, settings: SamCliSettings): Promise<void> {
92121
lazyLoadSamTemplateStrings()
93122
ctx.extensionContext.subscriptions.push(
94123
Commands.register({ id: 'aws.samcli.detect', autoconnect: false }, () =>
@@ -123,6 +152,10 @@ async function registerServerlessCommands(ctx: ExtContext, settings: SamCliSetti
123152
settings,
124153
}
125154
)
155+
}),
156+
Commands.register({ id: 'aws.toggleSamCodeLenses', autoconnect: false }, async () => {
157+
const toggled = !settings.get('enableCodeLenses', false)
158+
settings.update('enableCodeLenses', toggled)
126159
})
127160
)
128161
}
@@ -158,12 +191,70 @@ async function activateCodeLensRegistry(context: ExtContext) {
158191
context.extensionContext.subscriptions.push(globals.codelensRootRegistry)
159192
}
160193

161-
async function activateCodeLensProviders(
194+
async function samDebugConfigCmd() {
195+
const activeEditor = vscode.window.activeTextEditor
196+
if (!activeEditor) {
197+
getLogger().error(`aws.addSamDebugConfig was called without an active text editor`)
198+
vscode.window.showErrorMessage(
199+
localize('AWS.pickDebugHandler.noEditor', 'Toolkit could not find an active editor')
200+
)
201+
202+
return
203+
}
204+
const document = activeEditor.document
205+
const provider = supportedLanguages[document.languageId]
206+
if (!provider) {
207+
getLogger().error(`aws.addSamDebugConfig called on a document with an invalid language: ${document.languageId}`)
208+
vscode.window.showErrorMessage(
209+
localize(
210+
'AWS.pickDebugHandler.invalidLanguage',
211+
'Toolkit cannot detect handlers in language: {0}',
212+
document.languageId
213+
)
214+
)
215+
216+
return
217+
}
218+
219+
// TODO: No reason for this to depend on the codelense provider (which scans the whole workspace and creates filewatchers).
220+
const lenses = (await provider.provideCodeLenses(document, new vscode.CancellationTokenSource().token, true)) ?? []
221+
codelensUtils.invokeCodeLensCommandPalette(document, lenses)
222+
}
223+
224+
/**
225+
* Creates vscode.CodeLensProvider for SAM "template.yaml" files.
226+
*
227+
* Used for:
228+
* 1. showing codelenses in SAM template.yaml files
229+
*/
230+
function activateSamYamlOverlays(): vscode.Disposable {
231+
return vscode.languages.registerCodeLensProvider(
232+
[
233+
{
234+
language: 'yaml',
235+
scheme: 'file',
236+
pattern: '**/*template.{yml,yaml}',
237+
},
238+
],
239+
new SamTemplateCodeLensProvider()
240+
)
241+
}
242+
243+
/**
244+
* EXPENSIVE AND SLOW. Creates filewatchers and vscode.CodeLensProvider objects
245+
* for codefiles (as opposed to SAM template.yaml files).
246+
*
247+
* Used for:
248+
* 1. showing codelenses
249+
* 2. "Add SAM Debug Configuration" command (TODO: remove dependency on
250+
* codelense provider (which scans the whole workspace and creates
251+
* filewatchers)).
252+
*/
253+
async function activateCodefileOverlays(
162254
context: ExtContext,
163-
configuration: SamCliSettings,
164-
toolkitOutputChannel: vscode.OutputChannel,
165-
telemetryService: TelemetryService
255+
configuration: SamCliSettings
166256
): Promise<vscode.Disposable[]> {
257+
const perflog = new PerfLog('activateCodefileOverlays')
167258
const disposables: vscode.Disposable[] = []
168259
const tsCodeLensProvider = codelensUtils.makeTypescriptCodeLensProvider(configuration)
169260
const pyCodeLensProvider = await codelensUtils.makePythonCodeLensProvider(configuration)
@@ -175,12 +266,8 @@ async function activateCodeLensProviders(
175266
// the event to notify on when their results change.
176267
await activateCodeLensRegistry(context)
177268

178-
const supportedLanguages: {
179-
[language: string]: codelensUtils.OverridableCodeLensProvider
180-
} = {
181-
[jsLensProvider.javascriptLanguage]: tsCodeLensProvider,
182-
[pyLensProvider.pythonLanguage]: pyCodeLensProvider,
183-
}
269+
supportedLanguages[jsLensProvider.javascriptLanguage] = tsCodeLensProvider
270+
supportedLanguages[pyLensProvider.pythonLanguage] = pyCodeLensProvider
184271

185272
if (!isCloud9()) {
186273
supportedLanguages[javaLensProvider.javaLanguage] = javaCodeLensProvider
@@ -189,66 +276,13 @@ async function activateCodeLensProviders(
189276
supportedLanguages[jsLensProvider.typescriptLanguage] = tsCodeLensProvider
190277
}
191278

192-
disposables.push(
193-
vscode.languages.registerCodeLensProvider(
194-
[
195-
{
196-
language: 'yaml',
197-
scheme: 'file',
198-
pattern: '**/*template.{yml,yaml}',
199-
},
200-
],
201-
new SamTemplateCodeLensProvider()
202-
)
203-
)
204-
205279
disposables.push(vscode.languages.registerCodeLensProvider(jsLensProvider.typescriptAllFiles, tsCodeLensProvider))
206280
disposables.push(vscode.languages.registerCodeLensProvider(pyLensProvider.pythonAllfiles, pyCodeLensProvider))
207281
disposables.push(vscode.languages.registerCodeLensProvider(javaLensProvider.javaAllfiles, javaCodeLensProvider))
208282
disposables.push(vscode.languages.registerCodeLensProvider(csLensProvider.csharpAllfiles, csCodeLensProvider))
209283
disposables.push(vscode.languages.registerCodeLensProvider(goLensProvider.goAllfiles, goCodeLensProvider))
210284

211-
disposables.push(
212-
Commands.register({ id: 'aws.toggleSamCodeLenses', autoconnect: false }, async () => {
213-
const toggled = !configuration.get('enableCodeLenses', false)
214-
configuration.update('enableCodeLenses', toggled)
215-
})
216-
)
217-
218-
disposables.push(
219-
Commands.register('aws.addSamDebugConfig', async () => {
220-
const activeEditor = vscode.window.activeTextEditor
221-
if (!activeEditor) {
222-
getLogger().error(`aws.addSamDebugConfig was called without an active text editor`)
223-
vscode.window.showErrorMessage(
224-
localize('AWS.pickDebugHandler.noEditor', 'Toolkit could not find an active editor')
225-
)
226-
227-
return
228-
}
229-
const document = activeEditor.document
230-
const provider = supportedLanguages[document.languageId]
231-
if (!provider) {
232-
getLogger().error(
233-
`aws.addSamDebugConfig called on a document with an invalid language: ${document.languageId}`
234-
)
235-
vscode.window.showErrorMessage(
236-
localize(
237-
'AWS.pickDebugHandler.invalidLanguage',
238-
'Toolkit cannot detect handlers in language: {0}',
239-
document.languageId
240-
)
241-
)
242-
243-
return
244-
}
245-
246-
const lenses =
247-
(await provider.provideCodeLenses(document, new vscode.CancellationTokenSource().token, true)) ?? []
248-
codelensUtils.invokeCodeLensCommandPalette(document, lenses)
249-
})
250-
)
251-
285+
perflog.done()
252286
return disposables
253287
}
254288

0 commit comments

Comments
 (0)