signalwire 1.4.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +55 -0
- data/.rubocop.yml +14 -2
- data/AUTHORS.md +1 -0
- data/CHANGELOG.md +30 -5
- data/Gemfile +4 -18
- data/LICENSE +21 -0
- data/README.md +22 -82
- data/Rakefile +0 -17
- data/examples/relay/inbound_consumer.rb +26 -0
- data/examples/relay/inbound_dial.rb +28 -0
- data/examples/relay/outbound_collect.rb +27 -0
- data/examples/relay/outbound_consumer.rb +22 -0
- data/examples/relay/outbound_record.rb +25 -0
- data/lib/signalwire.rb +13 -0
- data/lib/signalwire/blade.rb +12 -0
- data/lib/signalwire/blade/connection.rb +200 -0
- data/lib/signalwire/blade/event_handler.rb +15 -0
- data/lib/signalwire/blade/message.rb +38 -0
- data/lib/signalwire/blade/message/connect.rb +18 -0
- data/lib/signalwire/blade/message/execute.rb +16 -0
- data/lib/signalwire/blade/message/subscribe.rb +15 -0
- data/lib/signalwire/common.rb +6 -0
- data/lib/signalwire/logger.rb +27 -0
- data/lib/signalwire/relay.rb +40 -0
- data/lib/signalwire/relay/calling.rb +82 -0
- data/lib/signalwire/relay/calling/action.rb +16 -0
- data/lib/signalwire/relay/calling/action/connect_action.rb +11 -0
- data/lib/signalwire/relay/calling/action/play_action.rb +15 -0
- data/lib/signalwire/relay/calling/action/prompt_action.rb +15 -0
- data/lib/signalwire/relay/calling/action/record_action.rb +15 -0
- data/lib/signalwire/relay/calling/call.rb +210 -0
- data/lib/signalwire/relay/calling/call_convenience_methods.rb +79 -0
- data/lib/signalwire/relay/calling/component.rb +115 -0
- data/lib/signalwire/relay/calling/component/answer.rb +27 -0
- data/lib/signalwire/relay/calling/component/await.rb +20 -0
- data/lib/signalwire/relay/calling/component/connect.rb +45 -0
- data/lib/signalwire/relay/calling/component/dial.rb +34 -0
- data/lib/signalwire/relay/calling/component/hangup.rb +41 -0
- data/lib/signalwire/relay/calling/component/play.rb +46 -0
- data/lib/signalwire/relay/calling/component/prompt.rb +62 -0
- data/lib/signalwire/relay/calling/component/record.rb +53 -0
- data/lib/signalwire/relay/calling/control_component.rb +35 -0
- data/lib/signalwire/relay/calling/result.rb +16 -0
- data/lib/signalwire/relay/calling/result/answer_result.rb +6 -0
- data/lib/signalwire/relay/calling/result/connect_result.rb +9 -0
- data/lib/signalwire/relay/calling/result/dial_result.rb +7 -0
- data/lib/signalwire/relay/calling/result/hangup_result.rb +7 -0
- data/lib/signalwire/relay/calling/result/play_result.rb +6 -0
- data/lib/signalwire/relay/calling/result/prompt_result.rb +11 -0
- data/lib/signalwire/relay/calling/result/record_result.rb +7 -0
- data/lib/signalwire/relay/client.rb +147 -0
- data/lib/signalwire/relay/constants.rb +109 -0
- data/lib/signalwire/relay/consumer.rb +88 -0
- data/lib/signalwire/relay/event.rb +41 -0
- data/lib/signalwire/relay/request.rb +6 -0
- data/lib/signalwire/rest/client.rb +5 -5
- data/lib/signalwire/sdk/fax_response.rb +3 -3
- data/lib/signalwire/sdk/messaging_response.rb +0 -2
- data/lib/signalwire/sdk/twilio_set_fax.rb +9 -8
- data/lib/signalwire/sdk/twilio_set_host.rb +8 -3
- data/lib/signalwire/version.rb +5 -0
- data/signalwire.gemspec +36 -106
- metadata +173 -76
- data/LICENSE.txt +0 -20
- data/VERSION +0 -1
- data/spec/signalwire/rest/client_spec.rb +0 -30
- data/spec/signalwire/rest/integration_spec.rb +0 -102
- data/spec/signalwire/sdk/configuration_spec.rb +0 -28
- data/spec/signalwire/sdk/fax_response_spec.rb +0 -26
- data/spec/signalwire/sdk/messaging_response_spec.rb +0 -18
- data/spec/signalwire/sdk/voice_response_spec.rb +0 -20
- data/spec/signalwire/sdk_spec.rb +0 -27
- data/spec/spec_helper.rb +0 -119
- data/spec/vcr_cassettes/accounts.yml +0 -27
- data/spec/vcr_cassettes/applications.yml +0 -29
- data/spec/vcr_cassettes/get_fax.yml +0 -25
- data/spec/vcr_cassettes/get_fax_media_instance.yml +0 -27
- data/spec/vcr_cassettes/get_fax_media_list.yml +0 -47
- data/spec/vcr_cassettes/list_faxes.yml +0 -25
- data/spec/vcr_cassettes/local_numbers.yml +0 -26
- data/spec/vcr_cassettes/recordings.yml +0 -27
- data/spec/vcr_cassettes/send_fax.yml +0 -27
- data/spec/vcr_cassettes/toll_free_numbers.yml +0 -34
- data/spec/vcr_cassettes/transcriptions.yml +0 -28
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'forwardable'
|
|
4
|
+
|
|
5
|
+
module Signalwire::Relay::Calling
|
|
6
|
+
class Action
|
|
7
|
+
extend Forwardable
|
|
8
|
+
attr_reader :component
|
|
9
|
+
|
|
10
|
+
def_delegators :@component, :control_id, :payload, :completed, :state
|
|
11
|
+
|
|
12
|
+
def initialize(component:)
|
|
13
|
+
@component = component
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'forwardable'
|
|
4
|
+
|
|
5
|
+
module Signalwire::Relay::Calling
|
|
6
|
+
class Call
|
|
7
|
+
include Signalwire::Logger
|
|
8
|
+
include Signalwire::Common
|
|
9
|
+
include Signalwire::Blade::EventHandler
|
|
10
|
+
include Signalwire::Relay::Calling::CallConvenienceMethods
|
|
11
|
+
extend Forwardable
|
|
12
|
+
|
|
13
|
+
attr_reader :device, :type, :node_id, :context, :from, :to,
|
|
14
|
+
:timeout, :tag, :client, :state, :previous_state, :components,
|
|
15
|
+
:busy, :failed
|
|
16
|
+
def_delegators :@client, :relay_execute
|
|
17
|
+
|
|
18
|
+
def self.from_event(client, event)
|
|
19
|
+
new(client, event.call_params)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def initialize(client, call_options)
|
|
23
|
+
@client = client
|
|
24
|
+
|
|
25
|
+
@id = call_options[:call_id]
|
|
26
|
+
setup_call_options(call_options)
|
|
27
|
+
@type = @device[:type]
|
|
28
|
+
|
|
29
|
+
@from = @device[:params][:from_number]
|
|
30
|
+
@to = @device[:params][:to_number]
|
|
31
|
+
@timeout = @device[:params][:timeout] || 30
|
|
32
|
+
@tag = SecureRandom.uuid
|
|
33
|
+
|
|
34
|
+
@components = []
|
|
35
|
+
|
|
36
|
+
setup_call_event_handlers
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def setup_call_event_handlers
|
|
40
|
+
@client.on(:event, proc { |evt| call_match_event(evt) }) do |event|
|
|
41
|
+
case event.event_type
|
|
42
|
+
when 'calling.call.connect'
|
|
43
|
+
change_connect_state(event.call_params[:connect_state])
|
|
44
|
+
when 'calling.call.state'
|
|
45
|
+
change_call_state(event.event_params)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
broadcast :event, event
|
|
49
|
+
broadcast :state_change, event
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def change_call_state(event_params)
|
|
54
|
+
call_state = event_params[:params]
|
|
55
|
+
@previous_state = @state
|
|
56
|
+
@state = call_state[:call_state]
|
|
57
|
+
broadcast :call_state_change, previous_state: @previous_state, state: @state
|
|
58
|
+
|
|
59
|
+
update_call_fields(call_state)
|
|
60
|
+
broadcast @state.to_sym, previous_state: @previous_state, state: @state
|
|
61
|
+
finish_call(event_params) if @state == Relay::CallState::ENDED
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def update_call_fields(call_state)
|
|
65
|
+
@id = call_state[:call_id] if call_state[:call_id]
|
|
66
|
+
@node_id = call_state[:node_id] if call_state[:node_id]
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def change_connect_state(new_connect_state)
|
|
70
|
+
@previous_connect_state = @connect_state
|
|
71
|
+
@connect_state = new_connect_state
|
|
72
|
+
broadcast :connect_state_change, previous_state: @previous_connect_state, state: @connect_state
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def call_match_event(event)
|
|
76
|
+
event.event_type.match(/calling\.call/) &&
|
|
77
|
+
!event.event_type.match(/receive/) &&
|
|
78
|
+
(event.call_id == id || event.call_params[:tag] == tag)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def id
|
|
82
|
+
@id ||= SecureRandom.uuid
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def answered?
|
|
86
|
+
@state == 'answered'
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def ended?
|
|
90
|
+
@state == 'ending' || @state == 'ended'
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def active?
|
|
94
|
+
!ended?
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def answer
|
|
98
|
+
answer_component = Signalwire::Relay::Calling::Answer.new(call: self)
|
|
99
|
+
answer_component.wait_for(Relay::CallState::ANSWERED, Relay::CallState::ENDING, Relay::CallState::ENDED)
|
|
100
|
+
AnswerResult.new(component: answer_component)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def play(play_object)
|
|
104
|
+
play_component = Signalwire::Relay::Calling::Play.new(call: self, play: play_object)
|
|
105
|
+
play_component.wait_for(Relay::CallPlayState::FINISHED, Relay::CallPlayState::ERROR)
|
|
106
|
+
PlayResult.new(component: play_component)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def play!(play_object)
|
|
110
|
+
play_component = Signalwire::Relay::Calling::Play.new(call: self, play: play_object)
|
|
111
|
+
play_component.execute
|
|
112
|
+
PlayAction.new(component: play_component)
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def prompt(collect_object, play_object)
|
|
116
|
+
component = Prompt.new(call: self, collect: collect_object, play: play_object)
|
|
117
|
+
component.wait_for(Relay::CallPromptState::ERROR, Relay::CallPromptState::NO_INPUT,
|
|
118
|
+
Relay::CallPromptState::NO_MATCH, Relay::CallPromptState::DIGIT,
|
|
119
|
+
Relay::CallPromptState::SPEECH)
|
|
120
|
+
PromptResult.new(component: component)
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def prompt!(collect_object, play_object)
|
|
124
|
+
component = Prompt,new(call: self, collect: collect_object, play: play_object)
|
|
125
|
+
component.execute
|
|
126
|
+
PromptAction.new(component: component)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def connect(devices_object)
|
|
130
|
+
component = Connect.new(call: self, devices: devices_object)
|
|
131
|
+
component.wait_for(Relay::CallConnectState::CONNECTED, Relay::CallConnectState::FAILED)
|
|
132
|
+
ConnectResult.new(component: component)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def connect!(devices_object)
|
|
136
|
+
component = Connect.new(call: self, devices: devices_object)
|
|
137
|
+
component.execute
|
|
138
|
+
ConnectAction.new(component: component)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def record(record_object)
|
|
142
|
+
component = Record.new(call: self, record: record_object)
|
|
143
|
+
component.wait_for(Relay::CallRecordState::NO_INPUT, Relay::CallRecordState::FINISHED)
|
|
144
|
+
RecordResult.new(component: component)
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def record!(record_object)
|
|
148
|
+
component = Record.new(call: self, record: record_object)
|
|
149
|
+
component.execute
|
|
150
|
+
RecordAction.new(component: component)
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def hangup(reason = 'hangup')
|
|
154
|
+
hangup_component = Signalwire::Relay::Calling::Hangup.new(call: self, reason: reason)
|
|
155
|
+
hangup_component.wait_for(Relay::CallState::ENDED)
|
|
156
|
+
HangupResult.new(component: hangup_component)
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def dial
|
|
160
|
+
dial_component = Signalwire::Relay::Calling::Dial.new(call: self)
|
|
161
|
+
dial_component.wait_for(Relay::CallState::ANSWERED, Relay::CallState::ENDING, Relay::CallState::ENDED)
|
|
162
|
+
DialResult.new(component: dial_component)
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def wait_for(*events)
|
|
166
|
+
events = [Relay::CallState::ENDED] if events.empty?
|
|
167
|
+
|
|
168
|
+
current_state_index = Relay::CALL_STATES.find_index(@state)
|
|
169
|
+
max_index = events.map { |evt| Relay::CALL_STATES.find_index(evt) }.max
|
|
170
|
+
|
|
171
|
+
return true if current_state_index >= max_index
|
|
172
|
+
|
|
173
|
+
component = Await.new(call: self)
|
|
174
|
+
component.wait_for(*events)
|
|
175
|
+
component.successful
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def register_component(component)
|
|
179
|
+
@components << component
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def terminate_components(params = {})
|
|
183
|
+
@components.each do |comp|
|
|
184
|
+
comp.terminate(params) unless component.completed
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def finish_call(params)
|
|
189
|
+
terminate_components(params)
|
|
190
|
+
client.calling.end_call(id)
|
|
191
|
+
@busy = true if params[:reason] == Relay::DisconnectReason::BUSY
|
|
192
|
+
@failed = true if params[:reason] == Relay::DisconnectReason::FAILED
|
|
193
|
+
broadcast :ended, previous_state: @previous_state, state: @state
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
private
|
|
197
|
+
|
|
198
|
+
def setup_call_options(call_options)
|
|
199
|
+
@node_id = call_options[:node_id]
|
|
200
|
+
@context = call_options[:context]
|
|
201
|
+
@previous_state = nil
|
|
202
|
+
@state = call_options[:call_state]
|
|
203
|
+
@previous_connect_state = nil
|
|
204
|
+
@connect_state = call_options[:connect_state]
|
|
205
|
+
@device = call_options[:device]
|
|
206
|
+
@busy = false
|
|
207
|
+
@failed = false
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
end
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
module Signalwire::Relay::Calling
|
|
2
|
+
module CallConvenienceMethods
|
|
3
|
+
def play_audio(url)
|
|
4
|
+
play audio_payload(url)
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def play_audio!(url)
|
|
8
|
+
play! audio_payload(url)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def play_silence(duration)
|
|
12
|
+
play silence_payload(duration)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def play_silence!(duration)
|
|
16
|
+
play! silence_payload(duration)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def play_tts(sentence, language='en-US', gender='female')
|
|
20
|
+
play tts_payload(sentence, language, gender)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def play_tts!(sentence, language='en-US', gender='female')
|
|
24
|
+
play! tts_payload(sentence, language, gender)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def prompt_audio(collect, url)
|
|
28
|
+
prompt(collect, audio_payload(url))
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def prompt_audio!(collect, url)
|
|
32
|
+
prompt!(collect, audio_payload(url))
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def prompt_silence(collect, duration)
|
|
36
|
+
prompt(collect, silence_payload(duration))
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def prompt_silence!(collect, url)
|
|
40
|
+
prompt!(collect, silence_payload(duration))
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def prompt_tts(collect, sentence, language='en-US', gender='female')
|
|
44
|
+
prompt(collect, tts_payload(sentence, language, gender))
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def prompt_tts!(collect, sentence, language='en-US', gender='female')
|
|
48
|
+
prompt!(collect, tts_payload(sentence, language, gender))
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def wait_for_ringing
|
|
52
|
+
wait_for(Relay::CallState::RINGING)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def wait_for_answered
|
|
56
|
+
wait_for(Relay::CallState::ANSWERED)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def wait_for_ending
|
|
60
|
+
wait_for(Relay::CallState::ENDING)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def wait_for_ended
|
|
64
|
+
wait_for(Relay::CallState::ENDED)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def audio_payload(url)
|
|
68
|
+
[{ type: "audio", params: { url: url } }]
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def silence_payload(duration)
|
|
72
|
+
[{ type: "silence", params: { duration: duration } }]
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def tts_payload(sentence, language='en-US', gender='male')
|
|
76
|
+
[{ "type": 'tts', "params": { "text": sentence, "language": language, "gender": gender } }]
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Signalwire::Relay::Calling
|
|
4
|
+
class Component
|
|
5
|
+
attr_reader :completed, :state, :successful, :event, :execute_result, :call
|
|
6
|
+
|
|
7
|
+
def initialize(call:)
|
|
8
|
+
@call = call
|
|
9
|
+
@completed = false
|
|
10
|
+
@successful = false
|
|
11
|
+
|
|
12
|
+
@call.register_component(self)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Relay method corresponding to the command
|
|
16
|
+
#
|
|
17
|
+
def method
|
|
18
|
+
raise NotImplementedError, 'Define this method on the child classes'
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Relay payload
|
|
22
|
+
# Implement this on child classes
|
|
23
|
+
def payload
|
|
24
|
+
nil
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# The event type the subclass listens to
|
|
28
|
+
def event_type
|
|
29
|
+
raise NotImplementedError, 'Define this method on the child classes'
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def execute_params(method_suffix = nil)
|
|
33
|
+
{
|
|
34
|
+
protocol: @call.client.protocol,
|
|
35
|
+
method: method + method_suffix.to_s,
|
|
36
|
+
params: inner_params
|
|
37
|
+
}
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def inner_params
|
|
41
|
+
result = {
|
|
42
|
+
node_id: @call.node_id,
|
|
43
|
+
call_id: @call.id
|
|
44
|
+
}
|
|
45
|
+
result[:params] = payload if payload
|
|
46
|
+
result
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def execute
|
|
50
|
+
setup_handlers
|
|
51
|
+
@call.relay_execute execute_params do |event, outcome|
|
|
52
|
+
handle_execute_result(event, outcome)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def setup_handlers
|
|
57
|
+
@call.on :event, event_type: event_type do |evt|
|
|
58
|
+
notification_handler(evt)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def handle_execute_result(event, outcome)
|
|
63
|
+
@execute_result = event
|
|
64
|
+
terminate if outcome == :failure
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def terminate(event = nil)
|
|
68
|
+
@completed = true
|
|
69
|
+
@successful = false
|
|
70
|
+
@state = 'failed'
|
|
71
|
+
@event = event if event
|
|
72
|
+
blocker&.reject
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def setup_waiting_events(events)
|
|
76
|
+
@events_waiting = events
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def wait_for(*events)
|
|
80
|
+
setup_waiting_events(events)
|
|
81
|
+
execute
|
|
82
|
+
wait_on_blocker unless @completed
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def wait_on_blocker
|
|
86
|
+
create_blocker
|
|
87
|
+
blocker.wait
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# This is the most important method to implement in a subclass
|
|
91
|
+
#
|
|
92
|
+
def notification_handler(_event)
|
|
93
|
+
# to be implemented by subclasses. An example could be:
|
|
94
|
+
#
|
|
95
|
+
# if event.call_params[:call_state] == 'ended'
|
|
96
|
+
# unblock
|
|
97
|
+
# end
|
|
98
|
+
raise NotImplementedError, 'Define this method on the child classes'
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def create_blocker
|
|
102
|
+
@blocker = Concurrent::Promises.resolvable_future
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def unblock(value)
|
|
106
|
+
blocker&.resolve value
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
attr_reader :blocker
|
|
110
|
+
|
|
111
|
+
def check_for_waiting_events
|
|
112
|
+
unblock(event) if @events_waiting.include?(@state)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|