Sitelet https://github.com/dotnet/SqlClient/pull/4734
Skip to content

Fix access token expiry eviction in connection pool V2 - #4734

Merged
cheenamalhotra merged 1 commit into
mainfrom
dev/cheena/didactic-robot
Sep 23, 2026
Merged

cheenamalhotra merged 1 commit into
mainfrom
dev/cheena/didactic-robot

Conversation

@cheenamalhotra

Copy link
Copy Markdown
Member

Description

V2 did not check IsAccessTokenExpired before handing out pooled connections. This adds the missing checkout validation, matching V1 while preserving return-to-pool behavior and same-transaction reuse.

Adds sync/async coverage for idle, newly created, and queued connections, transaction affinity, and callback token-cache refresh/reuse. Clarifies callback documentation. No public API changes.

Testing

  • 421 pool and decimal tests passed on each of .NET 8 and .NET 9, including 46 token-expiry cases.
  • ManualTests builds successfully; live Entra ID tests require connection settings and were not run.
  • Used installed SDK 10.0.300; manual build disabled documentation generation because pinned SDK 10.0.401 is unavailable locally.

Checklist

  • Tests added or updated
  • Public API behavior documented; no API signature changes
  • Verified against customer repro (not provided)
  • No breaking API changes; V2 now matches V1 expiry behavior

Suggested release note: Fixed connection pool V2 reusing connections with expired or nearly expired access tokens.

Validate access token expiry before general checkout, preserving return and transaction-affinity behavior. Cover callback cache refresh and physical reuse across both pool implementations and sync/async opens.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@cheenamalhotra
cheenamalhotra requested a review from a team as a code owner September 23, 2026 00:36
Copilot AI balanced review requested due to automatic review settings September 23, 2026 00:36
@cheenamalhotra cheenamalhotra added the Area\Connection Pooling Use this label to tag issues that apply to problems with connection pool. label Sep 23, 2026
@github-project-automation github-project-automation Bot moved this to To triage in SqlClient Board Sep 23, 2026
@cheenamalhotra cheenamalhotra added this to the 8.0.0-preview1 milestone Sep 23, 2026

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.

Copilot review overview

🟢 Approval recommended

The implementation matches V1 semantics and includes focused coverage for all affected checkout paths.

Review effort: Balanced
Findings: None

What changed in this PR

Fixes connection pool V2 so expired access-token connections are rejected during checkout, matching V1 behavior.

Changes:

  • Adds checkout-time token-expiry validation while preserving transaction affinity.
  • Adds comprehensive sync/async unit and integration coverage.
  • Clarifies AccessTokenCallback pooling and refresh documentation.
File Description
DbConnectionPoolAccessTokenTest.cs Covers token eviction, replacement, transactions, and callback caching.
AADFedAuthTokenRefreshTest.cs Adds live Entra ID token-refresh coverage.
ChannelDbConnectionPool.cs Rejects expiring connections during general checkout.
SqlConnection.xml Documents callback refresh and pooled reuse behavior.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@codecov

codecov Bot commented Sep 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 64.83%. Comparing base (671d010) to head (027e755).
⚠️ Report is 3 commits behind head on main.

❗ There is a different number of reports uploaded between BASE (671d010) and HEAD (027e755). Click for more details.

HEAD has 1 upload less than BASE
Flag BASE (671d010) HEAD (027e755)
CI-SqlClient 1 0
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4734      +/-   ##
==========================================
- Coverage   71.96%   64.83%   -7.14%     
==========================================
  Files         291      285       -6     
  Lines       45110    68089   +22979     
==========================================
+ Hits        32462    44143   +11681     
- Misses      12648    23946   +11298     
Flag Coverage Δ
CI-SqlClient ?
PR-SqlClient-Project 64.83% <100.00%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@priyankatiwari08 priyankatiwari08 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.

Approach matches V1 and the test coverage is thorough (idle, new, queued-waiter, transacted, callback refresh). Two things to confirm:

  • Expired-but-idle connections still occupy pool slots and are invisible to the pruner/warmup, so a low-traffic pool with MinPoolSize > 0 can sit full of dead-token connections.
  • Rejecting a freshly created connection at checkout can churn create/destroy until the open timeout if the callback keeps returning short-lived tokens.

@cheenamalhotra

Copy link
Copy Markdown
Member Author
  • Expired-but-idle connections still occupy pool slots and are invisible to the pruner/warmup, so a low-traffic pool with MinPoolSize > 0 can sit full of dead-token connections.

This is acceptable.

  • Rejecting a freshly created connection at checkout can churn create/destroy until the open timeout if the callback keeps returning short-lived tokens.

Callback is client's implementation so yes, also client's responsibility.

@cheenamalhotra cheenamalhotra moved this from To triage to In review in SqlClient Board Sep 23, 2026
@cheenamalhotra
cheenamalhotra merged commit 7da9d39 into main Sep 23, 2026
221 of 222 checks passed
@cheenamalhotra
cheenamalhotra deleted the dev/cheena/didactic-robot branch September 23, 2026 18:06
@github-project-automation github-project-automation Bot moved this from In review to Done in SqlClient Board Sep 23, 2026
cheenamalhotra added a commit that referenced this pull request Sep 23, 2026
Validate access token expiry before general checkout, preserving return and transaction-affinity behavior. Cover callback cache refresh and physical reuse across both pool implementations and sync/async opens.

Co-authored-by: Cheena Malhotra <13396919+cheenamalhotra@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This was referenced Oct 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area\Connection Pooling Use this label to tag issues that apply to problems with connection pool.

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

4 participants