private RedisSentinelWorker GetNextSentinel()
        {
            RedisSentinelWorker disposeWorker = null;

            try {
                lock (this._oLock) {
                    if (this._worker != null)
                    {
                        disposeWorker = this._worker;
                        this._worker  = null;
                    }

                    if (++this._sentinelIndex >= this.SentinelEndpoints.Length)
                    {
                        this._sentinelIndex = 0;
                    }

                    var sentinelWorker = new RedisSentinelWorker(this, this.SentinelEndpoints[this._sentinelIndex])
                    {
                        OnSentinelError = this.OnSentinelError
                    };

                    return(sentinelWorker);
                }
            } finally {
                disposeWorker?.Dispose();
            }
        }
        private void OnSentinelError(Exception ex)
        {
            if (this._worker != null)
            {
                _logger.Error("Error on existing SentinelWorker, reconnecting...");

                this.OnWorkerError?.Invoke(ex);

                this._worker = this.GetNextSentinel();
                this._worker.BeginListeningForConfigurationChanges();
            }
        }
        public List <string> GetActiveSentinelHosts(IEnumerable <string> sentinelHosts)
        {
            var activeSentinelHosts = new List <string>();

            foreach (var sentinelHost in sentinelHosts.ToArray())
            {
                try {
                    if (_logger.IsDebugEnabled())
                    {
                        _logger.Debug("Connecting to all available Sentinels to discover Active Sentinel Hosts...");
                    }

                    var endpoint = RedisEndpoint.Create(sentinelHost, RedisConfig.DefaultPortSentinel);
                    using (var sentinelWorker = new RedisSentinelWorker(this, endpoint)) {
                        var activeHosts = sentinelWorker.GetSentinelHosts(this.MasterName);

                        if (!activeSentinelHosts.Contains(sentinelHost))
                        {
                            activeSentinelHosts.Add(sentinelHost);
                        }

                        foreach (var activeHost in activeHosts)
                        {
                            if (!activeSentinelHosts.Contains(activeHost))
                            {
                                activeSentinelHosts.Add(activeHost);
                            }
                        }
                    }

                    if (_logger.IsDebugEnabled())
                    {
                        _logger.Debug("All active Sentinels Found: " + string.Join(", ", activeSentinelHosts));
                    }
                } catch (Exception ex) {
                    _logger.Error(string.Format("Could not get active Sentinels from: {0}", sentinelHost), ex);
                }
            }

            return(activeSentinelHosts);
        }
        private RedisSentinelWorker GetValidSentinelWorker()
        {
            if (this._isDisposed)
            {
                throw new ObjectDisposedException(this.GetType().Name);
            }

            if (this._worker != null)
            {
                lock (this._oLock) {
                    return(this._worker);
                }
            }

            RedisException lastEx = null;

            while (this._worker == null && this.ShouldRetry())
            {
                try {
                    this._worker = this.GetNextSentinel();
                    this.GetRedisManager();

                    this._worker.BeginListeningForConfigurationChanges();
                    this._failures = 0; // reset
                    return(this._worker);
                } catch (RedisException ex) {
                    this.OnWorkerError?.Invoke(ex);

                    lastEx       = ex;
                    this._worker = null;
                    this._failures++;
                    Interlocked.Increment(ref RedisState.TotalFailedSentinelWorkers);
                }
            }

            this._failures = 0; // reset
            Thread.Sleep(this.WaitBetweenFailedHosts);
            throw new RedisException("No Redis Sentinels were available", lastEx);
        }