module Net::SSH::BufferedIo

This module is used to extend sockets and other IO objects, to allow them to be buffered for both read and write. This abstraction makes it quite easy to write a select-based event loop (see Net::SSH::Connection::Session#listen_to).

The general idea is that instead of calling read directly on an IO that has been extended with this module, you call fill (to add pending input to the internal read buffer), and then read_available (to read from that buffer). Likewise, you don’t call write directly, you call enqueue to add data to the write buffer, and then send_pending or wait_for_pending_sends to actually send the data across the wire.

In this way you can easily use the object as an argument to IO.select, calling fill when it is available for read, or send_pending when it is available for write, and then call enqueue and read_available during the idle times.

socket = TCPSocket.new(address, port)
socket.extend(Net::SSH::BufferedIo)

ssh.listen_to(socket)

ssh.loop do
  if socket.available > 0
    puts socket.read_available
    socket.enqueue("response\n")
  end
end

Note that this module must be used to extend an instance, and should not be included in a class. If you do want to use it via an include, then you must make sure to invoke the private initialize_buffered_io method in your class’ initialize method:

class Foo < IO
  include Net::SSH::BufferedIo

  def initialize
    initialize_buffered_io
    # ...
  end
end