4

Does Net::HTTP support an asynchronous syntax?

I'm looking for something like the code below.

The block would get called on the main thread after Net::HTTP has either received the response from the server (in which case,error would be nil) or encountered an error connecting to the server (in which case response would be nil).

Net::HTTP.get('http://stackoverflow.com') do |response, error|
  if error
    puts "Connection error: #{error.message}"
  elsif response.status_code != HTTPOK
    puts "Unexpected status code: #{response.status_code}"
    puts response.body
  else
    puts "Success!"
    puts response.body
  end
end

The following questions provide answers but I'm looking for a block-based solution.

Community
  • 1
  • 1
ma11hew28
  • 121,420
  • 116
  • 450
  • 651

1 Answers1

6

Have a look at the eventmachine and em-http-request gems. The equivalent to your above code would be

require 'rubygems'
require 'eventmachine'
require 'em-http'

HTTP_OK = 200

EM.run do
  http = EM::HttpRequest.new('http://example.com').get

  http.errback do
    puts "Connection error: #{http.error}"
    EM.stop
  end

  http.callback do
    if http.response_header.status == HTTP_OK
      puts "Success!"
      puts http.response
    else
      puts "Unexpected status code: #{http.response_header.status}"
    end
    EM.stop
  end
end

There is a very good example using fibers on the em-http-request Github page.

Edit: I also recommend reading http://www.igvita.com/2009/05/13/fibers-cooperative-scheduling-in-ruby/

Patrick Oscity
  • 53,604
  • 17
  • 144
  • 168
  • This is a good example, but testing a double negative seems like a bad idea. Testing for `== HTTP_OK` and then `else` would be easier to follow. Right now the success condition is "if not not okay". – tadman Jul 24 '12 at 17:39
  • @tadman thanks! you are right, fixed this. I guess i tried to reflect the op's code structure as much as possible. – Patrick Oscity Jul 24 '12 at 18:40