Skip to content

Commit 22d7408

Browse files
committed
Introduce Volo.Abp.DistributedLocking.Abstractions package abpframework#10032
1 parent 92c8aa5 commit 22d7408

16 files changed

+286
-1
lines changed

framework/Volo.Abp.sln

+16
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,7 @@ EndProject
372372
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.AzureServiceBus", "src\Volo.Abp.AzureServiceBus\Volo.Abp.AzureServiceBus.csproj", "{808EC18E-C8CC-4F5C-82B6-984EADBBF85D}"
373373
EndProject
374374
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.EventBus.Azure", "src\Volo.Abp.EventBus.Azure\Volo.Abp.EventBus.Azure.csproj", "{FB27F78E-F10E-4810-9B8E-BCD67DCFC8A2}"
375+
EndProject
375376
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Authorization.Abstractions", "src\Volo.Abp.Authorization.Abstractions\Volo.Abp.Authorization.Abstractions.csproj", "{87B0C2A8-FE95-4779-8B9C-2181AA52B3FA}"
376377
EndProject
377378
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.TextTemplating.Core", "src\Volo.Abp.TextTemplating.Core\Volo.Abp.TextTemplating.Core.csproj", "{184E859A-282D-44D7-B8E9-FEA874644013}"
@@ -393,10 +394,15 @@ EndProject
393394
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.EventBus.Boxes", "src\Volo.Abp.EventBus.Boxes\Volo.Abp.EventBus.Boxes.csproj", "{6E289F31-7924-418B-9DAC-62A7CFADF916}"
394395
EndProject
395396
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.DistributedLocking", "src\Volo.Abp.DistributedLocking\Volo.Abp.DistributedLocking.csproj", "{9A7EEA08-15BE-476D-8168-53039867038E}"
397+
EndProject
396398
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Auditing.Contracts", "src\Volo.Abp.Auditing.Contracts\Volo.Abp.Auditing.Contracts.csproj", "{508B6355-AD28-4E60-8549-266D21DBF2CF}"
397399
EndProject
398400
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.Http.Client.Web", "src\Volo.Abp.Http.Client.Web\Volo.Abp.Http.Client.Web.csproj", "{F7407459-8AFA-45E4-83E9-9BB01412CC08}"
399401
EndProject
402+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.DistributedLocking.Abstractions", "src\Volo.Abp.DistributedLocking.Abstractions\Volo.Abp.DistributedLocking.Abstractions.csproj", "{CA805B77-D50C-431F-B3CB-1111C9C6E807}"
403+
EndProject
404+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.DistributedLocking.Abstractions.Tests", "test\Volo.Abp.DistributedLocking.Abstractions.Tests\Volo.Abp.DistributedLocking.Abstractions.Tests.csproj", "{C4F54FB5-C828-414D-BA03-E8E7A10C784D}"
405+
EndProject
400406
Global
401407
GlobalSection(SolutionConfigurationPlatforms) = preSolution
402408
Debug|Any CPU = Debug|Any CPU
@@ -1187,6 +1193,14 @@ Global
11871193
{F7407459-8AFA-45E4-83E9-9BB01412CC08}.Debug|Any CPU.Build.0 = Debug|Any CPU
11881194
{F7407459-8AFA-45E4-83E9-9BB01412CC08}.Release|Any CPU.ActiveCfg = Release|Any CPU
11891195
{F7407459-8AFA-45E4-83E9-9BB01412CC08}.Release|Any CPU.Build.0 = Release|Any CPU
1196+
{CA805B77-D50C-431F-B3CB-1111C9C6E807}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
1197+
{CA805B77-D50C-431F-B3CB-1111C9C6E807}.Debug|Any CPU.Build.0 = Debug|Any CPU
1198+
{CA805B77-D50C-431F-B3CB-1111C9C6E807}.Release|Any CPU.ActiveCfg = Release|Any CPU
1199+
{CA805B77-D50C-431F-B3CB-1111C9C6E807}.Release|Any CPU.Build.0 = Release|Any CPU
1200+
{C4F54FB5-C828-414D-BA03-E8E7A10C784D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
1201+
{C4F54FB5-C828-414D-BA03-E8E7A10C784D}.Debug|Any CPU.Build.0 = Debug|Any CPU
1202+
{C4F54FB5-C828-414D-BA03-E8E7A10C784D}.Release|Any CPU.ActiveCfg = Release|Any CPU
1203+
{C4F54FB5-C828-414D-BA03-E8E7A10C784D}.Release|Any CPU.Build.0 = Release|Any CPU
11901204
EndGlobalSection
11911205
GlobalSection(SolutionProperties) = preSolution
11921206
HideSolutionNode = FALSE
@@ -1388,6 +1402,8 @@ Global
13881402
{9A7EEA08-15BE-476D-8168-53039867038E} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
13891403
{508B6355-AD28-4E60-8549-266D21DBF2CF} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
13901404
{F7407459-8AFA-45E4-83E9-9BB01412CC08} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
1405+
{CA805B77-D50C-431F-B3CB-1111C9C6E807} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6}
1406+
{C4F54FB5-C828-414D-BA03-E8E7A10C784D} = {447C8A77-E5F0-4538-8687-7383196D04EA}
13911407
EndGlobalSection
13921408
GlobalSection(ExtensibilityGlobals) = postSolution
13931409
SolutionGuid = {BB97ECF4-9A84-433F-A80B-2A3285BDD1D5}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
2+
<ConfigureAwait ContinueOnCapturedContext="false" />
3+
</Weavers>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
3+
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
4+
<xs:element name="Weavers">
5+
<xs:complexType>
6+
<xs:all>
7+
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
8+
<xs:complexType>
9+
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
10+
</xs:complexType>
11+
</xs:element>
12+
</xs:all>
13+
<xs:attribute name="VerifyAssembly" type="xs:boolean">
14+
<xs:annotation>
15+
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
16+
</xs:annotation>
17+
</xs:attribute>
18+
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
19+
<xs:annotation>
20+
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
21+
</xs:annotation>
22+
</xs:attribute>
23+
<xs:attribute name="GenerateXsd" type="xs:boolean">
24+
<xs:annotation>
25+
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
26+
</xs:annotation>
27+
</xs:attribute>
28+
</xs:complexType>
29+
</xs:element>
30+
</xs:schema>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<Import Project="..\..\..\configureawait.props" />
4+
<Import Project="..\..\..\common.props" />
5+
6+
<PropertyGroup>
7+
<TargetFramework>netstandard2.0</TargetFramework>
8+
<AssemblyName>Volo.Abp.DistributedLocking.Abstractions</AssemblyName>
9+
<PackageId>Volo.Abp.DistributedLocking.Abstractions</PackageId>
10+
<AssetTargetFallback>$(AssetTargetFallback);portable-net45+win8+wp8+wpa81;</AssetTargetFallback>
11+
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
12+
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
13+
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
14+
<RootNamespace />
15+
</PropertyGroup>
16+
17+
<ItemGroup>
18+
<ProjectReference Include="..\Volo.Abp.Core\Volo.Abp.Core.csproj" />
19+
</ItemGroup>
20+
21+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
using Volo.Abp.Modularity;
2+
3+
namespace Volo.Abp.DistributedLocking
4+
{
5+
public class AbpDistributedLockingAbstractionsModule : AbpModule
6+
{
7+
8+
}
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
using System;
2+
using System.Threading;
3+
using System.Threading.Tasks;
4+
using JetBrains.Annotations;
5+
6+
namespace Volo.Abp.DistributedLocking
7+
{
8+
public interface IAbpDistributedLock
9+
{
10+
/// <summary>
11+
/// Tries to acquire a named lock.
12+
/// Returns a disposable object to release the lock.
13+
/// It is suggested to use this method within a using block.
14+
/// Returns null if the lock could not be handled.
15+
/// </summary>
16+
/// <param name="name">The name of the lock</param>
17+
/// <param name="timeout">Timeout value</param>
18+
/// <param name="cancellationToken">Cancellation token</param>
19+
[ItemCanBeNull]
20+
Task<IAbpDistributedLockHandle> TryAcquireAsync(
21+
string name,
22+
TimeSpan timeout = default,
23+
CancellationToken cancellationToken = default
24+
);
25+
}
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
using System;
2+
3+
namespace Volo.Abp.DistributedLocking
4+
{
5+
public interface IAbpDistributedLockHandle : IAsyncDisposable
6+
{
7+
8+
}
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using System;
2+
using System.Collections.Concurrent;
3+
using System.Threading;
4+
using System.Threading.Tasks;
5+
using Volo.Abp.DependencyInjection;
6+
7+
namespace Volo.Abp.DistributedLocking
8+
{
9+
public class LocalAbpDistributedLock : IAbpDistributedLock, ISingletonDependency
10+
{
11+
private readonly ConcurrentDictionary<string, SemaphoreSlim> _localSyncObjects = new();
12+
13+
public async Task<IAbpDistributedLockHandle> TryAcquireAsync(
14+
string name,
15+
TimeSpan timeout = default,
16+
CancellationToken cancellationToken = default)
17+
{
18+
var semaphore = _localSyncObjects.GetOrAdd(name, _ => new SemaphoreSlim(1, 1));
19+
20+
if (!await semaphore.WaitAsync(timeout, cancellationToken))
21+
{
22+
return null;
23+
}
24+
25+
return new LocalAbpDistributedLockHandle(semaphore);
26+
}
27+
}
28+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using System.Threading;
2+
using System.Threading.Tasks;
3+
4+
namespace Volo.Abp.DistributedLocking
5+
{
6+
public class LocalAbpDistributedLockHandle : IAbpDistributedLockHandle
7+
{
8+
private readonly SemaphoreSlim _semaphore;
9+
10+
public LocalAbpDistributedLockHandle(SemaphoreSlim semaphore)
11+
{
12+
_semaphore = semaphore;
13+
}
14+
15+
public ValueTask DisposeAsync()
16+
{
17+
_semaphore.Release();
18+
return default;
19+
}
20+
}
21+
}

framework/src/Volo.Abp.DistributedLocking/Volo.Abp.DistributedLocking.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
</PropertyGroup>
1616

1717
<ItemGroup>
18-
<ProjectReference Include="..\Volo.Abp.Core\Volo.Abp.Core.csproj" />
18+
<ProjectReference Include="..\Volo.Abp.DistributedLocking.Abstractions\Volo.Abp.DistributedLocking.Abstractions.csproj" />
1919
</ItemGroup>
2020

2121
<ItemGroup>

framework/src/Volo.Abp.DistributedLocking/Volo/Abp/DistributedLocking/AbpDistributedLockingModule.cs

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
namespace Volo.Abp.DistributedLocking
44
{
5+
[DependsOn(
6+
typeof(AbpDistributedLockingAbstractionsModule)
7+
)]
58
public class AbpDistributedLockingModule : AbpModule
69
{
710

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<Import Project="..\..\..\common.test.props" />
4+
5+
<PropertyGroup>
6+
<TargetFramework>net6.0</TargetFramework>
7+
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
8+
<RootNamespace />
9+
</PropertyGroup>
10+
11+
<ItemGroup>
12+
<ProjectReference Include="..\..\src\Volo.Abp.DistributedLocking.Abstractions\Volo.Abp.DistributedLocking.Abstractions.csproj" />
13+
<ProjectReference Include="..\AbpTestBase\AbpTestBase.csproj" />
14+
<ProjectReference Include="..\..\src\Volo.Abp.Autofac\Volo.Abp.Autofac.csproj" />
15+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(MicrosoftNETTestSdkPackageVersion)" />
16+
</ItemGroup>
17+
18+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using Volo.Abp.Testing;
2+
3+
namespace Volo.Abp.DistributedLocking
4+
{
5+
public class AbpDistributedLockingAbstractionsTestBase : AbpIntegratedTest<AbpDistributedLockingAbstractionsTestModule>
6+
{
7+
protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options)
8+
{
9+
options.UseAutofac();
10+
}
11+
}
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using Volo.Abp.Autofac;
2+
using Volo.Abp.Modularity;
3+
4+
namespace Volo.Abp.DistributedLocking
5+
{
6+
[DependsOn(
7+
typeof(AbpTestBaseModule),
8+
typeof(AbpDistributedLockingAbstractionsModule),
9+
typeof(AbpAutofacModule)
10+
)]
11+
public class AbpDistributedLockingAbstractionsTestModule : AbpModule
12+
{
13+
14+
}
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
using System.Threading.Tasks;
2+
using Shouldly;
3+
using Xunit;
4+
5+
namespace Volo.Abp.DistributedLocking
6+
{
7+
public class LocalDistributedLock_Tests : AbpDistributedLockingAbstractionsTestBase
8+
{
9+
private readonly IAbpDistributedLock _distributedLock;
10+
11+
public LocalDistributedLock_Tests()
12+
{
13+
_distributedLock = GetRequiredService<IAbpDistributedLock>();
14+
}
15+
16+
[Fact]
17+
public void Should_Be_Instance_Of_LocalAbpDistributedLock()
18+
{
19+
_distributedLock.ShouldBeOfType<LocalAbpDistributedLock>();
20+
}
21+
22+
[Fact]
23+
public async Task Should_Lock_With_TryAcquire()
24+
{
25+
await using (var handle = await _distributedLock.TryAcquireAsync("lock1"))
26+
{
27+
handle.ShouldNotBeNull();
28+
}
29+
}
30+
31+
[Fact]
32+
public async Task Should_Not_Acquire_If_Already_Locked()
33+
{
34+
await using (var handle = await _distributedLock.TryAcquireAsync("lock1"))
35+
{
36+
handle.ShouldNotBeNull();
37+
38+
await Task.Run(async () =>
39+
{
40+
await using (var handle2 = await _distributedLock.TryAcquireAsync("lock1"))
41+
{
42+
handle2.ShouldBeNull();
43+
}
44+
});
45+
}
46+
47+
await Task.Run(async () =>
48+
{
49+
await using (var handle = await _distributedLock.TryAcquireAsync("lock1"))
50+
{
51+
handle.ShouldNotBeNull();
52+
}
53+
});
54+
}
55+
56+
[Fact]
57+
public async Task Should_Obtain_Multiple_Locks()
58+
{
59+
await using (var handle = await _distributedLock.TryAcquireAsync("lock1"))
60+
{
61+
handle.ShouldNotBeNull();
62+
63+
await Task.Run(async () =>
64+
{
65+
await using (var handle2 = await _distributedLock.TryAcquireAsync("lock2"))
66+
{
67+
handle2.ShouldNotBeNull();
68+
}
69+
});
70+
}
71+
}
72+
}
73+
}

nupkg/common.ps1

+1
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ $projects = (
9292
"framework/src/Volo.Abp.Ddd.Application",
9393
"framework/src/Volo.Abp.Ddd.Application.Contracts",
9494
"framework/src/Volo.Abp.Ddd.Domain",
95+
"framework/src/Volo.Abp.DistributedLocking.Abstractions",
9596
"framework/src/Volo.Abp.DistributedLocking",
9697
"framework/src/Volo.Abp.Emailing",
9798
"framework/src/Volo.Abp.EntityFrameworkCore",

0 commit comments

Comments
 (0)