1

I want to use Ruby EventMachine and em-http-request to run parallel HTTP synchronous requests triggered from different threads.

The idea is to run a single reactor in its own thread and push HTTP requests to complete on its event queue thanks to EM.next_tick.

The pattern for every call could be

def complete_request(url, options)
  Thread.new { EM.run } unless EM.reactor_running?
  EM.run do
    EM.next_tick do
      con = EventMachine::HttpRequest.new(url, options[:connection_headers])
      http = com.setup_request(verb, head: options[:headers], body: options[:body])
      http.errback { }
      http.callback { }
    end
  end
  # wait for request completion (but how?)
  ...
end

reqs = []
responses = []
reqs << Thread.new { responses << complete_request('http://www.stackoverflow.com', verb: get) }
reqs << Thread.new { responses << complete_request('http://www.flickr.com', verb: get) }
reqs.each { |req| req.join }    

To make the requests synchronous, I tried to use Fibers but unsuccessfully. Either the request fails to connect or it completes but never exits the event loop.

I don't want to call EM.stop in the callbacks because it would screw up other requests being executed in parallel I guess, and would also stop the reactor while I want it to run until I decide no more requests should be treated.

Does anyone already try to use EventMachine and em-http-request this way ? Can EventMachine support this use case ?

Laurent Farcy
  • 710
  • 4
  • 9
  • 1
    If you're going to use threads, you might want to skip the EventMachine layer entirely. They're two solutions to the same problem. – tadman Jul 27 '15 at 19:56
  • @tadman: this is the first time I use EventMachine. I selected it for its asynchronous processing of HTTP requests, especially when you deal with a streaming API. But I'm realizing it's not that thread-friendly, it may even not be threadsafe, as far as I can see. Now, if I decide to go away from EM and em-http-request to be multithreaded, how can I get the same level of asynchrony and performance that delivers EM together with em-http-request ? – Laurent Farcy Jul 28 '15 at 09:47
  • It looks like http.rb combined with Celluloid::IO can make it. See https://github.com/httprb/http/wiki/Parallel-requests-with-Celluloid%3A%3AIO. – Laurent Farcy Jul 28 '15 at 10:11
  • EventMachine isn't thread safe, but you can have multiple EventMachine instances in their own threads if they don't access the others. If you're doing huge amounts of HTTP, look at Jruby because it handles threads exceptionally well. – tadman Jul 28 '15 at 17:27
  • 1
    @tadman: I cannot afford switching to JRuby right now but I will definitely give multiple EventMachine instances, each in their own thread, a chance. – Laurent Farcy Jul 28 '15 at 21:03

0 Answers0