Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Distributed lock key prefix #13972

Merged
merged 2 commits into from
Sep 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions docs/en/Distributed-Locking.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
19 changes: 19 additions & 0 deletions docs/zh-Hans/Distributed-Locking.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)详细信息.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace Volo.Abp.DistributedLocking;

public class AbpDistributedLockOptions
{
/// <summary>
/// DistributedLock key prefix.
/// </summary>
public string KeyPrefix { get; set; }

public AbpDistributedLockOptions()
{
KeyPrefix = "";
}
}
Original file line number Diff line number Diff line change
@@ -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}";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Volo.Abp.DistributedLocking;

public interface IDistributedLockKeyNormalizer
{
string NormalizeKey(string name);

}
Original file line number Diff line number Diff line change
Expand Up @@ -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))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -32,10 +35,11 @@ public async Task<IAbpDistributedLockHandle> TryAcquireAsync(
}

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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -27,11 +31,12 @@ public async Task<IAbpDistributedLockHandle> TryAcquireAsync(
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)
);
Expand Down