-
Notifications
You must be signed in to change notification settings - Fork 646
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
WIP: Use POSIX::Spawn::Child instead of #popen3 to avoid deadlocks #738
base: master
Are you sure you want to change the base?
Conversation
Thank you for this. It sounds great. Have you been running this fork in your own apps and seen an improvement? For an introductory transition period, I think it's be great if we could add an option to I just fixed up the test suite. I had a dependency that wasn't pinned to a version update. If you rebase, you should be able to run the tests locally or on Travis-CI. |
sorry I missed the notification; I'll do the and dependencies versions… it happens |
sorry, I didn't answer: yes, I've been using it in production for ~20 days and no deadlocks (had 1 - 2 per week before) |
actually, historically we were seeing 1-2 per month (we process ~1000 PDFs a month), say ~0.2%; after an upgrade (Rails 4.1 -> 5.1, Ruby 2.1 -> 2.4) and a ~20% growth we started seeing ~1-2 per week, say ~0.6% (every once in a while we had weird spikes, which is the reason that I had to do this) |
Just curious why not use |
@allenwu1973 there are other advantages using posix-spawn. |
7ed3f91
to
28bae8e
Compare
@MidnightWonderer basically I missed it BUT not even their authors had noticed it. It may be useful as a fallback. |
would be great to see a switch to posix-spawn perhaps terrapin could help make the code simpler https://github.com/thoughtbot/terrapin It gives access to stdin and stderr - it returns this object (not documented in readme i believe) not sure how to get access to that if process doesn't return 0, because terrapin raises an error in that case you can pass in a logger to get ongoing output. not sure if that's out, or out+err. see "You can see what's getting run" in readme |
Years passed, I am surprised the thread has some updates. I moved to puppeteer already, which is more mainstream. |
@midnight-wonderer LOL, I just found your very helpful comment over on |
Problem
We are seeing
No live threads left. Deadlock?
in production a lot. This is not easy to reproduce, and it only happens under load.After upgrading to Ruby 2.4.2 and Rails 5.1 we started seeing this much more often.
Cause
Incorrect use of
#popen3
(whose API is badly designed). Particularly,This produces a deadlock in case the command filled the whole
stdout
buffer. In that case, the subprocess is waiting for that buffer to be consumed, and the parent process is waiting forstderr
's buffer to have content.Ruby core team's position is that this should be handled with
IO.select
(check ref 1).Solution
First alternative would be to use
IO.select
. But that sounds error-prone to me.I decided to use the
posix-spawn
gem (particularlyPOSIX::Spawn::Child
which handles this correctly). This behavior is optional (but default). This may break Windows compatibility (check Notes)References
Notes
posix-spawn
Windows support so I decided to make this behavior the default, but optional. SettingWICKED_POPEN
env variable toruby
uses the standard library'sOpen3
instead. Gem dependencies still install posix-spawn, so it may still fail on Windows.master
as it is today upstream.