Skip to content

fix(tree): address Copilot review findings for index count + tenant sign-in + multi-select#704

Open
hanhan761 wants to merge 7 commits into
microsoft:mainfrom
hanhan761:fix-692-copilot-review-fixes
Open

fix(tree): address Copilot review findings for index count + tenant sign-in + multi-select#704
hanhan761 wants to merge 7 commits into
microsoft:mainfrom
hanhan761:fix-692-copilot-review-fixes

Conversation

@hanhan761

Copy link
Copy Markdown

Summary

Addresses all Copilot review findings on PRs #692 (index count), #693 (multi-select when clauses), and #694 (tenant sign-in limiter).

Changes

Copilot review fixes (new commit)

  • Sort before caching: combinedIndexes/indexes are sorted BEFORE assignment to this.cachedIndexes, so getChildren() never mutates the shared array in-place — eliminates the race window Copilot identified
  • Error logging: listSearchIndexesForAtlas failures are now logged via ext.outputChannel.warn() in both fetchAndUpdateCount() and getChildren(), making transient network/auth errors diagnosable
  • Outer error logging: fetchAndUpdateCount outer catch also logs failures via ext.outputChannel.warn()

Previous commits (from ancestor branches)

Verification

  • TypeScript compilation: zero errors in src/ directory
  • All existing Copilot concerns addressed:
    • In-place sort mutation -> sort-before-cache pattern
    • Silent error swallowing -> ext.outputChannel.warn() logging
    • Hardcoded singular/plural -> l10n.t() with localization bundle
    • indexCount === null never retries -> guard uses typeof === number

🤖 Generated with Claude Code

hanhan761 and others added 5 commits May 29, 2026 20:43
@
feat(tree): show index count on Indexes folder node

Add lazy-loaded index count as the description on IndexesItem
tree items (e.g., "5 indexes" or "1 index"), following the same
pattern used by CollectionItem for document counts. The count is
fetched asynchronously via listIndexes() and includes search
indexes when supported by the platform.

Also add a stale-check guard (isCurrent) to IndexesItem so that
in-flight count work is discarded when the owning CollectionItem
is recreated on refresh or re-expand.

Closes microsoft#659
@
@
fix(tree): hide single-item context menu commands when multiple items selected

Add `&& !listMultiSelection` to the `when` clause of 36 context
menu commands in the Connections tree view. When multiple items
are selected (`listMultiSelection` is true), single-item commands
are now hidden, preventing silent failures or unexpected behavior.

Commands already supporting multi-select (removeConnection,
moveItems) and discovery-view-only commands are intentionally
left unchanged.

Closes microsoft#668
@
@
perf(azure): throttle parallel tenant sign-in checks with shared concurrency limiter

Replace unbounded Promise.all fan-outs against the Azure Identity
endpoint with a shared ConcurrencyLimiter (concurrency: 5). For
corporate users with many tenants, the original code issued an
unlimited number of parallel isSignedIn calls against Microsoft
Entra — the same anti-pattern that caused issues with
estimateDocumentCount in microsoft#685.

New shared limiter at api-shared/azure/tenantSignInLimiter.ts is
imported by both SelectAccountStep and InitializeFilteringStep,
ensuring total parallelism is bounded across the wizard.

Closes microsoft#688
@
@
fix(tree): address Copilot review findings for index count feature

Three targeted fixes from the PR microsoft#692 Copilot review:

1. loadIndexCount() guard: use typeof check instead of !== undefined
   so a prior failed fetch (null) can be retried after re-expand.

2. fetchAndUpdateCount(): wrap isLoadingCount reset in try/finally
   so early returns (stale-check bailout, error) never leave the
   instance permanently stuck in "loading" state.

3. CollectionItem.getChildren(): pass isCurrent predicate through
   to IndexesItem so background fetch work is properly discarded
   when the owning CollectionItem is recreated on refresh/re-expand.
@
- Sort combinedIndexes/indexes before assigning to cachedIndexes so
  getChildren() never mutates the shared array in-place
- Log listSearchIndexesForAtlas failures via ext.outputChannel.warn
  so transient network/auth errors are diagnosable
- Log outer index-load failures in fetchAndUpdateCount similarly

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 29, 2026 13:48
@hanhan761 hanhan761 requested a review from a team as a code owner May 29, 2026 13:48

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds an asynchronous index-count badge to the Indexes tree node and introduces a shared concurrency limiter for Azure tenant sign-in checks. Also disables single-select context menu actions when multiple tree items are selected.

Changes:

  • IndexesItem now loads index counts in the background, caches results, and displays them as a description; CollectionItem wires a stale-check predicate to invalidate background work on refresh/re-expand.
  • New shared tenantSignInLimiter (concurrency 5) wraps isSignedIn fan-out in SelectAccountStep and InitializeFilteringStep.
  • All single-target context menu commands in package.json gated with !listMultiSelection; new l10n entries added.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
src/tree/documentdb/IndexesItem.ts Adds background count load, cached indexes, stale-check predicate, and description rendering.
src/tree/documentdb/CollectionItem.ts Adds expansionGeneration and passes an isCurrent predicate to IndexesItem; kicks off background count load.
src/plugins/api-shared/azure/tenantSignInLimiter.ts New shared concurrency limiter (5) for tenant sign-in checks.
src/plugins/api-shared/azure/subscriptionFiltering/InitializeFilteringStep.ts Wraps isSignedIn calls with the shared limiter.
src/plugins/api-shared/azure/credentialsManagement/SelectAccountStep.ts Wraps isSignedIn calls with the shared limiter.
package.json Adds !listMultiSelection guard to single-target context menu commands.
l10n/bundle.l10n.json Adds "1 index" and "{0} indexes" strings.

Comment thread src/tree/documentdb/IndexesItem.ts Outdated
Comment on lines +167 to +169
if (!this.cachedIndexes) {
const client: ClustersClient = await ClustersClient.getClient(this.cluster.clusterId);
const indexes = await client.listIndexes(this.databaseInfo.name, this.collectionInfo.name);
ext.state.notifyChildrenChanged(this.id);
}

async getChildren(): Promise<TreeElement[]> {
// available — avoids a second round-trip for the same data. Fall
// back to fetching on-demand if the cache hasn't been populated yet
// (e.g. count load is still in-flight or failed).
if (!this.cachedIndexes) {
Comment thread src/tree/documentdb/IndexesItem.ts Outdated
// Build description based on index count state
let description: string | undefined;
if (typeof this.indexCount === 'number') {
description = this.indexCount === 1 ? l10n.t('1 index') : l10n.t('{0} indexes', this.indexCount);
Comment thread src/tree/documentdb/IndexesItem.ts Outdated
// Build description based on index count state
let description: string | undefined;
if (typeof this.indexCount === 'number') {
description = this.indexCount === 1 ? l10n.t('1 index') : l10n.t('{0} indexes', this.indexCount);
Comment thread src/tree/documentdb/CollectionItem.ts Outdated
Comment on lines +162 to +164
const myGeneration = ++this.expansionGeneration;
const parentIsCurrent = this.isCurrent;
const isCurrent = (): boolean => parentIsCurrent() && this.expansionGeneration === myGeneration;
hanhan761 and others added 2 commits May 29, 2026 21:58


- Extract shared fetchAndCacheIndexes() to eliminate duplicate fetch logic
- Add inFlightFetch Promise dedup so getChildren() and fetchAndUpdateCount()
  reuse the same round-trip instead of issuing parallel duplicate requests
- Replace generation-counter + isCurrent closure with AbortController
  (standard, composable cancellation primitive) in CollectionItem
- Pass AbortSignal to IndexesItem instead of isCurrent() closure
- Add visual states: loading indicator (…) while fetching, "No indexes"
  badge for empty collections, no badge for undefined/null state
- Check signal.aborted before making client calls in fetchAndCacheIndexes
- Suppress AbortError logging (expected during refresh/collapse)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@tnaum-ms tnaum-ms added the in-triage-queue We've seen your input and will triage it label Jun 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

in-triage-queue We've seen your input and will triage it

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants