class Adhearsion::CallController
Attributes
@private
@return [Call] The call object on which the controller is executing
@return [Hash] The controller's metadata provided at invocation
Public Class Methods
Execute a call controller, allowing passing control to another controller
@param [CallController] controller
# File lib/adhearsion/call_controller.rb, line 44 def exec(controller) controller.exec end
Include another module into all CallController
classes
# File lib/adhearsion/call_controller.rb, line 51 def mixin(mod) include mod end
Create a new instance
@param [Call] call the call to operate the controller on @param [Hash] metadata generic key-value storage applicable to the controller @param block to execute on the call
# File lib/adhearsion/call_controller.rb, line 75 def initialize(call, metadata = nil, &block) @call, @metadata, @block = call, metadata || {}, block @block_context = eval "self", @block.binding if @block @active_components = [] end
Public Instance Methods
@private
# File lib/adhearsion/call_controller.rb, line 194 def after_call @after_call ||= execute_callbacks :after_call end
Answer the call
@see Call#answer
# File lib/adhearsion/call_controller.rb, line 237 def answer(*args) block_until_resumed call.answer(*args) end
# File lib/adhearsion/call_controller.rb, line 101 def bg_exec(completion_callback = nil) Celluloid::ThreadHandle.new do catching_standard_errors do exec_with_callback completion_callback end end end
@private
# File lib/adhearsion/call_controller.rb, line 315 def block_until_resumed instance_variable_defined?(:@pause_latch) && @pause_latch.wait end
# File lib/adhearsion/call_controller.rb, line 336 def eql?(other) other.instance_of?(self.class) && call == other.call && metadata == other.metadata end
Execute the controller, allowing passing control to another controller
# File lib/adhearsion/call_controller.rb, line 92 def exec(controller = self) new_controller = catch :pass_controller do controller.execute! nil end exec new_controller if new_controller end
# File lib/adhearsion/call_controller.rb, line 109 def exec_with_callback(completion_callback = nil) exec ensure completion_callback.call call if completion_callback end
@private
# File lib/adhearsion/call_controller.rb, line 116 def execute!(*options) call.async.register_controller self execute_callbacks :before_call run rescue Call::Hangup, Call::ExpiredError rescue SyntaxError, StandardError => e Events.trigger :exception, [e, logger] on_error e raise ensure after_call logger.debug "Finished executing controller #{self.inspect}" end
@private
# File lib/adhearsion/call_controller.rb, line 185 def execute_callbacks(type) self.class.callbacks[type].each do |callback| catching_standard_errors do instance_exec(&callback) end end end
@private
# File lib/adhearsion/call_controller.rb, line 218 def execute_component_and_await_completion(component) write_and_await_response component yield component if block_given? complete_event = component.complete_event raise Adhearsion::Error, [complete_event.reason.details, component.inspect].join(": ") if complete_event.reason.is_a? Punchblock::Event::Complete::Error if complete_event.reason.is_a? Punchblock::Event::Complete::Hangup call.terminating! unless call.terminating? raise Call::Hangup end component end
Hangup the call, and execute after_call
callbacks
@param [Hash] headers
# File lib/adhearsion/call_controller.rb, line 247 def hangup(headers = nil) block_until_resumed call.hangup headers raise Call::Hangup end
Cease execution of this controller, including any components it is executing, and pass to another.
@param [Class] controller_class The class of controller to pass to @param [Hash] metadata generic key-value storage applicable to the controller
# File lib/adhearsion/call_controller.rb, line 178 def hard_pass(controller_class, metadata = nil) logger.info "Hard passing with active components #{@active_components.inspect}" stop_all_components pass controller_class, metadata end
@private
# File lib/adhearsion/call_controller.rb, line 332 def inspect "#<#{self.class} call=#{call.alive? ? call.id : ''}, metadata=#{metadata.inspect}>" end
Invoke another controller class within this controller, returning to this context on completion.
@param [Class] controller_class The class of controller to execute @param [Hash] metadata generic key-value storage applicable to the controller @return The return value of the controller's run method
# File lib/adhearsion/call_controller.rb, line 144 def invoke(controller_class, metadata = nil) controller = controller_class.new call, metadata controller.run end
Join the call to another call or a mixer, and block until the call is unjoined (by hangup or otherwise).
@param [Object] target See Call#join
for details @param [Hash] options @option options [Boolean] :async Return immediately, without waiting for the calls to unjoin. Defaults to false.
@see Call#join
# File lib/adhearsion/call_controller.rb, line 304 def join(target, options = {}) block_until_resumed async = (target.is_a?(Hash) ? target : options).delete :async join = call.join target, options waiter = async ? join[:joined_condition] : join[:unjoined_condition] waiter.wait end
Adhearsion::Logging::HasLogger#logger
# File lib/adhearsion/call_controller.rb, line 341 def logger call.logger rescue Celluloid::DeadActorError super end
# File lib/adhearsion/call_controller.rb, line 81 def method_missing(method_name, *args, &block) if @block_context @block_context.send method_name, *args, &block else super end end
Mute the call
@see Call#mute
# File lib/adhearsion/call_controller.rb, line 280 def mute(*args) block_until_resumed call.mute(*args) end
@private
# File lib/adhearsion/call_controller.rb, line 199 def on_error(e) @error = e @on_error ||= execute_callbacks :on_error end
Cease execution of this controller, and pass to another.
@param [Class] controller_class The class of controller to pass to @param [Hash] metadata generic key-value storage applicable to the controller
# File lib/adhearsion/call_controller.rb, line 155 def pass(controller_class, metadata = nil) throw :pass_controller, controller_class.new(call, metadata) end
@private
# File lib/adhearsion/call_controller.rb, line 320 def pause! @pause_latch = CountDownLatch.new 1 end
Redirect the call to some other target
@see Call#redirect
# File lib/adhearsion/call_controller.rb, line 269 def redirect(*args) block_until_resumed call.redirect(*args) raise Call::Hangup end
Reject the call
@see Call#reject
# File lib/adhearsion/call_controller.rb, line 258 def reject(*args) block_until_resumed call.reject(*args) raise Call::Hangup end
@private
# File lib/adhearsion/call_controller.rb, line 325 def resume! return unless @pause_latch @pause_latch.countdown! @pause_latch = nil end
Invoke the block supplied when creating the controller
# File lib/adhearsion/call_controller.rb, line 133 def run instance_exec(&block) if block end
Stop execution of all the components currently running in the controller.
# File lib/adhearsion/call_controller.rb, line 162 def stop_all_components logger.info "Stopping all controller components" @active_components.each do |component| begin component.stop! rescue Punchblock::Component::InvalidActionError end end end
Unmute the call
@see Call#unmute
# File lib/adhearsion/call_controller.rb, line 290 def unmute(*args) block_until_resumed call.unmute(*args) end
@private
# File lib/adhearsion/call_controller.rb, line 205 def write_and_await_response(command) block_until_resumed call.write_and_await_response command if command.is_a?(Punchblock::Component::ComponentNode) command.register_event_handler Punchblock::Event::Complete do |event| @active_components.delete command throw :pass end @active_components << command end end