Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 12 additions & 18 deletions src/NATS.Client.Core/Commands/CommandWriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -725,7 +725,7 @@ private async ValueTask ConnectStateMachineAsync(bool lockHeld, ClientOpts conne
{
if (!await _semLock.WaitAsync(_defaultCommandTimeout, cancellationToken).ConfigureAwait(false))
{
throw new OperationCanceledException();
NatsTimeoutException.Throw();
}
}

Expand All @@ -747,8 +747,7 @@ private async ValueTask ConnectStateMachineAsync(bool lockHeld, ClientOpts conne
catch (TimeoutException)
{
// WaitAsync throws a TimeoutException when the TimeSpan is exceeded
// standardize to an OperationCanceledException as if a cancellationToken was used
throw new OperationCanceledException();
NatsTimeoutException.Throw();
}
finally
{
Expand All @@ -762,7 +761,7 @@ private async ValueTask PingStateMachineAsync(bool lockHeld, PingCommand pingCom
{
if (!await _semLock.WaitAsync(_defaultCommandTimeout, cancellationToken).ConfigureAwait(false))
{
throw new OperationCanceledException();
NatsTimeoutException.Throw();
}
}

Expand All @@ -785,8 +784,7 @@ private async ValueTask PingStateMachineAsync(bool lockHeld, PingCommand pingCom
catch (TimeoutException)
{
// WaitAsync throws a TimeoutException when the TimeSpan is exceeded
// standardize to an OperationCanceledException as if a cancellationToken was used
throw new OperationCanceledException();
NatsTimeoutException.Throw();
}
finally
{
Expand All @@ -800,7 +798,7 @@ private async ValueTask PongStateMachineAsync(bool lockHeld, CancellationToken c
{
if (!await _semLock.WaitAsync(_defaultCommandTimeout, cancellationToken).ConfigureAwait(false))
{
throw new OperationCanceledException();
NatsTimeoutException.Throw();
}
}

Expand All @@ -822,8 +820,7 @@ private async ValueTask PongStateMachineAsync(bool lockHeld, CancellationToken c
catch (TimeoutException)
{
// WaitAsync throws a TimeoutException when the TimeSpan is exceeded
// standardize to an OperationCanceledException as if a cancellationToken was used
throw new OperationCanceledException();
NatsTimeoutException.Throw();
}
finally
{
Expand All @@ -842,7 +839,7 @@ private async ValueTask PublishStateMachineAsync(bool lockHeld, string subject,
{
if (!await _semLock.WaitAsync(_defaultCommandTimeout, cancellationToken).ConfigureAwait(false))
{
throw new OperationCanceledException();
NatsTimeoutException.Throw();
}
}

Expand All @@ -864,8 +861,7 @@ private async ValueTask PublishStateMachineAsync(bool lockHeld, string subject,
catch (TimeoutException)
{
// WaitAsync throws a TimeoutException when the TimeSpan is exceeded
// standardize to an OperationCanceledException as if a cancellationToken was used
throw new OperationCanceledException();
NatsTimeoutException.Throw();
}
finally
{
Expand All @@ -891,7 +887,7 @@ private async ValueTask SubscribeStateMachineAsync(bool lockHeld, int sid, strin
{
if (!await _semLock.WaitAsync(_defaultCommandTimeout, cancellationToken).ConfigureAwait(false))
{
throw new OperationCanceledException();
NatsTimeoutException.Throw();
}
}

Expand All @@ -913,8 +909,7 @@ private async ValueTask SubscribeStateMachineAsync(bool lockHeld, int sid, strin
catch (TimeoutException)
{
// WaitAsync throws a TimeoutException when the TimeSpan is exceeded
// standardize to an OperationCanceledException as if a cancellationToken was used
throw new OperationCanceledException();
NatsTimeoutException.Throw();
}
finally
{
Expand All @@ -928,7 +923,7 @@ private async ValueTask UnsubscribeStateMachineAsync(bool lockHeld, int sid, int
{
if (!await _semLock.WaitAsync(_defaultCommandTimeout, cancellationToken).ConfigureAwait(false))
{
throw new OperationCanceledException();
NatsTimeoutException.Throw();
}
}

Expand All @@ -950,8 +945,7 @@ private async ValueTask UnsubscribeStateMachineAsync(bool lockHeld, int sid, int
catch (TimeoutException)
{
// WaitAsync throws a TimeoutException when the TimeSpan is exceeded
// standardize to an OperationCanceledException as if a cancellationToken was used
throw new OperationCanceledException();
NatsTimeoutException.Throw();
}
finally
{
Expand Down
7 changes: 7 additions & 0 deletions src/NATS.Client.Core/NatsException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,10 @@ public NatsPayloadTooLargeException(string error)
}

public sealed class NatsConnectionFailedException(string message) : NatsException(message);

public sealed class NatsTimeoutException() : NatsException("Operation timed out")
{
[DoesNotReturn]
[MethodImpl(MethodImplOptions.NoInlining)]
public static void Throw() => throw new NatsTimeoutException();
}
8 changes: 4 additions & 4 deletions tests/NATS.Client.Core2.Tests/CancellationTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@ public async Task CommandTimeoutTest()
var stopToken = new CancellationTokenSource(TimeSpan.FromSeconds(10));
var stallTask = conn.CommandWriter.TestStallFlushAsync(TimeSpan.FromSeconds(10), stopToken.Token);

// commands that call ConnectAsync throw OperationCanceledException
await Assert.ThrowsAsync<OperationCanceledException>(() => conn.PingAsync(cancellationToken).AsTask());
await Assert.ThrowsAsync<OperationCanceledException>(() => conn.PublishAsync("test", cancellationToken: cancellationToken).AsTask());
await Assert.ThrowsAsync<OperationCanceledException>(async () =>
// commands that call ConnectAsync throw NatsTimeoutException
await Assert.ThrowsAsync<NatsTimeoutException>(() => conn.PingAsync(cancellationToken).AsTask());
await Assert.ThrowsAsync<NatsTimeoutException>(() => conn.PublishAsync("test", cancellationToken: cancellationToken).AsTask());
await Assert.ThrowsAsync<NatsTimeoutException>(async () =>
{
await foreach (var unused in conn.SubscribeAsync<string>("test", cancellationToken: cancellationToken))
{
Expand Down
Loading