Great question in GitHub issues, I hope this helps others:
I’m curious about how asynchronicity is implemented compared to Typhoeus.
When you call
Request#perform, that computation is performed independently of the main program flow. This action is always non-blocking. Consider this example:
require 'weary/request' request = Weary::Request.new "https://api.github.com/repos/mwunsch/weary" request.perform do |response| puts response.body end
perform takes a block that accepts a response and executes once the response has completed. When you execute this file as is you will not see the response’s body. Why? Because the main thread completes before the request has completed. Changing this to
require 'weary/request' request = Weary::Request.new "https://api.github.com/repos/mwunsch/weary" response = request.perform puts response.body
will produce the desired results, and here’s why:
Request#perform returns a Future — a lightweight proxy object wrapping the Response (Weary uses the promise gem under the hood). The main thread is only blocked when you call a method on the response. This is all done with plain ol’ Ruby Threads (of which there is a lot of FUD in the Ruby community because of the GIL, but this is a perfect use case for them).
Unlike Typhoeous, Weary does not provide a queue mechanism. But you could just do something like:
responses = [req1, req2].map(&:perform)
It might be helpful to look at how my Gilt gem performs multiple requests in parallel to get a sale’s products.
Also unlike Typhoueus, Weary provides no internal mechanisms for memoization or caching, but you can use Rack middleware to achieve the desired result. Hope that answers your question.