ServiceStack.Redis.RedisPubSubServer.RunLoop C# (CSharp) Method

RunLoop() private method

private RunLoop ( ) : void
return void
        private void RunLoop()
        {
            if (Interlocked.CompareExchange(ref status, Status.Started, Status.Starting) != Status.Starting) return;
            Interlocked.Increment(ref timesStarted);

            try
            {
                //RESET
                while (Interlocked.CompareExchange(ref status, 0, 0) == Status.Started)
                {
                    using (var redis = ClientsManager.GetReadOnlyClient())
                    {
                        masterClient = redis;

                        //Record that we had a good run...
                        Interlocked.CompareExchange(ref noOfContinuousErrors, 0, noOfContinuousErrors);

                        using (var subscription = redis.CreateSubscription())
                        {
                            subscription.OnUnSubscribe = HandleUnSubscribe;

                            subscription.OnMessage = (channel, msg) =>
                            {
                                if (string.IsNullOrEmpty(msg)) 
                                    return;

                                var ctrlMsg = msg.SplitOnFirst(':');
                                if (ctrlMsg[0] == ControlCommand.Control)
                                {
                                    var op = Interlocked.CompareExchange(ref doOperation, Operation.NoOp, doOperation);
                                    
                                    var msgType = ctrlMsg.Length > 1
                                        ? ctrlMsg[1]
                                        : null;

                                    if (OnControlCommand != null)
                                        OnControlCommand(msgType ?? Operation.GetName(op));

                                    switch (op)
                                    {
                                        case Operation.Stop:
                                            if (Log.IsDebugEnabled)
                                                Log.Debug("Stop Command Issued");

                                            Interlocked.CompareExchange(ref status, Status.Stopping, Status.Started);
                                            try
                                            {
                                                if (Log.IsDebugEnabled)
                                                    Log.Debug("UnSubscribe From All Channels...");

                                                subscription.UnSubscribeFromAllChannels(); //Un block thread.
                                            }
                                            finally
                                            {
                                                Interlocked.CompareExchange(ref status, Status.Stopped, Status.Stopping);
                                            }
                                            return;

                                        case Operation.Reset:
                                            subscription.UnSubscribeFromAllChannels(); //Un block thread.
                                            return;
                                    }

                                    switch (msgType)
                                    {
                                        case ControlCommand.Pulse:
                                            Pulse();
                                            break;
                                    }
                                }
                                else
                                {
                                    OnMessage(channel, msg);
                                }
                            };

                            //blocks thread
                            if (ChannelsMatching != null && ChannelsMatching.Length > 0)
                                subscription.SubscribeToChannelsMatching(ChannelsMatching);
                            else
                                subscription.SubscribeToChannels(Channels);             

                            masterClient = null;
                        }
                    }
                }

                if (OnStop != null)
                    OnStop();
            }
            catch (Exception ex)
            {
                lastExMsg = ex.Message;
                Interlocked.Increment(ref noOfErrors);
                Interlocked.Increment(ref noOfContinuousErrors);

                if (Interlocked.CompareExchange(ref status, Status.Stopped, Status.Started) != Status.Started)
                    Interlocked.CompareExchange(ref status, Status.Stopped, Status.Stopping);

                if (OnStop != null)
                    OnStop();

                if (this.OnError != null)
                    this.OnError(ex);
            }

            if (AutoRestart && Interlocked.CompareExchange(ref status, 0, 0) != Status.Disposed)
            {
                if (WaitBeforeNextRestart != null)
                    TaskUtils.Sleep(WaitBeforeNextRestart.Value);
                Start();
            }
        }