AsyncSourceKernel

module Kernel

Extensions to all Ruby objects.

Definitions

def Async(...)

  • public
  • asynchronous

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

The preferred method to invoke asynchronous behavior at the top level.

  • When invoked within an existing reactor task, it will run the given block asynchronously. Will return the task once it has been scheduled.
  • 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.

Signature

yields {|task| ...}

The block that will execute asynchronously.

parameter task Async::Task

The task that is executing the given block.

public

Since Async v1.

asynchronous

May block until given block completes executing.

Implementation

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)

  • public

Create a barrier, yield it to the block, and then wait for all tasks to complete.

If no scheduler is running, one will be created automatically for the duration of the block.

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.

Signature

parameter parent Task | Semaphore | Nil

The parent for holding any children tasks.

parameter **options Hash

Additional options passed to Kernel#Sync.

public

Since Async v2.34.

Implementation

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
  • asynchronous

Run the given block of code synchronously, but within a reactor if not already in one.

Signature

yields {|task| ...}

The block that will execute asynchronously.

parameter task Async::Task

The task that is executing the given block.

public

Since Async v1.

asynchronous

Will block until given block completes executing.

Implementation

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

Discussion