-
Notifications
You must be signed in to change notification settings - Fork 55
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
PHP hanging indefinitely #20
Comments
@leonardopcastro Released 1.2.3 containing this fix. Thanks for your help! |
@leonardopcastro This change seems to have introduced other problems now. See #21. |
As proposed in mikehaertl/phpwkhtmltopdf#78 (comment) and again in #9 (comment) we could try to add $descriptors = array(
1 => array('pipe','w'),
2 => array('pipe','w')
);
$process = proc_open($command, $descriptors, $pipes, $this->procCwd, $this->procEnv, $this->procOptions);
if (is_resource($process)) {
// set streams to non blocking mode
stream_set_blocking($pipes[1], 0);
stream_set_blocking($pipes[2], 0);
$this->_stdOut = trim(stream_get_contents($pipes[1]));
$this->_stdErr = trim(stream_get_contents($pipes[2]));
fclose($pipes[1]);
fclose($pipes[2]);
... There was one neutral feedback in #78 ("didn't fix it") and we have 2 positive in #6. So maybe we should really implement the fix suggested by @mkloosterman in #78. I'd feel better if we had reliable test cases that can reproduce the issue. Any volunteers? @schmunk42, @markdboyd, @epicwally? |
@mikehaertl I'm not sure when I'll have time to get to this, but would a test that reproduces the infinite hanging when trying to read the streams in this order be sufficient? I'm still not 100% clear on what the actual cause of the hanging is, but for me it seemed directly related to the size of the PDFs I was trying to generate. |
@markdboyd I'd say the size of the PDF should not matter as the problem seems to be more on the side of the buffers for error and standard message output. So I think it's about the length of the command which of course increases if you have more pages in your PDF (each page == one more argument to An ideal test would use some regular shell command ( I can't promise that I find time for this soon - even more so as I never had the issue myself 😛 . |
Hi all, We ran into this problem and ended up fixing it in exactly this way, and only found this post after the fact. I can confirm that setting the streams to non-blocking mode mode resolved the problem for us as well.
For what its worth :) |
@patrict Thanks for your feedback. I've finally added this feature - but it's weird: Now I feel like I'm missing something very obvious here because several people reported success. Maybe you can have a look at the merge request and see if that code works for you? It also contains a check for Windows systems because it was reported that non-blocking mode does not work there. |
@mikehaertl I've implemented your exact code and I am unable to reproduce the error you get - in my environment proc_close() always returns 0. I did note the following on the PHP proc_close() documentation page: Return Values Then look at the most recent user contributed notes by Uwe Ohse:
On the system I tested this on, Im running PHP 5.6.40 (yes yes, don't judge...) In light of this I would suggest simply testing for an exit code < 0, which will tell you there is an error, but not what/why. HTH |
@patrict Thanks for the update. This is very weird. Are you sure, you've used exactly the same code I have in my latest pull request? You can see, that we get the same error also for the Travis tests (even for PHP 5.6), so it's not a local issue on my machine. Regarding the exit code: For shell commands it's usually
So does your quote mean that Apart from that the question is still, why does |
Hi @mikehaertl
Yup, I used your exact version
Agreed
Exactly - unexpected and strange, but that's what the documentation seems to indicate. From the user contributed notes:
That is a good question. I can't even think of a reason to speculate on 🤕 The only thing I can think of is to dig into and debug the PHP source, which is a bit of a shlep to say the least... Read all the user contributed notes on the proc_close() page, all except the last one are about the return value: |
@patrict Just curious: Did you also run the test cases with phpunit? If not, could you maybe try that? I still can't believe that you get different results than me/travis. UPDATE: Running the tests is very easy: You only need |
@mikehaertl Ive installed phpunit 6.5.14 - do I need to specify a test file or any parameters?
|
Ah, sorry, seems like this version doesn't run with PHP 5.6 anymore. Hmm, older versions are probably incompatible with some test assertions. Well, then nevermind and thanks for trying. I still need to find some time to think about a proper fix for this mess :). |
@mikehaertl I tried PHPUnit 5.7.27 out of curiousity, and it seems you are right:
Im not familiar enough with PHPUnit to know what to do with that 😂 Sorry I could not be of more help, let me know if there is anything else you would like me to try |
The only option would be to let the tests run under PHP 7 somewhere. But I'm pretty sure you get the same results as me - otherwhise I'd start to loose confidence that this universe acts logically 👽 . Actually that you didn't run the tests so far explains why you get different results. It probably very much depends on the command you try to run. Can you share that command? If it's nothing weird I could try it on my machine and see if I get the same result. Maybe it also helps to better understand the return code logic. |
@mikehaertl Im not sure I understand correctly - are you asking what phpunit command I ran? |
No no, I mean, what did you use the php-shellcommand for? You said even with my change you get the correct exit code |
Ah, Im with you now. I grabbed your changes, then used phpwkhtmltopdf to generate the same dataset that I previously got the hang on, to see if it would successfully generate the PDF. The PDF did generate succesfully, which is what I based my response on :) |
Alright, thanks. Then I'll try this too. I want to get a better understanding of what this all means and how the comands differ. |
@patrict and all those interested, I share what I learned so far: When we set non-blocking mode then the PHP main process is - well - not blocked anymore. That means that the process opened by This basically means, that we need a loop where we check the process status with Now comes the tricky part: According to this comment, in that loop both pipes for I'm still thinking how to combine all the above in a proper fix. But I feel like I'm on the right track. Finally we can only pray that things will also work on Windows. |
@patrict It seems I finally have a working solution. It looks a bit complex but actually was the only way I could make everything work. The nice part: It now also works with huge inputs/outputs, even as streams. If you could help testing this (or even review if you dare) that would be great. |
@mikehaertl oh wow, well done! What a convoluted situation to have to handle! I reviewed your changes and everything looks good. Well done! |
Cool! I want to wait for some more feedback from @schmunk42 , too. He also had issues and I think he was using input streams (i.e. open file handles). If things go well I'll create a new release very soon. Thanks again for your help which brought me on the right track. |
I didn't further investigate the issue, so I can't really provide feedback. |
Just tried this branch in our linux environment, and it works comparably with the hack I had implemented a while ago. |
Issue #20 Add stream_set_blocking() calls for proc_open()
Release 1.5.0 now contains this new logic. Thanks everyone for the help and feedback! |
Awesome, thanks and well done! |
I was testing some html conversions using the mikehaertl/phpwkhtmltopdf, when I noticed one made PHP hang indefinitely.
Doing some debug, I found out that it was happening in the php-shellcommand/src/Command.php file at line number 317:
After some research, I found a similar problem in this stackoverflow question and an apparent solution. http://stackoverflow.com/questions/31194152/proc-open-hangs-when-trying-to-read-from-a-stream
According to the stackoverflow answer, there is a possibility of an execution not outputting anything to stdout (pipe[1]) when an error occurs, so stream_get_contents waits for a stream that never comes.
As pointed out in the stackoverflow answer, reading the stderr (pipe[2]) before stdout (pipe[1]) did the trick for me, with the PHP finishing execution and the error message being outputted.
My system config:
The text was updated successfully, but these errors were encountered: