fix: reduce listener leak from per-part show-checkmarks subscriptions#302589
Open
bryanchen-d wants to merge 2 commits intomainfrom
Open
fix: reduce listener leak from per-part show-checkmarks subscriptions#302589bryanchen-d wants to merge 2 commits intomainfrom
bryanchen-d wants to merge 2 commits intomainfrom
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Reduces configuration listener accumulation in the chat renderer by moving per-part ShowChatCheckmarks subscriptions to a single row-container level toggle, addressing listener leak warnings in long/agentic chat sessions.
Changes:
- Add a single
ShowChatCheckmarksclass toggle + configuration listener on each chat row container inChatListItemRenderer. - Remove per-instance
onDidChangeConfigurationsubscriptions forShowChatCheckmarksfrom tool progress parts and collapsed code block UI. - Clean up an unused
AccessibilityWorkbenchSettingIdimport after removing the per-part subscription.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
src/vs/workbench/contrib/chat/browser/widget/chatListRenderer.ts |
Adds row-container show-checkmarks class toggling driven by a single configuration listener per rendered row. |
src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolProgressPart.ts |
Removes per-subpart configuration subscription for ShowChatCheckmarks. |
src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatTerminalToolProgressPart.ts |
Removes per-part configuration subscription for ShowChatCheckmarks (non-collapsible path) and drops unused import. |
src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMarkdownContentPart.ts |
Removes per-instance configuration subscription for ShowChatCheckmarks from CollapsedCodeBlock. |
…#301186) Move the show-checkmarks class toggle from individual content parts to the row container level in chatListRenderer. This replaces N per-part onDidChangeConfiguration subscriptions (one per tool invocation, terminal tool, and code block pill) with a single subscription per rendered chat element, significantly reducing listener accumulation on the configuration service emitter in sessions with many tool invocations.
0665ea5 to
1c11056
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #301186
Reduces listener accumulation on the configuration service's
onDidChangeConfigurationemitter by consolidating per-partshow-checkmarksclass toggles into a single subscription at the row container level.Is this a real leak?
No — this is a false positive from the
LeakageMonitor, not a true memory leak. All the per-partonDidChangeConfigurationsubscriptions are properly registered viathis._register()and are correctly disposed when their owning parts are disposed. The issue is that VS Code'sLeakageMonitor(inevent.ts) fires aListenerLeakErrorwhen any single emitter exceeds a global listener threshold (175, set inworkbench.ts). In agentic sessions with 200+ simultaneous tool invocations, the sheer number of simultaneously alive listeners on the configuration service emitter (475+) crosses that threshold — even though none of them actually leak.That said, the fix is still worthwhile:
ListenerLeakErrorreportsWhat scenarios may trigger the error
Agentic chat sessions with many tool invocations (100+). Each tool invocation creates a
ChatToolProgressSubPart,ChatTerminalToolProgressPart, orCollapsedCodeBlock, each individually subscribing toconfigurationService.onDidChangeConfigurationfor theShowChatCheckmarksaccessibility setting. With 200+ tool invocations and additional subscribers from other VS Code components, the total listener count on the configuration service emitter exceeds the global leak warning threshold (175), triggering the '[044] potential listener LEAK detected' error.Code flow explaining why the error gets thrown and goes unhandled
ChatToolProgressSubPart,ChatTerminalToolProgressPart(non-collapsible case),CollapsedCodeBlock, andrenderConfirmationActionsubscribes toconfigurationService.onDidChangeConfigurationin its constructor/method to toggle theshow-checkmarksCSS class._onDidChangeConfigurationEmitter.LeakageMonitordetects this and throws aListenerLeakError, which propagates as an unhandled error to telemetry.Steps to validate manually
show-checkmarksclass toggle.How the fix addresses the issue
Instead of each content part individually subscribing to
onDidChangeConfigurationto toggle theshow-checkmarksCSS class, a single subscription is added at the row container level (templateData.rowContainer) in the chat list renderer. The existing CSS already uses descendant selectors (.show-checkmarks .progress-container > .codicon.codicon-check), so setting the class on the ancestor container propagates the style to all child parts.Changed files
show-checkmarksclass toggle ontemplateData.rowContainerwith oneonDidChangeConfigurationsubscription per rendered element (viaelementDisposables). Also removed the duplicate subscription fromrenderConfirmationAction.onDidChangeConfigurationsubscription andshow-checkmarksclass toggle fromChatToolProgressSubPart.onDidChangeConfigurationsubscription andshow-checkmarksclass toggle from the non-collapsible branch ofChatTerminalToolProgressPart. Cleaned up the unusedAccessibilityWorkbenchSettingIdimport.onDidChangeConfigurationsubscription andshow-checkmarksclass toggle fromCollapsedCodeBlock..detail.show-checkmarksCSS selector to.interactive-item-container.show-checkmarks .detailso it inherits from the container-level class.