示例#1
0
        public void UpdateAttemptState(ConnectionStateBase newState)
        {
            lock (_syncLock)
                switch (newState.State)
                {
                case ConnectionState.Connecting:
                    Attempts.Add(new ConnectionAttempt(Now()));
                    break;

                case ConnectionState.Failed:
                case ConnectionState.Closed:
                case ConnectionState.Connected:
                    Reset();
                    break;

                case ConnectionState.Suspended:
                case ConnectionState.Disconnected:
                    if (newState.Exception != null)
                    {
                        RecordAttemptFailure(newState.State, newState.Exception);
                    }
                    else
                    {
                        RecordAttemptFailure(newState.State, newState.Error);
                    }
                    break;
                }
        }
示例#2
0
        public void UpdateAttemptState(ConnectionStateBase newState, ILogger logger)
        {
            switch (newState.State)
            {
            case ConnectionState.Connecting:
                logger.Debug("Recording connection attempt.");
                Attempts.Add(new ConnectionAttempt(_now()));
                break;

            case ConnectionState.Failed:
            case ConnectionState.Closed:
            case ConnectionState.Connected:
                logger.Debug("Resetting Attempts collection.");
                Reset();
                break;

            case ConnectionState.Suspended:
            case ConnectionState.Disconnected:
                logger.Debug($"Recording failed attempt for state {newState.State}.");
                if (newState.Exception != null)
                {
                    RecordAttemptFailure(newState.State, newState.Exception);
                }
                else
                {
                    RecordAttemptFailure(newState.State, newState.Error);
                }

                break;
            }
        }
示例#3
0
            public ConnectionStateChange UpdateState(ConnectionStateBase state, ILogger logger)
            {
                if (!state.IsUpdate && state.State == State)
                {
                    return(null);
                }

                if (logger.IsDebug)
                {
                    logger.Debug($"Updating state to `{state.State}`");
                }

                var oldState = State;
                var newState = state.State;

                CurrentStateObject = state;
                ErrorReason        = state.Error;
                var connectionEvent = oldState == newState ? ConnectionEvent.Update : newState.ToConnectionEvent();

                return(new ConnectionStateChange(connectionEvent, oldState, newState, state.RetryIn, ErrorReason));
            }
示例#4
0
        internal void UpdateState(ConnectionStateBase state)
        {
            if (state.State == State)
            {
                return;
            }

            if (Logger.IsDebug)
            {
                Logger.Debug($"Connection notifying subscribers for state change `{state.State}`");
            }

            var oldState = ConnectionState.State;
            var newState = state.State;

            ConnectionState = state;
            ErrorReason     = state.Error;
            var stateChange = new ConnectionStateChange(oldState, newState, state.RetryIn, ErrorReason);

            var internalHandlers = Volatile.Read(ref InternalStateChanged);   //Make sure we get all the subscribers on all threads
            var externalHandlers = Volatile.Read(ref ConnectionStateChanged); //Make sure we get all the subscribers on all threads

            internalHandlers(this, stateChange);

            RealtimeClient.NotifyExternalClients(() =>
            {
                try
                {
                    externalHandlers(this, stateChange);
                }
                catch (Exception ex)
                {
                    Logger.Error("Error notifying Connection state changed handlers", ex);
                }

                Emit(newState, stateChange);
            });
        }
示例#5
0
 public Task SetState(ConnectionStateBase state, bool skipAttach)
 {
     State        = state;
     LastSetState = state;
     return(TaskConstants.BooleanTrue);
 }
示例#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 (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;
                    }
                }
            }));
        }
示例#7
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;
                    }
                }
            }));
        }