We don’t use runspace pools directly in PSU. We have our own implementation that allows for more customization and that’s why you can seeing max\min set to 1.
I would recommend trying to see what is currently executing in the process. The code that is failing internally, is this. The max runspace setting changes the semaphore count. If an API call waits for more than 5 seconds before a runspace is available, what you are seeing will happen.
if (!_runspaceSemaphore.Wait(5000))
{
throw new Exception("Failed to get runspace.");
}
I created an endpoint in my example that can return the current runspace state. It would also be possible to run this directly on the PSU server by using Enter-PSHostProcess and running the Get-Runspace command over remoting.
New-PSUEndpoint -Url "/runspace-info" -Method @('GET') -Endpoint {
Get-Runspace | ForEach-Object {
@{
Name = $_.Name
Availability = $_.RunspaceAvailability.ToString()
CallStack = $_.Debugger.GetCallstack()
}
}
}
What is returned is this. Each object has the name and runspace availability. If it’s busy, you’ll see a call stack.
CallStack : {@{ScriptName=; ScriptLineNumber=2; InvocationInfo=; Position=; FunctionName=<ScriptBlock>},
@{ScriptName=; ScriptLineNumber=1; InvocationInfo=; Position=; FunctionName=<ScriptBlock>}}
Availability : Busy
Name : Runspace121
CallStack : {}
Availability : Busy
Name : Runspace126
$RS.CallStack.InvocationInfo | fl *
Accessing the CallStack.InvocationInfo property will display what’s happening in the runspace. You can see below that MyCommand is set to Start-Sleep 10.
MyCommand : @{ScriptBlock=
Start-Sleep 10
; Definition=
Start-Sleep 10
; OutputType=; Name=; CommandType=64; Source=; Version=; Visibility=0; ModuleName=; Module=;
RemotingCapability=1; Parameters=; ParameterSets=}
BoundParameters :
UnboundArguments : {}
ScriptLineNumber : 1
OffsetInLine : 1
HistoryId : 1
ScriptName :
Line : & $PSUSB
PositionMessage : At line:1 char:1
+ & $PSUSB
I would recommend trying to turn off RunspaceRecycling as it will periodically dispose of runspaces after they have been used a number of times. HighPerformanceRunspacePools were deprecated in v3 and the switch doesn’t actually do anything.
Additionally, we use MiniProfiler throughout the Runspace factory so if you switch to the integrated environment you can get timings for your endpoints and allocations in the factory.
using (MiniProfiler.Current.Step("UDRunspaceFactory.GetRunspace"))
{
If you want priority on things like this in the future, make sure to open a case by emailing support[@]ironmansoftware.com