Skip to content

Enable ConnectionPoolV2 by default - #4589

Open
mdaigle wants to merge 17 commits into
mainfrom
dev/automation/enable-connectionpool-v2-default
Open

Enable ConnectionPoolV2 by default#4589
mdaigle wants to merge 17 commits into
mainfrom
dev/automation/enable-connectionpool-v2-default

Conversation

@mdaigle

@mdaigle mdaigle commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Description

Changes the default connection pool from WaitHandleDbConnectionPool to ChannelDbConnectionPool. Applications can restore the legacy pool explicitly:

AppContext.SetSwitch("Switch.Microsoft.Data.SqlClient.UseConnectionPoolV2", false);

The full CI matrix exposed and this PR retains fixes for:

  • Reacquiring normally when connection resiliency has already removed the broken connection's pool slot.
  • Honoring an expired caller timeout before physical connection creation.
  • Unwrapping and observing Task<Task> in TvpTest.TestPacketNumberWraparound.
  • Replacing timing-based ambient transaction coverage with direct sync and async Enlist=false public-API coverage.

Flaky-test stabilization and quarantine changes discovered during investigation were removed for a separate PR. No public APIs change.

A best-of-three comparison covered 162 benchmarks with a 10% threshold. It found 41 improvements, 9 confirmed regressions, and 3 unconfirmed regressions. The strongest remaining regression signals are fixed overhead in pooled OpenAsync, synchronization in rapid open/close loops, and contention when MaxPoolSize is small relative to concurrency.

Issues

Supersedes #4537, which used a fork-backed branch.

The prerequisite emancipated connection reclamation fix merged through #4529.

Testing

  • ChannelDbConnectionPoolTest: 64/64 passed on net9.0 after rebasing onto main.
  • ChannelDbConnectionPoolReplaceConnectionTest: 16/16 passed on net8.0 and net9.0.
  • Open_WithEnlistDisabled_DoesNotEnlistInAmbientTransaction: sync and async cases passed on net8.0 and net9.0.
  • Default-switch and connection-pool unit selection: 332/332 passed on net8.0, net9.0, and net10.0.
  • The seven CI legs affected by the TVP test passed after the test fix.
  • A prior complete matrix had only unrelated macOS SQL Server container, ARM64 Azure SQL TLS, and managed identity infrastructure failures. The replacement PR starts a fresh current-head matrix.

Guidelines

Please review the contribution guidelines before submitting a pull request:

mdaigle and others added 16 commits August 21, 2026 14:10
Flip the default value of the UseConnectionPoolV2 AppContext switch
from false to true, making the new Channel-based connection pool
(ChannelDbConnectionPool) the default implementation. The legacy V1
pool (WaitHandleDbConnectionPool) remains available by explicitly
setting the switch to false.

- Update XML doc comment on the switch to reflect the new default
- Update features.instructions.md default value table
- Update LocalAppContextSwitchesTest default-value assertion

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Task.Factory.StartNew with an async lambda returns Task<Task>. Without
Unwrap(), Task.WhenAny observed only the outer task, which completed as
soon as the async lambda hit its first await, rather than waiting for
RunPacketNumberWraparound to actually finish. This masked itself under
the legacy WaitHandleDbConnectionPool's synchronous-leaning timing, but
was exposed by ChannelDbConnectionPool's genuinely asynchronous pooled
open path, producing spurious low-enumerator-count failures.

Also capture and await the winning task when it is actionTask so any
unexpected failure (e.g. a connection open failure) propagates as a
real exception instead of surfacing only as a generic count mismatch.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Use unique pool-group keys for ephemeral simulated servers and isolate login-token handling from fatal connection-break behavior.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Observe asynchronous stress workers so connection failures fail the test instead of terminating the test host, and quarantine the sync variant of the known transient retry timing flake.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Count completed failover logins so abandoned pre-login transport attempts do not obscure the fresh physical connection created after the pool is cleared.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@mdaigle
mdaigle requested review from a team and a lite review from Copilot August 24, 2026 22:04
@github-project-automation github-project-automation Bot moved this to To triage in SqlClient Board Aug 24, 2026
@mdaigle mdaigle added this to the 8.0.0 milestone Aug 24, 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.

Pull request overview

Enables ChannelDbConnectionPool (ConnectionPoolV2) as the default connection pooling implementation via LocalAppContextSwitches.UseConnectionPoolV2, updating documentation and tests to reflect the new default and to cover key behavioral/regression scenarios discovered during prior CI/perf validation.

Changes:

  • Flip UseConnectionPoolV2 default to true and update switch documentation + default-value unit test.
  • Add/adjust targeted tests covering (a) Enlist=false behavior under an ambient transaction (sync + async), (b) “expired timeout prevents physical creation”, and (c) resiliency replacement when the old connection was already removed.
  • Fix TvpTest.TestPacketNumberWraparound to correctly unwrap/observe the nested Task<Task> produced by Task.Factory.StartNew.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/LocalAppContextSwitches.cs Sets UseConnectionPoolV2 default to true and updates its XML doc comment accordingly.
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPool.cs Adjusts ReplaceConnection to reacquire via the normal path when the old connection is no longer in this pool.
src/Microsoft.Data.SqlClient/tests/UnitTests/Microsoft/Data/SqlClient/LocalAppContextSwitchesTest.cs Updates the default-switch assertion to expect UseConnectionPoolV2 == true.
src/Microsoft.Data.SqlClient/tests/UnitTests/ConnectionPool/ChannelDbConnectionPoolTest.cs Adds deterministic coverage ensuring expired timeouts prevent physical connection creation attempts.
src/Microsoft.Data.SqlClient/tests/UnitTests/ConnectionPool/ChannelDbConnectionPoolReplaceConnectionTest.cs Adds coverage for replacement after the old connection has already been removed; adds a test helper method to doom stub connections.
src/Microsoft.Data.SqlClient/tests/UnitTests/SimulatedServerTests/ConnectionTests.cs Adds an in-proc TDS server test verifying Enlist=false prevents ambient transaction enlistment for both Open and OpenAsync.
src/Microsoft.Data.SqlClient/tests/ManualTests/SQL/ParameterTest/TvpTest.cs Fixes nested-task handling from Task.Factory.StartNew by unwrapping and explicitly observing failures.
src/Microsoft.Data.SqlClient/tests/FunctionalTests/AmbientTransactionFailureTest.cs Removes the prior timing/ambient-transaction-based functional test (replaced by direct public-API coverage elsewhere in this PR).
.github/instructions/features.instructions.md Updates the switch table to reflect UseConnectionPoolV2 defaulting to true and how to restore V1.

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

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@paulmedynski paulmedynski moved this from To triage to In review in SqlClient Board Aug 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In review

Development

Successfully merging this pull request may close these issues.

5 participants