class EventMachine::Completion
Attributes
Public Class Methods
# File lib/em/completion.rb, line 171 def initialize @state = :unknown @callbacks = Hash.new { |h,k| h[k] = [] } @value = [] @timeout_timer = nil end
Public Instance Methods
Callbacks are called when you enter (or are in) a :succeeded state.
# File lib/em/completion.rb, line 206 def callback(*a, &b) stateback(:succeeded, *a, &b) end
Remove a callback. N.B. Some callbacks cannot be deleted. Usage is NOT recommended, this is an anti-pattern.
# File lib/em/completion.rb, line 272 def cancel_callback(*a, &b) @callbacks[:succeeded].delete(EM::Callback(*a, &b)) end
Remove an errback. N.B. Some errbacks cannot be deleted. Usage is NOT recommended, this is an anti-pattern.
# File lib/em/completion.rb, line 266 def cancel_errback(*a, &b) @callbacks[:failed].delete(EM::Callback(*a, &b)) end
Disable the timeout
# File lib/em/completion.rb, line 257 def cancel_timeout if @timeout_timer @timeout_timer.cancel @timeout_timer = nil end end
Enter a new state, setting the result value if given. If the state is one of :succeeded or :failed, then :completed callbacks will also be called.
# File lib/em/completion.rb, line 224 def change_state(state, *args) @value = args @state = state EM.schedule { execute_callbacks } end
Indicates that we’ve reached some kind of completion state, by default this is :succeeded or :failed. Due to these semantics, the :completed state is reserved for internal use.
# File lib/em/completion.rb, line 237 def completed? completion_states.any? { |s| state == s } end
Completions are called when you enter (or are in) either a :failed or a :succeeded state. They are stored as a special (reserved) state called :completed.
# File lib/em/completion.rb, line 218 def completion(*a, &b) stateback(:completed, *a, &b) end
Completion
states simply returns a list of completion states, by default this is :succeeded and :failed.
# File lib/em/completion.rb, line 243 def completion_states [:succeeded, :failed] end
Errbacks are called when you enter (or are in) a :failed state.
# File lib/em/completion.rb, line 211 def errback(*a, &b) stateback(:failed, *a, &b) end
Enter the :failed state, setting the result value if given.
# File lib/em/completion.rb, line 186 def fail(*args) change_state(:failed, *args) end
Statebacks are called when you enter (or are in) the named state.
# File lib/em/completion.rb, line 193 def stateback(state, *a, &b) # The following is quite unfortunate special casing for :completed # statebacks, but it's a necessary evil for latent completion # definitions. if :completed == state || !completed? || @state == state @callbacks[state] << EM::Callback(*a, &b) end execute_callbacks self end
Enter the :succeeded state, setting the result value if given.
# File lib/em/completion.rb, line 179 def succeed(*args) change_state(:succeeded, *args) end
Schedule a time which if passes before we enter a completion state, this deferrable will be failed with the given arguments.
# File lib/em/completion.rb, line 249 def timeout(time, *args) cancel_timeout @timeout_timer = EM::Timer.new(time) do fail(*args) unless completed? end end
Private Instance Methods
If we enter a completion state, clear other completion states after all callback chains are completed. This means that operation specific callbacks can’t be dual-called, which is most common user error.
# File lib/em/completion.rb, line 298 def clear_dead_callbacks completion_states.each do |state| @callbacks[state].clear end end
Execute all callbacks for the current state. If in a completed state, then call any statebacks associated with the completed state.
# File lib/em/completion.rb, line 279 def execute_callbacks execute_state_callbacks(state) if completed? execute_state_callbacks(:completed) clear_dead_callbacks cancel_timeout end end
Iterate all callbacks for a given state, and remove then call them.
# File lib/em/completion.rb, line 289 def execute_state_callbacks(state) while callback = @callbacks[state].shift callback.call(*value) end end