Skip to content

Commit 56d3eab

Browse files
authored
chore : Do not block async context on acquire lock (#1188)
Signed-off-by: Andre Hofmeister <9199345+HofmeisterAn@users.noreply.github.com>
1 parent 66bb577 commit 56d3eab

File tree

9 files changed

+60
-56
lines changed

9 files changed

+60
-56
lines changed

Directory.Packages.props

+1-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@
5757
<PackageVersion Include="MySqlConnector" Version="2.2.5"/>
5858
<PackageVersion Include="NATS.Client" Version="1.0.8"/>
5959
<PackageVersion Include="Neo4j.Driver" Version="5.5.0"/>
60-
<PackageVersion Include="Npgsql" Version="6.0.10"/>
60+
<PackageVersion Include="Npgsql" Version="6.0.11"/>
6161
<PackageVersion Include="Oracle.ManagedDataAccess.Core" Version="3.21.90"/>
6262
<PackageVersion Include="RabbitMQ.Client" Version="6.4.0"/>
6363
<PackageVersion Include="RavenDB.Client" Version="5.4.100"/>

src/Testcontainers/Configurations/WaitStrategies/RetryLimitExceededException.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
namespace DotNet.Testcontainers.Configurations
1+
namespace DotNet.Testcontainers.Configurations
22
{
33
using System;
44

src/Testcontainers/Containers/DockerContainer.cs

+21-20
Original file line numberDiff line numberDiff line change
@@ -261,34 +261,34 @@ public Task<long> GetExitCodeAsync(CancellationToken ct = default)
261261
/// <inheritdoc />
262262
public virtual async Task StartAsync(CancellationToken ct = default)
263263
{
264-
using (_ = AcquireLock())
265-
{
266-
var futureResources = Array.Empty<IFutureResource>()
267-
.Concat(_configuration.Mounts)
268-
.Concat(_configuration.Networks);
264+
using var disposable = await AcquireLockAsync(ct)
265+
.ConfigureAwait(false);
269266

270-
await Task.WhenAll(futureResources.Select(resource => resource.CreateAsync(ct)))
271-
.ConfigureAwait(false);
267+
var futureResources = Array.Empty<IFutureResource>()
268+
.Concat(_configuration.Mounts)
269+
.Concat(_configuration.Networks);
272270

273-
await Task.WhenAll(_configuration.Containers.Select(resource => resource.StartAsync(ct)))
274-
.ConfigureAwait(false);
271+
await Task.WhenAll(futureResources.Select(resource => resource.CreateAsync(ct)))
272+
.ConfigureAwait(false);
275273

276-
await UnsafeCreateAsync(ct)
277-
.ConfigureAwait(false);
274+
await Task.WhenAll(_configuration.Containers.Select(resource => resource.StartAsync(ct)))
275+
.ConfigureAwait(false);
278276

279-
await UnsafeStartAsync(ct)
280-
.ConfigureAwait(false);
281-
}
277+
await UnsafeCreateAsync(ct)
278+
.ConfigureAwait(false);
279+
280+
await UnsafeStartAsync(ct)
281+
.ConfigureAwait(false);
282282
}
283283

284284
/// <inheritdoc />
285285
public virtual async Task StopAsync(CancellationToken ct = default)
286286
{
287-
using (_ = AcquireLock())
288-
{
289-
await UnsafeStopAsync(ct)
290-
.ConfigureAwait(false);
291-
}
287+
using var disposable = await AcquireLockAsync(ct)
288+
.ConfigureAwait(false);
289+
290+
await UnsafeStopAsync(ct)
291+
.ConfigureAwait(false);
292292
}
293293

294294
/// <inheritdoc />
@@ -344,7 +344,8 @@ protected override async ValueTask DisposeAsyncCore()
344344
return;
345345
}
346346

347-
using (_ = AcquireLock())
347+
using (_ = await AcquireLockAsync()
348+
.ConfigureAwait(false))
348349
{
349350
if (Guid.Empty.Equals(_configuration.SessionId))
350351
{

src/Testcontainers/Images/FutureDockerImage.cs

+10-10
Original file line numberDiff line numberDiff line change
@@ -77,21 +77,21 @@ public string GetHostname()
7777
/// <inheritdoc />
7878
public async Task CreateAsync(CancellationToken ct = default)
7979
{
80-
using (_ = AcquireLock())
81-
{
82-
await UnsafeCreateAsync(ct)
83-
.ConfigureAwait(false);
84-
}
80+
using var disposable = await AcquireLockAsync(ct)
81+
.ConfigureAwait(false);
82+
83+
await UnsafeCreateAsync(ct)
84+
.ConfigureAwait(false);
8585
}
8686

8787
/// <inheritdoc />
8888
public async Task DeleteAsync(CancellationToken ct = default)
8989
{
90-
using (_ = AcquireLock())
91-
{
92-
await UnsafeDeleteAsync(ct)
93-
.ConfigureAwait(false);
94-
}
90+
using var disposable = await AcquireLockAsync(ct)
91+
.ConfigureAwait(false);
92+
93+
await UnsafeDeleteAsync(ct)
94+
.ConfigureAwait(false);
9595
}
9696

9797
/// <inheritdoc />

src/Testcontainers/Networks/DockerNetwork.cs

+10-10
Original file line numberDiff line numberDiff line change
@@ -43,21 +43,21 @@ public string Name
4343
/// <inheritdoc />
4444
public async Task CreateAsync(CancellationToken ct = default)
4545
{
46-
using (_ = AcquireLock())
47-
{
48-
await UnsafeCreateAsync(ct)
49-
.ConfigureAwait(false);
50-
}
46+
using var disposable = await AcquireLockAsync(ct)
47+
.ConfigureAwait(false);
48+
49+
await UnsafeCreateAsync(ct)
50+
.ConfigureAwait(false);
5151
}
5252

5353
/// <inheritdoc />
5454
public async Task DeleteAsync(CancellationToken ct = default)
5555
{
56-
using (_ = AcquireLock())
57-
{
58-
await UnsafeDeleteAsync(ct)
59-
.ConfigureAwait(false);
60-
}
56+
using var disposable = await AcquireLockAsync(ct)
57+
.ConfigureAwait(false);
58+
59+
await UnsafeDeleteAsync(ct)
60+
.ConfigureAwait(false);
6161
}
6262

6363
/// <inheritdoc />

src/Testcontainers/Resource.cs

+5-3
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,12 @@ protected virtual ValueTask DisposeAsyncCore()
6060
/// <summary>
6161
/// Acquires a lock to access the resource thread-safe.
6262
/// </summary>
63-
/// <returns>An <see cref="IDisposable" /> that releases the lock on <see cref="IDisposable.Dispose" />.</returns>
64-
protected virtual IDisposable AcquireLock()
63+
/// <returns>A <see cref="IDisposable" /> that releases the lock on <see cref="IDisposable.Dispose" />.</returns>
64+
protected virtual async Task<IDisposable> AcquireLockAsync(CancellationToken ct = default)
6565
{
66+
await _semaphoreSlim.WaitAsync(ct)
67+
.ConfigureAwait(false);
68+
6669
return new Lock(_semaphoreSlim);
6770
}
6871

@@ -102,7 +105,6 @@ private sealed class Lock : IDisposable
102105
public Lock(SemaphoreSlim semaphoreSlim)
103106
{
104107
_semaphoreSlim = semaphoreSlim;
105-
_semaphoreSlim.Wait();
106108
}
107109

108110
public void Dispose()

src/Testcontainers/Testcontainers.csproj

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
33
<TargetFrameworks>net6.0;net8.0;netstandard2.0;netstandard2.1</TargetFrameworks>
4+
<LangVersion>latest</LangVersion>
45
<Configurations>Debug;Release</Configurations>
56
<RootNamespace>DotNet.Testcontainers</RootNamespace>
67
</PropertyGroup>

src/Testcontainers/Volumes/DockerVolume.cs

+10-10
Original file line numberDiff line numberDiff line change
@@ -43,21 +43,21 @@ public string Name
4343
/// <inheritdoc />
4444
public async Task CreateAsync(CancellationToken ct = default)
4545
{
46-
using (_ = AcquireLock())
47-
{
48-
await UnsafeCreateAsync(ct)
49-
.ConfigureAwait(false);
50-
}
46+
using var disposable = await AcquireLockAsync(ct)
47+
.ConfigureAwait(false);
48+
49+
await UnsafeCreateAsync(ct)
50+
.ConfigureAwait(false);
5151
}
5252

5353
/// <inheritdoc />
5454
public async Task DeleteAsync(CancellationToken ct = default)
5555
{
56-
using (_ = AcquireLock())
57-
{
58-
await UnsafeDeleteAsync(ct)
59-
.ConfigureAwait(false);
60-
}
56+
using var disposable = await AcquireLockAsync(ct)
57+
.ConfigureAwait(false);
58+
59+
await UnsafeDeleteAsync(ct)
60+
.ConfigureAwait(false);
6161
}
6262

6363
/// <inheritdoc />

tests/Testcontainers.Platform.Linux.Tests/WaitStrategyTest.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
namespace Testcontainers.Tests;
1+
namespace Testcontainers.Tests;
22

33
public sealed class WaitStrategyTest
44
{

0 commit comments

Comments
 (0)