Export-DbaCsv - Close the database-scoped connection it opens per call - #10634
Conversation
Every call with -SqlInstance leaked one connection: Connect-DbaInstance is called with -Database, which returns a server whose connection was opened for this call, and the command never closed it. One sleeping session per call, held until the process exits. The test file left 18 sessions behind on its own; the first -CheckSleepingConnections full run flagged it as +17. The fix is the established #10554 pattern: ask Connect-DbaInstance via IsNewConnectionReference whether it opened the connection and close it with Disconnect-DbaInstance only then. The disconnect sits in a finally so it also runs when the export fails and the catch continues with the next instance, and when -WhatIf skips the export altogether. The new regression test counts sleeping dbatools sessions through a server object opened once, takes a warm-up call so the shared pooled connection exists before the baseline, and asserts three more calls add nothing. Verified red on the unfixed command (expected 14, got 17) and green on the fix (16 passed, 0 failed); the runner measurement of the whole file drops from 18 to 2. (do Export-DbaCsv) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
potatoqualitee
left a comment
There was a problem hiding this comment.
The new finally still leaks the command-owned database connection under Export-DbaCsv -WhatIf. The connection is opened before the outer ShouldProcess; then $WhatIfPreference propagates into Disconnect-DbaInstance, whose own ShouldProcess skips .Disconnect(). This directly contradicts the PR's claim that the -WhatIf path is closed. Please force cleanup semantics on the internal ownership call (for example Disconnect-DbaInstance -WhatIf:$false -Confirm:$false -Verbose:$false) and add a repeated -WhatIf connection-count regression.
Review follow-up: Disconnect-DbaInstance supports ShouldProcess, so the propagated WhatIf preference skipped the disconnect in the finally. The ownership cleanup now passes -WhatIf:$false -Confirm:$false - it is bookkeeping for a connection this command opened, not part of the user's operation. Probed on the lab: the skip is real, but no session leaks on this stack because SMO connects lazily and -WhatIf never runs a query on the clone - the defect is latent, so the new repeated -WhatIf counting regression guards the invariant without a red-on-old. (do Export-DbaCsv) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Fixed in 26cb375 - the ownership disconnect now passes One finding from verifying the mechanism on the lab (Windows PowerShell 5.1, instrumented run): the ShouldProcess skip is exactly as described - The requested repeated created by Claude and reviewed by Andreas Jordan |
potatoqualitee
left a comment
There was a problem hiding this comment.
The updated head resolves the prior blocking feedback; no material issues remain.
Summary
Second fix from the sleeping-connection inventory (first: #10633). Every
Export-DbaCsv -SqlInstancecall leaked one connection to the instance, held open until the process exits. The command's own test file left 18 sleeping sessions behind in an isolated runner measurement; the first-CheckSleepingConnectionsfull lab run flagged it at +17.Mechanism
The command calls
Connect-DbaInstance -Database $Database, which returns a server object whose connection was opened for this call (the database-scoped clone path), streams the data reader off its rawSqlConnectionObject- and never closes the connection. The throwaway server object keeps the session checked out of the pool.Fix
The established #10554 ownership pattern: pass
IsNewConnectionReference [ref]$isNewConnectiontoConnect-DbaInstanceand close viaDisconnect-DbaInstanceonly when it reports the connection as newly opened. The disconnect sits in afinallyso it also runs when the export fails (Stop-Function -Continueleaves the try block) and when-WhatIfskips the export - two paths where the sibling pattern inInvoke-DbaQueryplaces the disconnect after the catch and would miss it.Tests
New context counts sleeping dbatools sessions through a server object opened once (a per-call counting command would open connections of its own), with a warm-up call before the baseline, asserting three further calls add nothing. Verified red on the unfixed command ("Expected 14, but got 17") and green on the fix (16 passed, 0 failed via the lab harness on SQL03\SQL2019). Runner measurement of the whole file: 18 sleeping sessions before, 2 after.
created by Claude and reviewed by Andreas Jordan
馃 Generated with Claude Code