Skip to content

Commit

Permalink
Add -noCloseOnTimeout switch to block calling .dispose() on timed-out…
Browse files Browse the repository at this point in the history
… threads and to no .close() the runspace when threads have timed out in order to prevent hangs in certain circumstances.

Moved TimedOut thread logging to occur before the potential hang.
  • Loading branch information
psitem committed Dec 11, 2014
1 parent e30e388 commit 2f52593
Showing 1 changed file with 18 additions and 8 deletions.
26 changes: 18 additions & 8 deletions Invoke-Parallel.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@
WARNING: Using this parameter requires that maxQueue be set to throttle (it will be by default) for accurate timing. Details here:
http://gallery.technet.microsoft.com/Run-Parallel-Parallel-377fd430
.PARAMETER noCloseOnTimeout
Do not dispose of timed out tasks or attempt to close the runspace if threads have timed out. This will prevent the script from hanging in certain situations where threads become non-responsive, at the expense of leaking memory within the PowerShell host.
.PARAMETER maxQueue
Maximum number of powershell instances to add to runspace pool. If this is higher than $throttle, $timeout will be inaccurate
Expand Down Expand Up @@ -137,6 +140,8 @@

[int]$runspaceTimeout = 0,

[switch]$noCloseOnTimeout = $false,

[int]$maxQueue = $(
if($runspaceTimeout -ne 0){$Throttle}
else{$throttle * 3}
Expand Down Expand Up @@ -216,17 +221,18 @@
ElseIf ( $runspaceTimeout -ne 0 -and $runtime.totalseconds -gt $runspaceTimeout) {

$script:completedCount++
$timedOutTasks = $true

#add logging details and cleanup
$log.status = "TimedOut"
Write-verbose ($log | convertto-csv -Delimiter ";" -NoTypeInformation)[1]

#Depending on how it hangs, we could still get stuck here as dispose calls a synchronous method on the powershell instance
$runspace.powershell.dispose()
if ($noCloseOnTimeout) { $runspace.powershell.dispose() }
$runspace.Runspace = $null
$runspace.powershell = $null
$completedCount++

#add logging details and cleanup
$log.status = "TimedOut"
Write-verbose ($log | convertto-csv -Delimiter ";" -NoTypeInformation)[1]

}

#If runspace isn't null set more to true
Expand Down Expand Up @@ -306,6 +312,8 @@
$log.Details = $null
if($logFile) { ($log | convertto-csv -Delimiter ";" -NoTypeInformation)[1] | out-file $logFile -append }

$timedOutTasks = $false

#endregion INIT

}
Expand Down Expand Up @@ -379,9 +387,11 @@
Write-Verbose ( "Finish processing the remaining runspace jobs: {0}" -f (@(($runspaces | Where {$_.Runspace -ne $Null}).Count)) )
Get-RunspaceData -wait

Write-Verbose "Closing the runspace pool"
$runspacepool.close()

if ( ($timedOutTasks -eq $false) -or (($timedOutTasks -eq $true) -and ($noCloseOnTimeout -eq $false)) ) {
Write-Verbose "Closing the runspace pool"
$runspacepool.close()
}

#collect garbage
[gc]::Collect()
}
Expand Down

0 comments on commit 2f52593

Please sign in to comment.