class Concurrent::Async::AsyncDelegator

Delegates asynchronous, thread-safe method calls to the wrapped object.

@!visibility private

Public Class Methods

new(delegate) click to toggle source

Create a new delegator object wrapping the given delegate.

@param [Object] delegate the object to wrap and delegate method calls to

Calls superclass method
# File lib/concurrent-ruby/concurrent/async.rb, line 288
def initialize(delegate)
  super()
  @delegate = delegate
  @queue = []
  @executor = Concurrent.global_io_executor
  @ruby_pid = $$
end

Public Instance Methods

method_missing(method, *args, &block) click to toggle source

Delegates method calls to the wrapped object.

@param [Symbol] method the method being called @param [Array] args zero or more arguments to the method

@return [IVar] the result of the method call

@raise [NameError] the object does not respond to `method` method @raise [ArgumentError] the given `args` do not match the arity of `method`

Calls superclass method
# File lib/concurrent-ruby/concurrent/async.rb, line 305
def method_missing(method, *args, &block)
  super unless @delegate.respond_to?(method)
  Async::validate_argc(@delegate, method, *args)

  ivar = Concurrent::IVar.new
  synchronize do
    reset_if_forked
    @queue.push [ivar, method, args, block]
    @executor.post { perform } if @queue.length == 1
  end

  ivar
end
perform() click to toggle source

Perform all enqueued tasks.

This method must be called from within the executor. It must not be called while already running. It will loop until the queue is empty.

# File lib/concurrent-ruby/concurrent/async.rb, line 330
def perform
  loop do
    ivar, method, args, block = synchronize { @queue.first }
    break unless ivar # queue is empty

    begin
      ivar.set(@delegate.send(method, *args, &block))
    rescue => error
      ivar.fail(error)
    end

    synchronize do
      @queue.shift
      return if @queue.empty?
    end
  end
end
reset_if_forked() click to toggle source
# File lib/concurrent-ruby/concurrent/async.rb, line 348
def reset_if_forked
  if $$ != @ruby_pid
    @queue.clear
    @ruby_pid = $$
  end
end
respond_to_missing?(method, include_private = false) click to toggle source

Check whether the method is responsive

@param [Symbol] method the method being called

Calls superclass method
# File lib/concurrent-ruby/concurrent/async.rb, line 322
def respond_to_missing?(method, include_private = false)
  @delegate.respond_to?(method) || super
end