Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the preferred way of performing non blocking I/O in Ruby?

If say I want to retrieve a web page for parsing, but not block the CPU while the I/O is taking place. Is there something equivalent to Python's Eventlet library?

like image 805
Fast Fish Avatar asked Dec 17 '10 07:12

Fast Fish


2 Answers

The best HTTP client library for Ruby is Typhoeus, it can be used to perform multiple HTTP requests in parallel in a non-blocking fashion. There is a blocking and non-blocking interface:

# blocking
response = Typhoeus::Request.get("http://stackoverflow.com/")
puts response.body

# non-blocking
request1 = Typhoeus::Request.new("http://stackoverflow.com/")
request1.on_complete do |response|
  puts response.body
end
request2 = Typhoeus::Request.new("http://stackoverflow.com/questions")
request2.on_complete do |response|
  puts response.body
end
hydra = Typhoeus::Hydra.new
hydra.queue(request1)
hydra.queue(request2)
hydra.run # this call is blocking, though

Another option is em-http-request, which runs on top of EventMachine. It has a completely non-blocking interface:

EventMachine.run do
  request = EventMachine::HttpRequest.new('http://stackoverflow.com/').get
  request.callback do
    puts request.response
    EventMachine.stop
  end
end

There's also an interface for making many requests in parallel, similarly to Typhoeus Hydra.

The downside of em-http-request is that it is tied to EventMachine. EventMachine is an awesome framework in itself, but it's an all-or-nothing deal. You need to write your whole application in an evented/continuation-passing-style fashion, and that has been known to cause brain damage. Typhoeus is much better suited to applications that are not already evented.

like image 121
Theo Avatar answered Oct 30 '22 16:10

Theo


I'm not sure what Eventlet does, but Ruby has EventMachine, a library for non-blocking IO (amongst other things).

like image 5
maerics Avatar answered Oct 30 '22 17:10

maerics