Ruby 2 FIFO notes
I've been obsessed over the idea of getting FIFOs - Unix style - to work for a little game-project I got going on. - After all, write/read of one byte taking 30 microseconds over a TCP-socket would take roughly 5 microseconds over a UNIX socket! This makes FIFOs the fastest IPC-method after shared memory. Here are some notes.
FIFOs are monodirectional named pipes that can be accessed using a filepath. Data sent via a FIFO is sent between processes via kernel (not fs).
Getting the "Errno::EINTR" ?
I did, while trying to get my processes to open freshly created fifos. Incidentally, Starr Horne has a very nice list of all the error codes from Errno.
Turns out the solution in Ruby 2.1 is this:
# create a fifo
system("mkfifo #{Pipe_ui}") unless File.exists? Pipe_ui
# open it for reading
begin
@pipe_from_ui = open( Pipe_ui, "r" )
rescue Interrupt, Errno::EINTR
retry
end
It may be a good idea to add a limit to number of retries.
Naturally, a writer with the same semantics is also needed! Ruby 2.4 has File.mkfifo.
Assuming the pipes have been setup, the simplest way to r/w through a FIFO-pipe is:
...
# somewhere in your code
msg = @pipe_from_ui.gets # 'puts' for the writer
unless msg == nil
msg.strip!
# do stuff
end
...
In another process:
...
#
def send_fifo_msg a_string
@pipe_from_ui.puts a_string
@pipe_from_ui.flush
end
...
I'm still wondering if one should wrap the reader & writer methods in begin-rescue semantics or not. This will have to wait until I have the time to debug it more.