ably-rest 1.1.0 → 1.1.2
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/README.md +9 -1
- data/ably-rest.gemspec +1 -1
- data/lib/submodules/ably-ruby/.travis.yml +9 -6
- data/lib/submodules/ably-ruby/CHANGELOG.md +25 -2
- data/lib/submodules/ably-ruby/README.md +9 -1
- data/lib/submodules/ably-ruby/ably.gemspec +4 -4
- data/lib/submodules/ably-ruby/lib/ably/logger.rb +7 -1
- data/lib/submodules/ably-ruby/lib/ably/modules/state_machine.rb +1 -1
- data/lib/submodules/ably-ruby/lib/ably/realtime/client.rb +4 -3
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection.rb +26 -15
- data/lib/submodules/ably-ruby/lib/ably/realtime/connection/connection_manager.rb +19 -3
- data/lib/submodules/ably-ruby/lib/ably/rest/client.rb +4 -2
- data/lib/submodules/ably-ruby/lib/ably/version.rb +1 -1
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/auth_spec.rb +13 -10
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_history_spec.rb +26 -20
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/channel_spec.rb +11 -8
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/client_spec.rb +8 -4
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_failures_spec.rb +71 -5
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/connection_spec.rb +125 -14
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/message_spec.rb +17 -17
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/presence_spec.rb +196 -162
- data/lib/submodules/ably-ruby/spec/acceptance/realtime/push_admin_spec.rb +46 -6
- data/lib/submodules/ably-ruby/spec/acceptance/rest/channel_spec.rb +37 -0
- data/lib/submodules/ably-ruby/spec/acceptance/rest/channels_spec.rb +6 -0
- data/lib/submodules/ably-ruby/spec/acceptance/rest/message_spec.rb +8 -27
- data/lib/submodules/ably-ruby/spec/acceptance/rest/push_admin_spec.rb +64 -8
- data/lib/submodules/ably-ruby/spec/spec_helper.rb +1 -1
- data/lib/submodules/ably-ruby/spec/support/debug_failure_helper.rb +9 -5
- data/lib/submodules/ably-ruby/spec/unit/modules/enum_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/unit/realtime/client_spec.rb +1 -1
- data/lib/submodules/ably-ruby/spec/unit/realtime/connection_spec.rb +1 -1
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e3a45b0f4d3366a78d1eaa428c977ad09ee7f4865c11e2e38ef84c4e3e46601a
|
4
|
+
data.tar.gz: ec961d83634b624ca147bd391564659c06e9c0ca901bf0437eae61aa6ebdc7f7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 10abe88a9e2c047f946139306afc7d0b3fdd59af0dc778b3e262390a1c1d7c3d8e731faad3b510a2b6d7341117265f69396b662a945fa0e55f9001f7661b8981
|
7
|
+
data.tar.gz: 2a2769c4d6706950d1f204f3ffe764b5336d1c7710839dc549091db6eacbc0bafc2be5e9f5ac644209778f433c97c0add81378735287108ead5702c1b7480828
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
[](http://badge.fury.io/rb/ably-rest)
|
4
4
|
|
5
|
-
A Ruby REST client library for [www.ably.io](https://www.ably.io), the realtime messaging service.
|
5
|
+
A Ruby REST client library for [www.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.
|
6
6
|
|
7
7
|
## Documentation
|
8
8
|
|
@@ -14,6 +14,14 @@ This REST only library was created for developers who do not want EventMachine a
|
|
14
14
|
|
15
15
|
If however you need to use a realtime library that offers an asynchronous evented AP, then we recommended you [take a look at the combined REST & Realtime gem](https://rubygems.org/gems/ably).
|
16
16
|
|
17
|
+
## Known Limitations
|
18
|
+
|
19
|
+
This client library is currently *not compatible* with some of the Ably features:
|
20
|
+
|
21
|
+
| Feature |
|
22
|
+
| :--- |
|
23
|
+
| [Custom transportParams](https://www.ably.io/documentation/realtime/connection#client-options) |
|
24
|
+
|
17
25
|
## Installation
|
18
26
|
|
19
27
|
The client library is available as a [gem from RubyGems.org](https://rubygems.org/gems/ably-rest).
|
data/ably-rest.gemspec
CHANGED
@@ -42,7 +42,7 @@ Gem::Specification.new do |spec|
|
|
42
42
|
spec.add_runtime_dependency 'msgpack', '>= 0.6.2'
|
43
43
|
spec.add_runtime_dependency 'addressable', '>= 2.0.0'
|
44
44
|
|
45
|
-
spec.add_development_dependency 'bundler', '
|
45
|
+
spec.add_development_dependency 'bundler', '>= 1.3.0'
|
46
46
|
spec.add_development_dependency 'rake', '~> 11.3'
|
47
47
|
spec.add_development_dependency 'redcarpet', '~> 3.3'
|
48
48
|
spec.add_development_dependency 'rspec', '~> 3.2.0'
|
@@ -1,15 +1,18 @@
|
|
1
1
|
sudo: false
|
2
2
|
env:
|
3
|
-
- RSPEC_RETRY=true PARALLEL_TEST_PROCESSORS=
|
4
|
-
- RSPEC_RETRY=true PARALLEL_TEST_PROCESSORS=
|
3
|
+
- RSPEC_RETRY=true PARALLEL_TEST_PROCESSORS=2 PROTOCOL=json
|
4
|
+
- RSPEC_RETRY=true PARALLEL_TEST_PROCESSORS=2 PROTOCOL=msgpack
|
5
5
|
language: ruby
|
6
6
|
rvm:
|
7
7
|
- 1.9.3
|
8
|
-
- 2.0.0
|
9
8
|
- 2.1.10
|
10
|
-
- 2.2.
|
11
|
-
- 2.3.
|
12
|
-
- 2.
|
9
|
+
- 2.2.10
|
10
|
+
- 2.3.8
|
11
|
+
- 2.5.5
|
12
|
+
- 2.6.0
|
13
|
+
- 2.6.1
|
14
|
+
- 2.6.2
|
15
|
+
- 2.6.3
|
13
16
|
script: spec/run_parallel_tests
|
14
17
|
notifications:
|
15
18
|
slack:
|
@@ -1,7 +1,31 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
-
## [v1.1.
|
3
|
+
## [v1.1.2](https://github.com/ably/ably-ruby/tree/v1.1.2)
|
4
4
|
|
5
|
+
[Full Changelog](https://github.com/ably/ably-ruby/compare/v1.1.1...v1.1.2)
|
6
|
+
|
7
|
+
**Merged pull requests:**
|
8
|
+
|
9
|
+
- Remove legacy skipped tests and upgrade MsgPack [\#184](https://github.com/ably/ably-ruby/pull/184) ([mattheworiordan](https://github.com/mattheworiordan))
|
10
|
+
|
11
|
+
## [v1.1.1](https://github.com/ably/ably-ruby/tree/v1.1.1) (2019-05-06)
|
12
|
+
[Full Changelog](https://github.com/ably/ably-ruby/compare/v1.1.0...v1.1.1)
|
13
|
+
|
14
|
+
**Implemented enhancements:**
|
15
|
+
|
16
|
+
- Support transient publishes as part of 1.1 spec [\#164](https://github.com/ably/ably-ruby/issues/164)
|
17
|
+
|
18
|
+
**Fixed bugs:**
|
19
|
+
|
20
|
+
- RTN16b recovery not fully implemented [\#180](https://github.com/ably/ably-ruby/issues/180)
|
21
|
+
- Publishing a high number of messages before connected results in lost messages [\#179](https://github.com/ably/ably-ruby/issues/179)
|
22
|
+
|
23
|
+
**Merged pull requests:**
|
24
|
+
|
25
|
+
- msgSerial fixes including connection recovery fix [\#181](https://github.com/ably/ably-ruby/pull/181) ([mattheworiordan](https://github.com/mattheworiordan))
|
26
|
+
- Known limitations section in README [\#177](https://github.com/ably/ably-ruby/pull/177) ([Srushtika](https://github.com/Srushtika))
|
27
|
+
|
28
|
+
## [v1.1.0](https://github.com/ably/ably-ruby/tree/v1.1.0) (2019-02-06)
|
5
29
|
[Full Changelog](https://github.com/ably/ably-ruby/compare/v1.0.7...v1.1.0)
|
6
30
|
|
7
31
|
**Fixed bugs:**
|
@@ -50,7 +74,6 @@
|
|
50
74
|
**Closed issues:**
|
51
75
|
|
52
76
|
- Passing a frozen channel name or name gives an error on the REST client \[Reopen\] [\#145](https://github.com/ably/ably-ruby/issues/145)
|
53
|
-
- Passing a frozen channel name or name gives an error on the REST client [\#132](https://github.com/ably/ably-ruby/issues/132)
|
54
77
|
|
55
78
|
**Merged pull requests:**
|
56
79
|
|
@@ -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.
|
@@ -24,24 +24,24 @@ 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'
|
31
31
|
end
|
32
32
|
spec.add_runtime_dependency 'websocket-driver', '~> 0.7'
|
33
|
-
spec.add_runtime_dependency 'msgpack', '>=
|
33
|
+
spec.add_runtime_dependency 'msgpack', '>= 1.3.0'
|
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'
|
@@ -20,6 +20,8 @@ module Ably
|
|
20
20
|
ensure_logger_interface_is_valid
|
21
21
|
|
22
22
|
@logger.level = log_level
|
23
|
+
|
24
|
+
@log_mutex = Mutex.new
|
23
25
|
end
|
24
26
|
|
25
27
|
# The logger used by this class, defaults to {http://www.ruby-doc.org/stdlib-1.9.3/libdoc/logger/rdoc/Logger.html Ruby Logger}
|
@@ -38,7 +40,9 @@ module Ably
|
|
38
40
|
%w(fatal error warn info debug).each do |method_name|
|
39
41
|
define_method(method_name) do |*args, &block|
|
40
42
|
begin
|
41
|
-
|
43
|
+
log_mutex.synchronize do
|
44
|
+
logger.public_send(method_name, *args, &block)
|
45
|
+
end
|
42
46
|
rescue StandardError => e
|
43
47
|
logger.error "Logger: Failed to log #{method_name} block - #{e.class}: #{e.message}\n#{e.backtrace.join("\n")}"
|
44
48
|
end
|
@@ -46,6 +50,8 @@ module Ably
|
|
46
50
|
end
|
47
51
|
|
48
52
|
private
|
53
|
+
attr_reader :log_mutex
|
54
|
+
|
49
55
|
def client
|
50
56
|
@client
|
51
57
|
end
|
@@ -23,7 +23,7 @@ module Ably::Modules
|
|
23
23
|
def transition_state(state, *args)
|
24
24
|
unless result = transition_to(state.to_sym, *args)
|
25
25
|
exception = exception_for_state_change_to(state)
|
26
|
-
logger.fatal { "#{self.class}: #{exception.message}" }
|
26
|
+
logger.fatal { "#{self.class}: #{exception.message}\n#{caller[0..20].join("\n")}" }
|
27
27
|
end
|
28
28
|
result
|
29
29
|
end
|
@@ -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,12 +144,25 @@ 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
|
|
151
161
|
@state_machine = ConnectionStateMachine.new(self)
|
152
162
|
@state = STATE(state_machine.current_state)
|
153
163
|
@manager = ConnectionManager.new(self)
|
164
|
+
|
165
|
+
@current_host = client.endpoint.host
|
154
166
|
end
|
155
167
|
|
156
168
|
# Causes the connection to close, entering the closed state, from any state except
|
@@ -303,18 +315,17 @@ module Ably
|
|
303
315
|
# @!attribute [r] recovery_key
|
304
316
|
# @return [String] recovery key that can be used by another client to recover this connection with the :recover option
|
305
317
|
def recovery_key
|
306
|
-
"#{key}:#{serial}" if connection_resumable?
|
318
|
+
"#{key}:#{serial}:#{client_msg_serial}" if connection_resumable?
|
307
319
|
end
|
308
320
|
|
309
321
|
# Following a new connection being made, the connection ID, connection key
|
310
|
-
# and
|
322
|
+
# and connection serial need to match the details provided by the server.
|
311
323
|
#
|
312
324
|
# @return [void]
|
313
325
|
# @api private
|
314
326
|
def configure_new(connection_id, connection_key, connection_serial)
|
315
327
|
@id = connection_id
|
316
328
|
@key = connection_key
|
317
|
-
@client_serial = connection_serial
|
318
329
|
|
319
330
|
update_connection_serial connection_serial
|
320
331
|
end
|
@@ -542,11 +553,11 @@ module Ably
|
|
542
553
|
defaults.fetch(:realtime_request_timeout)
|
543
554
|
end
|
544
555
|
|
545
|
-
# Resets the client serial (msgSerial) sent to Ably for each new {Ably::Models::ProtocolMessage}
|
546
|
-
# (see #
|
556
|
+
# Resets the client message serial (msgSerial) sent to Ably for each new {Ably::Models::ProtocolMessage}
|
557
|
+
# (see #client_msg_serial)
|
547
558
|
# @api private
|
548
|
-
def
|
549
|
-
@
|
559
|
+
def reset_client_msg_serial
|
560
|
+
@client_msg_serial = -1
|
550
561
|
end
|
551
562
|
|
552
563
|
# When a hearbeat or any other message from Ably is received
|
@@ -568,15 +579,15 @@ module Ably
|
|
568
579
|
|
569
580
|
private
|
570
581
|
|
571
|
-
# The client serial is incremented for every message that is published that requires an ACK.
|
582
|
+
# The client message serial (msgSerial) is incremented for every message that is published that requires an ACK.
|
572
583
|
# Note that this is different to the connection serial that contains the last known serial number
|
573
584
|
# received from the server.
|
574
585
|
#
|
575
586
|
# A message serial number does not guarantee a message has been received, only sent.
|
576
587
|
# A connection serial guarantees the server has received the message and is thus used for connection recovery and resumes.
|
577
588
|
# @return [Integer] starting at -1 indicating no messages sent, 0 when the first message is sent
|
578
|
-
def
|
579
|
-
@
|
589
|
+
def client_msg_serial
|
590
|
+
@client_msg_serial
|
580
591
|
end
|
581
592
|
|
582
593
|
def resume_callbacks
|
@@ -601,11 +612,11 @@ module Ably
|
|
601
612
|
end
|
602
613
|
|
603
614
|
def add_message_serial_to(protocol_message)
|
604
|
-
@
|
605
|
-
protocol_message[:msgSerial] =
|
615
|
+
@client_msg_serial += 1
|
616
|
+
protocol_message[:msgSerial] = client_msg_serial
|
606
617
|
yield
|
607
618
|
rescue StandardError => e
|
608
|
-
@
|
619
|
+
@client_msg_serial -= 1
|
609
620
|
raise e
|
610
621
|
end
|
611
622
|
|
@@ -49,18 +49,31 @@ module Ably::Realtime
|
|
49
49
|
|
50
50
|
logger.debug { 'ConnectionManager: Opening a websocket transport connection' }
|
51
51
|
|
52
|
+
# The socket attempt can fail at the same time as a timer firing so ensure
|
53
|
+
# only one outcome is processed from this setup attempt
|
54
|
+
setup_attempt_status = {}
|
55
|
+
setup_failed = lambda do
|
56
|
+
return true if setup_attempt_status[:failed]
|
57
|
+
setup_attempt_status[:failed] = true
|
58
|
+
false
|
59
|
+
end
|
60
|
+
|
52
61
|
connection.create_websocket_transport.tap do |socket_deferrable|
|
53
62
|
socket_deferrable.callback do |websocket_transport|
|
54
63
|
subscribe_to_transport_events websocket_transport
|
55
64
|
yield websocket_transport if block_given?
|
56
65
|
end
|
57
66
|
socket_deferrable.errback do |error|
|
67
|
+
next if setup_failed.call
|
58
68
|
connection_opening_failed error
|
59
69
|
end
|
60
70
|
end
|
61
71
|
|
72
|
+
# The connection request timeout must be marginally higher than the REST request timeout to ensure
|
73
|
+
# any HTTP auth request failure due to timeout triggers before the connection timer kicks in
|
62
74
|
logger.debug { "ConnectionManager: Setting up automatic connection timeout timer for #{realtime_request_timeout}s" }
|
63
75
|
create_timeout_timer_whilst_in_state(:connecting, realtime_request_timeout) do
|
76
|
+
next if setup_failed.call
|
64
77
|
connection_opening_failed Ably::Exceptions::ConnectionTimeout.new("Connection to Ably timed out after #{realtime_request_timeout}s", nil, Ably::Exceptions::Codes::CONNECTION_TIMED_OUT)
|
65
78
|
end
|
66
79
|
end
|
@@ -80,7 +93,12 @@ module Ably::Realtime
|
|
80
93
|
|
81
94
|
logger.warn { "ConnectionManager: Connection to #{connection.current_host}:#{connection.port} failed; #{error.message}" }
|
82
95
|
next_state = get_next_retry_state_info
|
83
|
-
|
96
|
+
|
97
|
+
if connection.state == next_state.fetch(:state)
|
98
|
+
logger.error { "ConnectionManager: Skipping next retry state after connection opening failed as already in state #{next_state}\n#{caller[0..20].join("\n")}" }
|
99
|
+
else
|
100
|
+
connection.transition_state_machine next_state.fetch(:state), retry_in: next_state.fetch(:pause), reason: Ably::Exceptions::ConnectionError.new("Connection failed: #{error.message}", nil, Ably::Exceptions::Codes::CONNECTION_FAILED, error)
|
101
|
+
end
|
84
102
|
end
|
85
103
|
|
86
104
|
# Called whenever a new connection is made
|
@@ -100,13 +118,11 @@ module Ably::Realtime
|
|
100
118
|
resend_pending_message_ack_queue
|
101
119
|
else
|
102
120
|
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
121
|
nack_messages_on_all_channels protocol_message.error
|
105
122
|
force_reattach_on_channels protocol_message.error
|
106
123
|
end
|
107
124
|
else
|
108
125
|
logger.debug { "ConnectionManager: New connection created with ID #{protocol_message.connection_id} and key #{protocol_message.connection_key}" }
|
109
|
-
connection.reset_client_serial
|
110
126
|
end
|
111
127
|
|
112
128
|
reattach_suspended_channels protocol_message.error
|
@@ -471,11 +471,13 @@ module Ably
|
|
471
471
|
|
472
472
|
# Allowable duration for an external auth request
|
473
473
|
# For REST client this defaults to request_timeout
|
474
|
-
# For Realtime clients this defaults to realtime_request_timeout
|
474
|
+
# For Realtime clients this defaults to 250ms less than the realtime_request_timeout
|
475
|
+
# ensuring an auth failure will be triggered before the realtime request timeout fires
|
476
|
+
# which would lead to a misleading error message (connection timeout as opposed to auth request timeout)
|
475
477
|
# @api private
|
476
478
|
def auth_request_timeout
|
477
479
|
if @realtime_client
|
478
|
-
@realtime_client.connection.defaults.fetch(:realtime_request_timeout)
|
480
|
+
@realtime_client.connection.defaults.fetch(:realtime_request_timeout) - 0.25
|
479
481
|
else
|
480
482
|
http_defaults.fetch(:request_timeout)
|
481
483
|
end
|
@@ -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
|
@@ -1137,6 +1139,7 @@ describe Ably::Realtime::Auth, :event_machine do
|
|
1137
1139
|
context 'when credentials are invalid' do
|
1138
1140
|
let(:key_secret) { 'invalid' }
|
1139
1141
|
let(:token) { Faraday.get("#{auth_url}?keyName=#{key_name}&keySecret=#{key_secret}").body }
|
1142
|
+
let(:client_options) { { token: token, environment: environment, protocol: protocol, log_level: :none } }
|
1140
1143
|
|
1141
1144
|
it 'fails with an invalid signature error' do
|
1142
1145
|
client.connection.once(:disconnected) do |state_change|
|
@@ -1237,7 +1240,7 @@ describe Ably::Realtime::Auth, :event_machine do
|
|
1237
1240
|
Faraday.get("#{auth_url}?keyName=#{key_name}&keySecret=#{key_secret}&capability=#{URI.escape(basic_capability)}").body
|
1238
1241
|
end
|
1239
1242
|
end
|
1240
|
-
let(:client_options) { default_options.merge(auth_callback: auth_callback) }
|
1243
|
+
let(:client_options) { default_options.merge(auth_callback: auth_callback, log_level: :error) }
|
1241
1244
|
|
1242
1245
|
it 'client fails to publish to a channel with subscribe-only capability and publishes successfully on a channel with permissions' do
|
1243
1246
|
client.connection.once(:connected) do
|