|
|
|
@ -1,19 +1,14 @@ |
|
|
|
using System; |
|
|
|
using System.Runtime.CompilerServices; |
|
|
|
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 AsyncKeyedLocker<string> _localSyncObjects = new(o => |
|
|
|
{ |
|
|
|
o.PoolSize = 20; |
|
|
|
o.PoolInitialFill = 1; |
|
|
|
}); |
|
|
|
private readonly ConcurrentDictionary<string, SemaphoreSlim> _localSyncObjects = new(); |
|
|
|
protected IDistributedLockKeyNormalizer DistributedLockKeyNormalizer { get; } |
|
|
|
|
|
|
|
public LocalAbpDistributedLock(IDistributedLockKeyNormalizer distributedLockKeyNormalizer) |
|
|
|
@ -21,7 +16,6 @@ public class LocalAbpDistributedLock : IAbpDistributedLock, ISingletonDependency |
|
|
|
DistributedLockKeyNormalizer = distributedLockKeyNormalizer; |
|
|
|
} |
|
|
|
|
|
|
|
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
|
|
|
public async Task<IAbpDistributedLockHandle?> TryAcquireAsync( |
|
|
|
string name, |
|
|
|
TimeSpan timeout = default, |
|
|
|
@ -30,11 +24,8 @@ public class LocalAbpDistributedLock : IAbpDistributedLock, ISingletonDependency |
|
|
|
Check.NotNullOrWhiteSpace(name, nameof(name)); |
|
|
|
var key = DistributedLockKeyNormalizer.NormalizeKey(name); |
|
|
|
|
|
|
|
var timeoutReleaser = await _localSyncObjects.LockOrNullAsync(key, timeout, cancellationToken); |
|
|
|
if (timeoutReleaser is not null) |
|
|
|
{ |
|
|
|
return new LocalAbpDistributedLockHandle(timeoutReleaser); |
|
|
|
} |
|
|
|
return null; |
|
|
|
var semaphore = _localSyncObjects.GetOrAdd(key, _ => new SemaphoreSlim(1, 1)); |
|
|
|
var acquired = await semaphore.WaitAsync(timeout, cancellationToken); |
|
|
|
return acquired ? new LocalAbpDistributedLockHandle(semaphore) : null; |
|
|
|
} |
|
|
|
} |
|
|
|
|