Repository navigation
Read-DbaBackupHeader, Start-/Stop-DbaDbEncryption - Run the threads in a pool without a host and close it in a finally - #10789
Conversation
…n a pool without a host and close it in a finally The three commands created their runspace pool on $Host. Once a thread had run there, the warnings, verbose messages and progress records of the calling pipeline no longer reached the streams of a host created through the PowerShell API. The pool is now created without a host. The threads write no warnings of their own, except the encryption threads when their connection fails; they now connect with EnableException, so the reason lands in the Error of the result instead of a thread stream. The pool was closed only after the loop that receives the threads, and a failed thread skipped its Dispose(). A throw under EnableException, Ctrl+C or Select-Object -First left the pool open, and Read-DbaBackupHeader did not restore the default runspace. The finally now disposes every thread and closes and disposes the pool. Part of #10776. (do Read-DbaBackupHeader, Start-DbaDbEncryption, Stop-DbaDbEncryption, Restore-DbaDatabase, Get-DbaBackupInformation) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…it was Connect-DbaInstance throws by default and has -DisableException instead of -EnableException, so the threads already put the reason of a failed connection into the Error of their result. Passing EnableException failed every thread with a parameter binding error. (do Start-DbaDbEncryption, Stop-DbaDbEncryption) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…mplete The Stop-Function -Continue for a row with BackupName "*** INCOMPLETE ***" sat in the loop over the rows, so it only skipped the rest of that loop and the file was returned anyway. The rows are checked first now, and the -Continue skips the file, as its message says. No regression test: older SQL Server versions write that marker for a backup of a newer one. SQL Server 2019 reading a 2025 backup returns an empty BackupName and DatabaseVersion 998 instead, and neither the lab nor CI has an instance older than 2019. (do Read-DbaBackupHeader) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
potatoqualitee
left a comment
There was a problem hiding this comment.
Reviewed at f790dac231584131c7b07056ceb1e4ec2312fa7a. No material defect found.
Reviewed the complete six-file patch, worker/caller code, tests, description, discussions, and exact-head CI. The hostless pool preserves concurrency and parent-side warning/error reporting. The finally blocks cover failed result handling and early pipeline termination, and the added integration tests exercise API-host output and leaked-runspace detection.
Focused validation with the real PowerShell 7.6.7 runspace API confirmed worker cancellation, safe repeated disposal, and pool closure. All six changed files parsed successfully. All 20 executed head checks passed and one generic Windows check was skipped. The SQL Server integration suite was not rerun locally.
|
merci |
Part of #10776: section 1 and the pool items of section 2.
The problem
Read-DbaBackupHeader (and with it Restore-DbaDatabase and Get-DbaBackupInformation) and Start-/Stop-DbaDbEncryption
-Parallelcreated their runspace pool withCreateRunspacePool(1, 10, $initialSessionState, $Host). Once a thread of that pool had run, the warnings, verbose messages and progress records of the calling pipeline no longer reached the streams of a host created through the PowerShell API (automation hosts, SDK hosts, notebooks). In a console nobody notices, because the records go to the console UI. Through the API, a Restore-DbaDatabase loses every warning written after the backup headers were read, including the warnings of Stop-Function.The pool was also closed only after the loop that receives the threads, and a failed thread skipped its
Dispose(). A throw under-EnableException, Ctrl+C orSelect-Object -Firstleft the pool and its runspaces open, and Read-DbaBackupHeader left[Runspace]::DefaultRunspaceunrestored.The fix
CreateRunspacePool($initialSessionState)plusSetMaxRunspaces(10). There is no overload with minimum, maximum and session state but no host, and the minimum is 1 by default.trynow starts before the threads are created. Itsfinallydisposes every thread (a thread that still runs is stopped byDispose()), then closes and disposes the pool. Read-DbaBackupHeader also restores the default runspace there.Most of the diff is indentation: the loop that creates the threads moved into the
try.git diff -wshows the real change. The single quotes in the re-indented lines of Read-DbaBackupHeader became double quotes.Read-DbaBackupHeader: an incomplete header returned the file anyway
Found while re-checking the command, not in #10776. The
Stop-Function -Continuefor a row with BackupName*** INCOMPLETE ***("appears to be from a new version of SQL Server ..., skipping") sat in the loop over the rows, so it only skipped the rest of that loop and the file was returned anyway. The rows are checked first now, and the-Continueskips the file, as its message says.There is no regression test for this one: older SQL Server versions write that marker for a backup of a newer one. SQL Server 2019 reading a 2025 backup returns an empty BackupName and DatabaseVersion 998 instead (checked in the lab), and neither the lab nor CI has an instance older than 2019.
Tests
Every new context runs the command in a host created through the PowerShell API, the way the progress tests of #10773-#10775 do:
Select-Object -First 1and checks that no runspace is left open.-ParallelwithSelect-Object -First 1checks the result, the completion of progress bar Id 1 in the host's streams and the number of open runspaces.The comments in the existing progress contexts that said the
-Parallelbar cannot be checked this way got a line pointing to the new context.Verified
In the lab on SQL Server 2019 (single instance) and 2022/2025 (the others), on Windows PowerShell 5.1 and PowerShell 7.6. CI runs Pester on 5.1 only.
Read-DbaBackupHeader and dbatools.Tests.ps1 ran again at the last commit, with the same result.
No warnings in any of them. Against the old commands (5.1) the new tests fail with exactly the new assertions: the warning and the completed record never reach the host's streams, and
Select-Object -First 1leaves one runspace open in Read-DbaBackupHeader and two in Start-/Stop-DbaDbEncryption.Not in this PR
private/functions/flowcontrol/Invoke-Parallel.ps1:450creates its pool on$Hosttoo (callers: Start-/Stop-/Restart-DbaService through Update-ServiceStatus, Install-/Update-DbaInstance with two or more computers, Invoke-DbaPfRelog). There the threads do write warnings and progress that a console user sees live today, and Invoke-Parallel forwards only their errors, so it needs its own decision.🤖 Generated with Claude Code