public Task SetState(ConnectionStateBase newState, bool skipAttach = false)
        {
            if (Logger.IsDebug)
            {
                Logger.Debug($"xx Changing state from {ConnectionState} => {newState.State}. SkipAttach = {skipAttach}.");
            }

            _inTransitionToState = newState;

            return(ExecuteOnManagerThread(async() =>
            {
                try
                {
                    lock (_stateSyncLock)
                    {
                        if (State.State == newState.State)
                        {
                            if (Logger.IsDebug)
                            {
                                Logger.Debug($"xx State is already {State.State}. Skipping SetState action.");
                            }
                            return;
                        }

                        //Abort any timers on the old state
                        State.AbortTimer();
                        if (Logger.IsDebug)
                        {
                            Logger.Debug($"xx {newState.State}: BeforeTransition");
                        }
                        newState.BeforeTransition();

                        AttemptsInfo.UpdateAttemptState(newState);
                        Connection.UpdateState(newState);
                    }

                    if (skipAttach == false)
                    {
                        if (Logger.IsDebug)
                        {
                            Logger.Debug($"xx {newState.State}: Attaching state ");
                        }

                        await newState.OnAttachToContext();
                    }
                    else if (Logger.IsDebug)
                    {
                        Logger.Debug($"xx {newState.State}: Skipping attaching.");
                    }

                    await ProcessQueuedMessages();
                }
                catch (AblyException ex)
                {
                    Logger.Error("Error attaching to context", ex);

                    lock (_transportQueueLock)
                        _queuedTransportMessages.Clear();

                    Connection.UpdateState(newState);

                    newState.AbortTimer();

                    if (newState.State != Realtime.ConnectionState.Failed)
                    {
                        SetState(new ConnectionFailedState(this, ex.ErrorInfo));
                    }
                }
                finally
                {
                    //Clear the state in transition only if the current state hasn't updated it
                    if (_inTransitionToState == newState)
                    {
                        _inTransitionToState = null;
                    }
                }
            }));
        }
 public void ClearTokenAndRecordRetry()
 {
     RestClient.AblyAuth.ExpireCurrentToken();
     AttemptsInfo.RecordTokenRetry();
 }
 public Task <bool> CanUseFallBackUrl(ErrorInfo error)
 {
     return(AttemptsInfo.CanFallback(error));
 }
 internal async Task <TransportParams> CreateTransportParameters()
 {
     return(await TransportParams.Create(AttemptsInfo.GetHost(), RestClient.AblyAuth, Options, Connection.Key, Connection.Serial));
 }
 public bool ShouldSuspend()
 {
     return(AttemptsInfo.ShouldSuspend());
 }
Exemple #6
0
        public Task SetState(ConnectionStateBase newState, bool skipAttach = false)
        {
            if (Logger.IsDebug)
            {
                Logger.Debug(
                    $"xx Changing state from {ConnectionState} => {newState.State}. SkipAttach = {skipAttach}.");
            }

            _inTransitionToState = newState;

            return(ExecuteOnManagerThread(async() =>
            {
                try
                {
                    lock (_stateSyncLock)
                    {
                        if (!newState.IsUpdate)
                        {
                            if (State.State == newState.State)
                            {
                                if (Logger.IsDebug)
                                {
                                    Logger.Debug($"xx State is already {State.State}. Skipping SetState action.");
                                }

                                return;
                            }

                            AttemptsInfo.UpdateAttemptState(newState);
                            State.AbortTimer();
                        }

                        if (Logger.IsDebug)
                        {
                            Logger.Debug($"xx {newState.State}: BeforeTransition");
                        }

                        newState.BeforeTransition();

                        if (Logger.IsDebug)
                        {
                            Logger.Debug($"xx {newState.State}: BeforeTransition end");
                        }

                        Connection.UpdateState(newState);
                    }

                    if (skipAttach == false)
                    {
                        if (Logger.IsDebug)
                        {
                            Logger.Debug($"xx {newState.State}: Attaching state ");
                        }

                        await newState.OnAttachToContext();
                    }
                    else if (Logger.IsDebug)
                    {
                        Logger.Debug($"xx {newState.State}: Skipping attaching.");
                    }

                    await ProcessQueuedMessages();
                }
                catch (AblyException ex)
                {
                    Logger.Error("Error attaching to context", ex);

                    _queuedTransportMessages = new ConcurrentQueue <ProtocolMessage>();

                    Connection.UpdateState(newState);

                    newState.AbortTimer();

                    // RSA4c2 & RSA4d
                    if (newState.State == ConnectionState.Connecting &&
                        ex.ErrorInfo.Code == 80019 & !ex.ErrorInfo.IsForbiddenError)
                    {
                        await SetState(new ConnectionDisconnectedState(this, ex.ErrorInfo, Logger));
                    }
                    else if (newState.State != ConnectionState.Failed)
                    {
                        await SetState(new ConnectionFailedState(this, ex.ErrorInfo, Logger));
                    }
                }
                finally
                {
                    // Clear the state in transition only if the current state hasn't updated it
                    if (_inTransitionToState == newState)
                    {
                        _inTransitionToState = null;
                    }
                }
            }));
        }