ably 1.2.6 → 1.2.8

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.
data/ably.gemspec CHANGED
@@ -22,10 +22,11 @@ Gem::Specification.new do |spec|
22
22
  spec.add_runtime_dependency 'ably-em-http-request', '~> 1.1.8'
23
23
  spec.add_runtime_dependency 'statesman', '~> 9.0'
24
24
  spec.add_runtime_dependency 'faraday', '~> 2.2'
25
- spec.add_runtime_dependency 'faraday-typhoeus', '~> 0.2.0'
25
+ spec.add_runtime_dependency 'faraday-typhoeus', '~> 1.1.0'
26
26
  spec.add_runtime_dependency 'typhoeus', '~> 1.4'
27
27
  spec.add_runtime_dependency 'json'
28
- spec.add_runtime_dependency 'websocket-driver', '~> 0.7'
28
+ # We disallow minor version updates, because this gem has introduced breaking API changes in minor releases before (which it's within its rights to do, given it's pre-v1). If you want to allow a new minor version, bump here and run the tests.
29
+ spec.add_runtime_dependency 'websocket-driver', '~> 0.8.0'
29
30
  spec.add_runtime_dependency 'msgpack', '>= 1.3.0'
30
31
  spec.add_runtime_dependency 'addressable', '>= 2.0.0'
31
32
 
@@ -249,7 +249,6 @@ module Ably::Models
249
249
  # Return a JSON ready object from the underlying #attributes using Ably naming conventions for keys
250
250
  def as_json(*args)
251
251
  raise TypeError, ':action is missing, cannot generate a valid Hash for ProtocolMessage' unless action
252
- raise TypeError, ':msg_serial is missing, cannot generate a valid Hash for ProtocolMessage' if ack_required? && !has_message_serial?
253
252
 
254
253
  attributes.dup.tap do |hash_object|
255
254
  hash_object['action'] = action.to_i
@@ -257,7 +257,7 @@ module Ably::Realtime
257
257
  when :json
258
258
  JSON.parse(data)
259
259
  when :msgpack
260
- MessagePack.unpack(data.pack('C*'))
260
+ MessagePack.unpack(data)
261
261
  else
262
262
  client.logger.fatal { "WebsocketTransport: Unsupported Protocol Message format #{client.protocol}" }
263
263
  data
@@ -690,16 +690,44 @@ module Ably
690
690
  end
691
691
 
692
692
  def use_fallback_if_disconnected?
693
- second_reconnect_attempt_for(:disconnected, 1)
693
+ unless second_reconnect_attempt_for(:disconnected, 1)
694
+ return false
695
+ end
696
+
697
+ does_error_necessitate_fallback(reason_for_last_time_in(:disconnected))
694
698
  end
695
699
 
696
700
  def use_fallback_if_suspended?
697
- second_reconnect_attempt_for(:suspended, 2) # on first suspended state use default Ably host again
701
+ unless second_reconnect_attempt_for(:suspended, 2) # on first suspended state use default Ably host again
702
+ return false
703
+ end
704
+
705
+ does_error_necessitate_fallback(reason_for_last_time_in(:suspended))
698
706
  end
699
707
 
700
708
  def second_reconnect_attempt_for(state, first_attempt_count)
701
709
  previous_state == state && manager.retry_count_for_state(state) >= first_attempt_count
702
710
  end
711
+
712
+ # Provides a partial implementation of RTN17f's logic for whether an error necessitates a fallback host.
713
+ def does_error_necessitate_fallback(error)
714
+ return false unless error
715
+
716
+ # For now we just explicitly exclude token errors. TODO: implement properly in https://github.com/ably/ably-ruby/issues/444
717
+
718
+ if error.respond_to?(:status_code) && error.status_code == 401 && error.respond_to?(:code) && Ably::Exceptions::TOKEN_EXPIRED_CODE.include?(error.code)
719
+ return false
720
+ end
721
+
722
+ true
723
+ end
724
+
725
+ # Returns the error associated with the last state change to the given state (e.g. :disconnected).
726
+ def reason_for_last_time_in(state)
727
+ history_item = state_history.reverse.find do |history_item|
728
+ history_item.fetch(:state) == state
729
+ end.fetch(:metadata).reason
730
+ end
703
731
  end
704
732
  end
705
733
  end
data/lib/ably/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module Ably
2
- VERSION = '1.2.6'
2
+ VERSION = '1.2.8'
3
3
  # The level of compatibility with the Ably service that this SDK supports.
4
4
  # Also referred to as the 'wire protocol version'.
5
5
  # spec : CSV2
@@ -617,7 +617,6 @@ describe Ably::Realtime::Auth, :event_machine do
617
617
  deferrable.errback do |error|
618
618
  EventMachine.add_timer(0.2) do
619
619
  expect(connection_failed).to eql(true)
620
- expect(error.message).to match(/invalid.*accessToken/i)
621
620
  expect(error.code).to eql(40005)
622
621
  stop_reactor
623
622
  end
@@ -627,7 +626,6 @@ describe Ably::Realtime::Auth, :event_machine do
627
626
  end
628
627
 
629
628
  client.connection.once(:failed) do
630
- expect(client.connection.error_reason.message).to match(/invalid.*accessToken/i)
631
629
  expect(client.connection.error_reason.code).to eql(40005)
632
630
  connection_failed = true
633
631
  end
@@ -664,7 +662,6 @@ describe Ably::Realtime::Auth, :event_machine do
664
662
  channel.attach do
665
663
  channel.publish('not-allowed').errback do |error|
666
664
  expect(error.code).to eql(40160)
667
- expect(error.message).to match(/permission denied/)
668
665
 
669
666
  client.auth.authorize(nil, auth_callback: upgraded_token_cb)
670
667
  client.connection.once(:update) do
@@ -1058,7 +1055,6 @@ describe Ably::Realtime::Auth, :event_machine do
1058
1055
 
1059
1056
  it 'disconnected includes and invalid signature message' do
1060
1057
  client.connection.once(:disconnected) do |state_change|
1061
- expect(state_change.reason.message.match(/signature verification failed/i)).to_not be_nil
1062
1058
  expect(state_change.reason.code).to eql(40144)
1063
1059
  stop_reactor
1064
1060
  end
@@ -1111,7 +1107,6 @@ describe Ably::Realtime::Auth, :event_machine do
1111
1107
 
1112
1108
  it 'authentication fails and reason for disconnection is invalid signature' do
1113
1109
  client.connection.once(:disconnected) do |state_change|
1114
- expect(state_change.reason.message.match(/signature verification failed/i)).to_not be_nil
1115
1110
  expect(state_change.reason.code).to eql(40144)
1116
1111
  stop_reactor
1117
1112
  end
@@ -1143,7 +1138,6 @@ describe Ably::Realtime::Auth, :event_machine do
1143
1138
 
1144
1139
  it 'fails with an invalid signature error' do
1145
1140
  client.connection.once(:disconnected) do |state_change|
1146
- expect(state_change.reason.message.match(/signature verification failed/i)).to_not be_nil
1147
1141
  expect(state_change.reason.code).to eql(40144)
1148
1142
  stop_reactor
1149
1143
  end
@@ -1248,7 +1242,6 @@ describe Ably::Realtime::Auth, :event_machine do
1248
1242
  allowed_channel = client.channels.get(channel_with_publish_permissions)
1249
1243
  forbidden_channel.publish('not-allowed').errback do |error|
1250
1244
  expect(error.code).to eql(40160)
1251
- expect(error.message).to match(/permission denied/)
1252
1245
 
1253
1246
  allowed_channel.publish(message_name) do |message|
1254
1247
  expect(message.name).to eql(message_name)
@@ -34,7 +34,7 @@ describe Ably::Realtime::Client, :event_machine do
34
34
  client.connection.once(:failed) do
35
35
  expect(custom_logger_object.logs.find do |severity, message|
36
36
  next unless %w(fatal error).include?(severity.to_s)
37
- message.match(%r{https://help.ably.io/error/40400})
37
+ message.match(%r{https://help.ably.io/error/40101})
38
38
  end).to_not be_nil
39
39
  stop_reactor
40
40
  end
@@ -26,13 +26,13 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
26
26
  context 'with invalid app part of the key' do
27
27
  let(:invalid_key) { 'not_an_app.invalid_key_name:invalid_key_value' }
28
28
 
29
- it 'enters the failed state and returns a not found error' do
29
+ it 'enters the failed state and returns an invalid credentials error' do
30
30
  connection.on(:failed) do |connection_state_change|
31
31
  error = connection_state_change.reason
32
32
  expect(connection.state).to eq(:failed)
33
33
  # TODO: Check error type is an InvalidToken exception
34
- expect(error.status).to eq(404)
35
- expect(error.code).to eq(40400) # not found
34
+ expect(error.status).to eq(401)
35
+ expect(error.code).to eq(40101) # invalid credentials
36
36
  stop_reactor
37
37
  end
38
38
  end
@@ -46,7 +46,7 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
46
46
  error = connection_state_change.reason
47
47
  expect(connection.state).to eq(:failed)
48
48
  # TODO: Check error type is a TokenNotFound exception
49
- expect(error.status).to eq(401)
49
+ expect(error.status).to eq(404)
50
50
  expect(error.code).to eq(40400) # not found
51
51
  stop_reactor
52
52
  end
@@ -1396,10 +1396,10 @@ describe Ably::Realtime::Connection, 'failures', :event_machine do
1396
1396
  channel = client.channels.get("foo")
1397
1397
  channel.attach do
1398
1398
  connection.once(:failed) do |state_change|
1399
- expect(state_change.reason.code).to eql(40400)
1400
- expect(connection.error_reason.code).to eql(40400)
1399
+ expect(state_change.reason.code).to eql(40101)
1400
+ expect(connection.error_reason.code).to eql(40101)
1401
1401
  expect(channel).to be_failed
1402
- expect(channel.error_reason.code).to eql(40400)
1402
+ expect(channel.error_reason.code).to eql(40101)
1403
1403
  stop_reactor
1404
1404
  end
1405
1405
 
@@ -173,7 +173,7 @@ describe 'Ably::Realtime::Channel Message', :event_machine do
173
173
  end
174
174
 
175
175
  context 'JSON Array' do
176
- let(:data) { { 'push' => { 'data' => { 'key' => [ true, false, 55, nil, 'string', { 'Hash' => true }, ['array'] ] } } } }
176
+ let(:data) { { 'push' => { 'data' => { 'key' => [ true, false, 55.1, nil, 'string', { 'Hash' => true }, ['array'] ] } } } }
177
177
 
178
178
  it 'is encoded and decoded to the same Array' do
179
179
  publish_and_check_extras data
@@ -72,13 +72,12 @@ describe Ably::Rest do
72
72
 
73
73
  describe 'failed requests' do
74
74
  context 'due to invalid Auth' do
75
- it 'should raise an InvalidRequest exception with a valid error message and code' do
75
+ it 'should raise an UnauthorizedRequest exception with a valid error message and code' do
76
76
  invalid_client = Ably::Rest::Client.new(key: 'appid.keyuid:keysecret', environment: environment)
77
77
  expect { invalid_client.channel('test').publish('foo', 'choo') }.to raise_error do |error|
78
- expect(error).to be_a(Ably::Exceptions::ResourceMissing)
79
- expect(error.message).to match(/No application found/)
80
- expect(error.code).to eql(40400)
81
- expect(error.status).to eql(404)
78
+ expect(error).to be_a(Ably::Exceptions::UnauthorizedRequest)
79
+ expect(error.code).to eql(40101)
80
+ expect(error.status).to eql(401)
82
81
  end
83
82
  end
84
83
  end
@@ -33,9 +33,9 @@ describe Ably::Rest::Client do
33
33
  it 'logs an entry with a help href url matching the code #TI5' do
34
34
  begin
35
35
  client.channels.get('foo').publish('test')
36
- raise 'Expected Ably::Exceptions::ResourceMissing'
37
- rescue Ably::Exceptions::ResourceMissing => err
38
- expect err.to_s.match(%r{https://help.ably.io/error/40400})
36
+ raise 'Expected Ably::Exceptions::UnauthorizedRequest'
37
+ rescue Ably::Exceptions::UnauthorizedRequest => err
38
+ expect err.to_s.match(%r{https://help.ably.io/error/40101})
39
39
  end
40
40
  end
41
41
  end
@@ -397,14 +397,6 @@ describe Ably::Models::ProtocolMessage do
397
397
  end
398
398
  end
399
399
 
400
- context 'with missing msg_serial for ack message' do
401
- let(:model) { new_protocol_message({ :action => message_action }) }
402
-
403
- it 'it raises an exception' do
404
- expect { model.to_json }.to raise_error TypeError, /msg_serial.*missing/
405
- end
406
- end
407
-
408
400
  context 'is aliased by #to_s' do
409
401
  let(:model) { new_protocol_message({ :action => attached_action, :channelSerial => 'unique', messages: [message1, message2, message3], :timestamp => as_since_epoch(Time.now) }) }
410
402
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ably
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.6
4
+ version: 1.2.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lewis Marshall
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2024-07-08 00:00:00.000000000 Z
12
+ date: 2025-06-12 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: eventmachine
@@ -73,14 +73,14 @@ dependencies:
73
73
  requirements:
74
74
  - - "~>"
75
75
  - !ruby/object:Gem::Version
76
- version: 0.2.0
76
+ version: 1.1.0
77
77
  type: :runtime
78
78
  prerelease: false
79
79
  version_requirements: !ruby/object:Gem::Requirement
80
80
  requirements:
81
81
  - - "~>"
82
82
  - !ruby/object:Gem::Version
83
- version: 0.2.0
83
+ version: 1.1.0
84
84
  - !ruby/object:Gem::Dependency
85
85
  name: typhoeus
86
86
  requirement: !ruby/object:Gem::Requirement
@@ -115,14 +115,14 @@ dependencies:
115
115
  requirements:
116
116
  - - "~>"
117
117
  - !ruby/object:Gem::Version
118
- version: '0.7'
118
+ version: 0.8.0
119
119
  type: :runtime
120
120
  prerelease: false
121
121
  version_requirements: !ruby/object:Gem::Requirement
122
122
  requirements:
123
123
  - - "~>"
124
124
  - !ruby/object:Gem::Version
125
- version: '0.7'
125
+ version: 0.8.0
126
126
  - !ruby/object:Gem::Dependency
127
127
  name: msgpack
128
128
  requirement: !ruby/object:Gem::Requirement
@@ -607,7 +607,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
607
607
  - !ruby/object:Gem::Version
608
608
  version: '0'
609
609
  requirements: []
610
- rubygems_version: 3.5.4
610
+ rubygems_version: 3.3.7
611
611
  signing_key:
612
612
  specification_version: 4
613
613
  summary: A Ruby client library for ably.io realtime messaging implemented using EventMachine