Skip to content

Instantly share code, notes, and snippets.

@ilake
Last active December 16, 2015 23:39
Show Gist options
  • Select an option

  • Save ilake/5515031 to your computer and use it in GitHub Desktop.

Select an option

Save ilake/5515031 to your computer and use it in GitHub Desktop.

Pipe

  • uni-directional stream of data

  • data can be passed along the pipe but only in one direction. So if one process 'claims' the position of reader, rather than writer, it will not be able to write to the pipe. And vice versa.

        reader, writer = IO.pipe #=> [#<IO:fd 5>, #<IO:fd 6>]
    
  • Ruby's amazing IO class 1 is the superclass to File, TCPSocket, UDPSocket, and others. As such, all of these resources have a common interface.

        reader, writer = IO.pipe 
        writer.write("Into the pipe I go...")
        writer.close
        puts reader.read
    
        Notice that I had to close the writer after I wrote to the pipe? That's because when the reader calls IO#read it will continue trying to read data until it sees an EOF (aka. end-of-file marker 2). This tells the reader that no more data will be available for reading.
        
        So long as the writer is still open the reader might see more data, so it waits. By closing the writer before reading it puts an EOF on the pipe so the reader stops reading after it gets the initial data. If you skip closing the writer then the reader will block and continue trying to read indefinitely.
    
  • Pipes are considered a resource, they get their own file descriptors and everything, so they are shared with child processes.

  • I use #puts and #gets to read and write a String delimited with a newline.

  • pipes hold a stream of data.

Streams Vs Messages

  • stream I mean that when writing and reading data to a pipe there's no concept of beginning and end.

  • working with an IO stream, like pipes or TCP sockets, you write your data to the stream followed by some protocol-specific delimiter.

  • reading data from that IO stream you read it in one chunk at a time

  • That's why I used #puts and #gets in the last example: it used a newline as the delimiter for me.

  • We can't do it with pipe to communicate via messages instead of streams. but we can do it with Unix sockets.

  • Unix sockets are a type of socket that can only communicate on the same physical machine.

  • it's much faster than TCP sockets and is a great fit for IPC

        require 'socket'
        Socket.pair(:Unix, :DGRAM, 0) #=> [#<Socket:fd 15>, #<Socket:fd 16>]
    
  • These sockets communicate using datagrams, rather than a stream. In this way you write a whole message to one of the sockets and read a whole message from the other socket. No delimiters required.

  • a socket pair provides bi- directional communication. The parent socket can both read and write to the child socket, and vice versa.

Remote IPC?

Real World

  • They're often used as a communication channel
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment