Skip to content

Commit b971e84

Browse files
Merge pull request #443 from ably/2025-06-10-fix-ci
Fix decoding of MessagePack data, and other fixes to CI
2 parents e9a8a60 + dbd47b8 commit b971e84

8 files changed

Lines changed: 52 additions & 23 deletions

File tree

.github/workflows/check.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@ jobs:
3232
run: |
3333
mkdir junit
3434
bundle exec parallel_rspec --prefix-output-with-test-env-number --first-is-1 -- spec/${{ matrix.type }}
35-
- uses: actions/upload-artifact@v3
35+
- uses: actions/upload-artifact@v4
3636
with:
37+
name: test-results-ruby-${{ matrix.ruby }}-${{ matrix.protocol }}-${{ matrix.type }}
3738
path: |
3839
junit/
3940
coverage/
@@ -45,7 +46,7 @@ jobs:
4546
server-url: 'https://test-observability.herokuapp.com'
4647
server-auth: ${{ secrets.TEST_OBSERVABILITY_SERVER_AUTH_KEY }}
4748
path: 'junit/'
48-
- uses: coverallsapp/github-action@1.1.3
49+
- uses: coverallsapp/github-action@v2
4950
with:
5051
github-token: ${{ secrets.GITHUB_TOKEN }}
5152
flag-name: ruby-${{ matrix.ruby }}-${{ matrix.protocol }}-${{ matrix.type }}
@@ -55,7 +56,7 @@ jobs:
5556
runs-on: ubuntu-latest
5657
steps:
5758
- name: Coveralls Finished
58-
uses: coverallsapp/github-action@1.1.3
59+
uses: coverallsapp/github-action@v2
5960
with:
6061
github-token: ${{ secrets.github_token }}
6162
parallel-finished: true

ably.gemspec

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ Gem::Specification.new do |spec|
2525
spec.add_runtime_dependency 'faraday-typhoeus', '~> 0.2.0'
2626
spec.add_runtime_dependency 'typhoeus', '~> 1.4'
2727
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'
2930
spec.add_runtime_dependency 'msgpack', '>= 1.3.0'
3031
spec.add_runtime_dependency 'addressable', '>= 2.0.0'
3132

lib/ably/realtime/connection.rb

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -690,16 +690,44 @@ def disconnected_from_connected_state?
690690
end
691691

692692
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))
694698
end
695699

696700
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))
698706
end
699707

700708
def second_reconnect_attempt_for(state, first_attempt_count)
701709
previous_state == state && manager.retry_count_for_state(state) >= first_attempt_count
702710
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
703731
end
704732
end
705733
end

lib/ably/realtime/connection/websocket_transport.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ def parse_event_data(data)
257257
when :json
258258
JSON.parse(data)
259259
when :msgpack
260-
MessagePack.unpack(data.pack('C*'))
260+
MessagePack.unpack(data)
261261
else
262262
client.logger.fatal { "WebsocketTransport: Unsupported Protocol Message format #{client.protocol}" }
263263
data

spec/acceptance/realtime/client_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
client.connection.once(:failed) do
3535
expect(custom_logger_object.logs.find do |severity, message|
3636
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})
3838
end).to_not be_nil
3939
stop_reactor
4040
end

spec/acceptance/realtime/connection_failures_spec.rb

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,13 @@
2626
context 'with invalid app part of the key' do
2727
let(:invalid_key) { 'not_an_app.invalid_key_name:invalid_key_value' }
2828

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
3030
connection.on(:failed) do |connection_state_change|
3131
error = connection_state_change.reason
3232
expect(connection.state).to eq(:failed)
3333
# 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
3636
stop_reactor
3737
end
3838
end
@@ -46,7 +46,7 @@
4646
error = connection_state_change.reason
4747
expect(connection.state).to eq(:failed)
4848
# TODO: Check error type is a TokenNotFound exception
49-
expect(error.status).to eq(401)
49+
expect(error.status).to eq(404)
5050
expect(error.code).to eq(40400) # not found
5151
stop_reactor
5252
end
@@ -1396,10 +1396,10 @@ def kill_connection_transport_and_prevent_valid_resume
13961396
channel = client.channels.get("foo")
13971397
channel.attach do
13981398
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)
14011401
expect(channel).to be_failed
1402-
expect(channel.error_reason.code).to eql(40400)
1402+
expect(channel.error_reason.code).to eql(40101)
14031403
stop_reactor
14041404
end
14051405

spec/acceptance/rest/base_spec.rb

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,12 @@
7272

7373
describe 'failed requests' do
7474
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
7676
invalid_client = Ably::Rest::Client.new(key: 'appid.keyuid:keysecret', environment: environment)
7777
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)
8281
end
8382
end
8483
end

spec/acceptance/rest/client_spec.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ def encode64(text)
3333
it 'logs an entry with a help href url matching the code #TI5' do
3434
begin
3535
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})
3939
end
4040
end
4141
end

0 commit comments

Comments
 (0)