Add telemetry for tree view concurrent refresh#291540
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Adds telemetry and retry handling around tree view node resolution when concurrent refreshes invalidate child fetches.
Changes:
- Add bounded retry logic to
ExtHostTreeView._resolveTreeNodewhengetChildren()returnsundefineddue to concurrent refresh invalidation, and emit retry telemetry via the main thread. - Extend the ext host ↔ main thread protocol with
$logResolveTreeNodeRetryand implement telemetry emission inMainThreadTreeViews. - Update the
MainThreadTreeViewsbrowser test to pass a telemetry service.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/vs/workbench/api/test/browser/mainThreadTreeViews.test.ts | Passes NullTelemetryService to MainThreadTreeViews in the test setup. |
| src/vs/workbench/api/common/extHostTreeViews.ts | Implements retry-on-invalidated-children logic and calls into the main thread to log retry telemetry. |
| src/vs/workbench/api/common/extHost.protocol.ts | Adds $logResolveTreeNodeRetry to the MainThreadTreeViewsShape RPC surface. |
| src/vs/workbench/api/browser/mainThreadTreeViews.ts | Injects ITelemetryService and logs the new treeView.resolveRetry telemetry event. |
Comments suppressed due to low confidence (2)
src/vs/workbench/api/common/extHostTreeViews.ts:714
- The retry limit
3is hard-coded in multiple places (condition, log message, telemetry semantics). To avoid accidental divergence if this value changes, consider introducing a singleconst MAX_RESOLVE_RETRIES = 3(or similar) and reusing it for the comparison and for theattempt x/ymessage.
if (children === undefined && retryCount < 3) {
const newRetryCount = retryCount + 1;
this._logService.warn(`[${this._viewId}] Retrying _resolveTreeNode due to concurrent refresh (attempt ${newRetryCount}/3) for element ${handle} from extension ${this._extension.identifier.value}`);
src/vs/workbench/api/common/extHostTreeViews.ts:720
- The new retry/telemetry behavior in
_resolveTreeNodeisn’t covered by tests. Since this code path is race-sensitive (concurrent refresh invalidating_fetchChildrenNodesleading togetChildren()returningundefined), it would be good to add a focused unit test (e.g. insrc/vs/workbench/api/test/browser/extHostTreeViews.test.ts) that simulates token invalidation and asserts: (1)_resolveTreeNoderetries up to the limit and (2)$logResolveTreeNodeRetryis called with the expected parameters.
private async _resolveTreeNode(element: T, parent?: TreeNode, retryCount = 0): Promise<TreeNode> {
const node = this._nodes.get(element);
if (node) {
return node;
}
const extTreeItem = await asPromise(() => this._dataProvider.getTreeItem(element));
const handle = this._createHandle(element, extTreeItem, parent, true);
const children = await this.getChildren(parent ? parent.item.handle : undefined);
// If getChildren returned undefined, it means a concurrent refresh invalidated
// the fetch. Retry a limited number of times to handle transient refresh races.
if (children === undefined && retryCount < 3) {
const newRetryCount = retryCount + 1;
this._logService.warn(`[${this._viewId}] Retrying _resolveTreeNode due to concurrent refresh (attempt ${newRetryCount}/3) for element ${handle} from extension ${this._extension.identifier.value}`);
if (newRetryCount === 1) {
// Log telemetry on first retry
this._proxy.$logResolveTreeNodeRetry(this._viewId, this._extension.identifier.value, newRetryCount, false);
}
return this._resolveTreeNode(element, parent, newRetryCount);
}
Comment on lines
143
to
156
| $logResolveTreeNodeRetry(_treeViewId: string, extensionId: string, retryCount: number, exhausted: boolean): void { | ||
| type TreeViewResolveRetryEvent = { | ||
| extensionId: string; | ||
| retryCount: number; | ||
| exhausted: boolean; | ||
| }; | ||
| type TreeViewResolveRetryClassification = { | ||
| extensionId: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The extension identifier.' }; | ||
| retryCount: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; isMeasurement: true; comment: 'Number of retry attempts made.' }; | ||
| exhausted: { classification: 'SystemMetaData'; purpose: 'PerformanceAndHealth'; comment: 'Whether all retry attempts were exhausted.' }; | ||
| owner: 'alexr00'; | ||
| comment: 'Tracks tree view resolve retries due to concurrent refresh races.'; | ||
| }; | ||
| this.telemetryService.publicLog2<TreeViewResolveRetryEvent, TreeViewResolveRetryClassification>('treeView.resolveRetry', { |
There was a problem hiding this comment.
treeViewId is passed over RPC but intentionally unused here. If it’s not meant to be collected, consider removing it from the protocol/method signature to avoid confusion and unnecessary payload; if it is useful, consider including a sanitized/appropriate representation in the telemetry event so the parameter has a purpose.
sandy081
previously approved these changes
Jan 29, 2026
dbaeumer
approved these changes
Jan 29, 2026
alexr00
added a commit
that referenced
this pull request
Feb 2, 2026
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.
No description provided.