ably-rest 0.8.5 → 0.8.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/SPEC.md +1380 -631
- data/ably-rest.gemspec +11 -5
- data/lib/submodules/ably-ruby/.travis.yml +1 -1
- data/lib/submodules/ably-ruby/CHANGELOG.md +42 -48
- data/lib/submodules/ably-ruby/ably.gemspec +7 -1
- data/lib/submodules/ably-ruby/lib/ably.rb +2 -0
- data/lib/submodules/ably-ruby/lib/ably/auth.rb +155 -47
- data/lib/submodules/ably-ruby/lib/ably/exceptions.rb +2 -0
- data/lib/submodules/ably-ruby/lib/ably/models/channel_state_change.rb +2 -3
- data/lib/submodules/ably-ruby/lib/ably/models/connection_details.rb +54 -0
- data/lib/submodules/ably-ruby/lib/ably/models/protocol_message.rb +14 -4
- data/lib/submodules/ably-ruby/lib/ably/models/token_details.rb +13 -7
- data/lib/submodules/ably-ruby/lib/ably/models/token_request.rb +1 -2
- data/lib/submodules/ably-ruby/lib/ably/modules/ably.rb +3 -2
- data/lib/submodules/ably-ruby/lib/ably/modules/message_emitter.rb +1 -3
- data/lib/submodules/ably-ruby/lib/ably/modules/state_emitter.rb +2 -2
- data/lib/submodules/ably-ruby/lib/ably/realtime/auth.rb +6 -0
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel.rb +15 -4
- data/lib/submodules/ably-ruby/lib/ably/realtime/channel/channel_manager.rb +2 -0
- data/lib/submodules/ably-ruby/lib/ably/realtime/client.rb +10 -3
- data/lib/submodules/ably-ruby/lib/ably/realtime/client/incoming_message_dispatcher.rb +11 -1
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection.rb +62 -6
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection/connection_manager.rb +58 -54
- data/lib/submodules/ably-ruby/lib/ably/realtime/presence.rb +18 -5
- data/lib/submodules/ably-ruby/lib/ably/rest/channel.rb +9 -1
- data/lib/submodules/ably-ruby/lib/ably/rest/client.rb +32 -14
- data/lib/submodules/ably-ruby/lib/ably/rest/presence.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/version.rb +1 -1
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/auth_spec.rb +251 -11
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_history_spec.rb +12 -2
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_spec.rb +316 -24
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/client_spec.rb +93 -1
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_failures_spec.rb +177 -86
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_spec.rb +284 -60
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/message_spec.rb +45 -6
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_history_spec.rb +4 -0
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_spec.rb +181 -49
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/time_spec.rb +13 -0
- data/lib/submodules/ably-ruby/spec/acceptance/rest/auth_spec.rb +222 -4
- data/lib/submodules/ably-ruby/spec/acceptance/rest/channel_spec.rb +132 -1
- data/lib/submodules/ably-ruby/spec/acceptance/rest/client_spec.rb +129 -28
- data/lib/submodules/ably-ruby/spec/acceptance/rest/presence_spec.rb +7 -7
- data/lib/submodules/ably-ruby/spec/acceptance/rest/time_spec.rb +10 -0
- data/lib/submodules/ably-ruby/spec/shared/client_initializer_behaviour.rb +41 -17
- data/lib/submodules/ably-ruby/spec/spec_helper.rb +1 -0
- data/lib/submodules/ably-ruby/spec/support/debug_failure_helper.rb +16 -0
- data/lib/submodules/ably-ruby/spec/unit/models/connection_details_spec.rb +60 -0
- data/lib/submodules/ably-ruby/spec/unit/models/protocol_message_spec.rb +45 -0
- data/lib/submodules/ably-ruby/spec/unit/modules/event_emitter_spec.rb +3 -1
- data/lib/submodules/ably-ruby/spec/unit/realtime/channel_spec.rb +6 -5
- data/lib/submodules/ably-ruby/spec/unit/realtime/client_spec.rb +5 -1
- data/lib/submodules/ably-ruby/spec/unit/realtime/connection_spec.rb +5 -1
- data/lib/submodules/ably-ruby/spec/unit/realtime/realtime_spec.rb +5 -1
- metadata +57 -13
@@ -84,7 +84,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
84
84
|
end
|
85
85
|
|
86
86
|
context 'that expire' do
|
87
|
-
let(:client_options) { default_options.merge(log_level: :
|
87
|
+
let(:client_options) { default_options.merge(log_level: :error) }
|
88
88
|
|
89
89
|
before do
|
90
90
|
expect(client.rest_client.time.to_f).to be_within(2).of(Time.now.to_i), "Local clock is out of sync with Ably"
|
@@ -94,59 +94,97 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
94
94
|
# Ensure tokens issued expire immediately after issue
|
95
95
|
@original_renew_token_buffer = Ably::Auth::TOKEN_DEFAULTS.fetch(:renew_token_buffer)
|
96
96
|
stub_const 'Ably::Auth::TOKEN_DEFAULTS', Ably::Auth::TOKEN_DEFAULTS.merge(renew_token_buffer: 0)
|
97
|
-
|
98
|
-
# Authorise synchronously to ensure token has been issued
|
99
|
-
client.auth.authorise_sync(ttl: ttl)
|
100
97
|
end
|
101
98
|
|
102
99
|
let(:original_renew_token_buffer) { @original_renew_token_buffer }
|
103
100
|
|
104
101
|
context 'opening a new connection' do
|
105
|
-
context 'with
|
102
|
+
context 'with almost expired tokens' do
|
103
|
+
before do
|
104
|
+
# Authorise synchronously to ensure token has been issued
|
105
|
+
client.auth.authorise_sync(ttl: ttl)
|
106
|
+
end
|
107
|
+
|
106
108
|
let(:ttl) { 2 }
|
107
109
|
|
108
|
-
it 'renews
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
110
|
+
it 'renews token every time after it expires' do
|
111
|
+
started_at = Time.now.to_f
|
112
|
+
connected_times = 0
|
113
|
+
disconnected_times = 0
|
114
|
+
connection.on(:connected) do
|
115
|
+
connected_times += 1
|
116
|
+
end
|
117
|
+
connection.on(:disconnected) do
|
118
|
+
disconnected_times += 1
|
119
|
+
if disconnected_times == 3
|
120
|
+
expect(connected_times).to eql(3)
|
121
|
+
expect(Time.now.to_f - started_at).to be > ttl * 3
|
122
|
+
expect(Time.now.to_f - started_at).to be < (ttl * 2) * 3
|
115
123
|
stop_reactor
|
116
124
|
end
|
117
|
-
connection.once_state_changed do
|
118
|
-
raise "Invalid state #{connection.state}" unless connection.state == :connected
|
119
|
-
end
|
120
125
|
end
|
121
126
|
end
|
122
127
|
end
|
123
128
|
|
124
|
-
context 'with immediately
|
129
|
+
context 'with immediately expired token' do
|
125
130
|
let(:ttl) { 0.001 }
|
131
|
+
let(:auth_requests) { [] }
|
132
|
+
let(:token_callback) do
|
133
|
+
Proc.new do
|
134
|
+
auth_requests << Time.now
|
135
|
+
Ably::Rest::Client.new(default_options).auth.request_token(ttl: ttl).token
|
136
|
+
end
|
137
|
+
end
|
138
|
+
let(:client_options) { default_options.merge(auth_callback: token_callback) }
|
126
139
|
|
127
|
-
it 'renews the token on connect, and
|
128
|
-
|
140
|
+
it 'renews the token on connect, and makes one immediate subsequent attempt to obtain a new token' do
|
141
|
+
started_at = Time.now.to_f
|
129
142
|
connection.once(:disconnected) do
|
130
|
-
connection.once(:
|
143
|
+
connection.once(:disconnected) do |connection_state_change|
|
131
144
|
expect(connection_state_change.reason.code).to eql(40140) # token expired
|
145
|
+
expect(Time.now.to_f - started_at).to be < 1000
|
146
|
+
expect(auth_requests.count).to eql(2)
|
132
147
|
stop_reactor
|
133
148
|
end
|
134
149
|
end
|
135
150
|
end
|
136
151
|
|
137
|
-
|
138
|
-
|
152
|
+
context 'when disconnected_retry_timeout is 0.5 seconds' do
|
153
|
+
let(:client_options) { default_options.merge(disconnected_retry_timeout: 0.5, auth_callback: token_callback, log_level: :error) }
|
154
|
+
|
155
|
+
it 'renews the token on connect, and continues to attempt renew based on the retry schedule' do
|
156
|
+
started_at = Time.now.to_f
|
157
|
+
disconnect_count = 0
|
158
|
+
connection.on(:disconnected) do |connection_state_change|
|
159
|
+
expect(connection_state_change.reason.code).to eql(40140) # token expired
|
160
|
+
disconnect_count += 1
|
161
|
+
if disconnect_count == 6
|
162
|
+
expect(Time.now.to_f - started_at).to be > 4 * 0.5 # at least 4 0.5 second pauses should have happened
|
163
|
+
expect(Time.now.to_f - started_at).to be < 9 # allow 1.5 seconds for each authentication cycle
|
164
|
+
stop_reactor
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
context 'using implicit token auth' do
|
171
|
+
let(:client_options) { default_options.merge(use_token_auth: true, token_params: { ttl: ttl }) }
|
172
|
+
|
173
|
+
before do
|
174
|
+
stub_const 'Ably::Models::TokenDetails::TOKEN_EXPIRY_BUFFER', -10 # ensure client lib thinks token is still valid
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'uses the primary host for subsequent connection and auth requests' do
|
139
178
|
connection.once(:disconnected) do
|
140
179
|
expect(client.rest_client.connection).to receive(:post).
|
141
180
|
with(/requestToken$/, anything).
|
142
|
-
|
181
|
+
exactly(:once).
|
143
182
|
and_call_original
|
144
183
|
|
145
184
|
expect(client.rest_client).to_not receive(:fallback_connection)
|
146
185
|
expect(client).to_not receive(:fallback_endpoint)
|
147
186
|
|
148
|
-
connection.once(:
|
149
|
-
connection.off
|
187
|
+
connection.once(:disconnected) do
|
150
188
|
stop_reactor
|
151
189
|
end
|
152
190
|
end
|
@@ -157,15 +195,16 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
157
195
|
|
158
196
|
context 'when connected with a valid non-expired token' do
|
159
197
|
context 'that then expires following the connection being opened' do
|
160
|
-
let(:ttl)
|
161
|
-
let(:
|
198
|
+
let(:ttl) { 5 }
|
199
|
+
let(:channel_name) { random_str }
|
200
|
+
let(:channel) { client.channel(channel_name) }
|
201
|
+
let(:client_options) { default_options.merge(use_token_auth: true, token_params: { ttl: ttl }) }
|
162
202
|
|
163
203
|
context 'the server' do
|
164
204
|
it 'disconnects the client, and the client automatically renews the token and then reconnects', em_timeout: 15 do
|
165
|
-
original_token = client.auth.current_token_details
|
166
|
-
expect(original_token).to_not be_expired
|
167
|
-
|
168
205
|
connection.once(:connected) do
|
206
|
+
original_token = client.auth.current_token_details
|
207
|
+
expect(original_token).to_not be_expired
|
169
208
|
started_at = Time.now
|
170
209
|
connection.once(:disconnected) do |connection_state_change|
|
171
210
|
expect(connection_state_change.reason.code).to eq(40140) # Token expired
|
@@ -189,8 +228,86 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
189
228
|
end
|
190
229
|
end
|
191
230
|
|
192
|
-
|
193
|
-
|
231
|
+
context 'connection state' do
|
232
|
+
let(:ttl) { 4 }
|
233
|
+
let(:auth_requests) { [] }
|
234
|
+
let(:token_callback) do
|
235
|
+
Proc.new do
|
236
|
+
sleep 2
|
237
|
+
auth_requests << Time.now
|
238
|
+
Ably::Rest::Client.new(default_options).auth.request_token(ttl: ttl).token
|
239
|
+
end
|
240
|
+
end
|
241
|
+
let(:client_options) { default_options.merge(auth_callback: token_callback) }
|
242
|
+
let(:publishing_client) { auto_close Ably::Realtime::Client.new(default_options) }
|
243
|
+
let(:publishing_channel) { publishing_client.channels.get(channel_name) }
|
244
|
+
let(:messages_received) { [] }
|
245
|
+
|
246
|
+
def publish_and_check_first_disconnect
|
247
|
+
10.times.each { |index| publishing_channel.publish('event', index.to_s) }
|
248
|
+
channel.subscribe('event') do |message|
|
249
|
+
messages_received << message.data.to_i
|
250
|
+
if messages_received.count == 10
|
251
|
+
expect(messages_received).to match(10.times)
|
252
|
+
expect(auth_requests.count).to eql(2)
|
253
|
+
EventMachine.add_timer(1) do
|
254
|
+
channel.unsubscribe 'event'
|
255
|
+
yield
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
def publish_and_check_second_disconnect
|
262
|
+
10.times.each { |index| publishing_channel.publish('event', (index + 10).to_s) }
|
263
|
+
channel.subscribe('event') do |message|
|
264
|
+
messages_received << message.data.to_i
|
265
|
+
if messages_received.count == 20
|
266
|
+
expect(messages_received).to match(20.times)
|
267
|
+
expect(auth_requests.count).to eql(3)
|
268
|
+
stop_reactor
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
it 'retains messages published when disconnected twice during authentication', em_timeout: 20 do
|
274
|
+
publishing_channel.attach do
|
275
|
+
channel.attach do
|
276
|
+
connection.once(:disconnected) do
|
277
|
+
publish_and_check_first_disconnect do
|
278
|
+
connection.once(:disconnected) do
|
279
|
+
publish_and_check_second_disconnect
|
280
|
+
end
|
281
|
+
end
|
282
|
+
end
|
283
|
+
end
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
context 'and subsequent token is invalid' do
|
289
|
+
let(:ttl) { 2 }
|
290
|
+
let(:token_callback) do
|
291
|
+
Proc.new do
|
292
|
+
if @token_issued
|
293
|
+
"#{app_id}.invalid-token-invalid-token-invalid-token"
|
294
|
+
else
|
295
|
+
@token_issued = true
|
296
|
+
Ably::Rest::Client.new(default_options).auth.request_token(ttl: ttl).token
|
297
|
+
end
|
298
|
+
end
|
299
|
+
end
|
300
|
+
let(:client_options) { default_options.merge(auth_callback: token_callback, log_level: :none) }
|
301
|
+
|
302
|
+
it 'transitions the connection to the failed state' do
|
303
|
+
connection.once(:disconnected) do
|
304
|
+
connection.once(:failed) do
|
305
|
+
expect(connection.error_reason.code).to eql(40101)
|
306
|
+
stop_reactor
|
307
|
+
end
|
308
|
+
end
|
309
|
+
end
|
310
|
+
end
|
194
311
|
end
|
195
312
|
end
|
196
313
|
end
|
@@ -228,6 +345,50 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
228
345
|
end
|
229
346
|
end
|
230
347
|
end
|
348
|
+
|
349
|
+
context 'with opaque token string that contain an implicit client_id' do
|
350
|
+
let(:client_options) { default_options.merge(token: token_string, key: nil) }
|
351
|
+
let(:rest_auth_client) { Ably::Rest::Client.new(default_options.merge(key: api_key)) }
|
352
|
+
let(:token_string) { rest_auth_client.auth.request_token(client_id: client_id).token }
|
353
|
+
|
354
|
+
context 'string' do
|
355
|
+
let(:client_id) { random_str }
|
356
|
+
|
357
|
+
it 'sets the Client#client_id and Auth#client_id once CONNECTED' do
|
358
|
+
expect(client.client_id).to be_nil
|
359
|
+
client.connection.once(:connected) do
|
360
|
+
expect(client.client_id).to eql(client_id)
|
361
|
+
stop_reactor
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
context 'that is incompatible with the current client client_id' do
|
366
|
+
let(:client_id) { random_str }
|
367
|
+
let(:client_options) { default_options.merge(client_id: 'incompatible', token: token_string, key: nil, log_level: :none) }
|
368
|
+
|
369
|
+
it 'fails the connection' do
|
370
|
+
expect(client.client_id).to eql('incompatible')
|
371
|
+
client.connection.once(:failed) do
|
372
|
+
expect(client.client_id).to eql('incompatible')
|
373
|
+
expect(client.connection.error_reason.code).to eql(40101) # Invalid clientId for credentials
|
374
|
+
stop_reactor
|
375
|
+
end
|
376
|
+
end
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
380
|
+
context 'wildcard' do
|
381
|
+
let(:client_id) { '*' }
|
382
|
+
|
383
|
+
it 'configures the Client#client_id and Auth#client_id with a wildcard once CONNECTED' do
|
384
|
+
expect(client.client_id).to be_nil
|
385
|
+
client.connection.once(:connected) do
|
386
|
+
expect(client.client_id).to eql('*')
|
387
|
+
stop_reactor
|
388
|
+
end
|
389
|
+
end
|
390
|
+
end
|
391
|
+
end
|
231
392
|
end
|
232
393
|
end
|
233
394
|
|
@@ -277,6 +438,50 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
277
438
|
end
|
278
439
|
end
|
279
440
|
|
441
|
+
it 'calls the provided block on success even if state changes to disconnected first' do
|
442
|
+
been_disconnected = false
|
443
|
+
|
444
|
+
connection.once(:disconnected) do
|
445
|
+
been_disconnected = true
|
446
|
+
end
|
447
|
+
connection.once(:connecting) do
|
448
|
+
close_if_transport_available = proc do
|
449
|
+
EventMachine.add_timer(0.001) do
|
450
|
+
if connection.transport
|
451
|
+
connection.transport.close_connection_after_writing
|
452
|
+
else
|
453
|
+
close_if_transport_available.call
|
454
|
+
end
|
455
|
+
end
|
456
|
+
end
|
457
|
+
close_if_transport_available.call
|
458
|
+
end
|
459
|
+
|
460
|
+
connection.connect do
|
461
|
+
expect(connection.state).to eq(:connected)
|
462
|
+
expect(been_disconnected).to be_truthy
|
463
|
+
stop_reactor
|
464
|
+
end
|
465
|
+
end
|
466
|
+
|
467
|
+
context 'with invalid auth details' do
|
468
|
+
let(:client_options) { default_options.merge(key: 'this.is:invalid', log_level: :none) }
|
469
|
+
|
470
|
+
it 'calls the Deferrable errback only once on connection failure' do
|
471
|
+
errback_called = false
|
472
|
+
connection.connect.errback do
|
473
|
+
expect(connection.state).to eq(:failed)
|
474
|
+
|
475
|
+
raise 'Errback already called' if errback_called
|
476
|
+
errback_called = true
|
477
|
+
|
478
|
+
connection.connect.errback do
|
479
|
+
EventMachine.add_timer(0.5) { stop_reactor }
|
480
|
+
end
|
481
|
+
end
|
482
|
+
end
|
483
|
+
end
|
484
|
+
|
280
485
|
context 'when already connected' do
|
281
486
|
it 'does nothing and no further state changes are emitted' do
|
282
487
|
connection.once(:connected) do
|
@@ -509,12 +714,10 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
509
714
|
end
|
510
715
|
|
511
716
|
context 'with an unresponsive connection' do
|
512
|
-
let(:
|
717
|
+
let(:custom_timeout) { 2 }
|
718
|
+
let(:client_options) { default_options.merge(realtime_request_timeout: custom_timeout) }
|
513
719
|
|
514
720
|
before do
|
515
|
-
stub_const 'Ably::Realtime::Connection::ConnectionManager::TIMEOUTS',
|
516
|
-
Ably::Realtime::Connection::ConnectionManager::TIMEOUTS.merge(close: stubbed_timeout)
|
517
|
-
|
518
721
|
connection.on(:connected) do
|
519
722
|
# Prevent all incoming & outgoing ProtocolMessages from being processed by the client library
|
520
723
|
connection.__outgoing_protocol_msgbus__.unsubscribe
|
@@ -527,7 +730,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
527
730
|
close_requested_at = Time.now
|
528
731
|
|
529
732
|
connection.on(:closed) do
|
530
|
-
expect(Time.now - close_requested_at).to be >=
|
733
|
+
expect(Time.now - close_requested_at).to be >= custom_timeout
|
531
734
|
expect(connection.state).to eq(:closed)
|
532
735
|
expect(events[:error_emitted]).to_not eql(true)
|
533
736
|
expect(events[:closed_message_from_server_received]).to_not eql(true)
|
@@ -571,6 +774,30 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
571
774
|
end
|
572
775
|
end
|
573
776
|
end
|
777
|
+
|
778
|
+
context 'when ping times out' do
|
779
|
+
let(:client_options) { default_options.merge(log_level: :error) }
|
780
|
+
|
781
|
+
it 'logs a warning' do
|
782
|
+
connection.once(:connected) do
|
783
|
+
allow(connection).to receive(:defaults).and_return(connection.defaults.merge(realtime_request_timeout: 0.0001))
|
784
|
+
expect(connection.logger).to receive(:warn).with(/Ping timed out/) do
|
785
|
+
stop_reactor
|
786
|
+
end
|
787
|
+
connection.ping
|
788
|
+
end
|
789
|
+
end
|
790
|
+
|
791
|
+
it 'yields to the block with a nil value' do
|
792
|
+
connection.once(:connected) do
|
793
|
+
allow(connection).to receive(:defaults).and_return(connection.defaults.merge(realtime_request_timeout: 0.0001))
|
794
|
+
connection.ping do |time_elapsed|
|
795
|
+
expect(time_elapsed).to be_nil
|
796
|
+
stop_reactor
|
797
|
+
end
|
798
|
+
end
|
799
|
+
end
|
800
|
+
end
|
574
801
|
end
|
575
802
|
|
576
803
|
context 'recovery' do
|
@@ -580,15 +807,14 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
580
807
|
auto_close Ably::Realtime::Client.new(client_options)
|
581
808
|
end
|
582
809
|
let(:publishing_client_channel) { publishing_client.channel(channel_name) }
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
)
|
810
|
+
|
811
|
+
let(:client_options) do
|
812
|
+
default_options.merge(
|
813
|
+
log_level: :none,
|
814
|
+
disconnected_retry_timeout: 0.1,
|
815
|
+
suspended_retry_timeout: 0.1,
|
816
|
+
connection_state_ttl: 0.2
|
817
|
+
)
|
592
818
|
end
|
593
819
|
|
594
820
|
describe '#recovery_key' do
|
@@ -597,7 +823,6 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
597
823
|
end
|
598
824
|
let(:available_states) { self.class.available_states }
|
599
825
|
let(:states) { Hash.new }
|
600
|
-
let(:client_options) { default_options.merge(log_level: :none) }
|
601
826
|
let(:channel) { client.channel(random_str) }
|
602
827
|
|
603
828
|
it 'is composed of connection key and serial that is kept up to date with each message ACK received' do
|
@@ -641,6 +866,11 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
641
866
|
end
|
642
867
|
end
|
643
868
|
|
869
|
+
connection.once(:suspended) do
|
870
|
+
error_message = Ably::Models::ProtocolMessage.new(action: 9, error: { message: 'force failure' })
|
871
|
+
connection.__incoming_protocol_msgbus__.publish :protocol_message, error_message
|
872
|
+
end
|
873
|
+
|
644
874
|
connection.once(:failed) do
|
645
875
|
expect(states.keys).to match_array(available_states)
|
646
876
|
stop_reactor
|
@@ -659,8 +889,6 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
659
889
|
|
660
890
|
context "opening a new connection using a recently disconnected connection's #recovery_key" do
|
661
891
|
context 'connection#id and connection#key after recovery' do
|
662
|
-
let(:client_options) { default_options.merge(log_level: :none) }
|
663
|
-
|
664
892
|
it 'remains the same' do
|
665
893
|
previous_connection_id = nil
|
666
894
|
previous_connection_key = nil
|
@@ -701,8 +929,6 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
701
929
|
|
702
930
|
context 'when messages have been sent whilst the old connection is disconnected' do
|
703
931
|
describe 'the new connection' do
|
704
|
-
let(:client_options) { default_options.merge(log_level: :none) }
|
705
|
-
|
706
932
|
it 'recovers server-side queued messages' do
|
707
933
|
channel.attach do
|
708
934
|
connection.transition_state_machine! :failed
|
@@ -774,7 +1000,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
774
1000
|
|
775
1001
|
it 'opens each with a unique connection#id and connection#key' do
|
776
1002
|
connection_count.times.map do
|
777
|
-
Ably::Realtime::Client.new(client_options)
|
1003
|
+
auto_close Ably::Realtime::Client.new(client_options)
|
778
1004
|
end.each do |client|
|
779
1005
|
client.connection.on(:connected) do
|
780
1006
|
connection_ids << client.connection.id
|
@@ -943,15 +1169,13 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
943
1169
|
end
|
944
1170
|
|
945
1171
|
context 'when connection enters the :suspended state' do
|
946
|
-
let(:client_options)
|
947
|
-
|
948
|
-
|
949
|
-
|
950
|
-
|
951
|
-
|
952
|
-
|
953
|
-
suspended: { retry_every: 60, max_time_in_state: 60 }
|
954
|
-
)
|
1172
|
+
let(:client_options) do
|
1173
|
+
default_options.merge(
|
1174
|
+
log_level: :fatal,
|
1175
|
+
disconnected_retry_timeout: 0.02,
|
1176
|
+
suspended_retry_timeout: 60,
|
1177
|
+
connection_state_ttl: 0.05
|
1178
|
+
)
|
955
1179
|
end
|
956
1180
|
|
957
1181
|
it 'detaches the channels and prevents publishing of messages on those channels' do
|