Repository navigation
Worker rules: allow cmdlets, check by default, refuse scriptblock job values - #5
Merged
Merged
Conversation
… values Cmdlets in workers don't hang. The hangs blamed on them came from scriptblocks running on another runspace's thread (PowerShell issue #4003): a delegate, or a scriptblock passed in as a job value. - Test-PkWorkerSafety no longer flags cmdlets. DelegateCast messages say "hang or crash" instead of "deadlock". - Functions from a module (Get-FileHash in 5.1) no longer count as unshared functions; they autoload in the worker. - Invoke-PkRunspaceJobs runs the safety check by default; -CheckWorkerSafety:$false turns it off. - With the check on, a job value that is (or directly holds) a scriptblock is refused: before any worker starts for -JobParams, per job for -NextJobProvider. The message gives the pass-as-text workaround. - README: two rules instead of three, the real mechanism, new FAQ answers, and the hashing example uses Get-FileHash. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Test-PkWorkerSafety only caught a scriptblock written directly in a
.NET call. It now also flags a variable assigned a scriptblock literal
(or { }.GetNewClosure()) in the same code when that variable is passed
to a .NET method or constructor, e.g. [System.Lazy[object]]::new($f).
.ForEach()/.Where() stay exempt. README lists comparers and event/task
callbacks among the delegate cases.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <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.
What was wrong. The README's rule 2 banned cmdlets in worker code, blaming a race in first-time cmdlet setup. Stress testing doesn't back that up: thousands of rounds of 8 workers calling cmdlets at the same instant never hung. The real cause is a scriptblock running on another runspace's thread (PowerShell/PowerShell#4003). With an inner scriptblock (
Where-Object { }, a nested delegate) that deadlocks, and even without one it can crash the process. A scriptblock passed in as a job value is the same case and the checker couldn't see it: 8 workers running one passed from the main thread broke 88 of 90 stress runs, while the same code passed as text and rebuilt with[scriptblock]::Createran clean in 30 of 30.What changed.
Test-PkWorkerSafetydrops theCmdletrule.DelegateCastmessages say "hang or crash".{ }.GetNewClosure()) when it's passed to a .NET method or constructor, e.g.[System.Lazy[object]]::new($factory).Get-FileHash, a script function in 5.1) are no longer reported as unshared functions; they autoload in the worker.Invoke-PkRunspaceJobsruns the safety check by default (-CheckWorkerSafety:$falseturns it off). Existing-CheckWorkerSafetycalls still work.-JobParams, per job for-NextJobProvider. The error names the job and key and gives the pass-as-text workaround.Get-FileHash.Breaking: worker code with delegates, or jobs carrying scriptblocks, that used to launch is now refused unless the check is turned off. Intended for v2.0.
Testing. Harness: 179 assertions pass. The new assertions (cmdlets pass the check, the check runs unasked, scriptblock job values refused for a fixed list / inside an array / from
-NextJobProvider) fail againstmain's kit (5 failures); the two scriptblock-variable assertions fail against the first commit's kit. The README's hashing example was run as written.🤖 Generated with Claude Code