Add RAII lease handle (LeaseScopeAsync) + leak metric; move Smtp.Pool tests out of CI - #3
Merged
Conversation
LeaseScopeAsync wraps a leased item in a disposable Lease<TPoolItem> so a `using` returns it on scope exit. Disposal is idempotent and single-shot (immune to the double-release footgun), and if the pool was disposed while the item was out on lease the lease disposes the orphaned item itself. A Lease garbage-collected without being disposed is recorded on a new pool.leases.leaked counter (published on the MSL.Pool meter, tagged pool.name) so leaks are observable. The finalizer is suppressed up front in Dispose, so an unexpected Release failure still propagates but is never miscounted as a leak. Purely additive: builds on the existing public LeaseAsync/Release, so it needs no change to Pool, IPool, or IPoolMetrics and works with any IPool implementation. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Convert the integration test's lease/try/finally to a scoped `using` lease, and update SmtpConnection's send doc comment to recommend the scoped pattern. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The Smtp.Pool sample's unit and integration test projects move from tests/ to samples/ alongside the sample, with their ProjectReference paths fixed, and are removed from Pool.slnx so neither CI workflow runs them (both test Pool.slnx, and the integration suite needs Docker). A new samples/Smtp.Pool.slnx (sample + its tests + Pool) keeps them runnable locally as a unit. Also includes CI housekeeping staged alongside: a setup-dotnet composite action, a dependabot config, and workflow trigger/cleanup updates. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two independent, additive changes on top of the already-merged metrics modernization:
samples/and out of the CI gate, plus some CI housekeeping.No breaking changes in this PR. (The metrics rename to OTEL conventions already landed on
mainasmetrics modernization; this branch builds on it.)1. RAII lease handle (
LeaseScopeAsync)LeaseScopeAsync(extension over the existing publicLeaseAsync/Release) returns a disposableLease<TPoolItem>; theusingreturns the item on scope exit.Leasegarbage-collected without being disposed is recorded on a newpool.leases.leakedcounter (published on theMSL.Poolmeter, taggedpool.name). The finalizer is suppressed up front inDispose, so an unexpectedReleasefailure still propagates but is never miscounted as a leak.Pool,IPool, orIPoolMetrics; works with anyIPoolimplementation. The Smtp.Pool sample's send path now uses it.2. Move Smtp.Pool tests into
samples/, out of the CI gateSmtp.Pool.TestsandSmtp.Pool.Integration.Testsmove fromtests/tosamples/alongside the sample (git mv, history preserved).Pool.slnx, so neither CI workflow runs them (both testPool.slnx; the integration suite needs Docker and shouldn't gate the library).samples/Smtp.Pool.slnx(sample + its tests +Pool) keeps them runnable locally as a unit.setup-dotnetcomposite action, a dependabot config, and workflow trigger/cleanup updates.Verification
dotnet test Pool.slnx→ 94 tests, onlyPool.Tests(smtp suite no longer in the CI solution).dotnet build samples/Smtp.Pool.slnx→ full graph, 0 warnings.samples/Smtp.Pool.Tests→ 43 pass, coverage above its floor (rootDirectory.Build.propsstill applies).AnalysisMode=all+ warnings-as-errors; Pool.Tests coverage 100% line / 92% branch / 100% method (above the 95/90/95 ratchet).🤖 Generated with Claude Code