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); }
/// <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); }
/// <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)); }