Skip to content

Commit

Permalink
6.2.2 — Fixed potential unnecessary slowdown.
Browse files Browse the repository at this point in the history
  • Loading branch information
MarkCiliaVincenti committed Oct 9, 2023
1 parent 370b23d commit c23365b
Show file tree
Hide file tree
Showing 6 changed files with 32 additions and 33 deletions.
8 changes: 4 additions & 4 deletions AsyncKeyedLock.Tests/AsyncKeyedLock.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.11.0" />
<PackageReference Include="FluentAssertions" Version="6.12.0" />
<PackageReference Include="ListShuffle" Version="1.1.5" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.0" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.7.2" />
<PackageReference Include="xunit" Version="2.5.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.5.1">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
Expand Down
5 changes: 2 additions & 3 deletions AsyncKeyedLock.Tests/StripedAsyncKeyedLocker/OriginalTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using ListShuffle;
using System.Collections.Concurrent;
using System.Threading.Tasks;
using Xunit;

namespace AsyncKeyedLock.Tests.StripedAsyncKeyedLocker
Expand Down Expand Up @@ -180,7 +179,7 @@ public async Task BenchmarkSimulationTest()
{
var key = i % NumberOfLocks;

using (var myLock = await AsyncKeyedLocker.LockAsync(key.ToString()).ConfigureAwait(false))
using (var myLock = await AsyncKeyedLocker.LockAsync(key.ToString()))
{
for (int j = 0; j < GuidReversals; j++)
{
Expand All @@ -199,7 +198,7 @@ public async Task BenchmarkSimulationTest()
await Task.Yield();
}).AsParallel();

await Task.WhenAll(AsyncKeyedLockerTasks).ConfigureAwait(false);
await Task.WhenAll(AsyncKeyedLockerTasks);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@ public async Task ShouldRunThreadsWithDistinctKeysInParallel()

// 100 threads, 100 keys
var threads = Enumerable.Range(0, 100)
.Select(i => Task.Run(async () => await OccupyTheLockALittleBit(i).ConfigureAwait(false)))
.Select(i => Task.Run(async () => await OccupyTheLockALittleBit(i)))
.ToList();

// Act
await Task.WhenAll(threads).ConfigureAwait(false);
await Task.WhenAll(threads);

maxParallelism.Should().BeGreaterThan(10);

Expand All @@ -44,7 +44,7 @@ async Task OccupyTheLockALittleBit(int key)

const int delay = 250;

await Task.Delay(TimeSpan.FromMilliseconds(delay)).ConfigureAwait(false);
await Task.Delay(TimeSpan.FromMilliseconds(delay));

Interlocked.Decrement(ref currentParallelism);
}
Expand All @@ -62,11 +62,11 @@ public async Task ShouldRunThreadsWithSameKeysLinearly()

// 100 threads, 10 keys
var threads = Enumerable.Range(0, 100)
.Select(i => Task.Run(async () => await OccupyTheLockALittleBit(i % 10).ConfigureAwait(false)))
.Select(i => Task.Run(async () => await OccupyTheLockALittleBit(i % 10)))
.ToList();

// Act + Assert
await Task.WhenAll(threads).ConfigureAwait(false);
await Task.WhenAll(threads);

maxParallelism.Should().BeLessOrEqualTo(10);

Expand All @@ -93,7 +93,7 @@ async Task OccupyTheLockALittleBit(int key)

const int delay = 10;

await Task.Delay(TimeSpan.FromMilliseconds(delay)).ConfigureAwait(false);
await Task.Delay(TimeSpan.FromMilliseconds(delay));

if (!runningTasksIndex.TryRemove(key, out var value))
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ public async Task ShouldRunThreadsWithDistinctKeysInParallel()

// 100 threads, 100 keys
var threads = Enumerable.Range(0, 100)
.Select(i => Task.Run(async () => await OccupyTheLockALittleBit(i).ConfigureAwait(false)))
.Select(i => Task.Run(async () => await OccupyTheLockALittleBit(i)))
.ToList();

// Act
await Task.WhenAll(threads).ConfigureAwait(false);
await Task.WhenAll(threads);

maxParallelism.Should().BeGreaterThan(10);
foreach (var key in Enumerable.Range(0, 100))
Expand All @@ -46,7 +46,7 @@ async Task OccupyTheLockALittleBit(int key)
const int delay = 250;


await Task.Delay(TimeSpan.FromMilliseconds(delay)).ConfigureAwait(false);
await Task.Delay(TimeSpan.FromMilliseconds(delay));

Interlocked.Decrement(ref currentParallelism);
}
Expand All @@ -65,11 +65,11 @@ public async Task ShouldRunThreadsWithSameKeysLinearly()

// 100 threads, 10 keys
var threads = Enumerable.Range(0, 100)
.Select(i => Task.Run(async () => await OccupyTheLockALittleBit(i % 10).ConfigureAwait(false)))
.Select(i => Task.Run(async () => await OccupyTheLockALittleBit(i % 10)))
.ToList();

// Act + Assert
await Task.WhenAll(threads).ConfigureAwait(false);
await Task.WhenAll(threads);

maxParallelism.Should().BeLessOrEqualTo(10);
foreach (var key in Enumerable.Range(0, 100))
Expand Down Expand Up @@ -99,7 +99,7 @@ async Task OccupyTheLockALittleBit(int key)

const int delay = 10;

await Task.Delay(TimeSpan.FromMilliseconds(delay)).ConfigureAwait(false);
await Task.Delay(TimeSpan.FromMilliseconds(delay));

if (!runningTasksIndex.TryRemove(key, out var value))
{
Expand Down Expand Up @@ -135,11 +135,11 @@ public async Task ShouldNeverCreateTwoSemaphoresForTheSameKey()

// Many threads, 1 key
var threads = Enumerable.Range(0, 100)
.Select(_ => Task.Run(async () => await OccupyTheLockALittleBit(1).ConfigureAwait(false)))
.Select(_ => Task.Run(async () => await OccupyTheLockALittleBit(1)))
.ToList();

// Act + Assert
await Task.WhenAll(threads).ConfigureAwait(false);
await Task.WhenAll(threads);

maxParallelism.Should().Be(1);
stripedAyncKeyedLocks.IsInUse(1).Should().BeFalse();
Expand All @@ -150,7 +150,7 @@ async Task OccupyTheLockALittleBit(int key)
var currentTaskId = Task.CurrentId ?? -1;
var delay = random.Next(500);

await Task.Delay(delay).ConfigureAwait(false);
await Task.Delay(delay);

using (await stripedAyncKeyedLocks.LockAsync(key))
{
Expand Down Expand Up @@ -201,11 +201,11 @@ public async Task ShouldRunThreadsWithDistinctStringKeysInParallel()

// 100 threads, 100 keys
var threads = Enumerable.Range(0, 100)
.Select(i => Task.Run(async () => await OccupyTheLockALittleBit(i).ConfigureAwait(false)))
.Select(i => Task.Run(async () => await OccupyTheLockALittleBit(i)))
.ToList();

// Act
await Task.WhenAll(threads).ConfigureAwait(false);
await Task.WhenAll(threads);

maxParallelism.Should().BeGreaterThan(10);
foreach (var key in Enumerable.Range(0, 100))
Expand All @@ -226,7 +226,7 @@ async Task OccupyTheLockALittleBit(int key)

const int delay = 250;

await Task.Delay(TimeSpan.FromMilliseconds(delay)).ConfigureAwait(false);
await Task.Delay(TimeSpan.FromMilliseconds(delay));

Interlocked.Decrement(ref currentParallelism);
}
Expand All @@ -241,11 +241,11 @@ public async Task IsInUseShouldReturnTrueWhenLockedAndFalseWhenNotLocked()

// 10 threads, 10 keys
var threads = Enumerable.Range(0, 10)
.Select(i => Task.Run(async () => await OccupyTheLockALittleBit(i).ConfigureAwait(false)))
.Select(i => Task.Run(async () => await OccupyTheLockALittleBit(i)))
.ToList();

// Act
await Task.WhenAll(threads).ConfigureAwait(false);
await Task.WhenAll(threads);
foreach (var key in Enumerable.Range(0, 10))
{
stripedAyncKeyedLocks.IsInUse(key).Should().BeFalse();
Expand All @@ -259,7 +259,7 @@ async Task OccupyTheLockALittleBit(int key)
{
const int delay = 250;

await Task.Delay(TimeSpan.FromMilliseconds(delay)).ConfigureAwait(false);
await Task.Delay(TimeSpan.FromMilliseconds(delay));

stripedAyncKeyedLocks.IsInUse(key).Should().BeTrue();
}
Expand Down
8 changes: 4 additions & 4 deletions AsyncKeyedLock/AsyncKeyedLock.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@
<PackageProjectUrl>https://github.com/MarkCiliaVincenti/AsyncKeyedLock</PackageProjectUrl>
<Copyright>MIT</Copyright>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<Version>6.2.1</Version>
<Version>6.2.2</Version>
<PackageIcon>logo.png</PackageIcon>
<PackageReleaseNotes>Implemented IDisposable.</PackageReleaseNotes>
<PackageReleaseNotes>Fixed potential unnecessary slowdown.</PackageReleaseNotes>
<Description>An asynchronous .NET Standard 2.0 library that allows you to lock based on a key (keyed semaphores), limiting concurrent threads sharing the same key to a specified number, with optional pooling for reducing memory allocations.</Description>
<Copyright>© 2023 Mark Cilia Vincenti</Copyright>
<PackageTags>async,lock,key,keyed,semaphore,striped,dictionary,concurrentdictionary,pooling,duplicate,synchronization</PackageTags>
<RepositoryType>git</RepositoryType>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<AssemblyVersion>6.2.1.0</AssemblyVersion>
<FileVersion>6.2.1.0</FileVersion>
<AssemblyVersion>6.2.2.0</AssemblyVersion>
<FileVersion>6.2.2.0</FileVersion>
<PackageReadmeFile>README.md</PackageReadmeFile>
<IsPackable>true</IsPackable>
<IsTrimmable>true</IsTrimmable>
Expand Down
2 changes: 1 addition & 1 deletion AsyncKeyedLock/AsyncKeyedLockDictionary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public AsyncKeyedLockReleaser<TKey> GetOrAdd(TKey key)
}
if (releaser.TryIncrement(key))
{
releaser.IsNotInUse = true;
releaserToAdd.IsNotInUse = true;
_pool.PutObject(releaserToAdd);
return releaser;
}
Expand Down

0 comments on commit c23365b

Please sign in to comment.