|
|
|
|
@ -1,14 +1,18 @@
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Concurrent;
|
|
|
|
|
using System.Threading;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using AsyncKeyedLock;
|
|
|
|
|
using Volo.Abp.DependencyInjection;
|
|
|
|
|
|
|
|
|
|
namespace Volo.Abp.DistributedLocking;
|
|
|
|
|
|
|
|
|
|
public class LocalAbpDistributedLock : IAbpDistributedLock, ISingletonDependency
|
|
|
|
|
{
|
|
|
|
|
private readonly ConcurrentDictionary<string, SemaphoreSlim> _localSyncObjects = new();
|
|
|
|
|
private readonly AsyncKeyedLocker<string> _localSyncObjects = new(o =>
|
|
|
|
|
{
|
|
|
|
|
o.PoolSize = 20;
|
|
|
|
|
o.PoolInitialFill = 1;
|
|
|
|
|
});
|
|
|
|
|
protected IDistributedLockKeyNormalizer DistributedLockKeyNormalizer { get; }
|
|
|
|
|
|
|
|
|
|
public LocalAbpDistributedLock(IDistributedLockKeyNormalizer distributedLockKeyNormalizer)
|
|
|
|
|
@ -23,14 +27,18 @@ public class LocalAbpDistributedLock : IAbpDistributedLock, ISingletonDependency
|
|
|
|
|
{
|
|
|
|
|
Check.NotNullOrWhiteSpace(name, nameof(name));
|
|
|
|
|
var key = DistributedLockKeyNormalizer.NormalizeKey(name);
|
|
|
|
|
|
|
|
|
|
var semaphore = _localSyncObjects.GetOrAdd(key, _ => new SemaphoreSlim(1, 1));
|
|
|
|
|
|
|
|
|
|
if (!await semaphore.WaitAsync(timeout, cancellationToken))
|
|
|
|
|
if (timeout == default)
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
var releaser = await _localSyncObjects.LockAsync(key, cancellationToken);
|
|
|
|
|
return new LocalAbpDistributedLockHandle(releaser);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return new LocalAbpDistributedLockHandle(semaphore);
|
|
|
|
|
var timeoutReleaser = await _localSyncObjects.LockAsync(key, timeout, cancellationToken);
|
|
|
|
|
if (!timeoutReleaser.EnteredSemaphore)
|
|
|
|
|
{
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
return new LocalAbpDistributedLockHandle(timeoutReleaser);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|