123456789_123456789_123456789_123456789_123456789_

Module: EventMachine::Deferrable

Constant Summary

Class Method Summary

Instance Method Summary

Class Method Details

.future(arg, cb = nil, eb = nil, &blk)

A future is a sugaring of a typical deferrable usage.

[ GitHub ]

  
# File 'lib/em/future.rb', line 44

def self.future arg, cb=nil, eb=nil, &blk
  arg = arg.call if arg.respond_to?(:call)

  if arg.respond_to?(:set_deferred_status)
    if cb || eb
      arg.callback(&cb) if cb
      arg.errback(&eb) if eb
    else
      arg.callback(&blk) if blk
    end
  end

  arg
end

Instance Method Details

#callback(&block)

Specify a block to be executed if and when the Deferrable object receives a status of :succeeded. See #set_deferred_status for more information.

Calling this method on a Deferrable object whose status is not yet known will cause the callback block to be stored on an internal list. If you call this method on a Deferrable whose status is :succeeded, the block will be executed immediately, receiving the parameters given to the prior #set_deferred_status call.

[ GitHub ]

  
# File 'lib/em/deferrable.rb', line 44

def callback &block
  return unless block
  @deferred_status ||= :unknown
  if @deferred_status == :succeeded
    block.call(*@deferred_args)
  elsif @deferred_status != :failed
    @callbacks ||= []
    @callbacks.unshift block # << block
  end
  self
end

#cancel_callback(block)

Cancels an outstanding callback to &block if any. Undoes the action of #callback.

[ GitHub ]

  
# File 'lib/em/deferrable.rb', line 58

def cancel_callback block
  @callbacks ||= []
  @callbacks.delete block
end

#cancel_errback(block)

Cancels an outstanding errback to &block if any. Undoes the action of #errback.

[ GitHub ]

  
# File 'lib/em/deferrable.rb', line 84

def cancel_errback block
  @errbacks ||= []
  @errbacks.delete block
end

#cancel_timeout

Cancels an outstanding timeout if any. Undoes the action of #timeout.

[ GitHub ]

  
# File 'lib/em/deferrable.rb', line 179

def cancel_timeout
  @deferred_timeout ||= nil
  if @deferred_timeout
    @deferred_timeout.cancel
    @deferred_timeout = nil
  end
end

#errback(&block)

Specify a block to be executed if and when the Deferrable object receives a status of :failed. See #set_deferred_status for more information.

[ GitHub ]

  
# File 'lib/em/deferrable.rb', line 70

def errback &block
  return unless block
  @deferred_status ||= :unknown
  if @deferred_status == :failed
    block.call(*@deferred_args)
  elsif @deferred_status != :succeeded
    @errbacks ||= []
    @errbacks.unshift block # << block
  end
  self
end

#fail(*args) Also known as: #set_deferred_failure

Sugar for set_deferred_status(:failed, ...)

[ GitHub ]

  
# File 'lib/em/deferrable.rb', line 197

def fail *args
  set_deferred_status :failed, *args
end

#set_deferred_failure(*args)

Alias for #fail.

[ GitHub ]

  
# File 'lib/em/deferrable.rb', line 200

alias set_deferred_failure fail

#set_deferred_status(status, *args)

Sets the "disposition" (status) of the Deferrable object. See also the large set of sugarings for this method. Note that if you call this method without arguments, no arguments will be passed to the callback/errback. If the user has coded these with arguments, then the user code will throw an argument exception. Implementors of deferrable classes must document the arguments they will supply to user callbacks.

OBSERVE SOMETHING VERY SPECIAL here: you may call this method even on the INSIDE of a callback. This is very useful when a previously-registered callback wants to change the parameters that will be passed to subsequently-registered ones.

You may give either :succeeded or :failed as the status argument.

If you pass :succeeded, then all of the blocks passed to the object using the #callback method (if any) will be executed BEFORE the #set_deferred_status method returns. All of the blocks passed to the object using #errback will be discarded.

If you pass :failed, then all of the blocks passed to the object using the #errback method (if any) will be executed BEFORE the #set_deferred_status method returns. All of the blocks passed to the object using # callback will be discarded.

If you pass any arguments to #set_deferred_status in addition to the status argument, they will be passed as arguments to any callbacks or errbacks that are executed. It's your responsibility to ensure that the argument lists specified in your callbacks and errbacks match the arguments given in calls to #set_deferred_status, otherwise Ruby will raise an ArgumentError.

[ GitHub ]

  
# File 'lib/em/deferrable.rb', line 141

def set_deferred_status status, *args
  cancel_timeout
  @errbacks ||= nil
  @callbacks ||= nil
  @deferred_status = status
  @deferred_args = args
  case @deferred_status
  when :succeeded
    if @callbacks
      while cb = @callbacks.pop
        cb.call(*@deferred_args)
      end
    end
    @errbacks.clear if @errbacks
  when :failed
    if @errbacks
      while eb = @errbacks.pop
        eb.call(*@deferred_args)
      end
    end
    @callbacks.clear if @callbacks
  end
end

#set_deferred_success(*args)

Alias for #succeed.

[ GitHub ]

  
# File 'lib/em/deferrable.rb', line 193

alias set_deferred_success succeed

#succeed(*args) Also known as: #set_deferred_success

Sugar for set_deferred_status(:succeeded, ...)

[ GitHub ]

  
# File 'lib/em/deferrable.rb', line 190

def succeed *args
  set_deferred_status :succeeded, *args
end

#timeout(seconds, *args)

Setting a timeout on a Deferrable causes it to go into the failed state after the Timeout expires (passing no arguments to the object's errbacks). Setting the status at any time prior to a call to the expiration of the timeout will cause the timer to be cancelled.

[ GitHub ]

  
# File 'lib/em/deferrable.rb', line 170

def timeout seconds, *args
  cancel_timeout
  me = self
  @deferred_timeout = EventMachine::Timer.new(seconds) {me.fail(*args)}
  self
end