module Kernel
def Async(...)
@public Since *Async v1*.
@parameter task [Async::Task] The task that is executing the given block.
@yields {|task| ...} The block that will execute asynchronously.
running.
the block as an asynchronous task. Will block until the reactor finishes
- When invoked at the top level, will create and run a reactor, and invoke
asynchronously. Will return the task once it has been scheduled.
- When invoked within an existing reactor task, it will run the given block
The preferred method to invoke asynchronous behavior at the top level.
Run the given block of code in a task, asynchronously, creating a reactor if necessary.
def Async(...) if current = ::Async::Task.current? return current.async(...) elsif scheduler = Fiber.scheduler ::Async::Task.run(scheduler, ...) else # This calls Fiber.set_scheduler(self): reactor = ::Async::Reactor.new begin return reactor.run(...) ensure Fiber.set_scheduler(nil) end end end
def Barrier(parent: Async::Idler.new, **options)
@parameter **options [Hash] Additional options passed to {Kernel::Sync}.
@parameter parent [Task | Semaphore | Nil] The parent for holding any children tasks.
By default, the barrier uses an `Async::Idler` to manage load, but this can be overridden by providing a different parent or `nil` to disable load management.
If no scheduler is running, one will be created automatically for the duration of the block.
Create a barrier, yield it to the block, and then wait for all tasks to complete.
def Barrier(parent: Async::Idler.new, **options) Sync(**options) do |task| barrier = ::Async::Barrier.new(parent: parent) yield barrier barrier.wait ensure barrier&.stop end end
def Sync(annotation: nil, &block)
@public Since *Async v1*.
@parameter task [Async::Task] The task that is executing the given block.
@yields {|task| ...} The block that will execute asynchronously.
Run the given block of code synchronously, but within a reactor if not already in one.
def Sync(annotation: nil, &block) if task = ::Async::Task.current? if annotation task.annotate(annotation) {yield task} else yield task end elsif scheduler = Fiber.scheduler ::Async::Task.run(scheduler, &block).wait else # This calls Fiber.set_scheduler(self): reactor = Async::Reactor.new begin # Use finished: false to suppress warnings since we're handling exceptions explicitly task = reactor.async(annotation: annotation, finished: false, &block) reactor.run return task.wait ensure Fiber.set_scheduler(nil) end end end