ably 1.1.0 → 1.1.1
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/.travis.yml +7 -4
- data/CHANGELOG.md +18 -1
- data/README.md +9 -1
- data/ably.gemspec +3 -3
- data/lib/ably/realtime/client.rb +4 -3
- data/lib/ably/realtime/connection.rb +24 -15
- data/lib/ably/realtime/connection/connection_manager.rb +0 -2
- data/lib/ably/version.rb +1 -1
- data/spec/acceptance/realtime/auth_spec.rb +11 -9
- data/spec/acceptance/realtime/channel_history_spec.rb +26 -20
- data/spec/acceptance/realtime/connection_failures_spec.rb +3 -3
- data/spec/acceptance/realtime/connection_spec.rb +116 -14
- data/spec/acceptance/realtime/message_spec.rb +15 -13
- data/spec/acceptance/realtime/presence_spec.rb +196 -162
- data/spec/acceptance/realtime/push_admin_spec.rb +6 -4
- data/spec/acceptance/rest/channel_spec.rb +37 -0
- data/spec/acceptance/rest/channels_spec.rb +6 -0
- data/spec/acceptance/rest/message_spec.rb +7 -25
- data/spec/spec_helper.rb +1 -1
- data/spec/unit/realtime/connection_spec.rb +1 -1
- metadata +17 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 26f56201f9faae28b9b74ef9223e8d50c049a25d065f80d8612ce0013da46783
|
4
|
+
data.tar.gz: f74af9b0f0178576e41094fccf80821983da0b896e6bd7667fe534abe0d096bb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2a4c6c4006a176c01eacd9f38d9f11a61fb7f64880a764a663eca26e2ed2b7806203f972edf7cb5f0dec1034e6776d6b6dac459766ba920cc09ea156022640a9
|
7
|
+
data.tar.gz: 59d33ebc03521cf47449140715b5506dca17ac6b3708b914b6b0987d038c56667231086c8ff81c8d740d8a62c4474ac78c9839360b795e2d5c8f779ad972e3a5
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,24 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
-
## [v1.1.
|
3
|
+
## [v1.1.1](https://github.com/ably/ably-ruby/tree/v1.1.1)
|
4
4
|
|
5
|
+
[Full Changelog](https://github.com/ably/ably-ruby/compare/v1.1.0...v1.1.1)
|
6
|
+
|
7
|
+
**Implemented enhancements:**
|
8
|
+
|
9
|
+
- Support transient publishes as part of 1.1 spec [\#164](https://github.com/ably/ably-ruby/issues/164)
|
10
|
+
|
11
|
+
**Fixed bugs:**
|
12
|
+
|
13
|
+
- RTN16b recovery not fully implemented [\#180](https://github.com/ably/ably-ruby/issues/180)
|
14
|
+
- Publishing a high number of messages before connected results in lost messages [\#179](https://github.com/ably/ably-ruby/issues/179)
|
15
|
+
|
16
|
+
**Merged pull requests:**
|
17
|
+
|
18
|
+
- msgSerial fixes including connection recovery fix [\#181](https://github.com/ably/ably-ruby/pull/181) ([mattheworiordan](https://github.com/mattheworiordan))
|
19
|
+
- Known limitations section in README [\#177](https://github.com/ably/ably-ruby/pull/177) ([Srushtika](https://github.com/Srushtika))
|
20
|
+
|
21
|
+
## [v1.1.0](https://github.com/ably/ably-ruby/tree/v1.1.0) (2019-02-06)
|
5
22
|
[Full Changelog](https://github.com/ably/ably-ruby/compare/v1.0.7...v1.1.0)
|
6
23
|
|
7
24
|
**Fixed bugs:**
|
data/README.md
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
[](http://badge.fury.io/rb/ably)
|
4
4
|
[](https://coveralls.io/r/ably/ably-ruby)
|
5
5
|
|
6
|
-
A Ruby client library for [ably.io](https://www.ably.io), the realtime messaging service.
|
6
|
+
A Ruby client library for [ably.io](https://www.ably.io), the realtime messaging service. This library currently targets the [Ably 1.1 client library specification](https://www.ably.io/documentation/client-lib-development-guide/features/). You can jump to the '[Known Limitations](#known-limitations)' section to see the features this client library does not yet support or [view our client library SDKs feature support matrix](https://www.ably.io/download/sdk-feature-support-matrix) to see the list of all the available features.
|
7
7
|
|
8
8
|
## Supported platforms
|
9
9
|
|
@@ -13,6 +13,14 @@ We regression-test the SDK against a selection of Ruby versions (which we update
|
|
13
13
|
|
14
14
|
If you find any compatibility issues, please [do raise an issue](https://github.com/ably/ably-ruby/issues/new) in this repository or [contact Ably customer support](https://support.ably.io/) for advice.
|
15
15
|
|
16
|
+
## Known Limitations
|
17
|
+
|
18
|
+
This client library is currently *not compatible* with some of the Ably features:
|
19
|
+
|
20
|
+
| Feature |
|
21
|
+
| :--- |
|
22
|
+
| [Custom transportParams](https://www.ably.io/documentation/realtime/connection#client-options) |
|
23
|
+
|
16
24
|
## Documentation
|
17
25
|
|
18
26
|
Visit https://www.ably.io/documentation for a complete API reference and more examples.
|
data/ably.gemspec
CHANGED
@@ -24,7 +24,7 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.add_runtime_dependency 'faraday', '~> 0.12'
|
25
25
|
spec.add_runtime_dependency 'excon', '~> 0.55'
|
26
26
|
|
27
|
-
if RUBY_VERSION.match(/^1
|
27
|
+
if RUBY_VERSION.match(/^1\./)
|
28
28
|
spec.add_runtime_dependency 'json', '< 2.0'
|
29
29
|
else
|
30
30
|
spec.add_runtime_dependency 'json'
|
@@ -33,15 +33,15 @@ Gem::Specification.new do |spec|
|
|
33
33
|
spec.add_runtime_dependency 'msgpack', '>= 0.6.2'
|
34
34
|
spec.add_runtime_dependency 'addressable', '>= 2.0.0'
|
35
35
|
|
36
|
-
spec.add_development_dependency 'bundler', '~> 1.3'
|
37
36
|
spec.add_development_dependency 'rake', '~> 11.3'
|
38
37
|
spec.add_development_dependency 'redcarpet', '~> 3.3'
|
39
38
|
spec.add_development_dependency 'rspec', '~> 3.3.0' # version lock, see config.around(:example, :event_machine) in event_machine_helper.rb
|
40
39
|
spec.add_development_dependency 'rspec-retry', '~> 0.6'
|
41
40
|
spec.add_development_dependency 'yard', '~> 0.9'
|
42
41
|
spec.add_development_dependency 'rspec-instafail', '~> 1.0'
|
42
|
+
spec.add_development_dependency 'bundler', '>= 1.3.0'
|
43
43
|
|
44
|
-
if RUBY_VERSION.match(/^1
|
44
|
+
if RUBY_VERSION.match(/^1\./)
|
45
45
|
spec.add_development_dependency 'public_suffix', '~> 1.4.6' # Later versions do not support Ruby 1.9
|
46
46
|
spec.add_development_dependency 'webmock', '2.2'
|
47
47
|
spec.add_development_dependency 'parallel_tests', '~> 2.9.0'
|
data/lib/ably/realtime/client.rb
CHANGED
@@ -110,9 +110,6 @@ module Ably
|
|
110
110
|
end
|
111
111
|
|
112
112
|
@rest_client = Ably::Rest::Client.new(options.merge(realtime_client: self))
|
113
|
-
@auth = Ably::Realtime::Auth.new(self)
|
114
|
-
@channels = Ably::Realtime::Channels.new(self)
|
115
|
-
@connection = Ably::Realtime::Connection.new(self, options)
|
116
113
|
@echo_messages = rest_client.options.fetch(:echo_messages, true) == false ? false : true
|
117
114
|
@queue_messages = rest_client.options.fetch(:queue_messages, true) == false ? false : true
|
118
115
|
@custom_realtime_host = rest_client.options[:realtime_host] || rest_client.options[:ws_host]
|
@@ -120,6 +117,10 @@ module Ably
|
|
120
117
|
@recover = rest_client.options[:recover]
|
121
118
|
|
122
119
|
raise ArgumentError, "Recovery key '#{recover}' is invalid" if recover && !recover.match(Connection::RECOVER_REGEX)
|
120
|
+
|
121
|
+
@auth = Ably::Realtime::Auth.new(self)
|
122
|
+
@channels = Ably::Realtime::Channels.new(self)
|
123
|
+
@connection = Ably::Realtime::Connection.new(self, options)
|
123
124
|
end
|
124
125
|
|
125
126
|
# Return a {Ably::Realtime::Channel Realtime Channel} for the given name
|
@@ -66,7 +66,7 @@ module Ably
|
|
66
66
|
ensure_state_machine_emits 'Ably::Models::ConnectionStateChange'
|
67
67
|
|
68
68
|
# Expected format for a connection recover key
|
69
|
-
RECOVER_REGEX = /^(?<recover>[
|
69
|
+
RECOVER_REGEX = /^(?<recover>[^:]+):(?<connection_serial>[^:]+):(?<msg_serial>\-?\d+)$/
|
70
70
|
|
71
71
|
# Defaults for automatic connection recovery and timeouts
|
72
72
|
DEFAULTS = {
|
@@ -137,7 +137,6 @@ module Ably
|
|
137
137
|
@client = client
|
138
138
|
@__outgoing_message_queue__ = []
|
139
139
|
@__pending_message_ack_queue__ = []
|
140
|
-
reset_client_serial
|
141
140
|
|
142
141
|
@defaults = DEFAULTS.dup
|
143
142
|
options.each do |key, val|
|
@@ -145,6 +144,17 @@ module Ably
|
|
145
144
|
end if options.kind_of?(Hash)
|
146
145
|
@defaults.freeze
|
147
146
|
|
147
|
+
# If a recover client options is provided, then we need to ensure that the msgSerial matches the
|
148
|
+
# recover serial immediately at client library instantiation. This is done immediately so that any queued
|
149
|
+
# publishes use the correct serial number for these queued messages as well.
|
150
|
+
# There is no harm if the msgSerial is higher than expected if the recover fails.
|
151
|
+
recovery_msg_serial = connection_recover_parts && connection_recover_parts[:msg_serial].to_i
|
152
|
+
if recovery_msg_serial
|
153
|
+
@client_msg_serial = recovery_msg_serial
|
154
|
+
else
|
155
|
+
reset_client_msg_serial
|
156
|
+
end
|
157
|
+
|
148
158
|
Client::IncomingMessageDispatcher.new client, self
|
149
159
|
Client::OutgoingMessageDispatcher.new client, self
|
150
160
|
|
@@ -303,18 +313,17 @@ module Ably
|
|
303
313
|
# @!attribute [r] recovery_key
|
304
314
|
# @return [String] recovery key that can be used by another client to recover this connection with the :recover option
|
305
315
|
def recovery_key
|
306
|
-
"#{key}:#{serial}" if connection_resumable?
|
316
|
+
"#{key}:#{serial}:#{client_msg_serial}" if connection_resumable?
|
307
317
|
end
|
308
318
|
|
309
319
|
# Following a new connection being made, the connection ID, connection key
|
310
|
-
# and
|
320
|
+
# and connection serial need to match the details provided by the server.
|
311
321
|
#
|
312
322
|
# @return [void]
|
313
323
|
# @api private
|
314
324
|
def configure_new(connection_id, connection_key, connection_serial)
|
315
325
|
@id = connection_id
|
316
326
|
@key = connection_key
|
317
|
-
@client_serial = connection_serial
|
318
327
|
|
319
328
|
update_connection_serial connection_serial
|
320
329
|
end
|
@@ -542,11 +551,11 @@ module Ably
|
|
542
551
|
defaults.fetch(:realtime_request_timeout)
|
543
552
|
end
|
544
553
|
|
545
|
-
# Resets the client serial (msgSerial) sent to Ably for each new {Ably::Models::ProtocolMessage}
|
546
|
-
# (see #
|
554
|
+
# Resets the client message serial (msgSerial) sent to Ably for each new {Ably::Models::ProtocolMessage}
|
555
|
+
# (see #client_msg_serial)
|
547
556
|
# @api private
|
548
|
-
def
|
549
|
-
@
|
557
|
+
def reset_client_msg_serial
|
558
|
+
@client_msg_serial = -1
|
550
559
|
end
|
551
560
|
|
552
561
|
# When a hearbeat or any other message from Ably is received
|
@@ -568,15 +577,15 @@ module Ably
|
|
568
577
|
|
569
578
|
private
|
570
579
|
|
571
|
-
# The client serial is incremented for every message that is published that requires an ACK.
|
580
|
+
# The client message serial (msgSerial) is incremented for every message that is published that requires an ACK.
|
572
581
|
# Note that this is different to the connection serial that contains the last known serial number
|
573
582
|
# received from the server.
|
574
583
|
#
|
575
584
|
# A message serial number does not guarantee a message has been received, only sent.
|
576
585
|
# A connection serial guarantees the server has received the message and is thus used for connection recovery and resumes.
|
577
586
|
# @return [Integer] starting at -1 indicating no messages sent, 0 when the first message is sent
|
578
|
-
def
|
579
|
-
@
|
587
|
+
def client_msg_serial
|
588
|
+
@client_msg_serial
|
580
589
|
end
|
581
590
|
|
582
591
|
def resume_callbacks
|
@@ -601,11 +610,11 @@ module Ably
|
|
601
610
|
end
|
602
611
|
|
603
612
|
def add_message_serial_to(protocol_message)
|
604
|
-
@
|
605
|
-
protocol_message[:msgSerial] =
|
613
|
+
@client_msg_serial += 1
|
614
|
+
protocol_message[:msgSerial] = client_msg_serial
|
606
615
|
yield
|
607
616
|
rescue StandardError => e
|
608
|
-
@
|
617
|
+
@client_msg_serial -= 1
|
609
618
|
raise e
|
610
619
|
end
|
611
620
|
|
@@ -100,13 +100,11 @@ module Ably::Realtime
|
|
100
100
|
resend_pending_message_ack_queue
|
101
101
|
else
|
102
102
|
logger.debug { "ConnectionManager: Connection was not resumed, old connection ID #{connection.id} has been updated with new connection ID #{protocol_message.connection_id} and key #{protocol_message.connection_key}" }
|
103
|
-
connection.reset_client_serial
|
104
103
|
nack_messages_on_all_channels protocol_message.error
|
105
104
|
force_reattach_on_channels protocol_message.error
|
106
105
|
end
|
107
106
|
else
|
108
107
|
logger.debug { "ConnectionManager: New connection created with ID #{protocol_message.connection_id} and key #{protocol_message.connection_key}" }
|
109
|
-
connection.reset_client_serial
|
110
108
|
end
|
111
109
|
|
112
110
|
reattach_suspended_channels protocol_message.error
|
data/lib/ably/version.rb
CHANGED
@@ -661,17 +661,19 @@ describe Ably::Realtime::Auth, :event_machine do
|
|
661
661
|
client.connection.once(:disconnected) { raise 'Upgrade does not require a disconnect' }
|
662
662
|
|
663
663
|
channel = client.channels.get('foo')
|
664
|
-
channel.
|
665
|
-
|
666
|
-
|
664
|
+
channel.attach do
|
665
|
+
channel.publish('not-allowed').errback do |error|
|
666
|
+
expect(error.code).to eql(40160)
|
667
|
+
expect(error.message).to match(/permission denied/)
|
667
668
|
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
669
|
+
client.auth.authorize(nil, auth_callback: upgraded_token_cb)
|
670
|
+
client.connection.once(:update) do
|
671
|
+
expect(client.connection.error_reason).to be_nil
|
672
|
+
channel.subscribe('now-allowed') do |message|
|
673
|
+
stop_reactor
|
674
|
+
end
|
675
|
+
channel.publish 'now-allowed'
|
673
676
|
end
|
674
|
-
channel.publish 'now-allowed'
|
675
677
|
end
|
676
678
|
end
|
677
679
|
end
|
@@ -112,22 +112,26 @@ describe Ably::Realtime::Channel, '#history', :event_machine do
|
|
112
112
|
|
113
113
|
context 'in multiple ProtocolMessages', em_timeout: (30 / 10) + 5 do
|
114
114
|
it 'retrieves limited history forwards with pagination' do
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
115
|
+
channel.attach do
|
116
|
+
messages_sent.times do |index|
|
117
|
+
EventMachine.add_timer(index.to_f / rate_per_second) do
|
118
|
+
channel.publish('event', "history#{index}") do
|
119
|
+
next unless index == messages_sent - 1
|
120
|
+
ensure_message_history_direction_and_paging_is_correct :forwards
|
121
|
+
end
|
120
122
|
end
|
121
123
|
end
|
122
124
|
end
|
123
125
|
end
|
124
126
|
|
125
127
|
it 'retrieves limited history backwards with pagination' do
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
128
|
+
channel.attach do
|
129
|
+
messages_sent.times.to_a.reverse.each do |index|
|
130
|
+
EventMachine.add_timer((messages_sent - index).to_f / rate_per_second) do
|
131
|
+
channel.publish('event', "history#{index}") do
|
132
|
+
next unless index == 0
|
133
|
+
ensure_message_history_direction_and_paging_is_correct :backwards if index == 0
|
134
|
+
end
|
131
135
|
end
|
132
136
|
end
|
133
137
|
end
|
@@ -139,18 +143,20 @@ describe Ably::Realtime::Channel, '#history', :event_machine do
|
|
139
143
|
let(:messages_per_batch) { 10 }
|
140
144
|
|
141
145
|
it 'return the same results with unique matching message IDs' do
|
142
|
-
|
143
|
-
|
144
|
-
|
146
|
+
channel.attach do
|
147
|
+
batches.times do |batch|
|
148
|
+
EventMachine.add_timer(batch.to_f / batches.to_f) do
|
149
|
+
messages_per_batch.times { |index| channel.publish('event') }
|
150
|
+
end
|
145
151
|
end
|
146
|
-
end
|
147
152
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
153
|
+
channel.subscribe('event') do |message|
|
154
|
+
messages << message
|
155
|
+
if messages.count == batches * messages_per_batch
|
156
|
+
channel.history do |page|
|
157
|
+
expect(page.items.map(&:id).sort).to eql(messages.map(&:id).sort)
|
158
|
+
stop_reactor
|
159
|
+
end
|
154
160
|
end
|
155
161
|
end
|
156
162
|
end
|
@@ -921,7 +921,7 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
|
|
921
921
|
end
|
922
922
|
end
|
923
923
|
|
924
|
-
it 'retains the
|
924
|
+
it 'retains the client_msg_serial (#RTN15c2, #RTN15c3)' do
|
925
925
|
last_message = nil
|
926
926
|
channel = client.channels.get("foo")
|
927
927
|
|
@@ -1103,7 +1103,7 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
|
|
1103
1103
|
end
|
1104
1104
|
end
|
1105
1105
|
|
1106
|
-
it '
|
1106
|
+
it 'continues to use the client_msg_serial (#RTN15c3)' do
|
1107
1107
|
last_message = nil
|
1108
1108
|
channel = client.channels.get("foo")
|
1109
1109
|
|
@@ -1121,7 +1121,7 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
|
|
1121
1121
|
connection.once(:connected) do
|
1122
1122
|
channel.publish("first on new connection") do
|
1123
1123
|
# Message serial reset after failed resume
|
1124
|
-
expect(last_message.message_serial).to eql(
|
1124
|
+
expect(last_message.message_serial).to eql(2)
|
1125
1125
|
stop_reactor
|
1126
1126
|
end
|
1127
1127
|
end
|
@@ -264,7 +264,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
264
264
|
channel.subscribe('event') do |message|
|
265
265
|
messages_received << message.data.to_i
|
266
266
|
if messages_received.count == total_expected
|
267
|
-
expect(messages_received).to match(total_expected.times)
|
267
|
+
expect(messages_received).to match(total_expected.times.to_a)
|
268
268
|
expect(auth_requests.count).to eql(iteration + 1)
|
269
269
|
EventMachine.add_timer(1) do
|
270
270
|
channel.unsubscribe 'event'
|
@@ -649,16 +649,47 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
649
649
|
end
|
650
650
|
|
651
651
|
it 'is set to 1 when the second message is received' do
|
652
|
-
channel.
|
653
|
-
|
652
|
+
channel.attach do
|
653
|
+
messages = []
|
654
|
+
channel.subscribe do |message|
|
655
|
+
messages << message
|
656
|
+
if messages.length == 2
|
657
|
+
expect(connection.serial).to eql(1)
|
658
|
+
stop_reactor
|
659
|
+
end
|
660
|
+
end
|
661
|
+
|
662
|
+
channel.publish('event', 'data') do
|
663
|
+
channel.publish('event', 'data')
|
664
|
+
end
|
654
665
|
end
|
666
|
+
end
|
667
|
+
end
|
655
668
|
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
669
|
+
describe '#msgSerial' do
|
670
|
+
context 'when messages are queued for publish before a connection is established' do
|
671
|
+
let(:batches) { 6 }
|
672
|
+
let(:messages_per_batch) { 10 }
|
673
|
+
|
674
|
+
let(:publishing_client) { auto_close Ably::Realtime::Client.new(default_options) }
|
675
|
+
let(:channel_name) { random_str }
|
676
|
+
let(:publishing_channel) { publishing_client.channels.get(channel_name) }
|
677
|
+
let(:receiving_channel) { client.channels.get(channel_name) }
|
678
|
+
|
679
|
+
it 'the msgSerial is always incrementing (and not reset when the new connection is established) ensuring messages are never de-duped by the realtime service' do
|
680
|
+
messages = []
|
681
|
+
|
682
|
+
receiving_channel.attach do
|
683
|
+
receiving_channel.subscribe('event') do |message|
|
684
|
+
messages << message
|
685
|
+
stop_reactor if messages.count == batches * messages_per_batch
|
686
|
+
end
|
687
|
+
|
688
|
+
batches.times do |batch|
|
689
|
+
EventMachine.add_timer(batch.to_f / batches.to_f) do
|
690
|
+
messages_per_batch.times { |index| publishing_channel.publish('event') }
|
691
|
+
end
|
692
|
+
end
|
662
693
|
end
|
663
694
|
end
|
664
695
|
end
|
@@ -1005,10 +1036,9 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1005
1036
|
let(:client_options) { default_options.merge(websocket_heartbeats_disabled: true) }
|
1006
1037
|
|
1007
1038
|
it 'does not provide the heartbeats argument in the websocket connection params (#RTN23b)' do
|
1008
|
-
skip 'Native heartbeats not yet supported in the WS driver https://github.com/ably/ably-ruby/issues/116'
|
1009
1039
|
expect(EventMachine).to receive(:connect) do |host, port, transport, object, url|
|
1010
1040
|
uri = URI.parse(url)
|
1011
|
-
expect(CGI::parse(uri.query)['heartbeats'][0]).to
|
1041
|
+
expect(CGI::parse(uri.query)['heartbeats'][0]).to eql('true')
|
1012
1042
|
stop_reactor
|
1013
1043
|
end
|
1014
1044
|
client
|
@@ -1126,7 +1156,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1126
1156
|
expected_serial += 1 # attach message received
|
1127
1157
|
expect(connection.serial).to eql(expected_serial)
|
1128
1158
|
|
1129
|
-
expect(connection.recovery_key).to eql("#{connection.key}:#{connection.serial}")
|
1159
|
+
expect(connection.recovery_key).to eql("#{connection.key}:#{connection.serial}:#{connection.send(:client_msg_serial)}")
|
1130
1160
|
stop_reactor
|
1131
1161
|
end
|
1132
1162
|
end
|
@@ -1237,6 +1267,78 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1237
1267
|
end
|
1238
1268
|
end
|
1239
1269
|
end
|
1270
|
+
|
1271
|
+
context 'when messages have been published' do
|
1272
|
+
describe 'the new connection' do
|
1273
|
+
it 'uses the correct msgSerial from the old connection' do
|
1274
|
+
msg_serial, recovery_key, connection_id = nil, nil, nil
|
1275
|
+
|
1276
|
+
channel.attach do
|
1277
|
+
expect(connection.send(:client_msg_serial)).to eql(-1) # no messages published yet
|
1278
|
+
connection_id = client.connection.id
|
1279
|
+
connection.transport.__incoming_protocol_msgbus__
|
1280
|
+
channel.publish('event', 'message') do
|
1281
|
+
msg_serial = connection.send(:client_msg_serial)
|
1282
|
+
expect(msg_serial).to eql(0)
|
1283
|
+
recovery_key = client.connection.recovery_key
|
1284
|
+
connection.transition_state_machine! :failed
|
1285
|
+
end
|
1286
|
+
end
|
1287
|
+
|
1288
|
+
connection.on(:failed) do
|
1289
|
+
recover_client = auto_close Ably::Realtime::Client.new(default_options.merge(recover: recovery_key))
|
1290
|
+
recover_client_channel = recover_client.channel(channel_name)
|
1291
|
+
recover_client_channel.attach do
|
1292
|
+
expect(recover_client.connection.id).to eql(connection_id)
|
1293
|
+
expect(recover_client.connection.send(:client_msg_serial)).to eql(msg_serial)
|
1294
|
+
stop_reactor
|
1295
|
+
end
|
1296
|
+
end
|
1297
|
+
end
|
1298
|
+
end
|
1299
|
+
end
|
1300
|
+
|
1301
|
+
context 'when messages are published before the new connection is recovered' do
|
1302
|
+
describe 'the new connection' do
|
1303
|
+
it 'uses the correct msgSerial from the old connection for the queued messages' do
|
1304
|
+
msg_serial, recovery_key, connection_id = nil, nil, nil
|
1305
|
+
|
1306
|
+
channel.attach do
|
1307
|
+
expect(connection.send(:client_msg_serial)).to eql(-1) # no messages published yet
|
1308
|
+
connection_id = client.connection.id
|
1309
|
+
connection.transport.__incoming_protocol_msgbus__
|
1310
|
+
channel.publish('event', 'message-1') do
|
1311
|
+
msg_serial = connection.send(:client_msg_serial)
|
1312
|
+
expect(msg_serial).to eql(0)
|
1313
|
+
recovery_key = client.connection.recovery_key
|
1314
|
+
connection.transition_state_machine! :failed
|
1315
|
+
end
|
1316
|
+
end
|
1317
|
+
|
1318
|
+
connection.on(:failed) do
|
1319
|
+
recover_client = auto_close Ably::Realtime::Client.new(default_options.merge(recover: recovery_key))
|
1320
|
+
recover_client_channel = recover_client.channel(channel_name)
|
1321
|
+
expect(recover_client.connection.send(:client_msg_serial)).to eql(msg_serial)
|
1322
|
+
|
1323
|
+
recover_client.connection.once(:connecting) do
|
1324
|
+
recover_client_channel.publish('event', 'message-2')
|
1325
|
+
expect(recover_client.connection.send(:client_msg_serial)).to eql(msg_serial + 1)
|
1326
|
+
end
|
1327
|
+
|
1328
|
+
recover_client_channel.attach do
|
1329
|
+
expect(recover_client.connection.id).to eql(connection_id)
|
1330
|
+
|
1331
|
+
recover_client_channel.subscribe do |message|
|
1332
|
+
raise "Unexpected message #{message}" if message.data != 'message-2'
|
1333
|
+
EventMachine.add_timer(2) do
|
1334
|
+
stop_reactor
|
1335
|
+
end
|
1336
|
+
end
|
1337
|
+
end
|
1338
|
+
end
|
1339
|
+
end
|
1340
|
+
end
|
1341
|
+
end
|
1240
1342
|
end
|
1241
1343
|
|
1242
1344
|
context 'with :recover option' do
|
@@ -1250,7 +1352,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1250
1352
|
end
|
1251
1353
|
|
1252
1354
|
context 'with invalid formatted value sent to server' do
|
1253
|
-
let(:client_options) { default_options.merge(recover: 'not-a-valid-connection-key:1', log_level: :none) }
|
1355
|
+
let(:client_options) { default_options.merge(recover: 'not-a-valid-connection-key:1:0', log_level: :none) }
|
1254
1356
|
|
1255
1357
|
it 'sets the #error_reason and moves the connection to FAILED' do
|
1256
1358
|
connection.once(:failed) do |state_change|
|
@@ -1265,7 +1367,7 @@ describe Ably::Realtime::Connection, :event_machine do
|
|
1265
1367
|
end
|
1266
1368
|
|
1267
1369
|
context 'with expired (missing) value sent to server' do
|
1268
|
-
let(:client_options) { default_options.merge(recover: 'wVIsgTHAB1UvXh7z-1991d8586:0', log_level: :fatal) }
|
1370
|
+
let(:client_options) { default_options.merge(recover: 'wVIsgTHAB1UvXh7z-1991d8586:0:0', log_level: :fatal) }
|
1269
1371
|
|
1270
1372
|
it 'connects but sets the error reason and includes the reason in the state change' do
|
1271
1373
|
connection.once(:connected) do |state_change|
|