Class: SignalWire::Relay::Action

Inherits:
Object
  • Object
show all
Defined in:
lib/signalwire/relay/action.rb

Overview

Base class for async action handles (play, record, detect, etc.).

Holds a control_id and back-reference to the Call. Resolves when the server sends a terminal event for this control_id.

Uses Ruby’s Queue for blocking wait semantics.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(call, control_id, terminal_event, terminal_states) ⇒ Action

Returns a new instance of Action.



19
20
21
22
23
24
25
26
27
28
29
# File 'lib/signalwire/relay/action.rb', line 19

def initialize(call, control_id, terminal_event, terminal_states)
  @call             = call
  @control_id       = control_id
  @terminal_event   = terminal_event
  @terminal_states  = terminal_states
  @result           = nil
  @completed        = false
  @mutex            = Mutex.new
  @condition        = ConditionVariable.new
  @on_completed     = nil
end

Instance Attribute Details

#callObject (readonly)

Returns the value of attribute call.



17
18
19
# File 'lib/signalwire/relay/action.rb', line 17

def call
  @call
end

#completedObject (readonly)

Returns the value of attribute completed.



17
18
19
# File 'lib/signalwire/relay/action.rb', line 17

def completed
  @completed
end

#control_idObject (readonly)

Returns the value of attribute control_id.



17
18
19
# File 'lib/signalwire/relay/action.rb', line 17

def control_id
  @control_id
end

#resultObject (readonly)

Returns the value of attribute result.



17
18
19
# File 'lib/signalwire/relay/action.rb', line 17

def result
  @result
end

Instance Method Details

#_check_event(event) ⇒ Object

Called by Call when an event matches our control_id.



42
43
44
45
46
47
# File 'lib/signalwire/relay/action.rb', line 42

def _check_event(event)
  state = event.params['state'] || ''
  if @terminal_states.include?(state) && !@completed
    _resolve(event)
  end
end

#_resolve(event) ⇒ Object

Mark the action as completed and fire the on_completed callback.



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/signalwire/relay/action.rb', line 50

def _resolve(event)
  @mutex.synchronize do
    return if @completed

    @result    = event
    @completed = true
    @condition.broadcast
  end
  if @on_completed
    begin
      @on_completed.call(event)
    rescue => e
      $stderr.puts "[RELAY] Error in on_completed callback for #{@control_id}: #{e.message}"
    end
  end
end

#_set_on_completed(callback) ⇒ Object

Called internally to set the on_completed callback from options.



37
38
39
# File 'lib/signalwire/relay/action.rb', line 37

def _set_on_completed(callback)
  @on_completed = callback
end

#done?Boolean Also known as: is_done?

Returns:

  • (Boolean)


89
90
91
# File 'lib/signalwire/relay/action.rb', line 89

def done?
  @completed
end

#on_completed(&block) ⇒ Object

Set the on_completed callback.



32
33
34
# File 'lib/signalwire/relay/action.rb', line 32

def on_completed(&block)
  @on_completed = block
end

#wait(timeout: nil) ⇒ Object

Wait for the action to complete. Returns the terminal event. Raises ActionTimeoutError if timeout is specified and exceeded.



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

def wait(timeout: nil)
  @mutex.synchronize do
    return @result if @completed

    if timeout
      deadline = Time.now + timeout
      while !@completed
        remaining = deadline - Time.now
        if remaining <= 0
          raise ActionTimeoutError, "Action #{@control_id} timed out after #{timeout}s"
        end
        @condition.wait(@mutex, remaining)
      end
    else
      @condition.wait(@mutex) until @completed
    end
    @result
  end
end