コード例 #1
0
        /// <summary>
        /// Tries to lock the given key.
        /// </summary>
        /// <param name="key">The key to lock.</param>
        /// <param name="luaScript">The lua script to lock the key.</param>
        /// <param name="extraKeys">The extra keys that will be provided to the <paramref name="luaScript"/></param>
        /// <param name="extraValues">The extra values that will be provided to the <paramref name="luaScript"/></param>
        /// <returns>The lock value used to lock the key.</returns>
        /// <exception cref="CacheException">Thrown if the lock was not acquired.</exception>
        public string Lock(string key, string luaScript, RedisKey[] extraKeys, RedisValue[] extraValues)
        {
            if (key == null)
            {
                throw new ArgumentNullException(nameof(key));
            }
            var lockKey = $"{key}{_lockKeySuffix}";

            string Context() => lockKey;

            return(_retryPolicy.Execute(() =>
            {
                var lockValue = _lockValueProvider.GetValue();
                if (!string.IsNullOrEmpty(luaScript))
                {
                    var keys = new RedisKey[] { lockKey };
                    if (extraKeys != null)
                    {
                        keys = keys.Concat(extraKeys).ToArray();
                    }
                    var values = new RedisValue[] { lockValue, (long)_lockTimeout.TotalMilliseconds };
                    if (extraValues != null)
                    {
                        values = values.Concat(extraValues).ToArray();
                    }
                    var result = (RedisValue[])_database.ScriptEvaluate(luaScript, keys, values);
                    if ((bool)result[0])
                    {
                        return lockValue;
                    }
                }
                else if (_database.LockTake(lockKey, lockValue, _lockTimeout))
                {
                    return lockValue;
                }

                return null;                 // retry
            }, Context));
        }