Skip to content

Add automatic pool size reduction (pruning) to ChannelDbConnectionPool#4304

Open
apoorvdeshmukh wants to merge 20 commits into
mainfrom
dev/ad/conn-prune
Open

Add automatic pool size reduction (pruning) to ChannelDbConnectionPool#4304
apoorvdeshmukh wants to merge 20 commits into
mainfrom
dev/ad/conn-prune

Conversation

@apoorvdeshmukh
Copy link
Copy Markdown
Contributor

@apoorvdeshmukh apoorvdeshmukh commented May 21, 2026

Description

Summary

Implements automatic pool size reduction for ChannelDbConnectionPool (connection pool V2). When demand drops, excess idle connections are gradually closed based on observed usage patterns rather than reacting to instantaneous idle counts.

Design

  • Sampling-based pruning: A one-shot timer fires every 10 seconds, recording the current idle connection count into a circular buffer.
  • Median-based decision: Once the buffer fills, samples are sorted and the median is used as the prune target. This smooths out brief traffic lulls and avoids over-pruning.
  • Sample window: LoadBalanceTimeout / PruningInterval samples (defaults to 300s / 10s = 30 samples when Connection Lifetime is 0), clamped to MaxSampleSize (300).
  • MinPoolSize floor: Pruning never reduces the pool below MinPoolSize.
  • Fixed-size pools skip pruning: When MinPoolSize >= MaxPoolSize, no PoolPruner is created.

Architecture

Pruning logic is encapsulated in a dedicated PoolPruner class (IDisposable):

  • PoolPruner owns the timer, sample buffer, and sampling/pruning logic.
  • ChannelDbConnectionPool holds a nullable Pruner auto-property — null for fixed-size pools.
  • The pool calls Pruner?.UpdateTimer() after connections are opened or closed.
  • The pool exposes PruneConnections(int count) for the pruner to call back into.
  • ChannelDbConnectionPool implements IDisposable (delegates to Shutdown()).

Changes

  • PoolPruner.cs (new): Encapsulates all pruning state and logic — timer, sample buffer, median calculation, enable/disable, and disposal.
  • ChannelDbConnectionPool.cs: Added PoolPruner? Pruner auto-property, PruneConnections() callback method, IDisposable implementation, and pruner creation in constructor.
  • ChannelDbConnectionPoolPruningTest.cs (new): Unit tests for pruning behavior.

Thread Safety

  • Timer callback acquires lock(_timer) to read/write shared sample state.
  • Dispose() acquires the same lock with a _disposed guard to prevent double-disposal.
  • UpdateTimer() checks _pool.IsRunning both before and inside the lock to avoid post-shutdown races.
  • Prune loop runs outside the lock and checks IsRunning and MinPoolSize floor on each iteration.
  • Timer uses ADP.UnsafeCreateTimer to avoid capturing ExecutionContext onto the long-lived timer.

Issues

AB#44848

Testing

Tests

  • ChannelDbConnectionPoolPruningTest.cs: 19 test methods (28 runtime cases including Theory data) covering:
    • Timer creation and configuration (fixed-size pool skips, sample size calculation, clamp)
    • UpdateTimer enable/disable logic
    • Pruning callback: sampling, buffer reset, MinPoolSize floor, in-use connection safety
    • Sample values verified after each callback
    • DivideRoundingUp correctness (7 cases)
    • Shutdown/Dispose behavior
    • Integration: full prune to zero, median prevents aggressive pruning during brief lulls
  • All tests use using var pool for deterministic cleanup via IDisposable
  • GetPruner() helper eliminates null-forgiving operator noise

Guidelines

Please review the contribution guidelines before submitting a pull request:

@apoorvdeshmukh apoorvdeshmukh requested a review from a team as a code owner May 21, 2026 16:17
Copilot AI review requested due to automatic review settings May 21, 2026 16:17
@github-project-automation github-project-automation Bot moved this to To triage in SqlClient Board May 21, 2026
@apoorvdeshmukh apoorvdeshmukh marked this pull request as draft May 21, 2026 16:17
@apoorvdeshmukh apoorvdeshmukh added this to the 7.1.0-preview2 milestone May 21, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds an automatic “pruning” mechanism to ChannelDbConnectionPool (pool V2) to gradually reduce excess idle connections during low demand by sampling idle counts over time and pruning based on the median sample.

Changes:

  • Introduces pruning state, sampling logic, and a one-shot timer callback to periodically evaluate and close excess idle connections.
  • Wires pruning timer enable/disable behavior into connection add/remove paths and disposes the timer during pool shutdown.
  • Adds a dedicated unit test suite validating pruning configuration, sampling/median behavior, floors (MinPoolSize), and shutdown behavior.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
src/Microsoft.Data.SqlClient/src/Microsoft/Data/SqlClient/ConnectionPool/ChannelDbConnectionPool.cs Implements the pruning timer, sampling window/median computation, and integrates timer lifecycle with pool growth/shrink/shutdown.
src/Microsoft.Data.SqlClient/tests/UnitTests/ConnectionPool/ChannelDbConnectionPoolPruningTest.cs Adds unit tests covering pruning timer creation/configuration, sampling/median pruning behavior, and shutdown semantics.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

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

@apoorvdeshmukh apoorvdeshmukh marked this pull request as ready for review May 27, 2026 13:44
Copilot AI review requested due to automatic review settings May 27, 2026 13:44
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 27, 2026

Codecov Report

❌ Patch coverage is 98.27586% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 64.64%. Comparing base (bfbdd30) to head (3e43ad2).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
...rosoft/Data/SqlClient/ConnectionPool/PoolPruner.cs 97.26% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4304      +/-   ##
==========================================
- Coverage   66.69%   64.64%   -2.05%     
==========================================
  Files         284      280       -4     
  Lines       43238    66162   +22924     
==========================================
+ Hits        28836    42773   +13937     
- Misses      14402    23389    +8987     
Flag Coverage Δ
CI-SqlClient ?
PR-SqlClient-Project 64.64% <98.27%> (?)

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.

Copy link
Copy Markdown
Contributor

@mdaigle mdaigle left a comment

Choose a reason for hiding this comment

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

Would like to see some improvements to the tests, otherwise looks good!

@github-project-automation github-project-automation Bot moved this from To triage to Waiting for customer in SqlClient Board May 27, 2026
@apoorvdeshmukh apoorvdeshmukh requested a review from mdaigle May 29, 2026 17:08
Copilot AI review requested due to automatic review settings May 30, 2026 10:33
Copilot AI review requested due to automatic review settings June 3, 2026 20:25
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

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

@apoorvdeshmukh apoorvdeshmukh moved this from Waiting for customer to In review in SqlClient Board Jun 3, 2026
@paulmedynski paulmedynski added Area\Connection Pooling Use this label to tag issues that apply to problems with connection pool. Author attention needed PRs that require author to respond or make updates to PR. labels Jun 4, 2026
@apoorvdeshmukh apoorvdeshmukh removed the Author attention needed PRs that require author to respond or make updates to PR. label Jun 4, 2026
Copy link
Copy Markdown
Contributor

@paulmedynski paulmedynski left a comment

Choose a reason for hiding this comment

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

Looks good - just a few minor tweaks.

@github-project-automation github-project-automation Bot moved this from In review to Waiting for customer in SqlClient Board Jun 4, 2026
@paulmedynski paulmedynski added the Author attention needed PRs that require author to respond or make updates to PR. label Jun 4, 2026
Copilot AI review requested due to automatic review settings June 4, 2026 18:13
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@apoorvdeshmukh apoorvdeshmukh removed the Author attention needed PRs that require author to respond or make updates to PR. label Jun 4, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@paulmedynski paulmedynski added the Author attention needed PRs that require author to respond or make updates to PR. label Jun 4, 2026
Copilot stopped reviewing on behalf of apoorvdeshmukh due to an error June 4, 2026 19:13
@apoorvdeshmukh apoorvdeshmukh removed the Author attention needed PRs that require author to respond or make updates to PR. label Jun 4, 2026
}

[Fact]
public void PruneIdleConnections_SecondWindowAfterPrune_RecomputesMedianFromFreshSamples()
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.

👍

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: Waiting for customer

Development

Successfully merging this pull request may close these issues.

5 participants