示例#1
0
        public RedisCacheHandle(CacheManagerConfiguration managerConfiguration, CacheHandleConfiguration configuration, ILoggerFactory loggerFactory, ICacheSerializer serializer)
            : base(managerConfiguration, configuration)
        {
            NotNull(loggerFactory, nameof(loggerFactory));
            NotNull(managerConfiguration, nameof(managerConfiguration));
            EnsureNotNull(serializer, "A serializer is required for the redis cache handle");

            this.managerConfiguration = managerConfiguration;
            this.Logger             = loggerFactory.CreateLogger(this);
            this.valueConverter     = new RedisValueConverter(serializer);
            this.redisConfiguration = RedisConfigurations.GetConfiguration(configuration.Key);
            this.connection         = new RedisConnectionManager(this.redisConfiguration, loggerFactory);
        }
示例#2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="RedisCacheHandle{TCacheValue}"/> class.
        /// </summary>
        /// <param name="managerConfiguration">The manager configuration.</param>
        /// <param name="configuration">The cache handle configuration.</param>
        /// <param name="loggerFactory">The logger factory.</param>
        /// <param name="serializer">The serializer.</param>
        public RedisCacheHandle(ICacheManagerConfiguration managerConfiguration, CacheHandleConfiguration configuration, ILoggerFactory loggerFactory, ICacheSerializer serializer)
            : base(managerConfiguration, configuration)
        {
            NotNull(loggerFactory, nameof(loggerFactory));
            NotNull(managerConfiguration, nameof(managerConfiguration));
            NotNull(configuration, nameof(configuration));
            EnsureNotNull(serializer, "A serializer is required for the redis cache handle");

            Logger = loggerFactory.CreateLogger(this);
            _managerConfiguration = managerConfiguration;
            _valueConverter       = new RedisValueConverter(serializer);
            _redisConfiguration   = RedisConfigurations.GetConfiguration(configuration.Key);
            _connection           = new RedisConnectionManager(_redisConfiguration, loggerFactory);
            _isLuaAllowed         = _connection.Features.Scripting;

            // disable preloading right away if twemproxy mode, as this is not supported.
            _canPreloadScripts = _redisConfiguration.TwemproxyEnabled ? false : true;

            if (_redisConfiguration.KeyspaceNotificationsEnabled)
            {
                // notify-keyspace-events needs to be set to "Exe" at least! Otherwise we will not receive any events.
                // this must be configured per server and should probably not be done automagically as this needs admin rights!
                // Let's try to check at least if those settings are configured (the check also works only if useAdmin is set to true though).
                try
                {
                    var configurations = _connection.GetConfiguration("notify-keyspace-events");
                    foreach (var cfg in configurations)
                    {
                        if (!cfg.Value.Contains("E"))
                        {
                            Logger.LogWarn("Server {0} is missing configuration value 'E' in notify-keyspace-events to enable keyevents.", cfg.Key);
                        }

                        if (!(cfg.Value.Contains("A") ||
                              (cfg.Value.Contains("x") && cfg.Value.Contains("e"))))
                        {
                            Logger.LogWarn("Server {0} is missing configuration value 'A' or 'x' and 'e' in notify-keyspace-events to enable keyevents for expired and evicted keys.", cfg.Key);
                        }
                    }
                }
                catch
                {
                    Logger.LogDebug("Could not read configuration from redis to validate notify-keyspace-events. Most likely useAdmin is not set to true.");
                }

                SubscribeKeyspaceNotifications();
            }
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="RedisCacheBackplane"/> class.
        /// </summary>
        /// <param name="configuration">The cache manager configuration.</param>
        /// <param name="loggerFactory">The logger factory</param>
        public RedisCacheBackplane(CacheManagerConfiguration configuration, ILoggerFactory loggerFactory)
            : base(configuration)
        {
            NotNull(configuration, nameof(configuration));
            NotNull(loggerFactory, nameof(loggerFactory));

            this.logger = loggerFactory.CreateLogger(this);
            this.channelName = configuration.BackplaneChannelName ?? "CacheManagerBackplane";
            this.identifier = Guid.NewGuid().ToString();

            var cfg = RedisConfigurations.GetConfiguration(this.ConfigurationKey);
            this.connection = new RedisConnectionManager(
                cfg,
                loggerFactory);

            RetryHelper.Retry(() => this.Subscribe(), configuration.RetryTimeout, configuration.MaxRetries, this.logger);
        }
示例#4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="RedisCacheBackplane"/> class.
        /// </summary>
        /// <param name="configuration">The cache manager configuration.</param>
        /// <param name="loggerFactory">The logger factory</param>
        public RedisCacheBackplane(CacheManagerConfiguration configuration, ILoggerFactory loggerFactory)
            : base(configuration)
        {
            NotNull(configuration, nameof(configuration));
            NotNull(loggerFactory, nameof(loggerFactory));

            this.logger      = loggerFactory.CreateLogger(this);
            this.channelName = configuration.BackplaneChannelName ?? "CacheManagerBackplane";
            this.identifier  = Guid.NewGuid().ToString();

            var cfg = RedisConfigurations.GetConfiguration(this.ConfigurationKey);

            this.connection = new RedisConnectionManager(
                cfg,
                loggerFactory);

            RetryHelper.Retry(() => this.Subscribe(), configuration.RetryTimeout, configuration.MaxRetries, this.logger);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="RedisCacheBackplane"/> class.
        /// </summary>
        /// <param name="configuration">The cache manager configuration.</param>
        /// <param name="loggerFactory">The logger factory</param>
        public RedisCacheBackplane(ICacheManagerConfiguration configuration, ILoggerFactory loggerFactory)
            : base(configuration)
        {
            NotNull(configuration, nameof(configuration));
            NotNull(loggerFactory, nameof(loggerFactory));

            _logger      = loggerFactory.CreateLogger(this);
            _channelName = configuration.BackplaneChannelName ?? "CacheManagerBackplane";
            _identifier  = Encoding.UTF8.GetBytes(Guid.NewGuid().ToString());

            var cfg = RedisConfigurations.GetConfiguration(ConfigurationKey);

            _connection = new RedisConnectionManager(
                cfg,
                loggerFactory);

            RetryHelper.Retry(() => Subscribe(), configuration.RetryTimeout, configuration.MaxRetries, _logger);

            // adding additional timer based send message invoke (shouldn't do anything if there are no messages,
            // but in really rare race conditions, it might happen messages do not get send if SendMEssages only get invoked through "NotifyXyz"
            _timer = new Timer(SendMessages, true, 1000, 1000);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="RedisCacheBackPlate"/> class.
        /// </summary>
        /// <param name="configuration">The cache manager configuration.</param>
        /// <param name="loggerFactory">The logger factory</param>
        public RedisCacheBackPlate(CacheManagerConfiguration configuration, ILoggerFactory loggerFactory)
            : base(configuration)
        {
            NotNull(configuration, nameof(configuration));
            NotNull(loggerFactory, nameof(loggerFactory));

            this.logger      = loggerFactory.CreateLogger(this);
            this.channelName = configuration.BackPlateChannelName ?? "CacheManagerBackPlate";
            this.identifier  = Guid.NewGuid().ToString();

            var cfg = RedisConfigurations.GetConfiguration(this.ConfigurationKey);

            this.connection = new RedisConnectionManager(
                cfg,
                loggerFactory);

            RetryHelper.Retry(() => this.Subscribe(), configuration.RetryTimeout, configuration.MaxRetries, logger);

            this.timer = new Timer(
                (obj) =>
            {
                if (this.sending)
                {
                    return;
                }

                lock (this.messageLock)
                {
                    try
                    {
                        this.sending = true;
                        if (this.messages != null && this.messages.Count > 0)
                        {
                            var msgs = string.Join(",", this.messages);
                            if (this.logger.IsEnabled(LogLevel.Debug))
                            {
                                this.logger.LogDebug("Back-plate is sending {0} messages ({1} skipped).", this.messages.Count, this.skippedMessages);
                            }

                            RetryHelper.Retry(
                                () =>
                            {
                                this.Publish(msgs);
                            },
                                configuration.RetryTimeout,
                                configuration.MaxRetries,
                                this.logger);

                            this.skippedMessages = 0;
                            this.messages.Clear();
                        }
                    }
                    catch (Exception ex)
                    {
                        this.logger.LogError(ex, "Error occurred sending back plate messages.");
                    }
                    finally
                    {
                        this.sending = false;
                    }
                }
            },
                this,
                TimeSpan.FromMilliseconds(100),
                TimeSpan.FromMilliseconds(100));
        }