Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Errno::EPIPE: Broken pipe exception is raised

Tags:

fork

ruby

pipe

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 retrying 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

like image 763
ian Avatar asked Jun 18 '17 16:06

ian


People also ask

What is ePipe error in Linux?

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.

What is broken pipe error in Linux?

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?

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).

What is brokenpipeerror in Python?

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).


1 Answers

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.

like image 80
user208769 Avatar answered Oct 04 '22 02:10

user208769