Skip to content

Commit dbd47b8

Browse files
Don't use fallback hosts for Realtime token errors
This is a partial fix for #444 (nature of error not considered when deciding whether to use a fallback host for realtime connections). Here, I implement just enough of RTN17f to make sure that we don't use a fallback host in response to a token error. This fixes an intermittent failure in the test case on connection_failures_spec.rb:1361, which tests that we correctly handle token errors when resuming a connection per RTN15c5. This test was intermittently failing because it would incorrectly try and use a fallback host after receiving the token error, causing the resume attempt to sometimes fail with "Unable to resume connection from another site". I don't have loads of time on to spend on this issue right now, which is why I'm applying the smallest possible fix. We need to return to #444 and properly consider how to identify the types of errors mentioned in RTN17f.
1 parent 9db3a61 commit dbd47b8

1 file changed

Lines changed: 30 additions & 2 deletions

File tree

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

0 commit comments

Comments
 (0)