Search code examples
rubyiononblocking

ruby non-blocking line read


I'm trying to read a line from an io in a non-blocking way.

Unfortunately readline blocks. I think I can solve this with read_nonblock with an additional buffer where I store partial result, check if there are multiple lines in the buffer, etc.. but it seems a bit complicated for a simple task like this. Is there a better way to do this?

Note: I'm using event demultiplexing (select) and I'm quite happy with it, I don't want to create threads, use EventMachine, etc...


Solution

  • I think the read_nonblock solution is probably the way to go. Simple, not maximally efficient monkey-patch version:

    class IO
      def readline_nonblock
        rlnb_buffer = ""
        while ch = self.read_nonblock(1) 
          rlnb_buffer << ch
          if ch == "\n" then
            result = rlnb_buffer
            return result
          end
        end     
      end
    end      
    

    That throws an exception if there's no data ready, just like read_nonblock, so you have to rescue that to just get a nil back, etc.