public RedisQueue(RedisQueueOptions <T> options) : base(options)
        {
            if (options.ConnectionMultiplexer == null)
            {
                throw new ArgumentException("ConnectionMultiplexer is required.");
            }

            options.ConnectionMultiplexer.ConnectionRestored += ConnectionMultiplexerOnConnectionRestored;
            _cache = new RedisCacheClient(new RedisCacheClientOptions {
                ConnectionMultiplexer = options.ConnectionMultiplexer, Serializer = _serializer
            });

            _payloadTimeToLive = GetPayloadTtl();
            _subscriber        = _options.ConnectionMultiplexer.GetSubscriber();
            _redisServerType   = GetRedisServerType();

            if (_redisServerType == ServerType.Cluster || _redisServerType == ServerType.Twemproxy)
            {
                QueueListName = "{q:" + _options.Name + "}:in";
                WorkListName  = "{q:" + _options.Name + "}:work";
                WaitListName  = "{q:" + _options.Name + "}:wait";
                DeadListName  = "{q:" + _options.Name + "}:dead";
            }
            else
            {
                QueueListName = "q:" + _options.Name + ":in";
                WorkListName  = "q:" + _options.Name + ":work";
                WaitListName  = "q:" + _options.Name + ":wait";
                DeadListName  = "q:" + _options.Name + ":dead";
            }

            // min is 1 second, max is 1 minute
            var interval = _options.WorkItemTimeout > TimeSpan.FromSeconds(1) ? _options.WorkItemTimeout.Min(TimeSpan.FromMinutes(1)) : TimeSpan.FromSeconds(1);

            _maintenanceLockProvider = new ThrottlingLockProvider(_cache, 1, interval);

            if (_logger.IsEnabled(LogLevel.Trace))
            {
                _logger.LogTrace("Queue {QueueId} created. Retries: {Retries} Retry Delay: {RetryDelay}", QueueId, _options.Retries, _options.RetryDelay.ToString());
            }
        }
        public RedisQueue(RedisQueueOptions <T> options) : base(options)
        {
            if (options.ConnectionMultiplexer == null)
            {
                throw new ArgumentException("ConnectionMultiplexer is required.");
            }

            options.ConnectionMultiplexer.ConnectionRestored += ConnectionMultiplexerOnConnectionRestored;
            _cache = new RedisCacheClient(new RedisCacheClientOptions {
                ConnectionMultiplexer = options.ConnectionMultiplexer, Serializer = _serializer
            });

            _payloadTimeToLive = GetPayloadTtl();
            _subscriber        = _options.ConnectionMultiplexer.GetSubscriber();

            string listPrefix = _options.ConnectionMultiplexer.IsCluster() ? "{q:" + _options.Name + "}" : $"q:{_options.Name}";

            _queueListName = $"{listPrefix}:in";
            _workListName  = $"{listPrefix}:work";
            _waitListName  = $"{listPrefix}:wait";
            _deadListName  = $"{listPrefix}:dead";

            // min is 1 second, max is 1 minute
            var interval = _options.WorkItemTimeout > TimeSpan.FromSeconds(1) ? _options.WorkItemTimeout.Min(TimeSpan.FromMinutes(1)) : TimeSpan.FromSeconds(1);

            _maintenanceLockProvider = new ThrottlingLockProvider(_cache, 1, interval);

            if (_logger.IsEnabled(LogLevel.Trace))
            {
                _logger.LogTrace("Queue {QueueId} created. Retries: {Retries} Retry Delay: {RetryDelay:g}, Maintenance Interval: {MaintenanceInterval:g}", QueueId, _options.Retries, _options.RetryDelay, interval);
            }
        }