Add automatic pool size reduction (pruning) to ChannelDbConnectionPool#4304
Add automatic pool size reduction (pruning) to ChannelDbConnectionPool#4304apoorvdeshmukh wants to merge 20 commits into
Conversation
There was a problem hiding this comment.
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. |
Codecov Report❌ Patch coverage is
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
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
mdaigle
left a comment
There was a problem hiding this comment.
Would like to see some improvements to the tests, otherwise looks good!
paulmedynski
left a comment
There was a problem hiding this comment.
Looks good - just a few minor tweaks.
| } | ||
|
|
||
| [Fact] | ||
| public void PruneIdleConnections_SecondWindowAfterPrune_RecomputesMedianFromFreshSamples() |
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
LoadBalanceTimeout / PruningIntervalsamples (defaults to 300s / 10s = 30 samples whenConnection Lifetimeis 0), clamped toMaxSampleSize(300).MinPoolSize.MinPoolSize >= MaxPoolSize, noPoolPruneris created.Architecture
Pruning logic is encapsulated in a dedicated
PoolPrunerclass (IDisposable):PoolPrunerowns the timer, sample buffer, and sampling/pruning logic.ChannelDbConnectionPoolholds a nullablePrunerauto-property —nullfor fixed-size pools.Pruner?.UpdateTimer()after connections are opened or closed.PruneConnections(int count)for the pruner to call back into.ChannelDbConnectionPoolimplementsIDisposable(delegates toShutdown()).Changes
PoolPruner.cs(new): Encapsulates all pruning state and logic — timer, sample buffer, median calculation, enable/disable, and disposal.ChannelDbConnectionPool.cs: AddedPoolPruner? Prunerauto-property,PruneConnections()callback method,IDisposableimplementation, and pruner creation in constructor.ChannelDbConnectionPoolPruningTest.cs(new): Unit tests for pruning behavior.Thread Safety
lock(_timer)to read/write shared sample state.Dispose()acquires the same lock with a_disposedguard to prevent double-disposal.UpdateTimer()checks_pool.IsRunningboth before and inside the lock to avoid post-shutdown races.IsRunningandMinPoolSizefloor on each iteration.ADP.UnsafeCreateTimerto avoid capturingExecutionContextonto the long-lived timer.Issues
AB#44848
Testing
Tests
ChannelDbConnectionPoolPruningTest.cs: 19 test methods (28 runtime cases including Theory data) covering:UpdateTimerenable/disable logicDivideRoundingUpcorrectness (7 cases)using var poolfor deterministic cleanup viaIDisposableGetPruner()helper eliminates null-forgiving operator noiseGuidelines
Please review the contribution guidelines before submitting a pull request: