rama creada apartir de master en j
This commit is contained in:
@@ -24,44 +24,55 @@ namespace adas_core.Application.Services.Caching
|
||||
private readonly ConcurrentDictionary<string, string> _tokens =
|
||||
new(StringComparer.Ordinal);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to acquire a distributed lock for the specified key using Redis, retrying until the timeout expires.
|
||||
/// Returns <c>false</c> if the Redis database is unavailable or if the lock cannot be acquired within the given timeout.
|
||||
/// </summary>
|
||||
/// <param name="key">The identifier of the resource to lock.</param>
|
||||
/// <param name="timeout">The maximum duration to keep retrying before giving up.</param>
|
||||
/// <returns><c>true</c> if the lock was successfully acquired; otherwise, <c>false</c>.</returns>
|
||||
public async Task<bool> AcquireAsync(string key, TimeSpan timeout)
|
||||
{
|
||||
var redis = getDatabase();
|
||||
if (redis is null) return false;
|
||||
|
||||
var redisKey = (RedisKey)(_prefix + key);
|
||||
var token = Guid.NewGuid().ToString("N");
|
||||
var end = DateTime.UtcNow.Add(timeout);
|
||||
|
||||
while (DateTime.UtcNow < end)
|
||||
{
|
||||
if (await redis.StringSetAsync(redisKey, token, _ttl, When.NotExists))
|
||||
{
|
||||
_tokens[key] = token;
|
||||
return true;
|
||||
var redis = getDatabase();
|
||||
if (redis is null) return false;
|
||||
|
||||
var redisKey = (RedisKey)(_prefix + key);
|
||||
var token = Guid.NewGuid().ToString("N");
|
||||
var end = DateTime.UtcNow.Add(timeout);
|
||||
|
||||
while (DateTime.UtcNow < end)
|
||||
{
|
||||
if (await redis.StringSetAsync(redisKey, token, _ttl, When.NotExists))
|
||||
{
|
||||
_tokens[key] = token;
|
||||
return true;
|
||||
}
|
||||
|
||||
await Task.Delay(_retryDelay);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
await Task.Delay(_retryDelay);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Asynchronously releases the token associated with the specified key by removing it from the in-memory token store and executing a Lua release script against Redis. If the key is not found in the local store, or the Redis database is unavailable, the method returns without performing any further action.
|
||||
/// </summary>
|
||||
/// <param name="key">The identifier of the token to release.</param>
|
||||
public async Task ReleaseAsync(string key)
|
||||
{
|
||||
if (!_tokens.TryRemove(key, out var token))
|
||||
return;
|
||||
|
||||
var redis = getDatabase();
|
||||
if (redis is null) return;
|
||||
|
||||
var redisKey = (RedisKey)(_prefix + key);
|
||||
|
||||
await redis.ScriptEvaluateAsync(
|
||||
LuaReleaseScript,
|
||||
[redisKey],
|
||||
[token]
|
||||
);
|
||||
}
|
||||
{
|
||||
if (!_tokens.TryRemove(key, out var token))
|
||||
return;
|
||||
|
||||
var redis = getDatabase();
|
||||
if (redis is null) return;
|
||||
|
||||
var redisKey = (RedisKey)(_prefix + key);
|
||||
|
||||
await redis.ScriptEvaluateAsync(
|
||||
LuaReleaseScript,
|
||||
[redisKey],
|
||||
[token]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user