Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion lib/ably/realtime/channel/channel_state_machine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,16 @@ class ChannelStateMachine
transition :from => :detaching, :to => [:detached, :attaching, :attached, :failed, :suspended]
transition :from => :detached, :to => [:attaching, :attached, :failed]
transition :from => :suspended, :to => [:attaching, :attached, :detached, :failed]
transition :from => :failed, :to => [:attaching]
transition :from => :failed, :to => [:attaching, :initialized]

after_transition do |channel, transition|
channel.synchronize_state_with_statemachine
end

after_transition(to: [:initialized]) do |channel|
channel.clear_error_reason
end

after_transition(to: [:attaching]) do |channel|
channel.manager.attach
end
Expand Down
9 changes: 9 additions & 0 deletions lib/ably/realtime/connection/connection_manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,15 @@ def fail_active_channels(error)
end
end

# @api private
def reintialize_failed_chanels
channels.select do |channel|
channel.failed?
end.each do |channel|
channel.transition_state_machine :initialized
end
end

# When continuity on a connection is lost all messages
# whether queued or awaiting an ACK must be NACK'd as we now have a new connection
def nack_messages_on_all_channels(error)
Expand Down
4 changes: 4 additions & 0 deletions lib/ably/realtime/connection/connection_state_machine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ class ConnectionStateMachine
connection.manager.setup_transport
end

after_transition(to: [:connecting], from: [:failed]) do |connection|
connection.manager.reintialize_failed_chanels
end

after_transition(to: [:connecting], from: [:disconnected, :suspended]) do |connection|
connection.manager.reconnect_transport
end
Expand Down
29 changes: 29 additions & 0 deletions spec/acceptance/realtime/connection_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,35 @@ def expect_ordered_phases
end
end

context 'when reconnecting a failed connection' do
let(:channel) { client.channel(random_str) }
let(:client_options) { default_options.merge(log_level: :none) }

it 'transitions all channels state to initialized and cleares error_reason' do
connection.on(:failed) do |connection_state_change|
expect(connection.error_reason).to be_a(Ably::Exceptions::BaseAblyException)
expect(channel.error_reason).to be_a(Ably::Exceptions::BaseAblyException)
expect(channel).to be_failed

connection.on(:connected) do
expect(connection.error_reason).to eq(nil)
expect(channel).to be_initialized
expect(channel.error_reason).to eq(nil)
stop_reactor
end

connection.connect
end

connection.connect do
channel.attach do
error = Ably::Exceptions::ConnectionFailed.new('forced failure', 500, 50000)
client.connection.manager.error_received_from_server error
end
end
end
end

context 'with invalid auth details' do
let(:client_options) { default_options.merge(key: 'this.is:invalid', log_level: :none) }

Expand Down