How to test for asynchronous HTTP requests in ruby using EventMachine

550 views Asked by At

I'm getting messages of a RabbitMQ queue and each message is a URL that I want to make a request to. Now I'm using the AMQP gem to subscribe to the queue and that uses EventMachine, so I'm using the the em-http-request library to make the http requests. According to the documentation here: https://github.com/igrigorik/em-http-request/wiki/Parallel-Requests The following will issue asynchronous http-requests:

EventMachine.run {
    http1 = EventMachine::HttpRequest.new('http://google.com/').get
    http2 = EventMachine::HttpRequest.new('http://yahoo.com/').get
    http1.callback { }
    http2.callback { } 
end

So when I subscribe to the RabbitMQ queue I have the following code:

x = 0
EventMachine.run do
    connection = AMQP.connect(:host => '127.0.0.1')
    channel  = AMQP::Channel.new(connection)
    channel.prefetch(50)
    queue    = channel.queue("http.requests")
    exchange = channel.direct("")

    queue.subscribe do |metadata, payload|
        url = payload.inspect
        eval "
        @http#{x} = EventMachine::HttpRequest.new(url).get
        @http#{x}.callback do
            puts \"got a response\"
            puts @http#{x}.response
        end
        x = x+1
        "
    end
end

This dynamically creates new variables and creates new http requests, similar to the way described in the em-http-request documentation. But is there a way to test whether the requests are actually being made asynchronously? Is it possible to write to the console every time a get request is fired off so I can see they are fired off one after the other without waiting for a response?

2

There are 2 answers

0
tbuehlmann On

A very simple example, demonstrating exactly what you want:

require 'em-http-request'

EM.run do
  # http://catnap.herokuapp.com/3 delays the HTTP response by 3 seconds.
  http1 = EventMachine::HttpRequest.new('http://catnap.herokuapp.com/3').get
  http1.callback { puts 'callback 1' }
  http1
  puts 'fired 1'

  http2 = EventMachine::HttpRequest.new('https://www.google.com/').get
  http2.callback { puts 'callback 2' }
  puts 'fired 2'
end

Output (for me):

fired 1
fired 2
callback 2
callback 1

Depending on your internet connection, Heroku and Google, the response to the second HTTP request will likely come in first and you can be sure, the requests are indeed done in parallel.

0
Tim Potter On

You can try running tcpdump and analysing the output. If you see the TCP three-way handshakes for the two connections being interleaved then the connections are happening in parallel.

This can't really be part of an automated test though, if that's what you're trying to aim for. I would be happy just to verify that the library does what it says it does once and not make it part of a test suite.