/// <summary> /// Tries to unlock the given keys. /// </summary> /// <param name="keys">The keys to unlock.</param> /// <param name="lockValue">The value that was used to lock the keys.</param> /// <param name="luaScript">The lua script to unlock the keys.</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>How many keys were unlocked.</returns> public int UnlockMany(string[] keys, string lockValue, string luaScript, RedisKey[] extraKeys, RedisValue[] extraValues) { if (keys == null) { throw new ArgumentNullException(nameof(keys)); } if (luaScript == null) { throw new ArgumentNullException(nameof(luaScript)); } var lockKeys = new RedisKey[keys.Length]; for (var i = 0; i < keys.Length; i++) { lockKeys[i] = $"{keys[i]}{_lockKeySuffix}"; } if (extraKeys != null) { lockKeys = lockKeys.Concat(extraKeys).ToArray(); } var values = new RedisValue[] { lockValue }; if (extraValues != null) { values = values.Concat(extraValues).ToArray(); } var result = (RedisValue[])_database.ScriptEvaluate(luaScript, lockKeys, values); return((int)result[0]); }
/// <summary> /// Tries to unlock the given key. /// </summary> /// <param name="key">The key to unlock.</param> /// <param name="lockValue">The value that was used to lock the key.</param> /// <param name="luaScript">The lua script to unlock 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>Whether the key was unlocked.</returns> public bool Unlock(string key, string lockValue, string luaScript, RedisKey[] extraKeys, RedisValue[] extraValues) { if (key == null) { throw new ArgumentNullException(nameof(key)); } var lockKey = $"{key}{_lockKeySuffix}"; if (string.IsNullOrEmpty(luaScript)) { return(_database.LockRelease(lockKey, lockValue)); } var keys = new RedisKey[] { lockKey }; if (extraKeys != null) { keys = keys.Concat(extraKeys).ToArray(); } var values = new RedisValue[] { lockValue }; if (extraValues != null) { values = values.Concat(extraValues).ToArray(); } var result = (RedisValue[])_database.ScriptEvaluate(luaScript, keys, values); return((bool)result[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> /// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param> /// <returns>The lock value used to lock the key.</returns> /// <exception cref="CacheException">Thrown if the lock was not acquired.</exception> public Task <string> LockAsync(string key, string luaScript, RedisKey[] extraKeys, RedisValue[] extraValues, CancellationToken cancellationToken) { if (key == null) { throw new ArgumentNullException(nameof(key)); } if (cancellationToken.IsCancellationRequested) { return(Task.FromCanceled <string>(cancellationToken)); } var lockKey = $"{key}{_lockKeySuffix}"; string Context() => lockKey; return(_retryPolicy.ExecuteAsync(async() => { 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[])await(_database.ScriptEvaluateAsync(luaScript, keys, values)).ConfigureAwait(false); if ((bool)result[0]) { return lockValue; } } else if (await(_database.LockTakeAsync(lockKey, lockValue, _lockTimeout)).ConfigureAwait(false)) { return lockValue; } return null; // retry }, Context, cancellationToken)); }
/// <summary> /// Tries to lock the given keys. /// </summary> /// <param name="keys">The keys to lock.</param> /// <param name="luaScript">The lua script to lock the keys.</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> /// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param> /// <returns>The lock value used to lock the keys.</returns> /// <exception cref="CacheException">Thrown if the lock was not acquired.</exception> public Task <string> LockManyAsync(string[] keys, string luaScript, RedisKey[] extraKeys, RedisValue[] extraValues, CancellationToken cancellationToken) { if (keys == null) { throw new ArgumentNullException(nameof(keys)); } if (luaScript == null) { throw new ArgumentNullException(nameof(luaScript)); } if (cancellationToken.IsCancellationRequested) { return(Task.FromCanceled <string>(cancellationToken)); } string Context() => string.Join(",", keys.Select(o => $"{o}{_lockKeySuffix}")); return(_retryPolicy.ExecuteAsync(async() => { var lockKeys = new RedisKey[keys.Length]; for (var i = 0; i < keys.Length; i++) { lockKeys[i] = $"{keys[i]}{_lockKeySuffix}"; } var lockValue = _lockValueProvider.GetValue(); if (extraKeys != null) { lockKeys = lockKeys.Concat(extraKeys).ToArray(); } var values = new RedisValue[] { lockValue, (long)_lockTimeout.TotalMilliseconds }; if (extraValues != null) { values = values.Concat(extraValues).ToArray(); } var result = (RedisValue[])await(_database.ScriptEvaluateAsync(luaScript, lockKeys, values)).ConfigureAwait(false); if ((bool)result[0]) { return lockValue; } return null; // retry }, Context, cancellationToken)); }
/// <summary> /// Tries to unlock the given keys. /// </summary> /// <param name="keys">The keys to unlock.</param> /// <param name="lockValue">The value that was used to lock the keys.</param> /// <param name="luaScript">The lua script to unlock the keys.</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> /// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param> /// <returns>How many keys were unlocked.</returns> public Task <int> UnlockManyAsync(string[] keys, string lockValue, string luaScript, RedisKey[] extraKeys, RedisValue[] extraValues, CancellationToken cancellationToken) { if (keys == null) { throw new ArgumentNullException(nameof(keys)); } if (luaScript == null) { throw new ArgumentNullException(nameof(luaScript)); } if (cancellationToken.IsCancellationRequested) { return(Task.FromCanceled <int>(cancellationToken)); } return(InternalUnlockManyAsync()); async Task <int> InternalUnlockManyAsync() { var lockKeys = new RedisKey[keys.Length]; for (var i = 0; i < keys.Length; i++) { lockKeys[i] = $"{keys[i]}{_lockKeySuffix}"; } if (extraKeys != null) { lockKeys = lockKeys.Concat(extraKeys).ToArray(); } var values = new RedisValue[] { lockValue }; if (extraValues != null) { values = values.Concat(extraValues).ToArray(); } cancellationToken.ThrowIfCancellationRequested(); var result = (RedisValue[])await(_database.ScriptEvaluateAsync(luaScript, lockKeys, values)).ConfigureAwait(false); return((int)result[0]); } }
/// <summary> /// Tries to unlock the given key. /// </summary> /// <param name="key">The key to unlock.</param> /// <param name="lockValue">The value that was used to lock the key.</param> /// <param name="luaScript">The lua script to unlock 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> /// <param name="cancellationToken">A cancellation token that can be used to cancel the work</param> /// <returns>Whether the key was unlocked.</returns> public Task <bool> UnlockAsync(string key, string lockValue, string luaScript, RedisKey[] extraKeys, RedisValue[] extraValues, CancellationToken cancellationToken) { if (key == null) { throw new ArgumentNullException(nameof(key)); } if (cancellationToken.IsCancellationRequested) { return(Task.FromCanceled <bool>(cancellationToken)); } return(InternalUnlockAsync()); async Task <bool> InternalUnlockAsync() { var lockKey = $"{key}{_lockKeySuffix}"; if (string.IsNullOrEmpty(luaScript)) { cancellationToken.ThrowIfCancellationRequested(); return(await(_database.LockReleaseAsync(lockKey, lockValue)).ConfigureAwait(false)); } var keys = new RedisKey[] { lockKey }; if (extraKeys != null) { keys = keys.Concat(extraKeys).ToArray(); } var values = new RedisValue[] { lockValue }; if (extraValues != null) { values = values.Concat(extraValues).ToArray(); } cancellationToken.ThrowIfCancellationRequested(); var result = (RedisValue[])await(_database.ScriptEvaluateAsync(luaScript, keys, values)).ConfigureAwait(false); return((bool)result[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)); }
/// <summary> /// Tries to lock the given keys. /// </summary> /// <param name="keys">The keys to lock.</param> /// <param name="luaScript">The lua script to lock the keys.</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 keys.</returns> /// <exception cref="CacheException">Thrown if the lock was not acquired.</exception> public string LockMany(string[] keys, string luaScript, RedisKey[] extraKeys, RedisValue[] extraValues) { if (keys == null) { throw new ArgumentNullException(nameof(keys)); } if (luaScript == null) { throw new ArgumentNullException(nameof(luaScript)); } string Context() => string.Join(",", keys.Select(o => $"{o}{_lockKeySuffix}")); return(_retryPolicy.Execute(() => { var lockKeys = new RedisKey[keys.Length]; for (var i = 0; i < keys.Length; i++) { lockKeys[i] = $"{keys[i]}{_lockKeySuffix}"; } var lockValue = _lockValueProvider.GetValue(); if (extraKeys != null) { lockKeys = lockKeys.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, lockKeys, values); if ((bool)result[0]) { return lockValue; } return null; // retry }, Context)); }