/// <summary>
        /// Default constructor.
        /// </summary>
        /// <param name="regionName">The region name.</param>
        /// <param name="database">The Redis database.</param>
        /// <param name="configuration">The lock configuration.</param>
        public RedisKeyLocker(
            string regionName,
            IDatabase database,
            RedisCacheLockConfiguration configuration)
        {
            _database          = database;
            _lockKeySuffix     = configuration.KeySuffix;
            _lockTimeout       = configuration.KeyTimeout;
            _lockValueProvider = configuration.ValueProvider;

            var acquireTimeout         = configuration.AcquireTimeout;
            var retryTimes             = configuration.RetryTimes;
            var maxRetryDelay          = configuration.MaxRetryDelay;
            var minRetryDelay          = configuration.MinRetryDelay;
            var lockRetryDelayProvider = configuration.RetryDelayProvider;

            _retryPolicy = new RetryPolicy <string, Func <string> >(
                retryTimes,
                acquireTimeout,
                () => lockRetryDelayProvider.GetValue(minRetryDelay, maxRetryDelay)
                )
                           .ShouldRetry(s => s == null)
                           .OnFailure((totalAttempts, elapsedMs, getKeysFn) =>
                                      throw new CacheException("Unable to acquire cache lock: " +
                                                               $"region='{regionName}', " +
                                                               $"keys='{getKeysFn()}', " +
                                                               $"total attempts='{totalAttempts}', " +
                                                               $"total acquiring time= '{elapsedMs}ms'"));
        }
Example #2
0
        /// <inheritdoc />
        public DistributedLocalCacheRegionStrategy(
            IConnectionMultiplexer connectionMultiplexer,
            RedisCacheRegionConfiguration configuration,
            RegionMemoryCacheBase memoryCache,
            IDictionary <string, string> properties)
            : base(connectionMultiplexer, configuration, properties)
        {
            var lockConfiguration      = configuration.LockConfiguration;
            var acquireTimeout         = lockConfiguration.AcquireTimeout;
            var retryTimes             = lockConfiguration.RetryTimes;
            var maxRetryDelay          = lockConfiguration.MaxRetryDelay;
            var minRetryDelay          = lockConfiguration.MinRetryDelay;
            var lockRetryDelayProvider = lockConfiguration.RetryDelayProvider;

            _usePipelining = GetBoolean("cache.region_strategy.distributed_local_cache.use_pipelining", properties, false);
            Log.Debug("Use pipelining for region {0}: {1}", RegionName, _usePipelining);

            _clientId = GetInteger("cache.region_strategy.distributed_local_cache.client_id", properties, Guid.NewGuid().GetHashCode());
            Log.Debug("Client id for region {0}: {1}", RegionName, _clientId);

            _maxSynchronizationTime = GetTimeSpanFromSeconds(
                "cache.region_strategy.distributed_local_cache.max_synchronization_time", properties, TimeSpan.FromSeconds(10));
            Log.Debug("Max synchronization time for region {0}: {1} seconds", RegionName, _maxSynchronizationTime.TotalSeconds);

            _memoryCache            = memoryCache;
            _synchronizationChannel = string.Concat("{", configuration.RegionKey, "}@", "Synchronization");
            _lockValueProvider      = lockConfiguration.ValueProvider;
            _lockKeySuffix          = lockConfiguration.KeySuffix;
            _lockAcquireTimeout     = lockConfiguration.AcquireTimeout;
            _lockKeyTimeout         = lockConfiguration.KeyTimeout;
            _retryPolicy            = new RetryPolicy <string, Func <object> >(
                retryTimes,
                acquireTimeout,
                () => lockRetryDelayProvider.GetValue(minRetryDelay, maxRetryDelay)
                )
                                      .ShouldRetry(s => s == null)
                                      .OnFailure(OnFailedLock);
            _subscriber = ConnectionMultiplexer.GetSubscriber();

            ConnectionMultiplexer.ConnectionFailed   += OnConnectionFailed;
            ConnectionMultiplexer.ConnectionRestored += OnConnectionRestored;
            ConnectionMultiplexer.ErrorMessage       += OnErrorMessage;
            _subscriber.Subscribe(_synchronizationChannel).OnMessage((Action <ChannelMessage>)OnSynchronizationMessage);
            _subscriber.Subscribe(GetClientChannel(_clientId)).OnMessage((Action <ChannelMessage>)OnPrivateMessage);
        }