Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to do parallel HTTP requests in Heroku?

I'm building a Ruby on Rails app that access about 6-7 APIs, grabs information from them based on user's input, compares and display results to the users (the information is not saved in the database). I will be using Heroku to deploy the app. I would like those HTTP requests to access the APIs to be done in parallel so the answer time is better instead of doing it sequential. What do you think is the best way to achieve this in Heroku?

Thank you very much for any suggestions!

like image 586
acadavid Avatar asked Nov 03 '10 15:11

acadavid


People also ask

How many API requests can Heroku handle?

Heroku API limits Calls to the Heroku API are limited to a rate of at most 4500 calls per hour.

Does Heroku allow HTTP?

The Heroku router only supports HTTP/1.0 and HTTP/1.1 clients. HTTP/0.9 and earlier are no longer supported. SPDY and HTTP/2 are not supported at this time.

Is Heroku free fast?

Heroku is a cloud Platform As A Service (PaaS) supporting Ruby on Rails, Java, Node. js, Scala, Clojure, Python, PHP, and Go. Heroku's free version offers 550–1000 dyno hours per month.

How long is Heroku free for?

Maximize your free platform services Get 1000 free dyno hours by verifying your Heroku account with a credit card; unverified accounts receive 550 free hours. You will not be charged, unless you decide to use a paid service.


2 Answers

If you want to actually do the requests on the server side (tfe's javascript solution is a good idea), your best bet would be using EventMachine. Using EventMachine gives a simple way to do non-blocking IO.

Also check out EM-Synchrony for a set of Ruby 1.9 fiber aware clients (including HTTP).

All you need to do for a non-blocking HTTP request is something like:

require "em-synchrony"
require "em-synchrony/em-http"
EM.synchrony do
    concurrency = 2
    urls = ['http://url.1.com', 'http://url2.com']

    # iterator will execute async blocks until completion, .each, .inject also work!
    results = EM::Synchrony::Iterator.new(urls, concurrency).map do |url, iter|

        # fire async requests, on completion advance the iterator
        http = EventMachine::HttpRequest.new(url).aget
        http.callback { iter.return(http) }
        http.errback { iter.return(http) }
    end

    p results # all completed requests
    EventMachine.stop
end

Goodluck!

like image 89
maxpenguin Avatar answered Oct 12 '22 23:10

maxpenguin


You could always make the requests client-side using Javascript. Then not only can you run them in parallel, but you won't even need the round-trip to your own server.

like image 25
tfe Avatar answered Oct 12 '22 23:10

tfe