Module: EventMachine::Deferrable

Included in:
Protocols::HttpClient, Protocols::TcpConnectTester
Defined in:
lib/em/future.rb,
lib/em/deferrable.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

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

Evaluate arg (which may be an expression or a block). What’s the class of arg? If arg is an ordinary expression, then return it. If arg is deferrable (responds to :set_deferred_status), then look at the arguments. If either callback or errback are defined, then use them. If neither are defined, then use the supplied block (if any) as the callback. Then return arg.



44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/em/future.rb', line 44

def 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) ⇒ Object



31
32
33
34
35
36
37
38
39
# File 'lib/em/deferrable.rb', line 31

def callback &block
  return unless block
  if @deferred_status == :succeeded
    block.call(*@deferred_args)
  else
    @callbacks ||= []
    @callbacks << block
  end
end

#errback(&block) ⇒ Object



41
42
43
44
45
46
47
48
49
# File 'lib/em/deferrable.rb', line 41

def errback &block
  return unless block
  if @deferred_status == :failed
    block.call(*@deferred_args)
  else
    @errbacks ||= []
    @errbacks << block
  end
end

#set_deferred_failure(*args) ⇒ Object

Equivalent to set_deferred_status(:failed, …)



96
97
98
# File 'lib/em/deferrable.rb', line 96

def set_deferred_failure *args
 set_deferred_status :failed, *args
end

#set_deferred_status(arg, *args) ⇒ Object

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. – We’re shifting callbacks off and discarding them as we execute them. This is valid because by definition callbacks are executed no more than once. It also has the magic effect of permitting recursive calls, which means that a callback can call #set_deferred_status and change the parameters that will be sent to subsequent callbacks down the chain.



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/em/deferrable.rb', line 69

def set_deferred_status arg, *args
  @deferred_status = arg
  @deferred_args = args
  case @deferred_status
  when :succeeded
    if @callbacks
      while cb = @callbacks.shift
        cb.call(*@deferred_args)
      end
    end
  when :failed
    if @errbacks
      while eb = @errbacks.shift
        eb.call(*@deferred_args)
      end
    end
  end
end

#set_deferred_success(*args) ⇒ Object

Equivalent to set_deferred_status(:succeeded, …)



90
91
92
# File 'lib/em/deferrable.rb', line 90

def set_deferred_success *args
 set_deferred_status :succeeded, *args
end