-
-
Notifications
You must be signed in to change notification settings - Fork 30
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
Exception "ProcessException: Received 0 of 5 expected bytes" when reading from stdout out of time #69
Comments
I have found that different programs can behave differently. For example, the jpegoptim utility simply terminates execution even if I don't read stdout output. And what's more interesting is that I can read this output even after the process has completed.
How to understand this behavior? But at least in this example there is no data loss or exception. But what should I do in the case of ImageMagick if my application is quite complex and has a lot of asynchronous processes? For example, I want to be able to read data from stdout not instantly, but after an indefinite time (more than 120 seconds). |
I continued my research and came to the conclusion that there are two problems here at once. Below I will consider the situation with the ImageMagick call and the exception after 120 seconds. First of all, I decided to try to reproduce this situation using
I wanted to understand how this code would behave, whether the process would hang at the But it turned out that the process terminates instantly with code 1. The stderr output looks like this:
So I decided instead of calling
But it turned out that the status does not change in any way even after 150 seconds (I didn’t wait any longer):
In general, I still don’t understand why the exception occurs after exactly 120 seconds when calling ImageMagick using Problem 1. The exception occurs in
This is a completely legitimate exception that can arise for various reasons. Although in my case this problem is 100% repeatable, it can be attributed to a feature of ImageMagick’s behavior (even if this is not confirmed by the experiment with Problem 2. If this exception only occurred when calling
On the 120th iteration, Please give me some comment on this so that I can move on. Is this normal behavior and should I be prepared to catch random exceptions from any async function? Or is this erroneous behavior that shouldn't exist? |
Hi @PhantomArt, this definitely doesn't sound like expected behavior. How do you know the exception is thrown there in the 120th iteration? |
Because I run a loop with a counter and a delay of 1 second inside, and the exception occurs after 120 iterations of 1 second. But even before that, I took a different approach. I didn't mention this to keep the code snippets more concise. Essentially all my tests are wrapped in try-finally:
Each time you start, the exception occurs after exactly 120 seconds (well, of course, with some fractions of milliseconds). |
I totally get that 120 seconds thing, which is another problem we need to look at, but my question was rather: You said the exception is thrown in that delay loop, are you sure about that? Can you catch it there? I'm asking because things are concurrent, so the exception being printed while that loop is running doesn't mean it's thrown into that loop. |
Yes, apparently it is. Here's an example:
After 120 seconds I see in the console:
The exception message looks strange, it contains a stack trace, but apparently this is intended. You should know better about this than I do. |
Thanks! That trace is quite helpful. There's an |
Great! Tell me how to install an exception handler that occurs in the event loop? I don't see this in the documentation. Do I understand correctly that if such an exception occurs, then even if it is intercepted using such a handler, a |
I found. I set up an event loop exception handler and tested what would happen with calls to
The console output looks like this:
The call to Now I'm ready for any surprises that happen in the event loop. Maybe this message will be useful to someone. Thank you. |
Yeah, exactly like that! You still get an exception, because there definitely seems to be a bug. It hangs indefinitely on Linux, but I can reproduce the 120 second "timeout" on Windows. |
I've been experimenting with Amp\Process to better understand how it works. I launched several processes, connecting them stdout -> stdin, simulated various situations in order to understand where errors could occur and how to handle them correctly, including so that there were no zombie processes left. I have encountered one problem, the nature of which is not clear to me.
Important: I am using the Windows 10 operating system and what I am working on will run on the same operating system.
I will give some synthetic examples. Most of them work correctly, but one works unexpectedly. In all examples, I will use the ImageMagick command to convert a PNG image to a JPEG.
Example 1 (works well):
Now I modify this example to pass the input image to stdin.
Example 2 (works well):
Next, I change the example so that the output image is sent to stdout.
Example 3 (works well):
Now I remove the code that reads from stdout. I expect the script to hang forever on the
\Revolt\EventLoop::run();
call. I realize this is stupid code, but it demonstrates the problem.Example 4 (not working correctly):
The script does hang at the line
\Revolt\EventLoop::run();
, but every time after exactly 120 seconds, I get an exception:The exception text is always identical, it reports the expected 5 bytes.
Then I additionally remove the code that sends the input image to stdin.
Example 5 (works well):
In this case, the script hangs indefinitely, as expected (perhaps not indefinitely, but certainly much longer than 120 seconds).
Then I try again to specify the input file as the command argument.
Example 6 (works well):
In this example, the script still hangs forever, as expected.
In each of the examples I tried replacing
\Revolt\EventLoop::run();
with$process->join();
, this did not affect the results in any way.Below I provide the full stack trace of the exception from example 4, but with
$process->join();
:The text was updated successfully, but these errors were encountered: