14 changed files with 253 additions and 18 deletions
@ -0,0 +1,10 @@ |
|||
namespace Dapr.Client; |
|||
|
|||
public static class IDaprClientFactoryExtensions |
|||
{ |
|||
public static DaprClient CreateClient( |
|||
this IDaprClientFactory clientFactory) |
|||
{ |
|||
return clientFactory.CreateClient("Default"); |
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd"> |
|||
<ConfigureAwait ContinueOnCapturedContext="false" /> |
|||
</Weavers> |
|||
@ -0,0 +1,30 @@ |
|||
<?xml version="1.0" encoding="utf-8"?> |
|||
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> |
|||
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. --> |
|||
<xs:element name="Weavers"> |
|||
<xs:complexType> |
|||
<xs:all> |
|||
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1"> |
|||
<xs:complexType> |
|||
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" /> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:all> |
|||
<xs:attribute name="VerifyAssembly" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="VerifyIgnoreCodes" type="xs:string"> |
|||
<xs:annotation> |
|||
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
<xs:attribute name="GenerateXsd" type="xs:boolean"> |
|||
<xs:annotation> |
|||
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation> |
|||
</xs:annotation> |
|||
</xs:attribute> |
|||
</xs:complexType> |
|||
</xs:element> |
|||
</xs:schema> |
|||
@ -0,0 +1,21 @@ |
|||
<Project Sdk="Microsoft.NET.Sdk"> |
|||
|
|||
<Import Project="..\..\..\configureawait.props" /> |
|||
<Import Project="..\..\..\common.props" /> |
|||
|
|||
<PropertyGroup> |
|||
<TargetFramework>net6.0</TargetFramework> |
|||
<RootNamespace /> |
|||
</PropertyGroup> |
|||
|
|||
<ItemGroup> |
|||
<PackageReference Include="Volo.Abp.Threading" Version="$(VoloAbpPackageVersion)" /> |
|||
<PackageReference Include="Volo.Abp.DistributedLocking.Abstractions" Version="$(VoloAbpPackageVersion)" /> |
|||
<PackageReference Include="Microsoft.Bcl.AsyncInterfaces" Version="$(MicrosoftPackageVersion)" /> |
|||
</ItemGroup> |
|||
|
|||
<ItemGroup> |
|||
<ProjectReference Include="..\LINGYUN.Abp.Dapr\LINGYUN.Abp.Dapr.csproj" /> |
|||
</ItemGroup> |
|||
|
|||
</Project> |
|||
@ -0,0 +1,15 @@ |
|||
using LINGYUN.Abp.Dapr; |
|||
using Volo.Abp.DistributedLocking; |
|||
using Volo.Abp.Modularity; |
|||
using Volo.Abp.Threading; |
|||
|
|||
namespace LINGYUN.Abp.DistributedLocking.Dapr; |
|||
|
|||
[DependsOn( |
|||
typeof(AbpDaprModule), |
|||
typeof(AbpThreadingModule), |
|||
typeof(AbpDistributedLockingAbstractionsModule))] |
|||
public class AbpDistributedLockingDaprModule : AbpModule |
|||
{ |
|||
|
|||
} |
|||
@ -0,0 +1,17 @@ |
|||
using System; |
|||
|
|||
namespace LINGYUN.Abp.DistributedLocking.Dapr; |
|||
|
|||
public class AbpDistributedLockingDaprOptions |
|||
{ |
|||
public string StoreName { get; set; } |
|||
public string ResourceId { get; set; } |
|||
public TimeSpan DefaultTimeout { get; set; } |
|||
|
|||
public AbpDistributedLockingDaprOptions() |
|||
{ |
|||
StoreName = "lockstore"; |
|||
ResourceId = "dapr-lock-id"; |
|||
DefaultTimeout = TimeSpan.FromSeconds(30); |
|||
} |
|||
} |
|||
@ -0,0 +1,51 @@ |
|||
using Dapr.Client; |
|||
using Microsoft.Extensions.Options; |
|||
using System; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DependencyInjection; |
|||
using Volo.Abp.DistributedLocking; |
|||
using Volo.Abp.Threading; |
|||
|
|||
namespace LINGYUN.Abp.DistributedLocking.Dapr; |
|||
|
|||
[Dependency(ReplaceServices = true)] |
|||
public class DaprAbpDistributedLock : IAbpDistributedLock, ITransientDependency |
|||
{ |
|||
protected IDaprClientFactory DaprClientFactory { get; } |
|||
protected AbpDistributedLockingDaprOptions Options { get; } |
|||
protected ICancellationTokenProvider CancellationTokenProvider { get; } |
|||
|
|||
public DaprAbpDistributedLock( |
|||
IDaprClientFactory daprClientFactory, |
|||
ICancellationTokenProvider cancellationTokenProvider, |
|||
IOptions<AbpDistributedLockingDaprOptions> options) |
|||
{ |
|||
Options = options.Value; |
|||
DaprClientFactory = daprClientFactory; |
|||
CancellationTokenProvider = cancellationTokenProvider; |
|||
} |
|||
|
|||
public async virtual Task<IAbpDistributedLockHandle> TryAcquireAsync(string name, TimeSpan timeout = default, CancellationToken cancellationToken = default) |
|||
{ |
|||
if (timeout == default) |
|||
{ |
|||
timeout = Options.DefaultTimeout; |
|||
} |
|||
var client = DaprClientFactory.CreateClient(); |
|||
|
|||
var res = await client.Lock(Options.StoreName, name, Options.ResourceId, (int)timeout.TotalSeconds, cancellationToken); |
|||
|
|||
if (res == null || !res.Success) |
|||
{ |
|||
return null; |
|||
} |
|||
|
|||
return new DaprAbpDistributedLockHandle(Options.StoreName, name, Options.ResourceId, client); |
|||
} |
|||
|
|||
protected virtual CancellationToken GetCancellationToken(CancellationToken cancellationToken = default) |
|||
{ |
|||
return CancellationTokenProvider.FallbackToProvider(cancellationToken); |
|||
} |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
using Dapr.Client; |
|||
using System.Threading.Tasks; |
|||
using Volo.Abp.DistributedLocking; |
|||
|
|||
namespace LINGYUN.Abp.DistributedLocking.Dapr; |
|||
|
|||
public class DaprAbpDistributedLockHandle : IAbpDistributedLockHandle |
|||
{ |
|||
protected string StoreName { get; } |
|||
protected string ResourceId { get; } |
|||
protected string LockOwner { get; } |
|||
protected DaprClient DaprClient { get; } |
|||
public DaprAbpDistributedLockHandle( |
|||
string storeName, |
|||
string resourceId, |
|||
string lockOwner, |
|||
DaprClient daprClient) |
|||
{ |
|||
StoreName = storeName; |
|||
ResourceId = resourceId; |
|||
LockOwner = lockOwner; |
|||
DaprClient = daprClient; |
|||
} |
|||
public async ValueTask DisposeAsync() |
|||
{ |
|||
await DaprClient.Unlock(StoreName, ResourceId, LockOwner); |
|||
} |
|||
} |
|||
@ -0,0 +1,34 @@ |
|||
# LINGYUN.Abp.DistributedLocking.Dapr |
|||
|
|||
Abp分布式锁的Dapr实现 |
|||
|
|||
See: https://docs.dapr.io/developing-applications/building-blocks/distributed-lock/distributed-lock-api-overview/ |
|||
|
|||
## 配置使用 |
|||
|
|||
模块按需引用 |
|||
|
|||
```csharp |
|||
[DependsOn(typeof(AbpDistributedLockingDaprModule))] |
|||
public class YouProjectModule : AbpModule |
|||
{ |
|||
public override void ConfigureServices(ServiceConfigurationContext context) |
|||
{ |
|||
Configure<AbpDistributedLockingDaprOptions>(options => |
|||
{ |
|||
options.StoreName = "store-name"; |
|||
options.ResourceId = "resource-id"; |
|||
options.DefaultTimeout = TimeSpan.FromSeconds(30); |
|||
}); |
|||
} |
|||
} |
|||
``` |
|||
|
|||
## 配置说明 |
|||
|
|||
* AbpDistributedLockingDaprOptions.StoreName 在dapr component文件中定义的metadata name,默认: lockstore; |
|||
* AbpDistributedLockingDaprOptions.ResourceId 自定义一个资源名称,用于向dapr提供锁定的标识,默认: dapr-lock-id; |
|||
* AbpDistributedLockingDaprOptions.DefaultTimeout 默认锁定超时时间,默认: 30s. |
|||
|
|||
|
|||
## 其他 |
|||
Loading…
Reference in new issue