Merge pull request #13972 from abpframework/liangshiwei/distributedlock

pull/13845/head^2
maliming 3 years ago committed by GitHub
commit 6514385e08
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -101,6 +101,25 @@ namespace AbpDemo
* `timeout` (`TimeSpan`): A timeout value to wait to obtain the lock. Default value is `TimeSpan.Zero`, which means it doesn't wait if the lock is already owned by another application.
* `cancellationToken`: A cancellation token that can be triggered later to cancel the operation.
### Configuration
#### AbpDistributedLockOptions
`AbpDistributedLockOptions` is the main options class to configure the distributed locking.
**Example: Set the distributed lock key prefix for the application**
Configure<AbpDistributedLockOptions>(options =>
{
options.KeyPrefix = "MyApp1";
});
> Write that code inside the `ConfigureServices` method of your [module class](Module-Development-Basics.md).
##### Available Options
* KeyPrefix (string, default: null): Specify the lock name prefix.
### Using DistributedLock Library's API
ABP's `IAbpDistributedLock` service is very limited and mainly designed to be internally used by the ABP Framework. For your own applications, you can use the DistributedLock library's own API. See its [own documentation](https://github.com/madelson/DistributedLock) for details.

@ -101,6 +101,25 @@ namespace AbpDemo
* `timeout` (`TimeSpan`): 等待获取锁的超时值. 默认值为`TimeSpan.Zero`, 这意味着如果锁已经被另一个应用程序拥有, 它不会等待.
* `cancellationToken`: 取消令牌可在触发后取消操作.
### 配置
#### AbpDistributedLockOptions
`AbpDistributedLockOptions` 是配置分布式锁的主要选项类.
**示例: 设置应用程序的分布式锁Key前缀**
Configure<AbpDistributedLockOptions>(options =>
{
options.KeyPrefix = "MyApp1";
});
> 在你的[模块类](Module-Development-Basics.md)中的 `ConfigureServices` 方法进行配置.
##### 可用选项
* KeyPrefix (string, 默认值: null): 指定分布式锁名称前缀.
### 使用DistributedLock库的API
ABP的`IAbpDistributedLock`服务非常有限, 主要用于ABP框架的内部使用. 对于你自己的应用程序, 可以使用DistributedLock库自己的API. 参见[文档](https://github.com/madelson/DistributedLock)详细信息.

@ -0,0 +1,14 @@
namespace Volo.Abp.DistributedLocking;
public class AbpDistributedLockOptions
{
/// <summary>
/// DistributedLock key prefix.
/// </summary>
public string KeyPrefix { get; set; }
public AbpDistributedLockOptions()
{
KeyPrefix = "";
}
}

@ -0,0 +1,19 @@
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.DistributedLocking;
public class DistributedLockKeyNormalizer : IDistributedLockKeyNormalizer, ITransientDependency
{
protected AbpDistributedLockOptions Options { get; }
public DistributedLockKeyNormalizer(IOptions<AbpDistributedLockOptions> options)
{
Options = options.Value;
}
public virtual string NormalizeKey(string name)
{
return $"{Options.KeyPrefix}{name}";
}
}

@ -0,0 +1,7 @@
namespace Volo.Abp.DistributedLocking;
public interface IDistributedLockKeyNormalizer
{
string NormalizeKey(string name);
}

@ -9,15 +9,22 @@ namespace Volo.Abp.DistributedLocking;
public class LocalAbpDistributedLock : IAbpDistributedLock, ISingletonDependency
{
private readonly ConcurrentDictionary<string, SemaphoreSlim> _localSyncObjects = new();
protected IDistributedLockKeyNormalizer DistributedLockKeyNormalizer { get; }
public LocalAbpDistributedLock(IDistributedLockKeyNormalizer distributedLockKeyNormalizer)
{
DistributedLockKeyNormalizer = distributedLockKeyNormalizer;
}
public async Task<IAbpDistributedLockHandle> TryAcquireAsync(
string name,
TimeSpan timeout = default,
CancellationToken cancellationToken = default)
{
Check.NotNullOrWhiteSpace(name, nameof(name));
var semaphore = _localSyncObjects.GetOrAdd(name, _ => new SemaphoreSlim(1, 1));
var key = DistributedLockKeyNormalizer.NormalizeKey(name);
var semaphore = _localSyncObjects.GetOrAdd(key, _ => new SemaphoreSlim(1, 1));
if (!await semaphore.WaitAsync(timeout, cancellationToken))
{

@ -10,13 +10,16 @@ public class DaprAbpDistributedLock : IAbpDistributedLock, ITransientDependency
protected AbpDaprClientFactory DaprClientFactory { get; }
protected AbpDistributedLockDaprOptions DistributedLockDaprOptions { get; }
protected AbpDaprOptions DaprOptions { get; }
protected IDistributedLockKeyNormalizer DistributedLockKeyNormalizer { get; }
public DaprAbpDistributedLock(
AbpDaprClientFactory daprClientFactory,
IOptions<AbpDistributedLockDaprOptions> distributedLockDaprOptions,
IOptions<AbpDaprOptions> daprOptions)
IOptions<AbpDaprOptions> daprOptions,
IDistributedLockKeyNormalizer distributedLockKeyNormalizer)
{
DaprClientFactory = daprClientFactory;
DistributedLockKeyNormalizer = distributedLockKeyNormalizer;
DaprOptions = daprOptions.Value;
DistributedLockDaprOptions = distributedLockDaprOptions.Value;
}
@ -32,10 +35,11 @@ public class DaprAbpDistributedLock : IAbpDistributedLock, ITransientDependency
}
var daprClient = await DaprClientFactory.CreateAsync();
var key = DistributedLockKeyNormalizer.NormalizeKey(name);
var lockResponse = await daprClient.Lock(
DistributedLockDaprOptions.StoreName,
name,
key,
DaprOptions.AppId,
(int)timeout.TotalSeconds,
cancellationToken);

@ -12,13 +12,17 @@ public class MedallionAbpDistributedLock : IAbpDistributedLock, ITransientDepend
{
protected IDistributedLockProvider DistributedLockProvider { get; }
protected ICancellationTokenProvider CancellationTokenProvider { get; }
protected IDistributedLockKeyNormalizer DistributedLockKeyNormalizer { get; }
public MedallionAbpDistributedLock(
IDistributedLockProvider distributedLockProvider,
ICancellationTokenProvider cancellationTokenProvider)
ICancellationTokenProvider cancellationTokenProvider,
IDistributedLockKeyNormalizer distributedLockKeyNormalizer)
{
DistributedLockProvider = distributedLockProvider;
CancellationTokenProvider = cancellationTokenProvider;
DistributedLockKeyNormalizer = distributedLockKeyNormalizer;
}
public async Task<IAbpDistributedLockHandle> TryAcquireAsync(
@ -27,11 +31,12 @@ public class MedallionAbpDistributedLock : IAbpDistributedLock, ITransientDepend
CancellationToken cancellationToken = default)
{
Check.NotNullOrWhiteSpace(name, nameof(name));
var key = DistributedLockKeyNormalizer.NormalizeKey(name);
CancellationTokenProvider.FallbackToProvider(cancellationToken);
var handle = await DistributedLockProvider.TryAcquireLockAsync(
name,
key,
timeout,
CancellationTokenProvider.FallbackToProvider(cancellationToken)
);

Loading…
Cancel
Save