Skip to content

Major differences with Net::HTTP. #211

@flavio-b

Description

@flavio-b

First of all, thank you for making these gems in the Async family. It's one of the most exciting developments in Ruby 3, in my opinion.

I've been working to replace threads, in several IO-heavy tasks, with Async. For example, downloading up to 500 images in parallel, and saving them to a tempfile:

Sync do |parent|
  urls.each do |url|
    parent.async { download_and_save(url) }
  end
end

The threaded version of this took 0.7s with 500 threads (as an experiment), and 2.5s with 12 threads as we cap to limit resource usage in prod.

download_and_save was written with Net::HTTP. I almost went back to threads because the download time increased to 13s in the Async version. Still better than doing it serially (55s), but much slower than threads.

Finally, I updated download_and_save to use Async::HTTP, and it managed in ~0.6s, with the advantage of consuming less memory and avoiding context switching! I was sold.

This was surprising since I always assumed the Fiber scheduler would work about the same with any library that does IO: that it could capture most blocking operations and pass work to other fibers. But, it sounds like either Net::HTTP has some blocking operations that can't be "seen" by the scheduler, or the HTTP2 aspect of Async::HTTP is making up the difference.

Can you share any comment on this? It look me a while to even think of trying Async::HTTP because I didn't know it would make such a difference.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions