if @block
rd, wr = IO.pipe
@pid = fork do
$0 = "Forked child from Page #{@path}"
rd.close
result = @block.call(@resp.body)
begin
wr.write Marshal.dump(result)
end
wr.close
This is a pretty standard way to share a pipe with a fork, yet as soon as rd.close
is called it breaks the pipe for wr
to use. Up until that line the pipe works as it should (I ran it line by line with Pry). As far as I'm aware it is good practice to close the reader inside the fork to stop it interfering with EOF being sent (I don't know why that works I just know that's the practice).
This is part of a library I call into a production app. The library's own specs never encounter this even though they run very similar code (only the @block
and @resp
will differ to any great degree). Obviously the app's code is more complex but I can't see how it would be interfering with this code. I searched through other libraries required by the app to see if any were trapping signals that might interfere with this but I found nothing.
Can anyone suggest what the problem could be or a work around for it? I've tried catching the Errno::EPIPE
exception and retry
ing but that doesn't fix it, reopening the pipe (I'm not entirely sure how to do that anyway as after the fork occurs it'd be hard to link it to the main process), emptying the block so it doesn't do any work… still no joy.
I have also found (via a comment on this question) that Ruby's Open3 in the standard library silently rescues and drops Errno::EPIPE
but no reason was given with the commit message. I don't know if it is related.
https://github.com/ruby/ruby/blob/e3c288569833b6777e7ecc0bbc26f8e6ca8f2ba7/lib/open3.rb#L268
It is generally raised while reading and writing files, or in other terms, performing file input/output or network input/output (through sockets). The equivalent Linux system error is EPIPE, excerpted from GNU libc error codes.
But along with the execution, the errors during the execution also comes into existence and it becomes difficult for the programmers to rectify the errors for the processing of the problem. A broken Pipe Error is generally an Input/Output Error, which is occurred at the Linux System level.
What causes " [Errno 32] Broken pipe" in Python? "Broken pipe" is usually considered an IOError (short for Input/Output Error) error, which occurred at the Linux system level. It is generally raised while reading and writing files, or in other terms, performing file input/output or network input/output (through sockets).
The following script raises BrokenPipeError: [Errno 32] Broken pipe, when piped to a command like head (unless the number of lines to head exceeds the number of lines printed by the Python script).
Not sure why this has taken so long to get answered. I suspect this is "fixed" in current versions of ruby as I was unable to replicate using simplified versions of your code, but for future reference, here's how I would have structured the code:
def test_my_pipes
rd, wr = IO.pipe
fork do
rd.close
sleep 5
wr.write "Hello world"
wr.close
end
wr.close # essential
puts "Waiting for sleepy fork"
puts rd.read
rd.close
end
Note that both inside and outside the fork block, we close both rd and wr. In actual fact, only the parent process wr.close
is essential, but definitely better to close all the ends of the pipe when not needed.
If this code still breaks, would be interested to see what versions of ruby they break for.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With