-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Use dedicated threads to read the redirected output and error streams from the child process for out-of-proc jobs #11713
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
Conversation
src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs
Outdated
Show resolved
Hide resolved
src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs
Outdated
Show resolved
Hide resolved
src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs
Outdated
Show resolved
Hide resolved
src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs
Outdated
Show resolved
Hide resolved
|
It creates its own thread, so it's not affected.
I don't think that's needed. Thread pool threads should only for short living tasks. When it comes to long-living tasks, even a separate dedicated thread pool will have the same starvation problem. |
|
Dedicated thread pool for thread jobs is not needed because both ThreadJob and ForEach-Object -Parallel have throttling and queuing, which is basically performs the same function as a thread pool. |
src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs
Outdated
Show resolved
Hide resolved
src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs
Outdated
Show resolved
Hide resolved
PaulHigin
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs
Outdated
Show resolved
Hide resolved
src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs
Outdated
Show resolved
Hide resolved
|
@PoshChan Please retry mac |
|
@daxian-dbw, I do not understand the build target(s) |
|
@PoshChan Please retry macos |
|
@daxian-dbw, successfully started retry of |
|
Turns out the failure in Windows build is a real issue that needs to be looked into. I will investigate and report back. |
|
@daxian-dbw Could you please address CI Windows fail? |
|
@daxian-dbw |
|
Thanks @PaulHigin for the pointers! |
… from the child process
|
All tests passed now 😄 _serverProcess.CancelOutputRead();
_serverProcess.CancelErrorRead();They should be called only if we are actively using the The issue results in 34 child pwsh processes not cleaned up after the jobs finish, which eat up the memory in the Windows CI environment. That's why we see the @PaulHigin @iSazonov Can you please take another look at the changes? Thank you! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add a test to ensure the child process is cleaned up on background job completion? Or whatever the scenario is that invokes KillServerProcess()?
|
Sure, I will add a test to verify the server process is terminated after the job is gone. |
|
@PaulHigin, tests are added to verify that the background process is cleaned up after job is gone. Please review it when you have time. Thanks! |
src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs
Show resolved
Hide resolved
src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs
Show resolved
Hide resolved
src/System.Management.Automation/engine/remoting/fanin/OutOfProcTransportManager.cs
Show resolved
Hide resolved
|
@iSazonov I think this is now ready to merge. But please take another look before you do so as there are changes after your last review. |
|
🎉 Handy links: |
PR Summary
Fix #11659
Use dedicated threads to read the redirected output and error streams from the child process for out-of-proc jobs.
PR Context
Currently, when
Start-Jobstarts a child PowerShell process, it depends on theProcesseventsOutputDataReceivedandErrorDataReceivedto handle messages from the output and error streams.Internally, the
Processimplementation uses 2 thread-pool threads to read messages from those 2 streams. Even though the implementation callsstream.ReadAsyncon those 2 streams, the actual read operation is synchronous because the underlying Win32 APICreatePipe()only allows the pipe handle to be created in"synchronous"mode.This results in 2 thread-pool threads being held up indefinitely for each out-of-proc job created. When more out-of-proc jobs are created at the same time, it quickly depletes the thread pool, and causing thread starvation for other tasks that depend on thread-pool threads until the thread pool manager realize it's time to increase the pool.
Thread-pool threads should be used for transient tasks that finish quickly, not for long-running tasks. In this case, reading from pipe in a blocking manner is obviously a long-running tasks and should be done with dedicated threads.
PR Checklist
.h,.cpp,.cs,.ps1and.psm1files have the correct copyright headerWIP:or[ WIP ]to the beginning of the title (theWIPbot will keep its status check atPendingwhile the prefix is present) and remove the prefix when the PR is ready.