6

With Ruby 3.0 the async gem is now compatible with blocking IO in standard library functions and I wanted to understand the basic functionality but am already confused by a simple example:

require 'async'

n = 10
n.times do |i|
  Async do
    HTTParty.get("https://httpbin.org/delay/1.6")
  end
end

This doesn't show any parallelism. Looking in the Gem's documentation about Kernel#async says:

Run the given block of code in a task, asynchronously, creating a reactor if necessary.

But the project documentation seems to clear it up:

When invoked at the top level, will create and run a reactor, and invoke the block as an asynchronous task. Will block until the reactor finishes running.

So to make the example from above work:

require 'async'

n = 10
Async do
  n.times do |i|
    Async do
      HTTParty.get("https://httpbin.org/delay/1.6")
    end
  end
end

This works, but seems confusing to the reader. How would we know as readers that the first Async do is blocking while the others are not?

Thus the question: What is the canonical basic usage of the async gem?

Further reading:

Christopher Oezbek
  • 23,994
  • 6
  • 61
  • 85
  • 1
    _**When invoked at the top level**, will create and run a reactor, and invoke the block as an asynchronous task. Will block until the reactor finishes running_ - only top level `Async` will be blocked – Fabio Nov 01 '21 at 10:51
  • 1
    From same docs: _When invoked within an existing reactor task, it will run the given block **asynchronously**_ – Fabio Nov 01 '21 at 10:53
  • Hey Fabio, makes sense, but how I know when looking at a piece of code if I am top level or not? – Christopher Oezbek Nov 01 '21 at 10:55
  • Top-level is top level of the `.rb` file (try `puts to_s`). Anything in the `module` or `class` block is not top level. – Fabio Nov 01 '21 at 11:14
  • No, this isn't what the documentation means. In this case it is about runtime nesting of Ractors. – Christopher Oezbek Nov 01 '21 at 11:23

0 Answers0