-
Notifications
You must be signed in to change notification settings - Fork 86
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Missing output from Start-RSJob *bug* #121
Comments
except online/offline problems I suspect bad behaviour of export-csv in multithreaded environment |
Thanks for the reply. I'm not sure how to check the PoshRS release version that I am currently running, but could this possibly be a bug that was fixed from an earlier release? I see that there is a new version of PoshRS that was released 9 days ago. I may try that if you think it could help. I'll also try the try/catch blocks like you suggested. |
This definitely sounds like an caused by multithreading with different runspaces fighting over who gets to write to a single file. I would recommend using something like a mutex in your scriptblock to help ensure that only run thread has access at a time to update the CSV file to avoid missing information. I wrote about using mutexes in PowerShell at the link below that might help you out. Using Mutexes to Write Data to the Same Logfile Across Processes With PowerShell |
Awesome, thanks for the reply! I'll read up on it and give it a shot. Not
sure if this could be an option to add into the next release of PoshRS or
not.
…On Jan 25, 2017 7:30 PM, "Boe Prox" ***@***.***> wrote:
This definitely sounds like an caused by multithreading with different
runspaces fighting over who gets to write to a single file. I would
recommend using something like a mutex in your scriptblock to help ensure
that only run thread has access at a time to update the CSV file to avoid
missing information. I wrote about using mutexes in PowerShell at the link
below that might help you out.
Using Mutexes to Write Data to the Same Logfile Across Processes With
PowerShell
<https://learn-powershell.net/2014/09/30/using-mutexes-to-write-data-to-the-same-logfile-across-processes-with-powershell/>
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#121 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AYJXxwLtGp6Z0OFBdEWSyoc8m88NXGR7ks5rV5TdgaJpZM4LsDh1>
.
|
@hou8182 Unfortunately, this would be difficult to do as you would really only want to use the mutex where needed which would rely on the person writing the code to identify where that would be. I could add some mutex code at the beginning and end of the scriptblock, but that type of block would impact the performance on the runspace jobs as each one would have to wait for the runspace holding the lock to complete before beginning the next job. |
@hou8182 do the jobs finish? Do they set the HasErrors flags? Or do they finish and with no errors but Receive-RSJob shows nothing? If so try setting Set-StrictMode -VersionLatest; $ErrorActionPreference = "Stop"; at the top of your script block so that any errors terminate and print out the cause. (Those will be shown on screen by Receive-RSJob but not directed to a variable, so you'd have to run it interactively or redirect the error stream). |
Just catched the same problem function DoTest {
$jobs = 1,2,3 | Start-RSJob { $_ }
#bad
$jobs | Wait-RSJob | Receive-RSJob | Sort
#good
# $wj = $jobs | Wait-RSJob
# $jobs | Receive-RSJob | Sort
$jobs | Remove-RSJob
}
Describe "Test Wait-RSJob | Receive-RSJob Scenario" -Tags Scenario {
Context "output" {
1..200 | Foreach-Object {
It "try $_, get 1,2,3" {
DoTest | Should -Be 1,2,3
}
}
}
} btw, for 1000 iterations I get memory problems |
debug output on good and error conditions:
|
Are you using the current version? Because Boe included a fix of mine a month or so ago. |
definitely. D:\Work\ps\Scripts\Pester\m> $PSVersionTable
Name Value
---- -----
PSVersion 5.1.14409.1005
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.14409.1005
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
D:\Work\ps\Scripts\Pester\m> Get-Module PoshRSJob
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Script 1.7.3.8 PoshRSJob {Get-RSJob, Receive-RSJob, Remove-RSJob, Start-RSJob...} |
Try to launch on other computer with more memory and Win10 onboard PS D:\Work\1> $PoshRS_RunspacePools.Count
810 may be btw, I'm not found any |
I think at least it is need to move [System.Threading.Monitor]::Enter($PoshRS_RunspacePools.syncroot)
[System.Threading.Monitor]::Exit($PoshRS_RunspacePools.syncroot) or (minimum) out of foreach into code branch after and move |
I'm got it so, to resolve race condition and garbage collection outside of Monitor for #48 diff --git a/PoshRSJob/PoshRSJob.psm1 b/PoshRSJob/PoshRSJob.psm1
index cb85242..1df46cb 100644
--- a/PoshRSJob/PoshRSJob.psm1
+++ b/PoshRSJob/PoshRSJob.psm1
@@ -153,13 +153,13 @@ $PoshRS_jobCleanup.PowerShell = [PowerShell]::Create().AddScript({
}
#$PoshRS_jobCleanup.Host.UI.WriteVerboseLine("$($Job.Id) Disposing job")
$job.InnerJob.dispose()
- $job.Completed = $True
#Return type from Invoke() is a generic collection; need to verify the first index is not NULL
If (($Data.Count -gt 0) -AND (-NOT ($Data.Count -eq 1 -AND $Null -eq $Data[0]))) {
$job.output = $Data
$job.HasMoreData = $True
}
$Error.Clear()
+ $job.Completed = $True
}
}
[System.Threading.Monitor]::Exit($PoshRS_Jobs.syncroot)
@@ -192,6 +192,10 @@ $PoshRS_RunspacePoolCleanup.PowerShell = [PowerShell]::Create().AddScript({
#Routine to handle completed runspaces
Do {
#$ParentHost.ui.WriteVerboseLine("Beginning Do Statement")
+ If ($DisposePoshRS_RunspacePools) {
+ #Perform garbage collection
+ [gc]::Collect()
+ }
$DisposePoshRS_RunspacePools=$False
If ($PoshRS_RunspacePools.Count -gt 0) {
#$ParentHost.ui.WriteVerboseLine("$($PoshRS_RunspacePools | Out-String)")
@@ -205,11 +209,6 @@ $PoshRS_RunspacePoolCleanup.PowerShell = [PowerShell]::Create().AddScript({
$RunspacePool.RunspacePool.Dispose()
$RunspacePool.CanDispose = $True
$DisposePoshRS_RunspacePools=$True
-
- #Perform garbage collection
- [gc]::Collect()
- Start-Sleep -Seconds 5
- [gc]::Collect()
}
} Else {
$RunspacePool.LastActivity = (Get-Date)
@@ -224,12 +223,20 @@ $PoshRS_RunspacePoolCleanup.PowerShell = [PowerShell]::Create().AddScript({
#$ParentHost.ui.WriteVerboseLine("Removing runspacepool <$($_.RunspaceID)>")
[void]$PoshRS_RunspacePools.Remove($_)
}
+ #Not setting this to silentlycontinue seems to cause another runspace to be created if an error occurs
+ Remove-Variable TempCollection -ErrorAction SilentlyContinue
}
- #Not setting this to silentlycontinue seems to cause another runspace to be created if an error occurs
- Remove-Variable TempCollection -ErrorAction SilentlyContinue
[System.Threading.Monitor]::Exit($PoshRS_RunspacePools.syncroot)
}
#$ParentHost.ui.WriteVerboseLine("Sleeping")
+ If ($DisposePoshRS_RunspacePools) {
+ #Perform garbage collection
+ [gc]::Collect()
+ # already have sleep later,
+ #Start-Sleep -Seconds 5
+ # optimization: moved to top of a cycle
+ #[gc]::Collect()
+ }
Start-Sleep -Milliseconds 5000
} while ($PoshRS_RunspacePoolCleanup.Flag)
}) |
on much more powerful computer (which can create a lot of RunspacePools in small time) there is a memory problems diff --git a/PoshRSJob/Public/Start-RSJob.ps1 b/PoshRSJob/Public/Start-RSJob.ps1
index 2ff9c86..88243d1 100644
--- a/PoshRSJob/Public/Start-RSJob.ps1
+++ b/PoshRSJob/Public/Start-RSJob.ps1
@@ -419,7 +419,12 @@ Function Start-RSJob {
}
[void]$RunspacePool.SetMaxRunspaces($Throttle)
If ($PSVersionTable.PSVersion.Major -gt 2) {
- $RunspacePool.CleanupInterval = [timespan]::FromMinutes(2)
+ if ($PSBoundParameters.ContainsKey('Batch')) {
+ $RunspacePool.CleanupInterval = [timespan]::FromMinutes(2)
+ }
+ else {
+ $RunspacePool.CleanupInterval = [timespan]::FromSeconds(10)
+ }
}
$RunspacePool.Open()
$RSPObject = New-Object RSRunspacePool -Property @{
so there is a fundamental problem with such usage pattern (or .Net limitations I not know about) |
I ran a script to return the number of days that a list of 10,000 computers has been online. I sent the output to a CSV file, but when I opened it I was missing results from over 4,000 machines. I have had other scripts that I've fed into Start-RSJob that have performed in a similar manner where the output results do not come back 100%.
I have to rerun the script over on everything that Start-RSJob did not return the first time around. Sometimes I have to do this several times. I'm not sure what the problem could be since I was able to verify that all machines were online and reachable. Is this a known bug that was fixed or is being worked on in a later release of PoshRSJob?
If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem
` $computers = Get-Content "C:\Users\Admin\Desktop\PowerShell Testing\DifferenceResults.txt"
Param($Computer)
$PSBoundParameters.GetEnumerator() | ForEach {
What is the expected behavior?
The script should return 100% of the uptime results into the CSV file that I named, but seems to only return about half of the results.
Which versions of Powershell and which OS are affected by this issue? Did this work in previous versions of our scripts?
I am running PS5 on Win7.
The text was updated successfully, but these errors were encountered: