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