diff --git a/build.ps1 b/build.ps1
index 2dbe9b0835..124320fdb8 100644
--- a/build.ps1
+++ b/build.ps1
@@ -23,7 +23,7 @@ if ($RunTests)
foreach ($csproj_file in $unit_csproj_file, $integration_csproj_file, $async_integration_csproj_file, $sequential_integration_csproj_file)
{
Write-Host "[INFO] running Unit / Integration tests from '$csproj_file' (all frameworks)" -ForegroundColor "Magenta"
- dotnet test $csproj_file --no-restore --no-build --logger "console;verbosity=detailed"
+ dotnet test $csproj_file --environment 'RABBITMQ_LONG_RUNNING_TESTS=true' --no-restore --no-build --logger "console;verbosity=detailed"
if ($LASTEXITCODE -ne 0)
{
Write-Host "[ERROR] tests errored, exiting" -Foreground "Red"
diff --git a/projects/Benchmarks/Benchmarks.csproj b/projects/Benchmarks/Benchmarks.csproj
index 19bfe18434..56a308e404 100644
--- a/projects/Benchmarks/Benchmarks.csproj
+++ b/projects/Benchmarks/Benchmarks.csproj
@@ -15,7 +15,7 @@
-
+
diff --git a/projects/Benchmarks/ConsumerDispatching/AsyncBasicConsumerFake.cs b/projects/Benchmarks/ConsumerDispatching/AsyncBasicConsumerFake.cs
index d9cf669f42..80c5fb9ce0 100644
--- a/projects/Benchmarks/ConsumerDispatching/AsyncBasicConsumerFake.cs
+++ b/projects/Benchmarks/ConsumerDispatching/AsyncBasicConsumerFake.cs
@@ -29,14 +29,15 @@ public AsyncBasicConsumerFake(ManualResetEventSlim autoResetEvent)
return Task.CompletedTask;
}
- void IBasicConsumer.HandleBasicDeliver(string consumerTag, ulong deliveryTag, bool redelivered, string exchange, string routingKey,
- in ReadOnlyBasicProperties properties, ReadOnlyMemory body)
+ Task IBasicConsumer.HandleBasicDeliverAsync(string consumerTag, ulong deliveryTag, bool redelivered, string exchange, string routingKey,
+ ReadOnlyBasicProperties properties, ReadOnlyMemory body)
{
if (Interlocked.Increment(ref _current) == Count)
{
_current = 0;
_autoResetEvent.Set();
}
+ return Task.CompletedTask;
}
public Task HandleBasicCancel(string consumerTag) => Task.CompletedTask;
diff --git a/projects/Benchmarks/Networking/Networking_BasicDeliver_Commons.cs b/projects/Benchmarks/Networking/Networking_BasicDeliver_Commons.cs
index 16a9f537cd..b4bb341ece 100644
--- a/projects/Benchmarks/Networking/Networking_BasicDeliver_Commons.cs
+++ b/projects/Benchmarks/Networking/Networking_BasicDeliver_Commons.cs
@@ -12,10 +12,10 @@ public class Networking_BasicDeliver_Commons
public static async Task Publish_Hello_World(IConnection connection, uint messageCount, byte[] body)
{
var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
- using (var channel = connection.CreateChannel())
+ using (IChannel channel = await connection.CreateChannelAsync())
{
- var queue = channel.QueueDeclare();
- var consumed = 0;
+ QueueDeclareOk queue = await channel.QueueDeclareAsync();
+ int consumed = 0;
var consumer = new EventingBasicConsumer(channel);
consumer.Received += (s, args) =>
{
@@ -24,14 +24,15 @@ public static async Task Publish_Hello_World(IConnection connection, uint messag
tcs.SetResult(true);
}
};
- channel.BasicConsume(queue.QueueName, true, consumer);
+ await channel.BasicConsumeAsync(queue.QueueName, true, consumer);
for (int i = 0; i < messageCount; i++)
{
- channel.BasicPublish("", queue.QueueName, body);
+ await channel.BasicPublishAsync("", queue.QueueName, body);
}
await tcs.Task;
+ await channel.CloseAsync();
}
}
}
diff --git a/projects/Benchmarks/Networking/Networking_BasicDeliver_ConnectionChurn.cs b/projects/Benchmarks/Networking/Networking_BasicDeliver_ConnectionChurn.cs
index b3003a3468..a2542b9037 100644
--- a/projects/Benchmarks/Networking/Networking_BasicDeliver_ConnectionChurn.cs
+++ b/projects/Benchmarks/Networking/Networking_BasicDeliver_ConnectionChurn.cs
@@ -30,7 +30,7 @@ public void GlobalCleanup()
public async Task Publish_Hello_World()
{
var cf = new ConnectionFactory { ConsumerDispatchConcurrency = 2 };
- using (var connection = cf.CreateConnection())
+ using (IConnection connection = await cf.CreateConnectionAsync())
{
await Publish_Hello_World(connection);
}
diff --git a/projects/Benchmarks/Networking/Networking_BasicDeliver_LongLivedConnection.cs b/projects/Benchmarks/Networking/Networking_BasicDeliver_LongLivedConnection.cs
index 6045382ee5..d60adbdc3d 100644
--- a/projects/Benchmarks/Networking/Networking_BasicDeliver_LongLivedConnection.cs
+++ b/projects/Benchmarks/Networking/Networking_BasicDeliver_LongLivedConnection.cs
@@ -21,7 +21,8 @@ public void GlobalSetup()
_container = RabbitMQBroker.Start();
var cf = new ConnectionFactory { ConsumerDispatchConcurrency = 2 };
- _connection = cf.CreateConnection();
+ // TODO / NOTE: https://github.com/dotnet/BenchmarkDotNet/issues/1738
+ _connection = cf.CreateConnectionAsync().EnsureCompleted();
}
[GlobalCleanup]
diff --git a/projects/RabbitMQ.Client.OAuth2/OAuth2Client.cs b/projects/RabbitMQ.Client.OAuth2/OAuth2Client.cs
index 9a8abb7ee5..ce93659a93 100644
--- a/projects/RabbitMQ.Client.OAuth2/OAuth2Client.cs
+++ b/projects/RabbitMQ.Client.OAuth2/OAuth2Client.cs
@@ -34,23 +34,22 @@
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Http.Json;
-using System.Text.Json.Serialization;
using System.Threading.Tasks;
namespace RabbitMQ.Client.OAuth2
{
public interface IOAuth2Client
{
- public IToken RequestToken();
- public IToken RefreshToken(IToken token);
+ IToken RequestToken();
+ IToken RefreshToken(IToken token);
}
public interface IToken
{
- public string AccessToken { get; }
- public string RefreshToken { get; }
- public TimeSpan ExpiresIn { get; }
- public bool hasExpired { get; }
+ string AccessToken { get; }
+ string RefreshToken { get; }
+ TimeSpan ExpiresIn { get; }
+ bool hasExpired { get; }
}
public class Token : IToken
diff --git a/projects/RabbitMQ.Client.OAuth2/RabbitMQ.Client.OAuth2.csproj b/projects/RabbitMQ.Client.OAuth2/RabbitMQ.Client.OAuth2.csproj
index 77f6d28b21..ce71a0075b 100644
--- a/projects/RabbitMQ.Client.OAuth2/RabbitMQ.Client.OAuth2.csproj
+++ b/projects/RabbitMQ.Client.OAuth2/RabbitMQ.Client.OAuth2.csproj
@@ -25,10 +25,8 @@
minimal
true
../../packages
- true
- latest
- 7.0
README.md
+ 7.3
@@ -58,7 +56,7 @@
-
+
diff --git a/projects/RabbitMQ.Client/PublicAPI.Unshipped.txt b/projects/RabbitMQ.Client/PublicAPI.Unshipped.txt
index e7b41970a3..3cda2e436f 100644
--- a/projects/RabbitMQ.Client/PublicAPI.Unshipped.txt
+++ b/projects/RabbitMQ.Client/PublicAPI.Unshipped.txt
@@ -66,7 +66,6 @@ override RabbitMQ.Client.Events.AsyncEventingBasicConsumer.HandleBasicDeliver(st
override RabbitMQ.Client.Events.AsyncEventingBasicConsumer.HandleChannelShutdown(object channel, RabbitMQ.Client.ShutdownEventArgs reason) -> System.Threading.Tasks.Task
override RabbitMQ.Client.Events.EventingBasicConsumer.HandleBasicCancelOk(string consumerTag) -> void
override RabbitMQ.Client.Events.EventingBasicConsumer.HandleBasicConsumeOk(string consumerTag) -> void
-override RabbitMQ.Client.Events.EventingBasicConsumer.HandleBasicDeliver(string consumerTag, ulong deliveryTag, bool redelivered, string exchange, string routingKey, in RabbitMQ.Client.ReadOnlyBasicProperties properties, System.ReadOnlyMemory body) -> void
override RabbitMQ.Client.Events.EventingBasicConsumer.HandleChannelShutdown(object channel, RabbitMQ.Client.ShutdownEventArgs reason) -> void
override RabbitMQ.Client.Exceptions.MalformedFrameException.ReplyCode.get -> ushort
override RabbitMQ.Client.Exceptions.SyntaxErrorException.ReplyCode.get -> ushort
@@ -212,20 +211,6 @@ RabbitMQ.Client.ConnectionFactory.ConsumerDispatchConcurrency.get -> int
RabbitMQ.Client.ConnectionFactory.ConsumerDispatchConcurrency.set -> void
RabbitMQ.Client.ConnectionFactory.ContinuationTimeout.get -> System.TimeSpan
RabbitMQ.Client.ConnectionFactory.ContinuationTimeout.set -> void
-RabbitMQ.Client.ConnectionFactory.CreateConnection() -> RabbitMQ.Client.IConnection
-RabbitMQ.Client.ConnectionFactory.CreateConnection(RabbitMQ.Client.IEndpointResolver endpointResolver, string clientProvidedName) -> RabbitMQ.Client.IConnection
-RabbitMQ.Client.ConnectionFactory.CreateConnection(string clientProvidedName) -> RabbitMQ.Client.IConnection
-RabbitMQ.Client.ConnectionFactory.CreateConnection(System.Collections.Generic.IEnumerable endpoints) -> RabbitMQ.Client.IConnection
-RabbitMQ.Client.ConnectionFactory.CreateConnection(System.Collections.Generic.IEnumerable endpoints, string clientProvidedName) -> RabbitMQ.Client.IConnection
-RabbitMQ.Client.ConnectionFactory.CreateConnection(System.Collections.Generic.IEnumerable hostnames) -> RabbitMQ.Client.IConnection
-RabbitMQ.Client.ConnectionFactory.CreateConnection(System.Collections.Generic.IEnumerable hostnames, string clientProvidedName) -> RabbitMQ.Client.IConnection
-RabbitMQ.Client.ConnectionFactory.CreateConnectionAsync(RabbitMQ.Client.IEndpointResolver endpointResolver, string clientProvidedName, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.ValueTask
-RabbitMQ.Client.ConnectionFactory.CreateConnectionAsync(string clientProvidedName, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.ValueTask
-RabbitMQ.Client.ConnectionFactory.CreateConnectionAsync(System.Collections.Generic.IEnumerable endpoints, string clientProvidedName, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.ValueTask
-RabbitMQ.Client.ConnectionFactory.CreateConnectionAsync(System.Collections.Generic.IEnumerable endpoints, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.ValueTask
-RabbitMQ.Client.ConnectionFactory.CreateConnectionAsync(System.Collections.Generic.IEnumerable hostnames, string clientProvidedName, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.ValueTask
-RabbitMQ.Client.ConnectionFactory.CreateConnectionAsync(System.Collections.Generic.IEnumerable hostnames, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.ValueTask
-RabbitMQ.Client.ConnectionFactory.CreateConnectionAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.ValueTask
RabbitMQ.Client.ConnectionFactory.CredentialsProvider.get -> RabbitMQ.Client.ICredentialsProvider
RabbitMQ.Client.ConnectionFactory.CredentialsProvider.set -> void
RabbitMQ.Client.ConnectionFactory.CredentialsRefresher.get -> RabbitMQ.Client.ICredentialsRefresher
@@ -442,7 +427,6 @@ RabbitMQ.Client.IBasicConsumer.ConsumerCancelled -> System.EventHandler void
RabbitMQ.Client.IBasicConsumer.HandleBasicCancelOk(string consumerTag) -> void
RabbitMQ.Client.IBasicConsumer.HandleBasicConsumeOk(string consumerTag) -> void
-RabbitMQ.Client.IBasicConsumer.HandleBasicDeliver(string consumerTag, ulong deliveryTag, bool redelivered, string exchange, string routingKey, in RabbitMQ.Client.ReadOnlyBasicProperties properties, System.ReadOnlyMemory body) -> void
RabbitMQ.Client.IBasicConsumer.HandleChannelShutdown(object channel, RabbitMQ.Client.ShutdownEventArgs reason) -> void
RabbitMQ.Client.IBasicProperties
RabbitMQ.Client.IBasicProperties.AppId.get -> string
@@ -492,84 +476,28 @@ RabbitMQ.Client.IBasicProperties.Type.set -> void
RabbitMQ.Client.IBasicProperties.UserId.get -> string
RabbitMQ.Client.IBasicProperties.UserId.set -> void
RabbitMQ.Client.IChannel
-RabbitMQ.Client.IChannel.BasicAck(ulong deliveryTag, bool multiple) -> void
RabbitMQ.Client.IChannel.BasicAckAsync(ulong deliveryTag, bool multiple) -> System.Threading.Tasks.ValueTask
RabbitMQ.Client.IChannel.BasicAcks -> System.EventHandler
-RabbitMQ.Client.IChannel.BasicCancel(string consumerTag) -> void
-RabbitMQ.Client.IChannel.BasicCancelAsync(string consumerTag) -> System.Threading.Tasks.ValueTask
-RabbitMQ.Client.IChannel.BasicCancelNoWait(string consumerTag) -> void
-RabbitMQ.Client.IChannel.BasicConsume(string queue, bool autoAck, string consumerTag, bool noLocal, bool exclusive, System.Collections.Generic.IDictionary arguments, RabbitMQ.Client.IBasicConsumer consumer) -> string
-RabbitMQ.Client.IChannel.BasicConsumeAsync(string queue, bool autoAck, string consumerTag, bool noLocal, bool exclusive, System.Collections.Generic.IDictionary arguments, RabbitMQ.Client.IBasicConsumer consumer) -> System.Threading.Tasks.ValueTask
-RabbitMQ.Client.IChannel.BasicGet(string queue, bool autoAck) -> RabbitMQ.Client.BasicGetResult
RabbitMQ.Client.IChannel.BasicGetAsync(string queue, bool autoAck) -> System.Threading.Tasks.ValueTask
-RabbitMQ.Client.IChannel.BasicNack(ulong deliveryTag, bool multiple, bool requeue) -> void
RabbitMQ.Client.IChannel.BasicNackAsync(ulong deliveryTag, bool multiple, bool requeue) -> System.Threading.Tasks.ValueTask
RabbitMQ.Client.IChannel.BasicNacks -> System.EventHandler
-RabbitMQ.Client.IChannel.BasicPublish(RabbitMQ.Client.CachedString exchange, RabbitMQ.Client.CachedString routingKey, in TProperties basicProperties, System.ReadOnlyMemory body = default(System.ReadOnlyMemory), bool mandatory = false) -> void
-RabbitMQ.Client.IChannel.BasicPublish(string exchange, string routingKey, in TProperties basicProperties, System.ReadOnlyMemory body = default(System.ReadOnlyMemory), bool mandatory = false) -> void
RabbitMQ.Client.IChannel.BasicPublishAsync(RabbitMQ.Client.CachedString exchange, RabbitMQ.Client.CachedString routingKey, in TProperties basicProperties, System.ReadOnlyMemory body = default(System.ReadOnlyMemory), bool mandatory = false) -> System.Threading.Tasks.ValueTask
RabbitMQ.Client.IChannel.BasicPublishAsync(string exchange, string routingKey, in TProperties basicProperties, System.ReadOnlyMemory body = default(System.ReadOnlyMemory), bool mandatory = false) -> System.Threading.Tasks.ValueTask
-RabbitMQ.Client.IChannel.BasicQos(uint prefetchSize, ushort prefetchCount, bool global) -> void
-RabbitMQ.Client.IChannel.BasicQosAsync(uint prefetchSize, ushort prefetchCount, bool global) -> System.Threading.Tasks.ValueTask
-RabbitMQ.Client.IChannel.BasicReject(ulong deliveryTag, bool requeue) -> void
-RabbitMQ.Client.IChannel.BasicRejectAsync(ulong deliveryTag, bool requeue) -> System.Threading.Tasks.ValueTask
RabbitMQ.Client.IChannel.BasicReturn -> System.EventHandler
RabbitMQ.Client.IChannel.CallbackException -> System.EventHandler
RabbitMQ.Client.IChannel.ChannelNumber.get -> int
RabbitMQ.Client.IChannel.ChannelShutdown -> System.EventHandler
-RabbitMQ.Client.IChannel.Close(ushort replyCode, string replyText, bool abort) -> void
-RabbitMQ.Client.IChannel.CloseAsync(RabbitMQ.Client.ShutdownEventArgs reason, bool abort) -> System.Threading.Tasks.ValueTask
-RabbitMQ.Client.IChannel.CloseAsync(ushort replyCode, string replyText, bool abort) -> System.Threading.Tasks.ValueTask
RabbitMQ.Client.IChannel.CloseReason.get -> RabbitMQ.Client.ShutdownEventArgs
-RabbitMQ.Client.IChannel.ConfirmSelect() -> void
-RabbitMQ.Client.IChannel.ConfirmSelectAsync() -> System.Threading.Tasks.ValueTask
-RabbitMQ.Client.IChannel.ConsumerCount(string queue) -> uint
RabbitMQ.Client.IChannel.ContinuationTimeout.get -> System.TimeSpan
RabbitMQ.Client.IChannel.ContinuationTimeout.set -> void
RabbitMQ.Client.IChannel.CurrentQueue.get -> string
RabbitMQ.Client.IChannel.DefaultConsumer.get -> RabbitMQ.Client.IBasicConsumer
RabbitMQ.Client.IChannel.DefaultConsumer.set -> void
-RabbitMQ.Client.IChannel.ExchangeBind(string destination, string source, string routingKey, System.Collections.Generic.IDictionary arguments) -> void
-RabbitMQ.Client.IChannel.ExchangeBindAsync(string destination, string source, string routingKey, System.Collections.Generic.IDictionary arguments) -> System.Threading.Tasks.ValueTask
-RabbitMQ.Client.IChannel.ExchangeBindNoWait(string destination, string source, string routingKey, System.Collections.Generic.IDictionary arguments) -> void
-RabbitMQ.Client.IChannel.ExchangeDeclare(string exchange, string type, bool durable, bool autoDelete, System.Collections.Generic.IDictionary arguments) -> void
-RabbitMQ.Client.IChannel.ExchangeDeclareAsync(string exchange, string type, bool passive, bool durable, bool autoDelete, System.Collections.Generic.IDictionary arguments) -> System.Threading.Tasks.ValueTask
-RabbitMQ.Client.IChannel.ExchangeDeclareNoWait(string exchange, string type, bool durable, bool autoDelete, System.Collections.Generic.IDictionary arguments) -> void
-RabbitMQ.Client.IChannel.ExchangeDeclarePassive(string exchange) -> void
-RabbitMQ.Client.IChannel.ExchangeDelete(string exchange, bool ifUnused) -> void
-RabbitMQ.Client.IChannel.ExchangeDeleteAsync(string exchange, bool ifUnused) -> System.Threading.Tasks.ValueTask
-RabbitMQ.Client.IChannel.ExchangeDeleteNoWait(string exchange, bool ifUnused) -> void
-RabbitMQ.Client.IChannel.ExchangeUnbind(string destination, string source, string routingKey, System.Collections.Generic.IDictionary arguments) -> void
-RabbitMQ.Client.IChannel.ExchangeUnbindAsync(string destination, string source, string routingKey, System.Collections.Generic.IDictionary arguments) -> System.Threading.Tasks.ValueTask
-RabbitMQ.Client.IChannel.ExchangeUnbindNoWait(string destination, string source, string routingKey, System.Collections.Generic.IDictionary arguments) -> void
RabbitMQ.Client.IChannel.FlowControl -> System.EventHandler
RabbitMQ.Client.IChannel.IsClosed.get -> bool
RabbitMQ.Client.IChannel.IsOpen.get -> bool
-RabbitMQ.Client.IChannel.MessageCount(string queue) -> uint
RabbitMQ.Client.IChannel.NextPublishSeqNo.get -> ulong
-RabbitMQ.Client.IChannel.QueueBind(string queue, string exchange, string routingKey, System.Collections.Generic.IDictionary arguments) -> void
-RabbitMQ.Client.IChannel.QueueBindAsync(string queue, string exchange, string routingKey, System.Collections.Generic.IDictionary arguments) -> System.Threading.Tasks.ValueTask
-RabbitMQ.Client.IChannel.QueueBindNoWait(string queue, string exchange, string routingKey, System.Collections.Generic.IDictionary arguments) -> void
-RabbitMQ.Client.IChannel.QueueDeclare(string queue, bool durable, bool exclusive, bool autoDelete, System.Collections.Generic.IDictionary arguments) -> RabbitMQ.Client.QueueDeclareOk
-RabbitMQ.Client.IChannel.QueueDeclareAsync(string queue, bool passive, bool durable, bool exclusive, bool autoDelete, System.Collections.Generic.IDictionary arguments) -> System.Threading.Tasks.ValueTask
-RabbitMQ.Client.IChannel.QueueDeclareNoWait(string queue, bool durable, bool exclusive, bool autoDelete, System.Collections.Generic.IDictionary arguments) -> void
-RabbitMQ.Client.IChannel.QueueDeclarePassive(string queue) -> RabbitMQ.Client.QueueDeclareOk
-RabbitMQ.Client.IChannel.QueueDelete(string queue, bool ifUnused, bool ifEmpty) -> uint
-RabbitMQ.Client.IChannel.QueueDeleteAsync(string queue, bool ifUnused, bool ifEmpty) -> System.Threading.Tasks.ValueTask
-RabbitMQ.Client.IChannel.QueueDeleteNoWait(string queue, bool ifUnused, bool ifEmpty) -> void
-RabbitMQ.Client.IChannel.QueuePurge(string queue) -> uint
-RabbitMQ.Client.IChannel.QueuePurgeAsync(string queue) -> System.Threading.Tasks.ValueTask
-RabbitMQ.Client.IChannel.QueueUnbind(string queue, string exchange, string routingKey, System.Collections.Generic.IDictionary arguments) -> void
-RabbitMQ.Client.IChannel.QueueUnbindAsync(string queue, string exchange, string routingKey, System.Collections.Generic.IDictionary arguments) -> System.Threading.Tasks.ValueTask
-RabbitMQ.Client.IChannel.TxCommit() -> void
-RabbitMQ.Client.IChannel.TxCommitAsync() -> System.Threading.Tasks.ValueTask
-RabbitMQ.Client.IChannel.TxRollback() -> void
-RabbitMQ.Client.IChannel.TxRollbackAsync() -> System.Threading.Tasks.ValueTask
-RabbitMQ.Client.IChannel.TxSelect() -> void
-RabbitMQ.Client.IChannel.TxSelectAsync() -> System.Threading.Tasks.ValueTask
-RabbitMQ.Client.IChannel.WaitForConfirms() -> bool
RabbitMQ.Client.IChannel.WaitForConfirmsAsync(System.Threading.CancellationToken token = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
-RabbitMQ.Client.IChannel.WaitForConfirmsOrDie() -> void
RabbitMQ.Client.IChannel.WaitForConfirmsOrDieAsync(System.Threading.CancellationToken token = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
RabbitMQ.Client.IChannelExtensions
RabbitMQ.Client.IConnection
@@ -577,16 +505,12 @@ RabbitMQ.Client.IConnection.CallbackException -> System.EventHandler ushort
RabbitMQ.Client.IConnection.ClientProperties.get -> System.Collections.Generic.IDictionary
RabbitMQ.Client.IConnection.ClientProvidedName.get -> string
-RabbitMQ.Client.IConnection.Close(ushort reasonCode, string reasonText, System.TimeSpan timeout, bool abort) -> void
-RabbitMQ.Client.IConnection.CloseAsync(ushort reasonCode, string reasonText, System.TimeSpan timeout, bool abort) -> System.Threading.Tasks.ValueTask
RabbitMQ.Client.IConnection.CloseReason.get -> RabbitMQ.Client.ShutdownEventArgs
RabbitMQ.Client.IConnection.ConnectionBlocked -> System.EventHandler
RabbitMQ.Client.IConnection.ConnectionRecoveryError -> System.EventHandler
RabbitMQ.Client.IConnection.ConnectionShutdown -> System.EventHandler
RabbitMQ.Client.IConnection.ConnectionUnblocked -> System.EventHandler
RabbitMQ.Client.IConnection.ConsumerTagChangeAfterRecovery -> System.EventHandler
-RabbitMQ.Client.IConnection.CreateChannel() -> RabbitMQ.Client.IChannel
-RabbitMQ.Client.IConnection.CreateChannelAsync() -> System.Threading.Tasks.ValueTask
RabbitMQ.Client.IConnection.Endpoint.get -> RabbitMQ.Client.AmqpTcpEndpoint
RabbitMQ.Client.IConnection.FrameMax.get -> uint
RabbitMQ.Client.IConnection.Heartbeat.get -> System.TimeSpan
@@ -597,7 +521,6 @@ RabbitMQ.Client.IConnection.RecoveringConsumer -> System.EventHandler System.EventHandler
RabbitMQ.Client.IConnection.ServerProperties.get -> System.Collections.Generic.IDictionary
RabbitMQ.Client.IConnection.ShutdownReport.get -> System.Collections.Generic.IEnumerable
-RabbitMQ.Client.IConnection.UpdateSecret(string newSecret, string reason) -> void
RabbitMQ.Client.IConnectionExtensions
RabbitMQ.Client.IConnectionFactory
RabbitMQ.Client.IConnectionFactory.AuthMechanismFactory(System.Collections.Generic.IEnumerable mechanismNames) -> RabbitMQ.Client.IAuthMechanismFactory
@@ -609,18 +532,6 @@ RabbitMQ.Client.IConnectionFactory.ConsumerDispatchConcurrency.get -> int
RabbitMQ.Client.IConnectionFactory.ConsumerDispatchConcurrency.set -> void
RabbitMQ.Client.IConnectionFactory.ContinuationTimeout.get -> System.TimeSpan
RabbitMQ.Client.IConnectionFactory.ContinuationTimeout.set -> void
-RabbitMQ.Client.IConnectionFactory.CreateConnection() -> RabbitMQ.Client.IConnection
-RabbitMQ.Client.IConnectionFactory.CreateConnection(string clientProvidedName) -> RabbitMQ.Client.IConnection
-RabbitMQ.Client.IConnectionFactory.CreateConnection(System.Collections.Generic.IEnumerable endpoints) -> RabbitMQ.Client.IConnection
-RabbitMQ.Client.IConnectionFactory.CreateConnection(System.Collections.Generic.IEnumerable endpoints, string clientProvidedName) -> RabbitMQ.Client.IConnection
-RabbitMQ.Client.IConnectionFactory.CreateConnection(System.Collections.Generic.IEnumerable hostnames) -> RabbitMQ.Client.IConnection
-RabbitMQ.Client.IConnectionFactory.CreateConnection(System.Collections.Generic.IEnumerable hostnames, string clientProvidedName) -> RabbitMQ.Client.IConnection
-RabbitMQ.Client.IConnectionFactory.CreateConnectionAsync(string clientProvidedName, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.ValueTask
-RabbitMQ.Client.IConnectionFactory.CreateConnectionAsync(System.Collections.Generic.IEnumerable endpoints, string clientProvidedName, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.ValueTask
-RabbitMQ.Client.IConnectionFactory.CreateConnectionAsync(System.Collections.Generic.IEnumerable endpoints, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.ValueTask
-RabbitMQ.Client.IConnectionFactory.CreateConnectionAsync(System.Collections.Generic.IEnumerable hostnames, string clientProvidedName, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.ValueTask
-RabbitMQ.Client.IConnectionFactory.CreateConnectionAsync(System.Collections.Generic.IEnumerable hostnames, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.ValueTask
-RabbitMQ.Client.IConnectionFactory.CreateConnectionAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.ValueTask
RabbitMQ.Client.IConnectionFactory.CredentialsProvider.get -> RabbitMQ.Client.ICredentialsProvider
RabbitMQ.Client.IConnectionFactory.CredentialsProvider.set -> void
RabbitMQ.Client.IConnectionFactory.CredentialsRefresher.get -> RabbitMQ.Client.ICredentialsRefresher
@@ -650,8 +561,7 @@ RabbitMQ.Client.ICredentialsProvider.Refresh() -> void
RabbitMQ.Client.ICredentialsProvider.UserName.get -> string
RabbitMQ.Client.ICredentialsProvider.ValidUntil.get -> System.TimeSpan?
RabbitMQ.Client.ICredentialsRefresher
-RabbitMQ.Client.ICredentialsRefresher.NotifyCredentialRefreshed
-RabbitMQ.Client.ICredentialsRefresher.Register(RabbitMQ.Client.ICredentialsProvider provider, RabbitMQ.Client.ICredentialsRefresher.NotifyCredentialRefreshed callback) -> RabbitMQ.Client.ICredentialsProvider
+RabbitMQ.Client.ICredentialsRefresher.NotifyCredentialRefreshedAsync
RabbitMQ.Client.ICredentialsRefresher.Unregister(RabbitMQ.Client.ICredentialsProvider provider) -> bool
RabbitMQ.Client.IEndpointResolver
RabbitMQ.Client.IEndpointResolver.All() -> System.Collections.Generic.IEnumerable
@@ -829,7 +739,6 @@ RabbitMQ.Client.TcpClientAdapter
RabbitMQ.Client.TcpClientAdapter.Dispose() -> void
RabbitMQ.Client.TcpClientAdapter.TcpClientAdapter(System.Net.Sockets.Socket socket) -> void
RabbitMQ.Client.TimerBasedCredentialRefresher
-RabbitMQ.Client.TimerBasedCredentialRefresher.Register(RabbitMQ.Client.ICredentialsProvider provider, RabbitMQ.Client.ICredentialsRefresher.NotifyCredentialRefreshed callback) -> RabbitMQ.Client.ICredentialsProvider
RabbitMQ.Client.TimerBasedCredentialRefresher.TimerBasedCredentialRefresher() -> void
RabbitMQ.Client.TimerBasedCredentialRefresher.Unregister(RabbitMQ.Client.ICredentialsProvider provider) -> bool
RabbitMQ.Client.TimerBasedCredentialRefresherEventSource
@@ -843,20 +752,12 @@ RabbitMQ.Client.TimerBasedCredentialRefresherEventSource.Unregistered(string nam
RabbitMQ.Client.TopologyRecoveryExceptionHandler
RabbitMQ.Client.TopologyRecoveryExceptionHandler.BindingRecoveryExceptionCondition.get -> System.Func
RabbitMQ.Client.TopologyRecoveryExceptionHandler.BindingRecoveryExceptionCondition.set -> void
-RabbitMQ.Client.TopologyRecoveryExceptionHandler.BindingRecoveryExceptionHandler.get -> System.Action
-RabbitMQ.Client.TopologyRecoveryExceptionHandler.BindingRecoveryExceptionHandler.set -> void
RabbitMQ.Client.TopologyRecoveryExceptionHandler.ConsumerRecoveryExceptionCondition.get -> System.Func
RabbitMQ.Client.TopologyRecoveryExceptionHandler.ConsumerRecoveryExceptionCondition.set -> void
-RabbitMQ.Client.TopologyRecoveryExceptionHandler.ConsumerRecoveryExceptionHandler.get -> System.Action
-RabbitMQ.Client.TopologyRecoveryExceptionHandler.ConsumerRecoveryExceptionHandler.set -> void
RabbitMQ.Client.TopologyRecoveryExceptionHandler.ExchangeRecoveryExceptionCondition.get -> System.Func
RabbitMQ.Client.TopologyRecoveryExceptionHandler.ExchangeRecoveryExceptionCondition.set -> void
-RabbitMQ.Client.TopologyRecoveryExceptionHandler.ExchangeRecoveryExceptionHandler.get -> System.Action
-RabbitMQ.Client.TopologyRecoveryExceptionHandler.ExchangeRecoveryExceptionHandler.set -> void
RabbitMQ.Client.TopologyRecoveryExceptionHandler.QueueRecoveryExceptionCondition.get -> System.Func
RabbitMQ.Client.TopologyRecoveryExceptionHandler.QueueRecoveryExceptionCondition.set -> void
-RabbitMQ.Client.TopologyRecoveryExceptionHandler.QueueRecoveryExceptionHandler.get -> System.Action
-RabbitMQ.Client.TopologyRecoveryExceptionHandler.QueueRecoveryExceptionHandler.set -> void
RabbitMQ.Client.TopologyRecoveryExceptionHandler.TopologyRecoveryExceptionHandler() -> void
RabbitMQ.Client.TopologyRecoveryFilter
RabbitMQ.Client.TopologyRecoveryFilter.BindingFilter.get -> System.Func
@@ -944,63 +845,9 @@ static RabbitMQ.Client.EndpointResolverExtensions.SelectOneAsync(this RabbitM
static RabbitMQ.Client.Events.CallbackExceptionEventArgs.Build(System.Exception e, string context) -> RabbitMQ.Client.Events.CallbackExceptionEventArgs
static RabbitMQ.Client.Events.CallbackExceptionEventArgs.Build(System.Exception e, string context, object consumer) -> RabbitMQ.Client.Events.CallbackExceptionEventArgs
static RabbitMQ.Client.ExchangeType.All() -> System.Collections.Generic.ICollection
-static RabbitMQ.Client.IChannelExtensions.Abort(this RabbitMQ.Client.IChannel channel) -> void
-static RabbitMQ.Client.IChannelExtensions.Abort(this RabbitMQ.Client.IChannel channel, ushort replyCode, string replyText) -> void
-static RabbitMQ.Client.IChannelExtensions.AbortAsync(this RabbitMQ.Client.IChannel channel) -> System.Threading.Tasks.ValueTask
-static RabbitMQ.Client.IChannelExtensions.BasicConsume(this RabbitMQ.Client.IChannel channel, RabbitMQ.Client.IBasicConsumer consumer, string queue, bool autoAck = false, string consumerTag = "", bool noLocal = false, bool exclusive = false, System.Collections.Generic.IDictionary arguments = null) -> string
-static RabbitMQ.Client.IChannelExtensions.BasicConsume(this RabbitMQ.Client.IChannel channel, string queue, bool autoAck, RabbitMQ.Client.IBasicConsumer consumer) -> string
-static RabbitMQ.Client.IChannelExtensions.BasicConsume(this RabbitMQ.Client.IChannel channel, string queue, bool autoAck, string consumerTag, RabbitMQ.Client.IBasicConsumer consumer) -> string
-static RabbitMQ.Client.IChannelExtensions.BasicConsume(this RabbitMQ.Client.IChannel channel, string queue, bool autoAck, string consumerTag, System.Collections.Generic.IDictionary arguments, RabbitMQ.Client.IBasicConsumer consumer) -> string
-static RabbitMQ.Client.IChannelExtensions.BasicConsumeAsync(this RabbitMQ.Client.IChannel channel, RabbitMQ.Client.IBasicConsumer consumer, string queue, bool autoAck = false, string consumerTag = "", bool noLocal = false, bool exclusive = false, System.Collections.Generic.IDictionary arguments = null) -> System.Threading.Tasks.ValueTask
-static RabbitMQ.Client.IChannelExtensions.BasicConsumeAsync(this RabbitMQ.Client.IChannel channel, string queue, bool autoAck, RabbitMQ.Client.IBasicConsumer consumer) -> System.Threading.Tasks.ValueTask
-static RabbitMQ.Client.IChannelExtensions.BasicConsumeAsync(this RabbitMQ.Client.IChannel channel, string queue, bool autoAck, string consumerTag, RabbitMQ.Client.IBasicConsumer consumer) -> System.Threading.Tasks.ValueTask
-static RabbitMQ.Client.IChannelExtensions.BasicConsumeAsync(this RabbitMQ.Client.IChannel channel, string queue, bool autoAck, string consumerTag, System.Collections.Generic.IDictionary arguments, RabbitMQ.Client.IBasicConsumer consumer) -> System.Threading.Tasks.ValueTask
-static RabbitMQ.Client.IChannelExtensions.BasicPublish(this RabbitMQ.Client.IChannel channel, RabbitMQ.Client.CachedString exchange, RabbitMQ.Client.CachedString routingKey, System.ReadOnlyMemory body = default(System.ReadOnlyMemory), bool mandatory = false) -> void
-static RabbitMQ.Client.IChannelExtensions.BasicPublish(this RabbitMQ.Client.IChannel channel, string exchange, string routingKey, System.ReadOnlyMemory body = default(System.ReadOnlyMemory), bool mandatory = false) -> void
-static RabbitMQ.Client.IChannelExtensions.BasicPublish(this RabbitMQ.Client.IChannel channel, RabbitMQ.Client.PublicationAddress addr, in T basicProperties, System.ReadOnlyMemory body) -> void
static RabbitMQ.Client.IChannelExtensions.BasicPublishAsync(this RabbitMQ.Client.IChannel channel, RabbitMQ.Client.CachedString exchange, RabbitMQ.Client.CachedString routingKey, System.ReadOnlyMemory body = default(System.ReadOnlyMemory), bool mandatory = false) -> System.Threading.Tasks.ValueTask
static RabbitMQ.Client.IChannelExtensions.BasicPublishAsync(this RabbitMQ.Client.IChannel channel, string exchange, string routingKey, System.ReadOnlyMemory body = default(System.ReadOnlyMemory), bool mandatory = false) -> System.Threading.Tasks.ValueTask
static RabbitMQ.Client.IChannelExtensions.BasicPublishAsync(this RabbitMQ.Client.IChannel channel, RabbitMQ.Client.PublicationAddress addr, in T basicProperties, System.ReadOnlyMemory body) -> System.Threading.Tasks.ValueTask
-static RabbitMQ.Client.IChannelExtensions.Close(this RabbitMQ.Client.IChannel channel) -> void
-static RabbitMQ.Client.IChannelExtensions.Close(this RabbitMQ.Client.IChannel channel, ushort replyCode, string replyText) -> void
-static RabbitMQ.Client.IChannelExtensions.CloseAsync(this RabbitMQ.Client.IChannel channel) -> System.Threading.Tasks.ValueTask
-static RabbitMQ.Client.IChannelExtensions.CloseAsync(this RabbitMQ.Client.IChannel channel, ushort replyCode, string replyText) -> System.Threading.Tasks.ValueTask
-static RabbitMQ.Client.IChannelExtensions.ExchangeBind(this RabbitMQ.Client.IChannel channel, string destination, string source, string routingKey, System.Collections.Generic.IDictionary arguments = null) -> void
-static RabbitMQ.Client.IChannelExtensions.ExchangeBindAsync(this RabbitMQ.Client.IChannel channel, string destination, string source, string routingKey, System.Collections.Generic.IDictionary arguments = null) -> System.Threading.Tasks.ValueTask
-static RabbitMQ.Client.IChannelExtensions.ExchangeBindNoWait(this RabbitMQ.Client.IChannel channel, string destination, string source, string routingKey, System.Collections.Generic.IDictionary arguments = null) -> void
-static RabbitMQ.Client.IChannelExtensions.ExchangeDeclare(this RabbitMQ.Client.IChannel channel, string exchange, string type, bool durable = false, bool autoDelete = false, System.Collections.Generic.IDictionary arguments = null) -> void
-static RabbitMQ.Client.IChannelExtensions.ExchangeDeclareAsync(this RabbitMQ.Client.IChannel channel, string exchange, string type, bool durable = false, bool autoDelete = false, System.Collections.Generic.IDictionary arguments = null) -> System.Threading.Tasks.ValueTask
-static RabbitMQ.Client.IChannelExtensions.ExchangeDeclareNoWait(this RabbitMQ.Client.IChannel channel, string exchange, string type, bool durable = false, bool autoDelete = false, System.Collections.Generic.IDictionary arguments = null) -> void
-static RabbitMQ.Client.IChannelExtensions.ExchangeDelete(this RabbitMQ.Client.IChannel channel, string exchange, bool ifUnused = false) -> void
-static RabbitMQ.Client.IChannelExtensions.ExchangeDeleteAsync(this RabbitMQ.Client.IChannel channel, string exchange, bool ifUnused = false) -> System.Threading.Tasks.ValueTask
-static RabbitMQ.Client.IChannelExtensions.ExchangeDeleteNoWait(this RabbitMQ.Client.IChannel channel, string exchange, bool ifUnused = false) -> void
-static RabbitMQ.Client.IChannelExtensions.ExchangeUnbind(this RabbitMQ.Client.IChannel channel, string destination, string source, string routingKey, System.Collections.Generic.IDictionary arguments = null) -> void
-static RabbitMQ.Client.IChannelExtensions.ExchangeUnbindAsync(this RabbitMQ.Client.IChannel channel, string destination, string source, string routingKey, System.Collections.Generic.IDictionary arguments = null) -> System.Threading.Tasks.ValueTask
-static RabbitMQ.Client.IChannelExtensions.QueueBind(this RabbitMQ.Client.IChannel channel, string queue, string exchange, string routingKey, System.Collections.Generic.IDictionary arguments = null) -> void
-static RabbitMQ.Client.IChannelExtensions.QueueBindAsync(this RabbitMQ.Client.IChannel channel, string queue, string exchange, string routingKey, System.Collections.Generic.IDictionary arguments = null) -> System.Threading.Tasks.ValueTask
-static RabbitMQ.Client.IChannelExtensions.QueueDeclare(this RabbitMQ.Client.IChannel channel, string queue = "", bool durable = false, bool exclusive = true, bool autoDelete = true, System.Collections.Generic.IDictionary arguments = null) -> RabbitMQ.Client.QueueDeclareOk
-static RabbitMQ.Client.IChannelExtensions.QueueDeclareAsync(this RabbitMQ.Client.IChannel channel, string queue = "", bool durable = false, bool exclusive = true, bool autoDelete = true, System.Collections.Generic.IDictionary arguments = null) -> System.Threading.Tasks.ValueTask
-static RabbitMQ.Client.IChannelExtensions.QueueDelete(this RabbitMQ.Client.IChannel channel, string queue, bool ifUnused = false, bool ifEmpty = false) -> uint
-static RabbitMQ.Client.IChannelExtensions.QueueDeleteAsync(this RabbitMQ.Client.IChannel channel, string queue, bool ifUnused = false, bool ifEmpty = false) -> System.Threading.Tasks.ValueTask
-static RabbitMQ.Client.IChannelExtensions.QueueDeleteNoWait(this RabbitMQ.Client.IChannel channel, string queue, bool ifUnused = false, bool ifEmpty = false) -> void
-static RabbitMQ.Client.IChannelExtensions.QueueUnbind(this RabbitMQ.Client.IChannel channel, string queue, string exchange, string routingKey, System.Collections.Generic.IDictionary arguments = null) -> void
-static RabbitMQ.Client.IChannelExtensions.QueueUnbindAsync(this RabbitMQ.Client.IChannel channel, string queue, string exchange, string routingKey, System.Collections.Generic.IDictionary arguments = null) -> System.Threading.Tasks.ValueTask
-static RabbitMQ.Client.IConnectionExtensions.Abort(this RabbitMQ.Client.IConnection connection) -> void
-static RabbitMQ.Client.IConnectionExtensions.Abort(this RabbitMQ.Client.IConnection connection, System.TimeSpan timeout) -> void
-static RabbitMQ.Client.IConnectionExtensions.Abort(this RabbitMQ.Client.IConnection connection, ushort reasonCode, string reasonText) -> void
-static RabbitMQ.Client.IConnectionExtensions.Abort(this RabbitMQ.Client.IConnection connection, ushort reasonCode, string reasonText, System.TimeSpan timeout) -> void
-static RabbitMQ.Client.IConnectionExtensions.AbortAsync(this RabbitMQ.Client.IConnection connection) -> System.Threading.Tasks.ValueTask
-static RabbitMQ.Client.IConnectionExtensions.AbortAsync(this RabbitMQ.Client.IConnection connection, System.TimeSpan timeout) -> System.Threading.Tasks.ValueTask
-static RabbitMQ.Client.IConnectionExtensions.AbortAsync(this RabbitMQ.Client.IConnection connection, ushort reasonCode, string reasonText) -> System.Threading.Tasks.ValueTask
-static RabbitMQ.Client.IConnectionExtensions.AbortAsync(this RabbitMQ.Client.IConnection connection, ushort reasonCode, string reasonText, System.TimeSpan timeout) -> System.Threading.Tasks.ValueTask
-static RabbitMQ.Client.IConnectionExtensions.Close(this RabbitMQ.Client.IConnection connection) -> void
-static RabbitMQ.Client.IConnectionExtensions.Close(this RabbitMQ.Client.IConnection connection, System.TimeSpan timeout) -> void
-static RabbitMQ.Client.IConnectionExtensions.Close(this RabbitMQ.Client.IConnection connection, ushort reasonCode, string reasonText) -> void
-static RabbitMQ.Client.IConnectionExtensions.Close(this RabbitMQ.Client.IConnection connection, ushort reasonCode, string reasonText, System.TimeSpan timeout) -> void
-static RabbitMQ.Client.IConnectionExtensions.CloseAsync(this RabbitMQ.Client.IConnection connection) -> System.Threading.Tasks.ValueTask
-static RabbitMQ.Client.IConnectionExtensions.CloseAsync(this RabbitMQ.Client.IConnection connection, System.TimeSpan timeout) -> System.Threading.Tasks.ValueTask
-static RabbitMQ.Client.IConnectionExtensions.CloseAsync(this RabbitMQ.Client.IConnection connection, ushort reasonCode, string reasonText) -> System.Threading.Tasks.ValueTask
-static RabbitMQ.Client.IConnectionExtensions.CloseAsync(this RabbitMQ.Client.IConnection connection, ushort reasonCode, string reasonText, System.TimeSpan timeout) -> System.Threading.Tasks.ValueTask
static RabbitMQ.Client.PublicationAddress.Parse(string uriLikeString) -> RabbitMQ.Client.PublicationAddress
static RabbitMQ.Client.PublicationAddress.TryParse(string uriLikeString, out RabbitMQ.Client.PublicationAddress result) -> bool
static RabbitMQ.Client.QueueDeclareOk.implicit operator string(RabbitMQ.Client.QueueDeclareOk declareOk) -> string
@@ -1023,7 +870,6 @@ virtual RabbitMQ.Client.AsyncDefaultBasicConsumer.OnCancel(params string[] consu
virtual RabbitMQ.Client.DefaultBasicConsumer.HandleBasicCancel(string consumerTag) -> void
virtual RabbitMQ.Client.DefaultBasicConsumer.HandleBasicCancelOk(string consumerTag) -> void
virtual RabbitMQ.Client.DefaultBasicConsumer.HandleBasicConsumeOk(string consumerTag) -> void
-virtual RabbitMQ.Client.DefaultBasicConsumer.HandleBasicDeliver(string consumerTag, ulong deliveryTag, bool redelivered, string exchange, string routingKey, in RabbitMQ.Client.ReadOnlyBasicProperties properties, System.ReadOnlyMemory body) -> void
virtual RabbitMQ.Client.DefaultBasicConsumer.HandleChannelShutdown(object channel, RabbitMQ.Client.ShutdownEventArgs reason) -> void
virtual RabbitMQ.Client.DefaultBasicConsumer.OnCancel(params string[] consumerTags) -> void
virtual RabbitMQ.Client.Exceptions.ProtocolException.ShutdownReason.get -> RabbitMQ.Client.ShutdownEventArgs
@@ -1035,3 +881,74 @@ virtual RabbitMQ.Client.TcpClientAdapter.Dispose(bool disposing) -> void
virtual RabbitMQ.Client.TcpClientAdapter.GetStream() -> System.Net.Sockets.NetworkStream
virtual RabbitMQ.Client.TcpClientAdapter.ReceiveTimeout.get -> System.TimeSpan
virtual RabbitMQ.Client.TcpClientAdapter.ReceiveTimeout.set -> void
+~override RabbitMQ.Client.Events.EventingBasicConsumer.HandleBasicDeliverAsync(string consumerTag, ulong deliveryTag, bool redelivered, string exchange, string routingKey, RabbitMQ.Client.ReadOnlyBasicProperties properties, System.ReadOnlyMemory body) -> System.Threading.Tasks.Task
+~RabbitMQ.Client.ConnectionFactory.CreateConnectionAsync(RabbitMQ.Client.IEndpointResolver endpointResolver, string clientProvidedName, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+~RabbitMQ.Client.ConnectionFactory.CreateConnectionAsync(string clientProvidedName, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+~RabbitMQ.Client.ConnectionFactory.CreateConnectionAsync(System.Collections.Generic.IEnumerable endpoints, string clientProvidedName, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+~RabbitMQ.Client.ConnectionFactory.CreateConnectionAsync(System.Collections.Generic.IEnumerable endpoints, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+~RabbitMQ.Client.ConnectionFactory.CreateConnectionAsync(System.Collections.Generic.IEnumerable hostnames, string clientProvidedName, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+~RabbitMQ.Client.ConnectionFactory.CreateConnectionAsync(System.Collections.Generic.IEnumerable hostnames, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+~RabbitMQ.Client.ConnectionFactory.CreateConnectionAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+~RabbitMQ.Client.IBasicConsumer.HandleBasicDeliverAsync(string consumerTag, ulong deliveryTag, bool redelivered, string exchange, string routingKey, RabbitMQ.Client.ReadOnlyBasicProperties properties, System.ReadOnlyMemory body) -> System.Threading.Tasks.Task
+~RabbitMQ.Client.IChannel.BasicCancelAsync(string consumerTag, bool noWait = false) -> System.Threading.Tasks.Task
+~RabbitMQ.Client.IChannel.BasicConsumeAsync(string queue, bool autoAck, string consumerTag, bool noLocal, bool exclusive, System.Collections.Generic.IDictionary arguments, RabbitMQ.Client.IBasicConsumer consumer) -> System.Threading.Tasks.Task
+~RabbitMQ.Client.IChannel.BasicQosAsync(uint prefetchSize, ushort prefetchCount, bool global) -> System.Threading.Tasks.Task
+~RabbitMQ.Client.IChannel.BasicRejectAsync(ulong deliveryTag, bool requeue) -> System.Threading.Tasks.Task
+~RabbitMQ.Client.IChannel.CloseAsync(RabbitMQ.Client.ShutdownEventArgs reason, bool abort) -> System.Threading.Tasks.Task
+~RabbitMQ.Client.IChannel.CloseAsync(ushort replyCode, string replyText, bool abort) -> System.Threading.Tasks.Task
+~RabbitMQ.Client.IChannel.ConfirmSelectAsync() -> System.Threading.Tasks.Task
+~RabbitMQ.Client.IChannel.ConsumerCountAsync(string queue) -> System.Threading.Tasks.Task
+~RabbitMQ.Client.IChannel.ExchangeBindAsync(string destination, string source, string routingKey, System.Collections.Generic.IDictionary arguments = null, bool noWait = false) -> System.Threading.Tasks.Task
+~RabbitMQ.Client.IChannel.ExchangeDeclareAsync(string exchange, string type, bool durable, bool autoDelete, System.Collections.Generic.IDictionary arguments = null, bool passive = false, bool noWait = false) -> System.Threading.Tasks.Task
+~RabbitMQ.Client.IChannel.ExchangeDeclarePassiveAsync(string exchange) -> System.Threading.Tasks.Task
+~RabbitMQ.Client.IChannel.ExchangeDeleteAsync(string exchange, bool ifUnused = false, bool noWait = false) -> System.Threading.Tasks.Task
+~RabbitMQ.Client.IChannel.ExchangeUnbindAsync(string destination, string source, string routingKey, System.Collections.Generic.IDictionary arguments = null, bool noWait = false) -> System.Threading.Tasks.Task
+~RabbitMQ.Client.IChannel.MessageCountAsync(string queue) -> System.Threading.Tasks.Task
+~RabbitMQ.Client.IChannel.QueueBindAsync(string queue, string exchange, string routingKey, System.Collections.Generic.IDictionary arguments = null, bool noWait = false) -> System.Threading.Tasks.Task
+~RabbitMQ.Client.IChannel.QueueDeclareAsync(string queue, bool durable, bool exclusive, bool autoDelete, System.Collections.Generic.IDictionary arguments = null, bool passive = false, bool noWait = false) -> System.Threading.Tasks.Task
+~RabbitMQ.Client.IChannel.QueueDeclarePassiveAsync(string queue) -> System.Threading.Tasks.Task
+~RabbitMQ.Client.IChannel.QueueDeleteAsync(string queue, bool ifUnused, bool ifEmpty, bool noWait = false) -> System.Threading.Tasks.Task
+~RabbitMQ.Client.IChannel.QueuePurgeAsync(string queue) -> System.Threading.Tasks.Task
+~RabbitMQ.Client.IChannel.QueueUnbindAsync(string queue, string exchange, string routingKey, System.Collections.Generic.IDictionary arguments) -> System.Threading.Tasks.Task
+~RabbitMQ.Client.IChannel.TxCommitAsync() -> System.Threading.Tasks.Task
+~RabbitMQ.Client.IChannel.TxRollbackAsync() -> System.Threading.Tasks.Task
+~RabbitMQ.Client.IChannel.TxSelectAsync() -> System.Threading.Tasks.Task
+~RabbitMQ.Client.IConnection.CloseAsync(ushort reasonCode, string reasonText, System.TimeSpan timeout, bool abort) -> System.Threading.Tasks.Task
+~RabbitMQ.Client.IConnection.CreateChannelAsync() -> System.Threading.Tasks.Task
+~RabbitMQ.Client.IConnection.UpdateSecretAsync(string newSecret, string reason) -> System.Threading.Tasks.Task
+~RabbitMQ.Client.IConnectionFactory.CreateConnectionAsync(string clientProvidedName, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+~RabbitMQ.Client.IConnectionFactory.CreateConnectionAsync(System.Collections.Generic.IEnumerable endpoints, string clientProvidedName, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+~RabbitMQ.Client.IConnectionFactory.CreateConnectionAsync(System.Collections.Generic.IEnumerable endpoints, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+~RabbitMQ.Client.IConnectionFactory.CreateConnectionAsync(System.Collections.Generic.IEnumerable hostnames, string clientProvidedName, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+~RabbitMQ.Client.IConnectionFactory.CreateConnectionAsync(System.Collections.Generic.IEnumerable hostnames, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+~RabbitMQ.Client.IConnectionFactory.CreateConnectionAsync(System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.Task
+~RabbitMQ.Client.ICredentialsRefresher.Register(RabbitMQ.Client.ICredentialsProvider provider, RabbitMQ.Client.ICredentialsRefresher.NotifyCredentialRefreshedAsync callback) -> RabbitMQ.Client.ICredentialsProvider
+~RabbitMQ.Client.TimerBasedCredentialRefresher.Register(RabbitMQ.Client.ICredentialsProvider provider, RabbitMQ.Client.ICredentialsRefresher.NotifyCredentialRefreshedAsync callback) -> RabbitMQ.Client.ICredentialsProvider
+~RabbitMQ.Client.TopologyRecoveryExceptionHandler.BindingRecoveryExceptionHandlerAsync.get -> System.Func
+~RabbitMQ.Client.TopologyRecoveryExceptionHandler.BindingRecoveryExceptionHandlerAsync.set -> void
+~RabbitMQ.Client.TopologyRecoveryExceptionHandler.ConsumerRecoveryExceptionHandlerAsync.get -> System.Func
+~RabbitMQ.Client.TopologyRecoveryExceptionHandler.ConsumerRecoveryExceptionHandlerAsync.set -> void
+~RabbitMQ.Client.TopologyRecoveryExceptionHandler.ExchangeRecoveryExceptionHandlerAsync.get -> System.Func
+~RabbitMQ.Client.TopologyRecoveryExceptionHandler.ExchangeRecoveryExceptionHandlerAsync.set -> void
+~RabbitMQ.Client.TopologyRecoveryExceptionHandler.QueueRecoveryExceptionHandlerAsync.get -> System.Func
+~RabbitMQ.Client.TopologyRecoveryExceptionHandler.QueueRecoveryExceptionHandlerAsync.set -> void
+~static RabbitMQ.Client.IChannelExtensions.AbortAsync(this RabbitMQ.Client.IChannel channel) -> System.Threading.Tasks.Task
+~static RabbitMQ.Client.IChannelExtensions.BasicConsumeAsync(this RabbitMQ.Client.IChannel channel, RabbitMQ.Client.IBasicConsumer consumer, string queue, bool autoAck = false, string consumerTag = "", bool noLocal = false, bool exclusive = false, System.Collections.Generic.IDictionary arguments = null) -> System.Threading.Tasks.Task
+~static RabbitMQ.Client.IChannelExtensions.BasicConsumeAsync(this RabbitMQ.Client.IChannel channel, string queue, bool autoAck, RabbitMQ.Client.IBasicConsumer consumer) -> System.Threading.Tasks.Task
+~static RabbitMQ.Client.IChannelExtensions.BasicConsumeAsync(this RabbitMQ.Client.IChannel channel, string queue, bool autoAck, string consumerTag, RabbitMQ.Client.IBasicConsumer consumer) -> System.Threading.Tasks.Task
+~static RabbitMQ.Client.IChannelExtensions.BasicConsumeAsync(this RabbitMQ.Client.IChannel channel, string queue, bool autoAck, string consumerTag, System.Collections.Generic.IDictionary arguments, RabbitMQ.Client.IBasicConsumer consumer) -> System.Threading.Tasks.Task
+~static RabbitMQ.Client.IChannelExtensions.CloseAsync(this RabbitMQ.Client.IChannel channel) -> System.Threading.Tasks.Task
+~static RabbitMQ.Client.IChannelExtensions.CloseAsync(this RabbitMQ.Client.IChannel channel, ushort replyCode, string replyText) -> System.Threading.Tasks.Task
+~static RabbitMQ.Client.IChannelExtensions.ExchangeDeclareAsync(this RabbitMQ.Client.IChannel channel, string exchange, string type, bool durable = false, bool autoDelete = false, System.Collections.Generic.IDictionary arguments = null, bool noWait = false) -> System.Threading.Tasks.Task
+~static RabbitMQ.Client.IChannelExtensions.QueueDeclareAsync(this RabbitMQ.Client.IChannel channel, string queue = "", bool durable = false, bool exclusive = true, bool autoDelete = true, System.Collections.Generic.IDictionary arguments = null, bool noWait = false) -> System.Threading.Tasks.Task
+~static RabbitMQ.Client.IChannelExtensions.QueueDeleteAsync(this RabbitMQ.Client.IChannel channel, string queue, bool ifUnused = false, bool ifEmpty = false) -> System.Threading.Tasks.Task
+~static RabbitMQ.Client.IChannelExtensions.QueueUnbindAsync(this RabbitMQ.Client.IChannel channel, string queue, string exchange, string routingKey, System.Collections.Generic.IDictionary arguments = null) -> System.Threading.Tasks.Task
+~static RabbitMQ.Client.IConnectionExtensions.AbortAsync(this RabbitMQ.Client.IConnection connection) -> System.Threading.Tasks.Task
+~static RabbitMQ.Client.IConnectionExtensions.AbortAsync(this RabbitMQ.Client.IConnection connection, System.TimeSpan timeout) -> System.Threading.Tasks.Task
+~static RabbitMQ.Client.IConnectionExtensions.AbortAsync(this RabbitMQ.Client.IConnection connection, ushort reasonCode, string reasonText) -> System.Threading.Tasks.Task
+~static RabbitMQ.Client.IConnectionExtensions.AbortAsync(this RabbitMQ.Client.IConnection connection, ushort reasonCode, string reasonText, System.TimeSpan timeout) -> System.Threading.Tasks.Task
+~static RabbitMQ.Client.IConnectionExtensions.CloseAsync(this RabbitMQ.Client.IConnection connection) -> System.Threading.Tasks.Task
+~static RabbitMQ.Client.IConnectionExtensions.CloseAsync(this RabbitMQ.Client.IConnection connection, System.TimeSpan timeout) -> System.Threading.Tasks.Task
+~static RabbitMQ.Client.IConnectionExtensions.CloseAsync(this RabbitMQ.Client.IConnection connection, ushort reasonCode, string reasonText) -> System.Threading.Tasks.Task
+~static RabbitMQ.Client.IConnectionExtensions.CloseAsync(this RabbitMQ.Client.IConnection connection, ushort reasonCode, string reasonText, System.TimeSpan timeout) -> System.Threading.Tasks.Task
+~virtual RabbitMQ.Client.DefaultBasicConsumer.HandleBasicDeliverAsync(string consumerTag, ulong deliveryTag, bool redelivered, string exchange, string routingKey, RabbitMQ.Client.ReadOnlyBasicProperties properties, System.ReadOnlyMemory body) -> System.Threading.Tasks.Task
diff --git a/projects/RabbitMQ.Client/RabbitMQ.Client.csproj b/projects/RabbitMQ.Client/RabbitMQ.Client.csproj
index 3ed292dfcd..e06dd89034 100644
--- a/projects/RabbitMQ.Client/RabbitMQ.Client.csproj
+++ b/projects/RabbitMQ.Client/RabbitMQ.Client.csproj
@@ -27,9 +27,13 @@
true
../../packages
true
- latest
- 7.0
README.md
+
+ 8.0
diff --git a/projects/RabbitMQ.Client/client/RentedMemory.cs b/projects/RabbitMQ.Client/client/RentedMemory.cs
index b4679e3b6d..6f52bf832e 100644
--- a/projects/RabbitMQ.Client/client/RentedMemory.cs
+++ b/projects/RabbitMQ.Client/client/RentedMemory.cs
@@ -46,6 +46,7 @@ internal RentedMemory(ReadOnlyMemory memory, byte[] rentedArray)
{
Memory = memory;
RentedArray = rentedArray;
+ _disposedValue = false;
}
internal readonly ReadOnlyMemory Memory;
diff --git a/projects/RabbitMQ.Client/client/TaskExtensions.cs b/projects/RabbitMQ.Client/client/TaskExtensions.cs
index 97eececaa3..b0328875af 100644
--- a/projects/RabbitMQ.Client/client/TaskExtensions.cs
+++ b/projects/RabbitMQ.Client/client/TaskExtensions.cs
@@ -37,6 +37,18 @@ namespace RabbitMQ.Client
{
internal static class TaskExtensions
{
+#if NET6_0_OR_GREATER
+ public static bool IsCompletedSuccessfully(this Task task)
+ {
+ return task.IsCompletedSuccessfully;
+ }
+#else
+ public static bool IsCompletedSuccessfully(this Task task)
+ {
+ return task.Status == TaskStatus.RanToCompletion;
+ }
+#endif
+
#if !NET6_0_OR_GREATER
private static readonly TaskContinuationOptions s_tco = TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.ExecuteSynchronously;
private static void IgnoreTaskContinuation(Task t, object s) => t.Exception.Handle(e => true);
@@ -59,7 +71,7 @@ public static async Task WithCancellation(this Task task, CancellationToken canc
}
#endif
- public static Task TimeoutAfter(this Task task, TimeSpan timeout)
+ public static Task WaitAsync(this Task task, TimeSpan timeout)
{
#if NET6_0_OR_GREATER
if (task.IsCompletedSuccessfully)
@@ -69,7 +81,7 @@ public static Task TimeoutAfter(this Task task, TimeSpan timeout)
return task.WaitAsync(timeout);
#else
- if (task.Status == TaskStatus.RanToCompletion)
+ if (task.IsCompletedSuccessfully())
{
return task;
}
diff --git a/projects/RabbitMQ.Client/client/api/AsyncDefaultBasicConsumer.cs b/projects/RabbitMQ.Client/client/api/AsyncDefaultBasicConsumer.cs
index a7a0fe4035..64fb982029 100644
--- a/projects/RabbitMQ.Client/client/api/AsyncDefaultBasicConsumer.cs
+++ b/projects/RabbitMQ.Client/client/api/AsyncDefaultBasicConsumer.cs
@@ -29,7 +29,7 @@ public AsyncDefaultBasicConsumer(IChannel channel)
///
/// Retrieve the consumer tags this consumer is registered as; to be used when discussing this consumer
- /// with the server, for instance with .
+ /// with the server, for instance with .
///
public string[] ConsumerTags
{
@@ -101,7 +101,7 @@ public virtual Task HandleBasicConsumeOk(string consumerTag)
/// Called each time a message is delivered for this consumer.
///
///
- /// This is a no-op implementation. It will not acknowledge deliveries via
+ /// This is a no-op implementation. It will not acknowledge deliveries via
/// if consuming in automatic acknowledgement mode.
/// Subclasses must copy or fully use delivery body before returning.
/// Accessing the body at a later point is unsafe as its memory can
@@ -166,8 +166,8 @@ void IBasicConsumer.HandleBasicConsumeOk(string consumerTag)
throw new InvalidOperationException("Should never be called. Enable 'DispatchConsumersAsync'.");
}
- void IBasicConsumer.HandleBasicDeliver(string consumerTag, ulong deliveryTag, bool redelivered, string exchange, string routingKey,
- in ReadOnlyBasicProperties properties, ReadOnlyMemory body)
+ Task IBasicConsumer.HandleBasicDeliverAsync(string consumerTag, ulong deliveryTag, bool redelivered, string exchange, string routingKey,
+ ReadOnlyBasicProperties properties, ReadOnlyMemory body)
{
throw new InvalidOperationException("Should never be called. Enable 'DispatchConsumersAsync'.");
}
diff --git a/projects/RabbitMQ.Client/client/api/BasicGetResult.cs b/projects/RabbitMQ.Client/client/api/BasicGetResult.cs
index 64a23a5f1f..aef3d51750 100644
--- a/projects/RabbitMQ.Client/client/api/BasicGetResult.cs
+++ b/projects/RabbitMQ.Client/client/api/BasicGetResult.cs
@@ -72,7 +72,7 @@ public sealed class BasicGetResult
public readonly ReadOnlyMemory Body;
///
- /// Retrieve the delivery tag for this message. See also .
+ /// Retrieve the delivery tag for this message. See also .
///
public readonly ulong DeliveryTag;
diff --git a/projects/RabbitMQ.Client/client/api/ConnectionFactory.cs b/projects/RabbitMQ.Client/client/api/ConnectionFactory.cs
index 7a50ae9e85..3cc437b4e4 100644
--- a/projects/RabbitMQ.Client/client/api/ConnectionFactory.cs
+++ b/projects/RabbitMQ.Client/client/api/ConnectionFactory.cs
@@ -403,19 +403,6 @@ public IAuthMechanismFactory AuthMechanismFactory(IEnumerable argServerM
return null;
}
- ///
- /// Create a connection to one of the endpoints provided by the IEndpointResolver
- /// returned by the EndpointResolverFactory. By default the configured
- /// hostname and port are used.
- ///
- ///
- /// When the configured hostname was not reachable.
- ///
- public IConnection CreateConnection()
- {
- return CreateConnection(ClientProvidedName);
- }
-
///
/// Asynchronously reate a connection to one of the endpoints provided by the IEndpointResolver
/// returned by the EndpointResolverFactory. By default the configured
@@ -425,31 +412,12 @@ public IConnection CreateConnection()
///
/// When the configured hostname was not reachable.
///
- public ValueTask CreateConnectionAsync(
+ public Task CreateConnectionAsync(
CancellationToken cancellationToken = default)
{
return CreateConnectionAsync(ClientProvidedName, cancellationToken);
}
- ///
- /// Create a connection to one of the endpoints provided by the IEndpointResolver
- /// returned by the EndpointResolverFactory. By default the configured
- /// hostname and port are used.
- ///
- ///
- /// Application-specific connection name, will be displayed in the management UI
- /// if RabbitMQ server supports it. This value doesn't have to be unique and cannot
- /// be used as a connection identifier, e.g. in HTTP API requests.
- /// This value is supposed to be human-readable.
- ///
- ///
- /// When the configured hostname was not reachable.
- ///
- public IConnection CreateConnection(string clientProvidedName)
- {
- return CreateConnection(EndpointResolverFactory(LocalEndpoints()), clientProvidedName);
- }
-
///
/// Asynchronously create a connection to one of the endpoints provided by the IEndpointResolver
/// returned by the EndpointResolverFactory. By default the configured
@@ -465,31 +433,12 @@ public IConnection CreateConnection(string clientProvidedName)
///
/// When the configured hostname was not reachable.
///
- public ValueTask CreateConnectionAsync(string clientProvidedName,
+ public Task CreateConnectionAsync(string clientProvidedName,
CancellationToken cancellationToken = default)
{
return CreateConnectionAsync(EndpointResolverFactory(LocalEndpoints()), clientProvidedName, cancellationToken);
}
- ///
- /// Create a connection using a list of hostnames using the configured port.
- /// By default each hostname is tried in a random order until a successful connection is
- /// found or the list is exhausted using the DefaultEndpointResolver.
- /// The selection behaviour can be overridden by configuring the EndpointResolverFactory.
- ///
- ///
- /// List of hostnames to use for the initial
- /// connection and recovery.
- ///
- /// Open connection
- ///
- /// When no hostname was reachable.
- ///
- public IConnection CreateConnection(IEnumerable hostnames)
- {
- return CreateConnection(hostnames, ClientProvidedName);
- }
-
///
/// Asynchronously create a connection using a list of hostnames using the configured port.
/// By default each hostname is tried in a random order until a successful connection is
@@ -505,38 +454,12 @@ public IConnection CreateConnection(IEnumerable hostnames)
///
/// When no hostname was reachable.
///
- public ValueTask CreateConnectionAsync(IEnumerable hostnames,
+ public Task CreateConnectionAsync(IEnumerable hostnames,
CancellationToken cancellationToken = default)
{
return CreateConnectionAsync(hostnames, ClientProvidedName, cancellationToken);
}
- ///
- /// Create a connection using a list of hostnames using the configured port.
- /// By default each endpoint is tried in a random order until a successful connection is
- /// found or the list is exhausted.
- /// The selection behaviour can be overridden by configuring the EndpointResolverFactory.
- ///
- ///
- /// List of hostnames to use for the initial
- /// connection and recovery.
- ///
- ///
- /// Application-specific connection name, will be displayed in the management UI
- /// if RabbitMQ server supports it. This value doesn't have to be unique and cannot
- /// be used as a connection identifier, e.g. in HTTP API requests.
- /// This value is supposed to be human-readable.
- ///
- /// Open connection
- ///
- /// When no hostname was reachable.
- ///
- public IConnection CreateConnection(IEnumerable hostnames, string clientProvidedName)
- {
- IEnumerable endpoints = hostnames.Select(h => new AmqpTcpEndpoint(h, Port, Ssl, MaxMessageSize));
- return CreateConnection(EndpointResolverFactory(endpoints), clientProvidedName);
- }
-
///
/// Asynchronously create a connection using a list of hostnames using the configured port.
/// By default each endpoint is tried in a random order until a successful connection is
@@ -558,31 +481,13 @@ public IConnection CreateConnection(IEnumerable hostnames, string client
///
/// When no hostname was reachable.
///
- public ValueTask CreateConnectionAsync(IEnumerable hostnames, string clientProvidedName,
+ public Task CreateConnectionAsync(IEnumerable hostnames, string clientProvidedName,
CancellationToken cancellationToken = default)
{
IEnumerable endpoints = hostnames.Select(h => new AmqpTcpEndpoint(h, Port, Ssl, MaxMessageSize));
return CreateConnectionAsync(EndpointResolverFactory(endpoints), clientProvidedName, cancellationToken);
}
- ///
- /// Create a connection using a list of endpoints. By default each endpoint will be tried
- /// in a random order until a successful connection is found or the list is exhausted.
- /// The selection behaviour can be overridden by configuring the EndpointResolverFactory.
- ///
- ///
- /// List of endpoints to use for the initial
- /// connection and recovery.
- ///
- /// Open connection
- ///
- /// When no hostname was reachable.
- ///
- public IConnection CreateConnection(IEnumerable endpoints)
- {
- return CreateConnection(endpoints, ClientProvidedName);
- }
-
///
/// Asynchronously create a connection using a list of endpoints. By default each endpoint will be tried
/// in a random order until a successful connection is found or the list is exhausted.
@@ -597,36 +502,12 @@ public IConnection CreateConnection(IEnumerable endpoints)
///
/// When no hostname was reachable.
///
- public ValueTask CreateConnectionAsync(IEnumerable endpoints,
+ public Task CreateConnectionAsync(IEnumerable endpoints,
CancellationToken cancellationToken = default)
{
return CreateConnectionAsync(endpoints, ClientProvidedName, cancellationToken);
}
- ///
- /// Create a connection using a list of endpoints. By default each endpoint will be tried
- /// in a random order until a successful connection is found or the list is exhausted.
- /// The selection behaviour can be overridden by configuring the EndpointResolverFactory.
- ///
- ///
- /// List of endpoints to use for the initial
- /// connection and recovery.
- ///
- ///
- /// Application-specific connection name, will be displayed in the management UI
- /// if RabbitMQ server supports it. This value doesn't have to be unique and cannot
- /// be used as a connection identifier, e.g. in HTTP API requests.
- /// This value is supposed to be human-readable.
- ///
- /// Open connection
- ///
- /// When no hostname was reachable.
- ///
- public IConnection CreateConnection(IEnumerable endpoints, string clientProvidedName)
- {
- return CreateConnection(EndpointResolverFactory(endpoints), clientProvidedName);
- }
-
///
/// Asynchronously create a connection using a list of endpoints. By default each endpoint will be tried
/// in a random order until a successful connection is found or the list is exhausted.
@@ -647,52 +528,12 @@ public IConnection CreateConnection(IEnumerable endpoints, stri
///
/// When no hostname was reachable.
///
- public ValueTask CreateConnectionAsync(IEnumerable endpoints, string clientProvidedName,
+ public Task CreateConnectionAsync(IEnumerable endpoints, string clientProvidedName,
CancellationToken cancellationToken = default)
{
return CreateConnectionAsync(EndpointResolverFactory(endpoints), clientProvidedName, cancellationToken);
}
- ///
- /// Create a connection using an IEndpointResolver.
- ///
- ///
- /// The endpointResolver that returns the endpoints to use for the connection attempt.
- ///
- ///
- /// Application-specific connection name, will be displayed in the management UI
- /// if RabbitMQ server supports it. This value doesn't have to be unique and cannot
- /// be used as a connection identifier, e.g. in HTTP API requests.
- /// This value is supposed to be human-readable.
- ///
- /// Open connection
- ///
- /// When no hostname was reachable.
- ///
- public IConnection CreateConnection(IEndpointResolver endpointResolver, string clientProvidedName)
- {
- ConnectionConfig config = CreateConfig(clientProvidedName);
- try
- {
- if (AutomaticRecoveryEnabled)
- {
- var c = new AutorecoveringConnection(config, endpointResolver);
- return (AutorecoveringConnection)c.Open();
- }
- else
- {
- IFrameHandler frameHandler = endpointResolver.SelectOneAsync(
- CreateFrameHandlerAsync, CancellationToken.None).EnsureCompleted();
- var c = new Connection(config, frameHandler);
- return (Connection)c.Open();
- }
- }
- catch (Exception ex)
- {
- throw new BrokerUnreachableException(ex);
- }
- }
-
///
/// Asynchronously create a connection using an IEndpointResolver.
///
@@ -710,7 +551,7 @@ public IConnection CreateConnection(IEndpointResolver endpointResolver, string c
///
/// When no hostname was reachable.
///
- public async ValueTask CreateConnectionAsync(IEndpointResolver endpointResolver, string clientProvidedName,
+ public async Task CreateConnectionAsync(IEndpointResolver endpointResolver, string clientProvidedName,
CancellationToken cancellationToken = default)
{
ConnectionConfig config = CreateConfig(clientProvidedName);
diff --git a/projects/RabbitMQ.Client/client/api/DefaultBasicConsumer.cs b/projects/RabbitMQ.Client/client/api/DefaultBasicConsumer.cs
index 15b40ea808..6d7e6c5b9a 100644
--- a/projects/RabbitMQ.Client/client/api/DefaultBasicConsumer.cs
+++ b/projects/RabbitMQ.Client/client/api/DefaultBasicConsumer.cs
@@ -32,6 +32,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Threading.Tasks;
using RabbitMQ.Client.Events;
using RabbitMQ.Client.Impl;
@@ -39,7 +40,7 @@ namespace RabbitMQ.Client
{
///
/// Useful default/base implementation of .
- /// Subclass and override in application code.
+ /// Subclass and override in application code.
///
///
/// Note that the "Handle*" methods run in the connection's thread!
@@ -68,7 +69,7 @@ public DefaultBasicConsumer(IChannel channel)
///
/// Retrieve the consumer tags this consumer is registered as; to be used to identify
- /// this consumer, for example, when cancelling it with .
+ /// this consumer, for example, when cancelling it with .
/// This value is an array because a single consumer instance can be reused to consume on
/// multiple channels.
///
@@ -141,21 +142,22 @@ public virtual void HandleBasicConsumeOk(string consumerTag)
/// Called each time a message is delivered for this consumer.
///
///
- /// This is a no-op implementation. It will not acknowledge deliveries via
+ /// This is a no-op implementation. It will not acknowledge deliveries via
/// if consuming in automatic acknowledgement mode.
/// Subclasses must copy or fully use delivery body before returning.
/// Accessing the body at a later point is unsafe as its memory can
/// be already released.
///
- public virtual void HandleBasicDeliver(string consumerTag,
+ public virtual Task HandleBasicDeliverAsync(string consumerTag,
ulong deliveryTag,
bool redelivered,
string exchange,
string routingKey,
- in ReadOnlyBasicProperties properties,
+ ReadOnlyBasicProperties properties,
ReadOnlyMemory body)
{
// Nothing to do here.
+ return Task.CompletedTask;
}
///
diff --git a/projects/RabbitMQ.Client/client/api/IAsyncBasicConsumer.cs b/projects/RabbitMQ.Client/client/api/IAsyncBasicConsumer.cs
index 291eda1293..2a3c2d1ce1 100644
--- a/projects/RabbitMQ.Client/client/api/IAsyncBasicConsumer.cs
+++ b/projects/RabbitMQ.Client/client/api/IAsyncBasicConsumer.cs
@@ -43,7 +43,7 @@ public interface IAsyncBasicConsumer
///
///
/// Does nothing with the passed in information.
- /// Note that in particular, some delivered messages may require acknowledgement via .
+ /// Note that in particular, some delivered messages may require acknowledgement via .
/// The implementation of this method in this class does NOT acknowledge such messages.
///
Task HandleBasicDeliver(string consumerTag,
diff --git a/projects/RabbitMQ.Client/client/api/IBasicConsumer.cs b/projects/RabbitMQ.Client/client/api/IBasicConsumer.cs
index d5244e973e..7c796911db 100644
--- a/projects/RabbitMQ.Client/client/api/IBasicConsumer.cs
+++ b/projects/RabbitMQ.Client/client/api/IBasicConsumer.cs
@@ -30,7 +30,7 @@
//---------------------------------------------------------------------------
using System;
-
+using System.Threading.Tasks;
using RabbitMQ.Client.Events;
namespace RabbitMQ.Client
@@ -86,15 +86,15 @@ public interface IBasicConsumer
///
///
/// Does nothing with the passed in information.
- /// Note that in particular, some delivered messages may require acknowledgement via .
+ /// Note that in particular, some delivered messages may require acknowledgement via .
/// The implementation of this method in this class does NOT acknowledge such messages.
///
- void HandleBasicDeliver(string consumerTag,
+ Task HandleBasicDeliverAsync(string consumerTag,
ulong deliveryTag,
bool redelivered,
string exchange,
string routingKey,
- in ReadOnlyBasicProperties properties,
+ ReadOnlyBasicProperties properties,
ReadOnlyMemory body);
///
diff --git a/projects/RabbitMQ.Client/client/api/IChannel.cs b/projects/RabbitMQ.Client/client/api/IChannel.cs
index 579ca518c4..5a98e65837 100644
--- a/projects/RabbitMQ.Client/client/api/IChannel.cs
+++ b/projects/RabbitMQ.Client/client/api/IChannel.cs
@@ -143,41 +143,15 @@ public interface IChannel : IDisposable
///
event EventHandler ChannelShutdown;
- /// Acknknowledges one or more messages.
- /// The delivery tag.
- /// Ack all messages up to the delivery tag if set to true.
- void BasicAck(ulong deliveryTag, bool multiple);
-
/// Asynchronously acknknowledges one or more messages.
/// The delivery tag.
/// Ack all messages up to the delivery tag if set to true.
ValueTask BasicAckAsync(ulong deliveryTag, bool multiple);
- /// Cancel a Basic content-class consumer.
- /// The consumer tag.
- void BasicCancel(string consumerTag);
-
/// Asynchronously cancel a Basic content-class consumer.
/// The consumer tag.
- ValueTask BasicCancelAsync(string consumerTag);
-
- ///
- /// Same as BasicCancel but sets nowait to true and returns void (as there
- /// will be no response from the server).
- ///
- /// The consumer tag.
- void BasicCancelNoWait(string consumerTag);
-
- /// Start a Basic content-class consumer.
- /// The queue.
- /// If set to true, automatically ack messages.
- /// The consumer tag.
- /// If set to true, this consumer will not receive messages published by the same connection.
- /// If set to true, the consumer is exclusive.
- /// Consumer arguments.
- /// The consumer, an instance of
- ///
- string BasicConsume(string queue, bool autoAck, string consumerTag, bool noLocal, bool exclusive, IDictionary arguments, IBasicConsumer consumer);
+ /// If set to true, do not require a response from the server.
+ Task BasicCancelAsync(string consumerTag, bool noWait = false);
/// Asynchronously start a Basic content-class consumer.
/// The queue.
@@ -188,17 +162,7 @@ public interface IChannel : IDisposable
/// Consumer arguments.
/// The consumer, an instance of
///
- ValueTask BasicConsumeAsync(string queue, bool autoAck, string consumerTag, bool noLocal, bool exclusive, IDictionary arguments, IBasicConsumer consumer);
-
- ///
- /// Retrieve an individual message, if
- /// one is available; returns null if the server answers that
- /// no messages are currently available. See also .
- ///
- /// The queue.
- /// If set to true, automatically ack the message.
- ///
- BasicGetResult BasicGet(string queue, bool autoAck);
+ Task BasicConsumeAsync(string queue, bool autoAck, string consumerTag, bool noLocal, bool exclusive, IDictionary arguments, IBasicConsumer consumer);
///
/// Asynchronously retrieve an individual message, if
@@ -210,14 +174,6 @@ public interface IChannel : IDisposable
///
ValueTask BasicGetAsync(string queue, bool autoAck);
- ///
- /// Nack one or more delivered message(s).
- ///
- /// The delivery tag.
- /// If set to true, nack all messages up to the current tag.
- /// If set to true, requeue nack'd messages.
- void BasicNack(ulong deliveryTag, bool multiple, bool requeue);
-
///
/// Asynchronously nack one or more delivered message(s).
///
@@ -228,28 +184,6 @@ public interface IChannel : IDisposable
#nullable enable
- ///
- /// Publishes a message.
- ///
- ///
- ///
- /// Routing key must be shorter than 255 bytes.
- ///
- ///
- void BasicPublish(string exchange, string routingKey, in TProperties basicProperties, ReadOnlyMemory body = default, bool mandatory = false)
- where TProperties : IReadOnlyBasicProperties, IAmqpHeader;
-
- ///
- /// Publishes a message.
- ///
- ///
- ///
- /// Routing key must be shorter than 255 bytes.
- ///
- ///
- void BasicPublish(CachedString exchange, CachedString routingKey, in TProperties basicProperties, ReadOnlyMemory body = default, bool mandatory = false)
- where TProperties : IReadOnlyBasicProperties, IAmqpHeader;
-
///
/// Asynchronously publishes a message.
///
@@ -281,28 +215,10 @@ ValueTask BasicPublishAsync(CachedString exchange, CachedString rou
/// The prefetch count.
/// If set to true, use global prefetch.
/// See the Consumer Prefetch documentation.
- void BasicQos(uint prefetchSize, ushort prefetchCount, bool global);
-
- ///
- /// Configures QoS parameters of the Basic content-class.
- ///
- /// Size of the prefetch in bytes.
- /// The prefetch count.
- /// If set to true, use global prefetch.
- /// See the Consumer Prefetch documentation.
- ValueTask BasicQosAsync(uint prefetchSize, ushort prefetchCount, bool global);
-
- /// Reject a delivered message.
- void BasicReject(ulong deliveryTag, bool requeue);
+ Task BasicQosAsync(uint prefetchSize, ushort prefetchCount, bool global);
/// Reject a delivered message.
- ValueTask BasicRejectAsync(ulong deliveryTag, bool requeue);
-
- /// Close this session.
- /// The reply code to send for closing (See under "Reply Codes" in the AMQP specification).
- /// The reply text to send for closing.
- /// Whether or not the close is an abort (ignoring certain exceptions).
- void Close(ushort replyCode, string replyText, bool abort);
+ Task BasicRejectAsync(ulong deliveryTag, bool requeue);
///
/// Asynchronously close this session.
@@ -310,7 +226,7 @@ ValueTask BasicPublishAsync(CachedString exchange, CachedString rou
/// The reply code to send for closing (See under "Reply Codes" in the AMQP specification).
/// The reply text to send for closing.
/// Whether or not the close is an abort (ignoring certain exceptions).
- ValueTask CloseAsync(ushort replyCode, string replyText, bool abort);
+ Task CloseAsync(ushort replyCode, string replyText, bool abort);
///
/// Asynchronously close this session.
@@ -318,23 +234,10 @@ ValueTask BasicPublishAsync(CachedString exchange, CachedString rou
/// The instance containing the close data.
/// Whether or not the close is an abort (ignoring certain exceptions).
///
- ValueTask CloseAsync(ShutdownEventArgs reason, bool abort);
-
- /// Enable publisher confirmations.
- void ConfirmSelect();
+ Task CloseAsync(ShutdownEventArgs reason, bool abort);
/// Asynchronously enable publisher confirmations.
- ValueTask ConfirmSelectAsync();
-
- ///
- /// Bind an exchange to an exchange.
- ///
- ///
- ///
- /// Routing key must be shorter than 255 bytes.
- ///
- ///
- void ExchangeBind(string destination, string source, string routingKey, IDictionary arguments);
+ Task ConfirmSelectAsync();
///
/// Asynchronously binds an exchange to an exchange.
@@ -344,40 +247,18 @@ ValueTask BasicPublishAsync(CachedString exchange, CachedString rou
/// Routing key must be shorter than 255 bytes.
///
///
- ValueTask ExchangeBindAsync(string destination, string source, string routingKey, IDictionary arguments);
-
- ///
- /// Like ExchangeBind but sets nowait to true.
- ///
- ///
- ///
- /// Routing key must be shorter than 255 bytes.
- ///
- ///
- void ExchangeBindNoWait(string destination, string source, string routingKey, IDictionary arguments);
-
- /// Declare an exchange.
- ///
- /// The exchange is declared non-passive and non-internal.
- /// The "nowait" option is not used.
- ///
- void ExchangeDeclare(string exchange, string type, bool durable, bool autoDelete, IDictionary arguments);
+ Task ExchangeBindAsync(string destination, string source, string routingKey,
+ IDictionary arguments = null, bool noWait = false);
/// Asynchronously declare an exchange.
///
/// The exchange is declared non-internal.
- /// The "nowait" option is not used.
///
- ValueTask ExchangeDeclareAsync(string exchange, string type, bool passive, bool durable, bool autoDelete, IDictionary arguments);
+ Task ExchangeDeclareAsync(string exchange, string type, bool durable, bool autoDelete,
+ IDictionary arguments = null, bool passive = false, bool noWait = false);
///
- /// Same as ExchangeDeclare but sets nowait to true and returns void (as there
- /// will be no response from the server).
- ///
- void ExchangeDeclareNoWait(string exchange, string type, bool durable, bool autoDelete, IDictionary arguments);
-
- ///
- /// Do a passive exchange declaration.
+ /// Asynchronously do a passive exchange declaration.
///
///
/// This method performs a "passive declare" on an exchange,
@@ -385,30 +266,12 @@ ValueTask BasicPublishAsync(CachedString exchange, CachedString rou
/// It will do nothing if the exchange already exists and result
/// in a channel-level protocol exception (channel closure) if not.
///
- void ExchangeDeclarePassive(string exchange);
-
- ///
- /// Delete an exchange.
- ///
- void ExchangeDelete(string exchange, bool ifUnused);
+ Task ExchangeDeclarePassiveAsync(string exchange);
///
/// Asynchronously delete an exchange.
///
- ValueTask ExchangeDeleteAsync(string exchange, bool ifUnused);
-
- ///
- /// Like ExchangeDelete but sets nowait to true.
- ///
- void ExchangeDeleteNoWait(string exchange, bool ifUnused);
-
- ///
- /// Unbind an exchange from an exchange.
- ///
- ///
- /// Routing key must be shorter than 255 bytes.
- ///
- void ExchangeUnbind(string destination, string source, string routingKey, IDictionary arguments);
+ Task ExchangeDeleteAsync(string exchange, bool ifUnused = false, bool noWait = false);
///
/// Asynchronously unbind an exchange from an exchange.
@@ -416,29 +279,8 @@ ValueTask BasicPublishAsync(CachedString exchange, CachedString rou
///
/// Routing key must be shorter than 255 bytes.
///
- ValueTask ExchangeUnbindAsync(string destination, string source, string routingKey, IDictionary arguments);
-
- ///
- /// Like ExchangeUnbind but sets nowait to true.
- ///
- ///
- ///
- /// Routing key must be shorter than 255 bytes.
- ///
- ///
- void ExchangeUnbindNoWait(string destination, string source, string routingKey, IDictionary arguments);
-
- ///
- /// Bind a queue to an exchange.
- ///
- /// The queue.
- /// The exchange.
- /// The routing key.
- /// The arguments.
- ///
- /// Routing key must be shorter than 255 bytes.
- ///
- void QueueBind(string queue, string exchange, string routingKey, IDictionary arguments);
+ Task ExchangeUnbindAsync(string destination, string source, string routingKey,
+ IDictionary arguments = null, bool noWait = false);
///
/// Asynchronously bind a queue to an exchange.
@@ -447,57 +289,33 @@ ValueTask BasicPublishAsync(CachedString exchange, CachedString rou
/// The exchange.
/// The routing key.
/// The arguments.
+ /// If set to true, do not require a response from the server.
///
/// Routing key must be shorter than 255 bytes.
///
- ValueTask QueueBindAsync(string queue, string exchange, string routingKey, IDictionary arguments);
-
- /// Same as QueueBind but sets nowait parameter to true.
- ///
- ///
- /// Routing key must be shorter than 255 bytes.
- ///
- ///
- void QueueBindNoWait(string queue, string exchange, string routingKey, IDictionary arguments);
-
- ///
- /// Declares a queue. See the Queues guide to learn more.
- ///
- /// The name of the queue. Pass an empty string to make the server generate a name.
- /// Should this queue will survive a broker restart?
- /// Should this queue use be limited to its declaring connection? Such a queue will be deleted when its declaring connection closes.
- /// Should this queue be auto-deleted when its last consumer (if any) unsubscribes?
- /// Optional; additional queue arguments, e.g. "x-queue-type"
- QueueDeclareOk QueueDeclare(string queue, bool durable, bool exclusive, bool autoDelete, IDictionary arguments);
+ Task QueueBindAsync(string queue, string exchange, string routingKey,
+ IDictionary arguments = null, bool noWait = false);
///
/// Asynchronously declares a queue. See the Queues guide to learn more.
///
/// The name of the queue. Pass an empty string to make the server generate a name.
- /// Set to true
to passively declare the queue (i.e. check for its existence)
/// Should this queue will survive a broker restart?
/// Should this queue use be limited to its declaring connection? Such a queue will be deleted when its declaring connection closes.
/// Should this queue be auto-deleted when its last consumer (if any) unsubscribes?
/// Optional; additional queue arguments, e.g. "x-queue-type"
- ValueTask QueueDeclareAsync(string queue, bool passive, bool durable, bool exclusive, bool autoDelete, IDictionary arguments);
+ /// Optional; Set to true
to passively declare the queue (i.e. check for its existence)
+ /// Optional; Set to true to not require a response from the server.
+ Task QueueDeclareAsync(string queue, bool durable, bool exclusive, bool autoDelete,
+ IDictionary arguments = null, bool passive = false, bool noWait = false);
- ///
- /// Declares a queue. See the Queues guide to learn more.
- ///
- /// The name of the queue. Pass an empty string to make the server generate a name.
- /// Should this queue will survive a broker restart?
- /// Should this queue use be limited to its declaring connection? Such a queue will be deleted when its declaring connection closes.
- /// Should this queue be auto-deleted when its last consumer (if any) unsubscribes?
- /// Optional; additional queue arguments, e.g. "x-queue-type"
- void QueueDeclareNoWait(string queue, bool durable, bool exclusive, bool autoDelete, IDictionary arguments);
-
- /// Declare a queue passively.
+ /// Asynchronously declare a queue passively.
///
///The queue is declared passive, non-durable,
///non-exclusive, and non-autodelete, with no arguments.
///The queue is declared passively; i.e. only check if it exists.
///
- QueueDeclareOk QueueDeclarePassive(string queue);
+ Task QueueDeclarePassiveAsync(string queue);
///
/// Returns the number of messages in a queue ready to be delivered
@@ -505,7 +323,7 @@ ValueTask BasicPublishAsync(CachedString exchange, CachedString rou
/// an exception will be closed with an exception.
///
/// The name of the queue
- uint MessageCount(string queue);
+ Task MessageCountAsync(string queue);
///
/// Returns the number of consumers on a queue.
@@ -513,56 +331,24 @@ ValueTask BasicPublishAsync(CachedString exchange, CachedString rou
/// an exception will be closed with an exception.
///
/// The name of the queue
- uint ConsumerCount(string queue);
+ Task ConsumerCountAsync(string queue);
///
- /// Deletes a queue. See the Queues guide to learn more.
+ /// Asynchronously deletes a queue. See the Queues guide to learn more.
///
/// The name of the queue.
/// Only delete the queue if it is unused.
/// Only delete the queue if it is empty.
- /// Returns the number of messages purged during deletion.
- uint QueueDelete(string queue, bool ifUnused, bool ifEmpty);
-
- ///
- /// Asynchronously deletes a queue. See the Queues guide to learn more.
- ///
+ /// If set to true, do not require a response from the server.
///
///Returns the number of messages purged during queue deletion.
///
- ValueTask QueueDeleteAsync(string queue, bool ifUnused, bool ifEmpty);
-
- ///
- ///Same as QueueDelete but sets nowait parameter to true
- ///and returns void (as there will be no response from the server)
- ///
- /// The name of the queue.
- /// Only delete the queue if it is unused.
- /// Only delete the queue if it is empty.
- /// Returns the number of messages purged during deletion.
- void QueueDeleteNoWait(string queue, bool ifUnused, bool ifEmpty);
-
- /// Asynchronously purge a queue of messages.
- /// The queue.
- /// Returns the number of messages purged.
- uint QueuePurge(string queue);
+ Task QueueDeleteAsync(string queue, bool ifUnused, bool ifEmpty, bool noWait = false);
/// Asynchronously purge a queue of messages.
/// The queue.
/// Returns the number of messages purged.
- ValueTask QueuePurgeAsync(string queue);
-
- ///
- /// Unbind a queue from an exchange.
- ///
- /// The queue.
- /// The exchange.
- /// The routing key.
- /// The arguments.
- ///
- /// Routing key must be shorter than 255 bytes.
- ///
- void QueueUnbind(string queue, string exchange, string routingKey, IDictionary arguments);
+ Task QueuePurgeAsync(string queue);
///
/// Asynchronously unbind a queue from an exchange.
@@ -574,38 +360,16 @@ ValueTask BasicPublishAsync(CachedString exchange, CachedString rou
///
/// Routing key must be shorter than 255 bytes.
///
- ValueTask QueueUnbindAsync(string queue, string exchange, string routingKey, IDictionary arguments);
-
- /// Commit this session's active TX transaction.
- void TxCommit();
+ Task QueueUnbindAsync(string queue, string exchange, string routingKey, IDictionary arguments);
/// Asynchronously commit this session's active TX transaction.
- ValueTask TxCommitAsync();
-
- /// Roll back this session's active TX transaction.
- void TxRollback();
+ Task TxCommitAsync();
/// Asynchronously roll back this session's active TX transaction.
- ValueTask TxRollbackAsync();
-
- /// Enable TX mode for this session.
- void TxSelect();
+ Task TxRollbackAsync();
/// Asynchronously enable TX mode for this session.
- ValueTask TxSelectAsync();
-
- ///
- /// Wait until all published messages on this channel have been confirmed.
- ///
- /// True if no nacks were received within the timeout, otherwise false.
- ///
- /// Waits until all messages published on this channel since the last call have
- /// been either ack'd or nack'd by the server. Returns whether
- /// all the messages were ack'd (and none were nack'd).
- /// Throws an exception when called on a channel
- /// that does not have publisher confirms enabled.
- ///
- bool WaitForConfirms();
+ Task TxSelectAsync();
///
/// Asynchronously wait until all published messages on this channel have been confirmed.
@@ -621,17 +385,6 @@ ValueTask BasicPublishAsync(CachedString exchange, CachedString rou
///
Task WaitForConfirmsAsync(CancellationToken token = default);
- ///
- /// Wait until all published messages on this channel have been confirmed.
- ///
- ///
- /// Waits until all messages published on this channel since the last call have
- /// been ack'd by the server. If a nack is received or the timeout
- /// elapses, throws an IOException exception immediately and closes
- /// the channel.
- ///
- void WaitForConfirmsOrDie();
-
///
/// Wait until all published messages on this channel have been confirmed.
///
diff --git a/projects/RabbitMQ.Client/client/api/IChannelExtensions.cs b/projects/RabbitMQ.Client/client/api/IChannelExtensions.cs
index 74edd17fb2..862035fa9b 100644
--- a/projects/RabbitMQ.Client/client/api/IChannelExtensions.cs
+++ b/projects/RabbitMQ.Client/client/api/IChannelExtensions.cs
@@ -38,21 +38,8 @@ namespace RabbitMQ.Client
{
public static class IChannelExtensions
{
- /// Start a Basic content-class consumer.
- public static string BasicConsume(this IChannel channel,
- IBasicConsumer consumer,
- string queue,
- bool autoAck = false,
- string consumerTag = "",
- bool noLocal = false,
- bool exclusive = false,
- IDictionary arguments = null)
- {
- return channel.BasicConsume(queue, autoAck, consumerTag, noLocal, exclusive, arguments, consumer);
- }
-
/// Asynchronously start a Basic content-class consumer.
- public static ValueTask BasicConsumeAsync(this IChannel channel,
+ public static Task BasicConsumeAsync(this IChannel channel,
IBasicConsumer consumer,
string queue,
bool autoAck = false,
@@ -64,33 +51,16 @@ public static class IChannelExtensions
return channel.BasicConsumeAsync(queue, autoAck, consumerTag, noLocal, exclusive, arguments, consumer);
}
- /// Start a Basic content-class consumer.
- public static string BasicConsume(this IChannel channel, string queue,
- bool autoAck,
- IBasicConsumer consumer)
- {
- return channel.BasicConsume(queue, autoAck, string.Empty, false, false, null, consumer);
- }
-
/// Asynchronously start a Basic content-class consumer.
- public static ValueTask BasicConsumeAsync(this IChannel channel, string queue,
+ public static Task BasicConsumeAsync(this IChannel channel, string queue,
bool autoAck,
IBasicConsumer consumer)
{
return channel.BasicConsumeAsync(queue, autoAck, string.Empty, false, false, null, consumer);
}
- /// Start a Basic content-class consumer.
- public static string BasicConsume(this IChannel channel, string queue,
- bool autoAck,
- string consumerTag,
- IBasicConsumer consumer)
- {
- return channel.BasicConsume(queue, autoAck, consumerTag, false, false, null, consumer);
- }
-
/// Asynchronously start a Basic content-class consumer.
- public static ValueTask BasicConsumeAsync(this IChannel channel, string queue,
+ public static Task BasicConsumeAsync(this IChannel channel, string queue,
bool autoAck,
string consumerTag,
IBasicConsumer consumer)
@@ -98,18 +68,8 @@ public static class IChannelExtensions
return channel.BasicConsumeAsync(queue, autoAck, consumerTag, false, false, null, consumer);
}
- /// Start a Basic content-class consumer.
- public static string BasicConsume(this IChannel channel, string queue,
- bool autoAck,
- string consumerTag,
- IDictionary arguments,
- IBasicConsumer consumer)
- {
- return channel.BasicConsume(queue, autoAck, consumerTag, false, false, arguments, consumer);
- }
-
/// Asynchronously start a Basic content-class consumer.
- public static ValueTask BasicConsumeAsync(this IChannel channel, string queue,
+ public static Task BasicConsumeAsync(this IChannel channel, string queue,
bool autoAck,
string consumerTag,
IDictionary arguments,
@@ -119,225 +79,64 @@ public static class IChannelExtensions
}
#nullable enable
+
///
/// (Extension method) Convenience overload of BasicPublish.
///
///
/// The publication occurs with mandatory=false and immediate=false.
///
- public static void BasicPublish(this IChannel channel, PublicationAddress addr, in T basicProperties, ReadOnlyMemory body)
- where T : IReadOnlyBasicProperties, IAmqpHeader
- {
- channel.BasicPublish(addr.ExchangeName, addr.RoutingKey, in basicProperties, body);
- }
-
public static ValueTask BasicPublishAsync(this IChannel channel, PublicationAddress addr, in T basicProperties, ReadOnlyMemory body)
where T : IReadOnlyBasicProperties, IAmqpHeader
{
return channel.BasicPublishAsync(addr.ExchangeName, addr.RoutingKey, in basicProperties, body);
}
- public static void BasicPublish(this IChannel channel, string exchange, string routingKey, ReadOnlyMemory body = default, bool mandatory = false)
- => channel.BasicPublish(exchange, routingKey, in EmptyBasicProperty.Empty, body, mandatory);
-
public static ValueTask BasicPublishAsync(this IChannel channel, string exchange, string routingKey, ReadOnlyMemory body = default, bool mandatory = false)
=> channel.BasicPublishAsync(exchange, routingKey, in EmptyBasicProperty.Empty, body, mandatory);
- public static void BasicPublish(this IChannel channel, CachedString exchange, CachedString routingKey, ReadOnlyMemory body = default, bool mandatory = false)
- => channel.BasicPublish(exchange, routingKey, in EmptyBasicProperty.Empty, body, mandatory);
-
public static ValueTask BasicPublishAsync(this IChannel channel, CachedString exchange, CachedString routingKey, ReadOnlyMemory body = default, bool mandatory = false)
=> channel.BasicPublishAsync(exchange, routingKey, in EmptyBasicProperty.Empty, body, mandatory);
-#nullable disable
- ///
- /// Declare a queue.
- ///
- public static QueueDeclareOk QueueDeclare(this IChannel channel, string queue = "", bool durable = false, bool exclusive = true,
- bool autoDelete = true, IDictionary arguments = null)
- {
- return channel.QueueDeclare(queue, durable, exclusive, autoDelete, arguments);
- }
+#nullable disable
///
/// Asynchronously declare a queue.
///
- public static ValueTask QueueDeclareAsync(this IChannel channel, string queue = "", bool durable = false, bool exclusive = true,
- bool autoDelete = true, IDictionary arguments = null)
+ public static Task QueueDeclareAsync(this IChannel channel, string queue = "", bool durable = false, bool exclusive = true,
+ bool autoDelete = true, IDictionary arguments = null, bool noWait = false)
{
return channel.QueueDeclareAsync(queue: queue, passive: false,
- durable: durable, exclusive: exclusive, autoDelete: autoDelete, arguments: arguments);
- }
-
- ///
- /// Bind an exchange to an exchange.
- ///
- public static void ExchangeBind(this IChannel channel, string destination, string source, string routingKey, IDictionary arguments = null)
- {
- channel.ExchangeBind(destination, source, routingKey, arguments);
- }
-
- ///
- /// Asynchronously bind an exchange to an exchange.
- ///
- public static ValueTask ExchangeBindAsync(this IChannel channel, string destination, string source, string routingKey, IDictionary arguments = null)
- {
- return channel.ExchangeBindAsync(destination, source, routingKey, arguments);
- }
-
- ///
- /// Like exchange bind but sets nowait to true.
- ///
- public static void ExchangeBindNoWait(this IChannel channel, string destination, string source, string routingKey, IDictionary arguments = null)
- {
- channel.ExchangeBindNoWait(destination, source, routingKey, arguments);
- }
-
- ///
- /// Declare an exchange.
- ///
- public static void ExchangeDeclare(this IChannel channel, string exchange, string type, bool durable = false, bool autoDelete = false,
- IDictionary arguments = null)
- {
- channel.ExchangeDeclare(exchange, type, durable, autoDelete, arguments);
+ durable: durable, exclusive: exclusive, autoDelete: autoDelete,
+ arguments: arguments, noWait: noWait);
}
///
/// Asynchronously declare an exchange.
///
- public static ValueTask ExchangeDeclareAsync(this IChannel channel, string exchange, string type, bool durable = false, bool autoDelete = false,
- IDictionary arguments = null)
+ public static Task ExchangeDeclareAsync(this IChannel channel, string exchange, string type, bool durable = false, bool autoDelete = false,
+ IDictionary arguments = null, bool noWait = false)
{
- return channel.ExchangeDeclareAsync(exchange, type, false, durable, autoDelete, arguments);
- }
-
- ///
- /// Like ExchangeDeclare but sets nowait to true.
- ///
- public static void ExchangeDeclareNoWait(this IChannel channel, string exchange, string type, bool durable = false, bool autoDelete = false,
- IDictionary arguments = null)
- {
- channel.ExchangeDeclareNoWait(exchange, type, durable, autoDelete, arguments);
- }
-
- ///
- /// Unbinds an exchange.
- ///
- public static void ExchangeUnbind(this IChannel channel, string destination,
- string source,
- string routingKey,
- IDictionary arguments = null)
- {
- channel.ExchangeUnbind(destination, source, routingKey, arguments);
- }
-
- ///
- /// Asynchronously unbinds an exchange.
- ///
- public static ValueTask ExchangeUnbindAsync(this IChannel channel, string destination,
- string source,
- string routingKey,
- IDictionary arguments = null)
- {
- return channel.ExchangeUnbindAsync(destination, source, routingKey, arguments);
- }
-
- ///
- /// Deletes an exchange.
- ///
- public static void ExchangeDelete(this IChannel channel, string exchange, bool ifUnused = false)
- {
- channel.ExchangeDelete(exchange, ifUnused);
- }
-
- ///
- /// Asynchronously deletes an exchange.
- ///
- public static ValueTask ExchangeDeleteAsync(this IChannel channel, string exchange, bool ifUnused = false)
- {
- return channel.ExchangeDeleteAsync(exchange, ifUnused);
- }
-
- ///
- /// Like ExchangeDelete but sets nowait to true.
- ///
- public static void ExchangeDeleteNoWait(this IChannel channel, string exchange, bool ifUnused = false)
- {
- channel.ExchangeDeleteNoWait(exchange, ifUnused);
- }
-
- ///
- /// Binds a queue.
- ///
- public static void QueueBind(this IChannel channel, string queue, string exchange, string routingKey, IDictionary arguments = null)
- {
- channel.QueueBind(queue, exchange, routingKey, arguments);
- }
-
- ///
- /// Asynchronously binds a queue.
- ///
- public static ValueTask QueueBindAsync(this IChannel channel, string queue, string exchange, string routingKey, IDictionary arguments = null)
- {
- return channel.QueueBindAsync(queue, exchange, routingKey, arguments);
- }
-
- ///
- /// Deletes a queue.
- ///
- public static uint QueueDelete(this IChannel channel, string queue, bool ifUnused = false, bool ifEmpty = false)
- {
- return channel.QueueDelete(queue, ifUnused, ifEmpty);
+ return channel.ExchangeDeclareAsync(exchange, type, durable, autoDelete,
+ arguments: arguments, passive: false, noWait: noWait);
}
///
/// Asynchronously deletes a queue.
///
- public static ValueTask QueueDeleteAsync(this IChannel channel, string queue, bool ifUnused = false, bool ifEmpty = false)
+ public static Task QueueDeleteAsync(this IChannel channel, string queue, bool ifUnused = false, bool ifEmpty = false)
{
return channel.QueueDeleteAsync(queue, ifUnused, ifEmpty);
}
- ///
- /// Like QueueDelete but sets nowait to true.
- ///
- public static void QueueDeleteNoWait(this IChannel channel, string queue, bool ifUnused = false, bool ifEmpty = false)
- {
- channel.QueueDeleteNoWait(queue, ifUnused, ifEmpty);
- }
-
- ///
- /// Unbinds a queue.
- ///
- public static void QueueUnbind(this IChannel channel, string queue, string exchange, string routingKey, IDictionary arguments = null)
- {
- channel.QueueUnbind(queue, exchange, routingKey, arguments);
- }
-
///
/// Asynchronously unbinds a queue.
///
- public static ValueTask QueueUnbindAsync(this IChannel channel, string queue, string exchange, string routingKey, IDictionary arguments = null)
+ public static Task QueueUnbindAsync(this IChannel channel, string queue, string exchange, string routingKey, IDictionary arguments = null)
{
return channel.QueueUnbindAsync(queue, exchange, routingKey, arguments);
}
- ///
- /// Abort this session.
- ///
- ///
- /// If the session is already closed (or closing), then this
- /// method does nothing but wait for the in-progress close
- /// operation to complete. This method will not return to the
- /// caller until the shutdown is complete.
- /// In comparison to normal method, will not throw
- /// or or any other during closing channel.
- ///
- public static void Abort(this IChannel channel)
- {
- channel.Close(Constants.ReplySuccess, "Goodbye", true);
- }
-
///
/// Asynchronously abort this session.
///
@@ -346,44 +145,14 @@ public static void Abort(this IChannel channel)
/// method does nothing but wait for the in-progress close
/// operation to complete. This method will not return to the
/// caller until the shutdown is complete.
- /// In comparison to normal method, will not throw
+ /// In comparison to normal method, will not throw
/// or or any other during closing channel.
///
- public static ValueTask AbortAsync(this IChannel channel)
+ public static Task AbortAsync(this IChannel channel)
{
return channel.CloseAsync(Constants.ReplySuccess, "Goodbye", true);
}
- ///
- /// Abort this session.
- ///
- ///
- /// The method behaves in the same way as , with the only
- /// difference that the channel is closed with the given channel close code and message.
- ///
- /// The close code (See under "Reply Codes" in the AMQP specification)
- ///
- ///
- /// A message indicating the reason for closing the channel
- ///
- ///
- public static void Abort(this IChannel channel, ushort replyCode, string replyText)
- {
- channel.Close(replyCode, replyText, true);
- }
-
- /// Close this session.
- ///
- /// If the session is already closed (or closing), then this
- /// method does nothing but wait for the in-progress close
- /// operation to complete. This method will not return to the
- /// caller until the shutdown is complete.
- ///
- public static void Close(this IChannel channel)
- {
- channel.Close(Constants.ReplySuccess, "Goodbye", false);
- }
-
/// Asynchronously close this session.
///
/// If the session is already closed (or closing), then this
@@ -391,32 +160,11 @@ public static void Close(this IChannel channel)
/// operation to complete. This method will not return to the
/// caller until the shutdown is complete.
///
- public static ValueTask CloseAsync(this IChannel channel)
+ public static Task CloseAsync(this IChannel channel)
{
return channel.CloseAsync(Constants.ReplySuccess, "Goodbye", false);
}
- ///
- /// Close this channel.
- ///
- /// The channel.
- /// The reply code.
- /// The reply text.
- ///
- /// The method behaves in the same way as Close(), with the only
- /// difference that the channel is closed with the given channel
- /// close code and message.
- ///
- /// The close code (See under "Reply Codes" in the AMQP specification)
- ///
- /// A message indicating the reason for closing the channel
- ///
- ///
- public static void Close(this IChannel channel, ushort replyCode, string replyText)
- {
- channel.Close(replyCode, replyText, false);
- }
-
///
/// Asynchronously close this channel.
///
@@ -433,7 +181,7 @@ public static void Close(this IChannel channel, ushort replyCode, string replyTe
/// A message indicating the reason for closing the channel
///
///
- public static ValueTask CloseAsync(this IChannel channel, ushort replyCode, string replyText)
+ public static Task CloseAsync(this IChannel channel, ushort replyCode, string replyText)
{
return channel.CloseAsync(replyCode, replyText, false);
}
diff --git a/projects/RabbitMQ.Client/client/api/IConnection.cs b/projects/RabbitMQ.Client/client/api/IConnection.cs
index 11653032a1..d7fec6358c 100644
--- a/projects/RabbitMQ.Client/client/api/IConnection.cs
+++ b/projects/RabbitMQ.Client/client/api/IConnection.cs
@@ -214,17 +214,7 @@ public interface IConnection : INetworkConnection, IDisposable
///
/// The new secret.
/// The reason for the secret update.
- void UpdateSecret(string newSecret, string reason);
-
- ///
- /// Close this connection and all its channels
- /// and wait with a timeout for all the in-progress close operations to complete.
- ///
- /// The close code (See under "Reply Codes" in the AMQP 0-9-1 specification).
- /// A message indicating the reason for closing the connection.
- /// Operation timeout.
- /// Whether or not this close is an abort (ignores certain exceptions).
- void Close(ushort reasonCode, string reasonText, TimeSpan timeout, bool abort);
+ Task UpdateSecretAsync(string newSecret, string reason);
///
/// Asynchronously close this connection and all its channels
@@ -234,17 +224,12 @@ public interface IConnection : INetworkConnection, IDisposable
/// A message indicating the reason for closing the connection.
/// Operation timeout.
/// Whether or not this close is an abort (ignores certain exceptions).
- ValueTask CloseAsync(ushort reasonCode, string reasonText, TimeSpan timeout, bool abort);
-
- ///
- /// Create and return a fresh channel, session, and channel.
- ///
- IChannel CreateChannel();
+ Task CloseAsync(ushort reasonCode, string reasonText, TimeSpan timeout, bool abort);
///
/// Asynchronously create and return a fresh channel, session, and channel.
///
// TODO cancellation token
- ValueTask CreateChannelAsync();
+ Task CreateChannelAsync();
}
}
diff --git a/projects/RabbitMQ.Client/client/api/IConnectionExtensions.cs b/projects/RabbitMQ.Client/client/api/IConnectionExtensions.cs
index fecb606b78..6f879fae0e 100644
--- a/projects/RabbitMQ.Client/client/api/IConnectionExtensions.cs
+++ b/projects/RabbitMQ.Client/client/api/IConnectionExtensions.cs
@@ -7,22 +7,6 @@ namespace RabbitMQ.Client
{
public static class IConnectionExtensions
{
- ///
- /// Close this connection and all its channels.
- ///
- ///
- /// Note that all active channels and sessions will be
- /// closed if this method is called. It will wait for the in-progress
- /// close operation to complete. This method will not return to the caller
- /// until the shutdown is complete. If the connection is already closed
- /// (or closing), then this method will do nothing.
- /// It can also throw when socket was closed unexpectedly.
- ///
- public static void Close(this IConnection connection)
- {
- connection.Close(Constants.ReplySuccess, "Goodbye", InternalConstants.DefaultConnectionCloseTimeout, false);
- }
-
///
/// Asynchronously close this connection and all its channels.
///
@@ -34,34 +18,16 @@ public static void Close(this IConnection connection)
/// (or closing), then this method will do nothing.
/// It can also throw when socket was closed unexpectedly.
///
- public static ValueTask CloseAsync(this IConnection connection)
+ public static Task CloseAsync(this IConnection connection)
{
return connection.CloseAsync(Constants.ReplySuccess, "Goodbye", InternalConstants.DefaultConnectionCloseTimeout, false);
}
- ///
- /// Close this connection and all its channels.
- ///
- ///
- /// The method behaves in the same way as , with the only
- /// difference that the connection is closed with the given connection close code and message.
- ///
- /// The close code (See under "Reply Codes" in the AMQP specification).
- ///
- ///
- /// A message indicating the reason for closing the connection.
- ///
- ///
- public static void Close(this IConnection connection, ushort reasonCode, string reasonText)
- {
- connection.Close(reasonCode, reasonText, InternalConstants.DefaultConnectionCloseTimeout, false);
- }
-
///
/// Asynchronously close this connection and all its channels.
///
///
- /// The method behaves in the same way as , with the only
+ /// The method behaves in the same way as , with the only
/// difference that the connection is closed with the given connection close code and message.
///
/// The close code (See under "Reply Codes" in the AMQP specification).
@@ -70,31 +36,11 @@ public static void Close(this IConnection connection, ushort reasonCode, string
/// A message indicating the reason for closing the connection.
///
///
- public static ValueTask CloseAsync(this IConnection connection, ushort reasonCode, string reasonText)
+ public static Task CloseAsync(this IConnection connection, ushort reasonCode, string reasonText)
{
return connection.CloseAsync(reasonCode, reasonText, InternalConstants.DefaultConnectionCloseTimeout, false);
}
- ///
- /// Close this connection and all its channels
- /// and wait with a timeout for all the in-progress close operations to complete.
- ///
- ///
- /// Note that all active channels and sessions will be
- /// closed if this method is called. It will wait for the in-progress
- /// close operation to complete with a timeout. If the connection is
- /// already closed (or closing), then this method will do nothing.
- /// It can also throw when socket was closed unexpectedly.
- /// If timeout is reached and the close operations haven't finished, then socket is forced to close.
- ///
- /// To wait infinitely for the close operations to complete use .
- ///
- ///
- public static void Close(this IConnection connection, TimeSpan timeout)
- {
- connection.Close(Constants.ReplySuccess, "Goodbye", timeout, false);
- }
-
///
/// Asynchronously close this connection and all its channels
/// and wait with a timeout for all the in-progress close operations to complete.
@@ -110,39 +56,17 @@ public static void Close(this IConnection connection, TimeSpan timeout)
/// To wait infinitely for the close operations to complete use .
///
///
- public static ValueTask CloseAsync(this IConnection connection, TimeSpan timeout)
+ public static Task CloseAsync(this IConnection connection, TimeSpan timeout)
{
return connection.CloseAsync(Constants.ReplySuccess, "Goodbye", timeout, false);
}
- ///
- /// Close this connection and all its channels
- /// and wait with a timeout for all the in-progress close operations to complete.
- ///
- ///
- /// The method behaves in the same way as , with the only
- /// difference that the connection is closed with the given connection close code and message.
- ///
- /// The close code (See under "Reply Codes" in the AMQP 0-9-1 specification).
- ///
- ///
- /// A message indicating the reason for closing the connection.
- ///
- ///
- /// Operation timeout.
- ///
- ///
- public static void Close(this IConnection connection, ushort reasonCode, string reasonText, TimeSpan timeout)
- {
- connection.Close(reasonCode, reasonText, timeout, false);
- }
-
///
/// Asynchronously close this connection and all its channels
/// and wait with a timeout for all the in-progress close operations to complete.
///
///
- /// The method behaves in the same way as , with the only
+ /// The method behaves in the same way as , with the only
/// difference that the connection is closed with the given connection close code and message.
///
/// The close code (See under "Reply Codes" in the AMQP 0-9-1 specification).
@@ -154,62 +78,30 @@ public static void Close(this IConnection connection, ushort reasonCode, string
/// Operation timeout.
///
///
- public static ValueTask CloseAsync(this IConnection connection, ushort reasonCode, string reasonText, TimeSpan timeout)
+ public static Task CloseAsync(this IConnection connection, ushort reasonCode, string reasonText, TimeSpan timeout)
{
return connection.CloseAsync(reasonCode, reasonText, timeout, false);
}
- ///
- /// Abort this connection and all its channels.
- ///
- ///
- /// Note that all active channels and sessions will be closed if this method is called.
- /// In comparison to normal method, will not throw
- /// during closing connection.
- ///This method waits infinitely for the in-progress close operation to complete.
- ///
- public static void Abort(this IConnection connection)
- {
- connection.Close(Constants.ReplySuccess, "Connection close forced", InternalConstants.DefaultConnectionAbortTimeout, true);
- }
-
///
/// Asynchronously abort this connection and all its channels.
///
///
/// Note that all active channels and sessions will be closed if this method is called.
- /// In comparison to normal method, will not throw
+ /// In comparison to normal method, will not throw
/// during closing connection.
///This method waits infinitely for the in-progress close operation to complete.
///
- public static ValueTask AbortAsync(this IConnection connection)
+ public static Task AbortAsync(this IConnection connection)
{
return connection.CloseAsync(Constants.ReplySuccess, "Connection close forced", InternalConstants.DefaultConnectionAbortTimeout, true);
}
- ///
- /// Abort this connection and all its channels.
- ///
- ///
- /// The method behaves in the same way as , with the only
- /// difference that the connection is closed with the given connection close code and message.
- ///
- /// The close code (See under "Reply Codes" in the AMQP 0-9-1 specification)
- ///
- ///
- /// A message indicating the reason for closing the connection
- ///
- ///
- public static void Abort(this IConnection connection, ushort reasonCode, string reasonText)
- {
- connection.Close(reasonCode, reasonText, InternalConstants.DefaultConnectionAbortTimeout, true);
- }
-
///
/// Asynchronously abort this connection and all its channels.
///
///
- /// The method behaves in the same way as , with the only
+ /// The method behaves in the same way as , with the only
/// difference that the connection is closed with the given connection close code and message.
///
/// The close code (See under "Reply Codes" in the AMQP 0-9-1 specification)
@@ -218,35 +110,17 @@ public static void Abort(this IConnection connection, ushort reasonCode, string
/// A message indicating the reason for closing the connection
///
///
- public static ValueTask AbortAsync(this IConnection connection, ushort reasonCode, string reasonText)
+ public static Task AbortAsync(this IConnection connection, ushort reasonCode, string reasonText)
{
return connection.CloseAsync(reasonCode, reasonText, InternalConstants.DefaultConnectionAbortTimeout, true);
}
- ///
- /// Abort this connection and all its channels and wait with a
- /// timeout for all the in-progress close operations to complete.
- ///
- ///
- /// This method, behaves in a similar way as method with the
- /// only difference that it explicitly specifies a timeout given
- /// for all the in-progress close operations to complete.
- /// If timeout is reached and the close operations haven't finished, then socket is forced to close.
- ///
- /// To wait infinitely for the close operations to complete use .
- ///
- ///
- public static void Abort(this IConnection connection, TimeSpan timeout)
- {
- connection.Close(Constants.ReplySuccess, "Connection close forced", timeout, true);
- }
-
///
/// Asynchronously abort this connection and all its channels and wait with a
/// timeout for all the in-progress close operations to complete.
///
///
- /// This method, behaves in a similar way as method with the
+ /// This method, behaves in a similar way as method with the
/// only difference that it explicitly specifies a timeout given
/// for all the in-progress close operations to complete.
/// If timeout is reached and the close operations haven't finished, then socket is forced to close.
@@ -254,36 +128,17 @@ public static void Abort(this IConnection connection, TimeSpan timeout)
/// To wait infinitely for the close operations to complete use .
///
///
- public static ValueTask AbortAsync(this IConnection connection, TimeSpan timeout)
+ public static Task AbortAsync(this IConnection connection, TimeSpan timeout)
{
return connection.CloseAsync(Constants.ReplySuccess, "Connection close forced", timeout, true);
}
- ///
- /// Abort this connection and all its channels and wait with a
- /// timeout for all the in-progress close operations to complete.
- ///
- ///
- /// The method behaves in the same way as , with the only
- /// difference that the connection is closed with the given connection close code and message.
- ///
- /// The close code (See under "Reply Codes" in the AMQP 0-9-1 specification).
- ///
- ///
- /// A message indicating the reason for closing the connection.
- ///
- ///
- public static void Abort(this IConnection connection, ushort reasonCode, string reasonText, TimeSpan timeout)
- {
- connection.Close(reasonCode, reasonText, timeout, true);
- }
-
///
/// Asynchronously abort this connection and all its channels and wait with a
/// timeout for all the in-progress close operations to complete.
///
///
- /// The method behaves in the same way as , with the only
+ /// The method behaves in the same way as , with the only
/// difference that the connection is closed with the given connection close code and message.
///
/// The close code (See under "Reply Codes" in the AMQP 0-9-1 specification).
@@ -292,7 +147,7 @@ public static void Abort(this IConnection connection, ushort reasonCode, string
/// A message indicating the reason for closing the connection.
///
///
- public static ValueTask AbortAsync(this IConnection connection, ushort reasonCode, string reasonText, TimeSpan timeout)
+ public static Task AbortAsync(this IConnection connection, ushort reasonCode, string reasonText, TimeSpan timeout)
{
return connection.CloseAsync(reasonCode, reasonText, timeout, true);
}
diff --git a/projects/RabbitMQ.Client/client/api/IConnectionFactory.cs b/projects/RabbitMQ.Client/client/api/IConnectionFactory.cs
index a555b8b039..f80391d969 100644
--- a/projects/RabbitMQ.Client/client/api/IConnectionFactory.cs
+++ b/projects/RabbitMQ.Client/client/api/IConnectionFactory.cs
@@ -98,28 +98,11 @@ public interface IConnectionFactory
///
IAuthMechanismFactory AuthMechanismFactory(IEnumerable mechanismNames);
- ///
- /// Create a connection to the specified endpoint.
- ///
- IConnection CreateConnection();
-
///
/// Asynchronously create a connection to the specified endpoint.
///
/// Cancellation token for this connection
- ValueTask CreateConnectionAsync(CancellationToken cancellationToken = default);
-
- ///
- /// Create a connection to the specified endpoint.
- ///
- ///
- /// Application-specific connection name, will be displayed in the management UI
- /// if RabbitMQ server supports it. This value doesn't have to be unique and cannot
- /// be used as a connection identifier, e.g. in HTTP API requests.
- /// This value is supposed to be human-readable.
- ///
- /// Open connection
- IConnection CreateConnection(string clientProvidedName);
+ Task CreateConnectionAsync(CancellationToken cancellationToken = default);
///
/// Asynchronously create a connection to the specified endpoint.
@@ -132,14 +115,7 @@ public interface IConnectionFactory
///
/// Cancellation token for this connection
/// Open connection
- ValueTask CreateConnectionAsync(string clientProvidedName, CancellationToken cancellationToken = default);
-
- ///
- /// Connects to the first reachable hostname from the list.
- ///
- /// List of host names to use
- /// Open connection
- IConnection CreateConnection(IEnumerable hostnames);
+ Task CreateConnectionAsync(string clientProvidedName, CancellationToken cancellationToken = default);
///
/// Asynchronously connects to the first reachable hostname from the list.
@@ -147,20 +123,7 @@ public interface IConnectionFactory
/// List of host names to use
/// Cancellation token for this connection
/// Open connection
- ValueTask CreateConnectionAsync(IEnumerable hostnames, CancellationToken cancellationToken = default);
-
- ///
- /// Connects to the first reachable hostname from the list.
- ///
- /// List of host names to use
- ///
- /// Application-specific connection name, will be displayed in the management UI
- /// if RabbitMQ server supports it. This value doesn't have to be unique and cannot
- /// be used as a connection identifier, e.g. in HTTP API requests.
- /// This value is supposed to be human-readable.
- ///
- /// Open connection
- IConnection CreateConnection(IEnumerable hostnames, string clientProvidedName);
+ Task CreateConnectionAsync(IEnumerable hostnames, CancellationToken cancellationToken = default);
///
/// Asynchronously connects to the first reachable hostname from the list.
@@ -174,23 +137,9 @@ public interface IConnectionFactory
///
/// Cancellation token for this connection
/// Open connection
- ValueTask CreateConnectionAsync(IEnumerable hostnames, string clientProvidedName,
+ Task CreateConnectionAsync(IEnumerable hostnames, string clientProvidedName,
CancellationToken cancellationToken = default);
- ///
- /// Create a connection using a list of endpoints.
- /// The selection behaviour can be overridden by configuring the EndpointResolverFactory.
- ///
- ///
- /// List of endpoints to use for the initial
- /// connection and recovery.
- ///
- /// Open connection
- ///
- /// When no hostname was reachable.
- ///
- IConnection CreateConnection(IEnumerable endpoints);
-
///
/// Asynchronously create a connection using a list of endpoints.
/// The selection behaviour can be overridden by configuring the EndpointResolverFactory.
@@ -204,27 +153,7 @@ public interface IConnectionFactory
///
/// When no hostname was reachable.
///
- ValueTask CreateConnectionAsync(IEnumerable endpoints, CancellationToken cancellationToken = default);
-
- ///
- /// Create a connection using a list of endpoints.
- /// The selection behaviour can be overridden by configuring the EndpointResolverFactory.
- ///
- ///
- /// List of endpoints to use for the initial
- /// connection and recovery.
- ///
- ///
- /// Application-specific connection name, will be displayed in the management UI
- /// if RabbitMQ server supports it. This value doesn't have to be unique and cannot
- /// be used as a connection identifier, e.g. in HTTP API requests.
- /// This value is supposed to be human-readable.
- ///
- /// Open connection
- ///
- /// When no hostname was reachable.
- ///
- IConnection CreateConnection(IEnumerable endpoints, string clientProvidedName);
+ Task CreateConnectionAsync(IEnumerable endpoints, CancellationToken cancellationToken = default);
///
/// Asynchronously create a connection using a list of endpoints.
@@ -245,7 +174,7 @@ public interface IConnectionFactory
///
/// When no hostname was reachable.
///
- ValueTask CreateConnectionAsync(IEnumerable endpoints, string clientProvidedName,
+ Task CreateConnectionAsync(IEnumerable endpoints, string clientProvidedName,
CancellationToken cancellationToken = default);
///
diff --git a/projects/RabbitMQ.Client/client/api/ICredentialsRefresher.cs b/projects/RabbitMQ.Client/client/api/ICredentialsRefresher.cs
index 08b474c2cb..2d648f1f87 100644
--- a/projects/RabbitMQ.Client/client/api/ICredentialsRefresher.cs
+++ b/projects/RabbitMQ.Client/client/api/ICredentialsRefresher.cs
@@ -33,14 +33,15 @@
using System.Collections.Concurrent;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.Tracing;
+using System.Threading.Tasks;
namespace RabbitMQ.Client
{
public interface ICredentialsRefresher
{
- ICredentialsProvider Register(ICredentialsProvider provider, NotifyCredentialRefreshed callback);
+ ICredentialsProvider Register(ICredentialsProvider provider, NotifyCredentialRefreshedAsync callback);
bool Unregister(ICredentialsProvider provider);
- delegate void NotifyCredentialRefreshed(bool successfully);
+ delegate Task NotifyCredentialRefreshedAsync(bool successfully);
}
[EventSource(Name = "TimerBasedCredentialRefresher")]
@@ -70,9 +71,9 @@ public class TimerBasedCredentialRefresherEventSource : EventSource
public class TimerBasedCredentialRefresher : ICredentialsRefresher
{
- private readonly ConcurrentDictionary _registrations = new();
+ private readonly ConcurrentDictionary _registrations = new ConcurrentDictionary();
- public ICredentialsProvider Register(ICredentialsProvider provider, ICredentialsRefresher.NotifyCredentialRefreshed callback)
+ public ICredentialsProvider Register(ICredentialsProvider provider, ICredentialsRefresher.NotifyCredentialRefreshedAsync callback)
{
if (!provider.ValidUntil.HasValue || provider.ValidUntil.Value.Equals(TimeSpan.Zero))
{
@@ -112,7 +113,7 @@ public bool Unregister(ICredentialsProvider provider)
}
}
- private System.Timers.Timer scheduleTimer(ICredentialsProvider provider, ICredentialsRefresher.NotifyCredentialRefreshed callback)
+ private System.Timers.Timer scheduleTimer(ICredentialsProvider provider, ICredentialsRefresher.NotifyCredentialRefreshedAsync callback)
{
System.Timers.Timer timer = new System.Timers.Timer();
timer.Interval = provider.ValidUntil.Value.TotalMilliseconds * (1.0 - (1 / 3.0));
@@ -142,7 +143,7 @@ private System.Timers.Timer scheduleTimer(ICredentialsProvider provider, ICreden
class NoOpCredentialsRefresher : ICredentialsRefresher
{
- public ICredentialsProvider Register(ICredentialsProvider provider, ICredentialsRefresher.NotifyCredentialRefreshed callback)
+ public ICredentialsProvider Register(ICredentialsProvider provider, ICredentialsRefresher.NotifyCredentialRefreshedAsync callback)
{
return provider;
}
diff --git a/projects/RabbitMQ.Client/client/api/TopologyRecoveryExceptionHandler.cs b/projects/RabbitMQ.Client/client/api/TopologyRecoveryExceptionHandler.cs
index a40097f383..4efc3c54e8 100644
--- a/projects/RabbitMQ.Client/client/api/TopologyRecoveryExceptionHandler.cs
+++ b/projects/RabbitMQ.Client/client/api/TopologyRecoveryExceptionHandler.cs
@@ -1,4 +1,5 @@
using System;
+using System.Threading.Tasks;
namespace RabbitMQ.Client
{
@@ -16,10 +17,10 @@ public class TopologyRecoveryExceptionHandler
private Func _queueRecoveryExceptionCondition;
private Func _bindingRecoveryExceptionCondition;
private Func _consumerRecoveryExceptionCondition;
- private Action _exchangeRecoveryExceptionHandler;
- private Action _queueRecoveryExceptionHandler;
- private Action _bindingRecoveryExceptionHandler;
- private Action _consumerRecoveryExceptionHandler;
+ private Func _exchangeRecoveryExceptionHandlerAsync;
+ private Func _queueRecoveryExceptionHandlerAsync;
+ private Func _bindingRecoveryExceptionHandlerAsync;
+ private Func _consumerRecoveryExceptionHandlerAsync;
///
/// Decides which exchange recovery exceptions the custom exception handler is applied to.
@@ -92,64 +93,72 @@ public class TopologyRecoveryExceptionHandler
///
/// Retries, or otherwise handles, an exception thrown when attempting to recover an exchange.
///
- public Action ExchangeRecoveryExceptionHandler
+ public Func ExchangeRecoveryExceptionHandlerAsync
{
- get => _exchangeRecoveryExceptionHandler;
+ get => _exchangeRecoveryExceptionHandlerAsync;
set
{
- if (_exchangeRecoveryExceptionHandler != null)
- throw new InvalidOperationException($"Cannot modify {nameof(ExchangeRecoveryExceptionHandler)} after it has been initialized.");
+ if (_exchangeRecoveryExceptionHandlerAsync != null)
+ {
+ throw new InvalidOperationException($"Cannot modify {nameof(ExchangeRecoveryExceptionHandlerAsync)} after it has been initialized.");
+ }
- _exchangeRecoveryExceptionHandler = value ?? throw new ArgumentNullException(nameof(ExchangeRecoveryExceptionHandler));
+ _exchangeRecoveryExceptionHandlerAsync = value ?? throw new ArgumentNullException(nameof(ExchangeRecoveryExceptionHandlerAsync));
}
}
///
/// Retries, or otherwise handles, an exception thrown when attempting to recover a queue.
///
- public Action QueueRecoveryExceptionHandler
+ public Func QueueRecoveryExceptionHandlerAsync
{
- get => _queueRecoveryExceptionHandler;
+ get => _queueRecoveryExceptionHandlerAsync;
set
{
- if (_queueRecoveryExceptionHandler != null)
- throw new InvalidOperationException($"Cannot modify {nameof(QueueRecoveryExceptionHandler)} after it has been initialized.");
+ if (_queueRecoveryExceptionHandlerAsync != null)
+ {
+ throw new InvalidOperationException($"Cannot modify {nameof(QueueRecoveryExceptionHandlerAsync)} after it has been initialized.");
+ }
- _queueRecoveryExceptionHandler = value ?? throw new ArgumentNullException(nameof(QueueRecoveryExceptionHandler));
+ _queueRecoveryExceptionHandlerAsync = value ?? throw new ArgumentNullException(nameof(QueueRecoveryExceptionHandlerAsync));
}
}
///
/// Retries, or otherwise handles, an exception thrown when attempting to recover a binding.
///
- public Action BindingRecoveryExceptionHandler
+ public Func BindingRecoveryExceptionHandlerAsync
{
- get => _bindingRecoveryExceptionHandler;
+ get => _bindingRecoveryExceptionHandlerAsync;
set
{
- if (_bindingRecoveryExceptionHandler != null)
- throw new InvalidOperationException($"Cannot modify {nameof(BindingRecoveryExceptionHandler)} after it has been initialized.");
+ if (_bindingRecoveryExceptionHandlerAsync != null)
+ {
+ throw new InvalidOperationException($"Cannot modify {nameof(BindingRecoveryExceptionHandlerAsync)} after it has been initialized.");
+ }
- _bindingRecoveryExceptionHandler = value ?? throw new ArgumentNullException(nameof(BindingRecoveryExceptionHandler));
+ _bindingRecoveryExceptionHandlerAsync = value ?? throw new ArgumentNullException(nameof(BindingRecoveryExceptionHandlerAsync));
}
}
///
/// Retries, or otherwise handles, an exception thrown when attempting to recover a consumer.
///
- public Action ConsumerRecoveryExceptionHandler
+ public Func ConsumerRecoveryExceptionHandlerAsync
{
- get => _consumerRecoveryExceptionHandler;
+ get => _consumerRecoveryExceptionHandlerAsync;
set
{
- if (_consumerRecoveryExceptionHandler != null)
- throw new InvalidOperationException($"Cannot modify {nameof(ConsumerRecoveryExceptionHandler)} after it has been initialized.");
+ if (_consumerRecoveryExceptionHandlerAsync != null)
+ {
+ throw new InvalidOperationException($"Cannot modify {nameof(ConsumerRecoveryExceptionHandlerAsync)} after it has been initialized.");
+ }
- _consumerRecoveryExceptionHandler = value ?? throw new ArgumentNullException(nameof(ConsumerRecoveryExceptionHandler));
+ _consumerRecoveryExceptionHandlerAsync = value ?? throw new ArgumentNullException(nameof(ConsumerRecoveryExceptionHandlerAsync));
}
}
}
diff --git a/projects/RabbitMQ.Client/client/events/EventingBasicConsumer.cs b/projects/RabbitMQ.Client/client/events/EventingBasicConsumer.cs
index 4a6bad730b..d69d72e23a 100644
--- a/projects/RabbitMQ.Client/client/events/EventingBasicConsumer.cs
+++ b/projects/RabbitMQ.Client/client/events/EventingBasicConsumer.cs
@@ -30,6 +30,7 @@
//---------------------------------------------------------------------------
using System;
+using System.Threading.Tasks;
namespace RabbitMQ.Client.Events
{
@@ -84,10 +85,10 @@ public override void HandleBasicConsumeOk(string consumerTag)
/// Accessing the body at a later point is unsafe as its memory can
/// be already released.
///
- public override void HandleBasicDeliver(string consumerTag, ulong deliveryTag, bool redelivered, string exchange, string routingKey,
- in ReadOnlyBasicProperties properties, ReadOnlyMemory body)
+ public override async Task HandleBasicDeliverAsync(string consumerTag, ulong deliveryTag, bool redelivered, string exchange, string routingKey,
+ ReadOnlyBasicProperties properties, ReadOnlyMemory body)
{
- base.HandleBasicDeliver(consumerTag, deliveryTag, redelivered, exchange, routingKey, properties, body);
+ await base.HandleBasicDeliverAsync(consumerTag, deliveryTag, redelivered, exchange, routingKey, properties, body);
Received?.Invoke(
this,
new BasicDeliverEventArgs(consumerTag, deliveryTag, redelivered, exchange, routingKey, properties, body));
diff --git a/projects/RabbitMQ.Client/client/framing/Channel.cs b/projects/RabbitMQ.Client/client/framing/Channel.cs
index 9b7246799e..129c4ee809 100644
--- a/projects/RabbitMQ.Client/client/framing/Channel.cs
+++ b/projects/RabbitMQ.Client/client/framing/Channel.cs
@@ -29,7 +29,6 @@
// Copyright (c) 2007-2020 VMware, Inc. All rights reserved.
//---------------------------------------------------------------------------
-using System.Collections.Generic;
using System.Threading.Tasks;
using RabbitMQ.Client.client.framing;
using RabbitMQ.Client.Impl;
@@ -47,21 +46,6 @@ public override void ConnectionTuneOk(ushort channelMax, uint frameMax, ushort h
ChannelSend(new ConnectionTuneOk(channelMax, frameMax, heartbeat));
}
- public override void _Private_BasicCancel(string consumerTag, bool nowait)
- {
- ChannelSend(new BasicCancel(consumerTag, nowait));
- }
-
- public override void _Private_BasicConsume(string queue, string consumerTag, bool noLocal, bool autoAck, bool exclusive, bool nowait, IDictionary arguments)
- {
- ChannelSend(new BasicConsume(queue, consumerTag, noLocal, autoAck, exclusive, nowait, arguments));
- }
-
- public override void _Private_BasicGet(string queue, bool autoAck)
- {
- ChannelSend(new BasicGet(queue, autoAck));
- }
-
public override void _Private_ChannelClose(ushort replyCode, string replyText, ushort classId, ushort methodId)
{
ChannelSend(new ChannelClose(replyCode, replyText, classId, methodId));
@@ -77,189 +61,27 @@ public override void _Private_ChannelFlowOk(bool active)
ChannelSend(new ChannelFlowOk(active));
}
- public override void _Private_ChannelOpen()
- {
- ChannelRpc(new ChannelOpen(), ProtocolCommandId.ChannelOpenOk);
- }
-
- public override void _Private_ConfirmSelect(bool nowait)
- {
- var method = new ConfirmSelect(nowait);
- if (nowait)
- {
- ChannelSend(method);
- }
- else
- {
- ChannelRpc(method, ProtocolCommandId.ConfirmSelectOk);
- }
- }
-
public override void _Private_ConnectionCloseOk()
{
ChannelSend(new ConnectionCloseOk());
}
- public override void _Private_UpdateSecret(byte[] newSecret, string reason)
- {
- ChannelRpc(new ConnectionUpdateSecret(newSecret, reason), ProtocolCommandId.ConnectionUpdateSecretOk);
- }
-
- public override void _Private_ExchangeBind(string destination, string source, string routingKey, bool nowait, IDictionary arguments)
- {
- var method = new ExchangeBind(destination, source, routingKey, nowait, arguments);
- if (nowait)
- {
- ChannelSend(method);
- }
- else
- {
- ChannelRpc(method, ProtocolCommandId.ExchangeBindOk);
- }
- }
-
- public override void _Private_ExchangeDeclare(string exchange, string type, bool passive, bool durable, bool autoDelete, bool @internal, bool nowait, IDictionary arguments)
- {
- var method = new ExchangeDeclare(exchange, type, passive, durable, autoDelete, @internal, nowait, arguments);
- if (nowait)
- {
- ChannelSend(method);
- }
- else
- {
- ChannelRpc(method, ProtocolCommandId.ExchangeDeclareOk);
- }
- }
-
- public override void _Private_ExchangeDelete(string exchange, bool ifUnused, bool nowait)
- {
- var method = new ExchangeDelete(exchange, ifUnused, nowait);
- if (nowait)
- {
- ChannelSend(method);
- }
- else
- {
- ChannelRpc(method, ProtocolCommandId.ExchangeDeleteOk);
- }
- }
-
- public override void _Private_ExchangeUnbind(string destination, string source, string routingKey, bool nowait, IDictionary arguments)
- {
- var method = new ExchangeUnbind(destination, source, routingKey, nowait, arguments);
- if (nowait)
- {
- ChannelSend(method);
- }
- else
- {
- ChannelRpc(method, ProtocolCommandId.ExchangeUnbindOk);
- }
- }
-
- public override void _Private_QueueBind(string queue, string exchange, string routingKey, bool nowait, IDictionary arguments)
- {
- var method = new QueueBind(queue, exchange, routingKey, nowait, arguments);
- if (nowait)
- {
- ChannelSend(method);
- }
- else
- {
- ChannelRpc(method, ProtocolCommandId.QueueBindOk);
- }
- }
-
- public override void _Private_QueueDeclare(string queue, bool passive, bool durable, bool exclusive, bool autoDelete, bool nowait, IDictionary arguments)
- {
- /*
- * Note:
- * Even though nowait is a parameter, ChannelSend must be used
- */
- var method = new QueueDeclare(queue, passive, durable, exclusive, autoDelete, nowait, arguments);
- ChannelSend(method);
- }
-
- public override uint _Private_QueueDelete(string queue, bool ifUnused, bool ifEmpty, bool nowait)
- {
- var method = new QueueDelete(queue, ifUnused, ifEmpty, nowait);
- if (nowait)
- {
- ChannelSend(method);
- return 0xFFFFFFFF;
- }
-
- return ChannelRpc(method, ProtocolCommandId.QueueDeleteOk, memory => new QueueDeleteOk(memory.Span)._messageCount);
- }
-
- public override uint _Private_QueuePurge(string queue, bool nowait)
- {
- var method = new QueuePurge(queue, nowait);
- if (nowait)
- {
- ChannelSend(method);
- return 0xFFFFFFFF;
- }
-
- return ChannelRpc(method, ProtocolCommandId.QueuePurgeOk, memory => new QueuePurgeOk(memory.Span)._messageCount);
- }
-
- public override void BasicAck(ulong deliveryTag, bool multiple)
- {
- ChannelSend(new BasicAck(deliveryTag, multiple));
- }
-
public override ValueTask BasicAckAsync(ulong deliveryTag, bool multiple)
{
var method = new BasicAck(deliveryTag, multiple);
return ModelSendAsync(method);
}
- public override void BasicNack(ulong deliveryTag, bool multiple, bool requeue)
- {
- ChannelSend(new BasicNack(deliveryTag, multiple, requeue));
- }
-
public override ValueTask BasicNackAsync(ulong deliveryTag, bool multiple, bool requeue)
{
var method = new BasicNack(deliveryTag, multiple, requeue);
return ModelSendAsync(method);
}
- public override void BasicQos(uint prefetchSize, ushort prefetchCount, bool global)
- {
- ChannelRpc(new BasicQos(prefetchSize, prefetchCount, global), ProtocolCommandId.BasicQosOk);
- }
-
- public override void BasicReject(ulong deliveryTag, bool requeue)
- {
- ChannelSend(new BasicReject(deliveryTag, requeue));
- }
-
- public override ValueTask BasicRejectAsync(ulong deliveryTag, bool requeue)
+ public override Task BasicRejectAsync(ulong deliveryTag, bool requeue)
{
var method = new BasicReject(deliveryTag, requeue);
- return ModelSendAsync(method);
- }
-
- public override void QueueUnbind(string queue, string exchange, string routingKey, IDictionary arguments)
- {
- ChannelRpc(new QueueUnbind(queue, exchange, routingKey, arguments), ProtocolCommandId.QueueUnbindOk);
- }
-
- public override void TxCommit()
- {
- ChannelRpc(new TxCommit(), ProtocolCommandId.TxCommitOk);
- }
-
- public override void TxRollback()
- {
- ChannelRpc(new TxRollback(), ProtocolCommandId.TxRollbackOk);
- }
-
- public override void TxSelect()
- {
- ChannelRpc(new TxSelect(), ProtocolCommandId.TxSelectOk);
+ return ModelSendAsync(method).AsTask();
}
protected override bool DispatchAsynchronous(in IncomingCommand cmd)
diff --git a/projects/RabbitMQ.Client/client/impl/AsyncRpcContinuations.cs b/projects/RabbitMQ.Client/client/impl/AsyncRpcContinuations.cs
index c4c4955fb2..f673e00091 100644
--- a/projects/RabbitMQ.Client/client/impl/AsyncRpcContinuations.cs
+++ b/projects/RabbitMQ.Client/client/impl/AsyncRpcContinuations.cs
@@ -126,7 +126,7 @@ public override void HandleCommand(in IncomingCommand cmd)
// What to do if setting a result fails?
_tcs.TrySetResult(new ConnectionSecureOrTune
{
- m_tuneDetails = new() { m_channelMax = tune._channelMax, m_frameMax = tune._frameMax, m_heartbeatInSeconds = tune._heartbeat }
+ m_tuneDetails = new ConnectionTuneDetails { m_channelMax = tune._channelMax, m_frameMax = tune._frameMax, m_heartbeatInSeconds = tune._heartbeat }
});
}
else
diff --git a/projects/RabbitMQ.Client/client/impl/AutorecoveringChannel.cs b/projects/RabbitMQ.Client/client/impl/AutorecoveringChannel.cs
index c2526f9954..3f6cdba60f 100644
--- a/projects/RabbitMQ.Client/client/impl/AutorecoveringChannel.cs
+++ b/projects/RabbitMQ.Client/client/impl/AutorecoveringChannel.cs
@@ -45,7 +45,7 @@ internal sealed class AutorecoveringChannel : IChannel, IRecoverable
private AutorecoveringConnection _connection;
private RecoveryAwareChannel _innerChannel;
private bool _disposed;
- private readonly List _recordedConsumerTags = new();
+ private readonly List _recordedConsumerTags = new List();
private ushort _prefetchCountConsumer;
private ushort _prefetchCountGlobal;
@@ -145,7 +145,7 @@ public IBasicConsumer DefaultConsumer
public string CurrentQueue => InnerChannel.CurrentQueue;
- internal async ValueTask AutomaticallyRecoverAsync(AutorecoveringConnection conn, bool recoverConsumers,
+ internal async Task AutomaticallyRecoverAsync(AutorecoveringConnection conn, bool recoverConsumers,
bool recordedEntitiesSemaphoreHeld = false)
{
if (false == recordedEntitiesSemaphoreHeld)
@@ -215,14 +215,14 @@ public void Close(ushort replyCode, string replyText, bool abort)
}
}
- public ValueTask CloseAsync(ushort replyCode, string replyText, bool abort)
+ public Task CloseAsync(ushort replyCode, string replyText, bool abort)
{
ThrowIfDisposed();
var args = new ShutdownEventArgs(ShutdownInitiator.Library, replyCode, replyText);
return CloseAsync(args, abort);
}
- public async ValueTask CloseAsync(ShutdownEventArgs args, bool abort)
+ public async Task CloseAsync(ShutdownEventArgs args, bool abort)
{
ThrowIfDisposed();
try
@@ -248,7 +248,12 @@ public void Dispose()
return;
}
- this.Abort();
+ // TODO rabbitmq-dotnet-client-1472
+ // this.Abort();
+ if (IsOpen)
+ {
+ throw new InvalidOperationException("AutorecoveringChannel must be closed before calling Dispose!");
+ }
_recordedConsumerTags.Clear();
_connection = null;
@@ -256,45 +261,17 @@ public void Dispose()
_disposed = true;
}
- public void BasicAck(ulong deliveryTag, bool multiple)
- => InnerChannel.BasicAck(deliveryTag, multiple);
-
public ValueTask BasicAckAsync(ulong deliveryTag, bool multiple)
=> InnerChannel.BasicAckAsync(deliveryTag, multiple);
- public void BasicCancel(string consumerTag)
- {
- ThrowIfDisposed();
- _connection.DeleteRecordedConsumer(consumerTag, recordedEntitiesSemaphoreHeld: false);
- _innerChannel.BasicCancel(consumerTag);
- }
-
- public ValueTask BasicCancelAsync(string consumerTag)
- {
- ThrowIfDisposed();
- _connection.DeleteRecordedConsumer(consumerTag, recordedEntitiesSemaphoreHeld: false);
- return _innerChannel.BasicCancelAsync(consumerTag);
- }
-
- public void BasicCancelNoWait(string consumerTag)
+ public Task BasicCancelAsync(string consumerTag, bool noWait)
{
ThrowIfDisposed();
_connection.DeleteRecordedConsumer(consumerTag, recordedEntitiesSemaphoreHeld: false);
- _innerChannel.BasicCancelNoWait(consumerTag);
+ return _innerChannel.BasicCancelAsync(consumerTag, noWait);
}
- public string BasicConsume(string queue, bool autoAck, string consumerTag, bool noLocal, bool exclusive,
- IDictionary arguments, IBasicConsumer consumer)
- {
- string resultConsumerTag = InnerChannel.BasicConsume(queue, autoAck, consumerTag, noLocal, exclusive, arguments, consumer);
- var rc = new RecordedConsumer(channel: this, consumer: consumer, consumerTag: resultConsumerTag,
- queue: queue, autoAck: autoAck, exclusive: exclusive, arguments: arguments);
- _connection.RecordConsumer(rc, recordedEntitiesSemaphoreHeld: false);
- _recordedConsumerTags.Add(resultConsumerTag);
- return resultConsumerTag;
- }
-
- public async ValueTask BasicConsumeAsync(string queue, bool autoAck, string consumerTag, bool noLocal, bool exclusive,
+ public async Task BasicConsumeAsync(string queue, bool autoAck, string consumerTag, bool noLocal, bool exclusive,
IDictionary arguments, IBasicConsumer consumer)
{
string resultConsumerTag = await InnerChannel.BasicConsumeAsync(queue, autoAck, consumerTag, noLocal, exclusive, arguments, consumer)
@@ -307,26 +284,12 @@ await _connection.RecordConsumerAsync(rc, recordedEntitiesSemaphoreHeld: false)
return resultConsumerTag;
}
- public BasicGetResult BasicGet(string queue, bool autoAck)
- => InnerChannel.BasicGet(queue, autoAck);
-
public ValueTask BasicGetAsync(string queue, bool autoAck)
=> InnerChannel.BasicGetAsync(queue, autoAck);
- public void BasicNack(ulong deliveryTag, bool multiple, bool requeue)
- => InnerChannel.BasicNack(deliveryTag, multiple, requeue);
-
public ValueTask BasicNackAsync(ulong deliveryTag, bool multiple, bool requeue)
=> InnerChannel.BasicNackAsync(deliveryTag, multiple, requeue);
- public void BasicPublish(string exchange, string routingKey, in TProperties basicProperties, ReadOnlyMemory body, bool mandatory)
- where TProperties : IReadOnlyBasicProperties, IAmqpHeader
- => InnerChannel.BasicPublish(exchange, routingKey, in basicProperties, body, mandatory);
-
- public void BasicPublish(CachedString exchange, CachedString routingKey, in TProperties basicProperties, ReadOnlyMemory body, bool mandatory)
- where TProperties : IReadOnlyBasicProperties, IAmqpHeader
- => InnerChannel.BasicPublish(exchange, routingKey, in basicProperties, body, mandatory);
-
public ValueTask BasicPublishAsync(string exchange, string routingKey, in TProperties basicProperties, ReadOnlyMemory body, bool mandatory)
where TProperties : IReadOnlyBasicProperties, IAmqpHeader
=> InnerChannel.BasicPublishAsync(exchange, routingKey, in basicProperties, body, mandatory);
@@ -335,23 +298,7 @@ public ValueTask BasicPublishAsync(CachedString exchange, CachedStr
where TProperties : IReadOnlyBasicProperties, IAmqpHeader
=> InnerChannel.BasicPublishAsync(exchange, routingKey, in basicProperties, body, mandatory);
- public void BasicQos(uint prefetchSize, ushort prefetchCount, bool global)
- {
- ThrowIfDisposed();
-
- if (global)
- {
- _prefetchCountGlobal = prefetchCount;
- }
- else
- {
- _prefetchCountConsumer = prefetchCount;
- }
-
- _innerChannel.BasicQos(prefetchSize, prefetchCount, global);
- }
-
- public ValueTask BasicQosAsync(uint prefetchSize, ushort prefetchCount, bool global)
+ public Task BasicQosAsync(uint prefetchSize, ushort prefetchCount, bool global)
{
ThrowIfDisposed();
@@ -367,55 +314,33 @@ public ValueTask BasicQosAsync(uint prefetchSize, ushort prefetchCount, bool glo
return _innerChannel.BasicQosAsync(prefetchSize, prefetchCount, global);
}
- public void BasicReject(ulong deliveryTag, bool requeue)
- => InnerChannel.BasicReject(deliveryTag, requeue);
-
- public ValueTask BasicRejectAsync(ulong deliveryTag, bool requeue)
+ public Task BasicRejectAsync(ulong deliveryTag, bool requeue)
=> InnerChannel.BasicRejectAsync(deliveryTag, requeue);
- public void ConfirmSelect()
- {
- InnerChannel.ConfirmSelect();
- _usesPublisherConfirms = true;
- }
-
- public async ValueTask ConfirmSelectAsync()
+ public async Task ConfirmSelectAsync()
{
await InnerChannel.ConfirmSelectAsync()
.ConfigureAwait(false);
_usesPublisherConfirms = true;
}
- public void ExchangeBind(string destination, string source, string routingKey, IDictionary arguments)
- {
- ThrowIfDisposed();
- var recordedBinding = new RecordedBinding(false, destination, source, routingKey, arguments);
- _connection.RecordBinding(recordedBinding, recordedEntitiesSemaphoreHeld: false);
- _innerChannel.ExchangeBind(destination, source, routingKey, arguments);
- }
-
- public async ValueTask ExchangeBindAsync(string destination, string source, string routingKey, IDictionary arguments)
+ public async Task ExchangeBindAsync(string destination, string source, string routingKey,
+ IDictionary arguments, bool noWait)
{
- await InnerChannel.ExchangeBindAsync(destination, source, routingKey, arguments)
+ await InnerChannel.ExchangeBindAsync(destination, source, routingKey, arguments, noWait)
.ConfigureAwait(false);
var recordedBinding = new RecordedBinding(false, destination, source, routingKey, arguments);
await _connection.RecordBindingAsync(recordedBinding, recordedEntitiesSemaphoreHeld: false)
.ConfigureAwait(false);
}
- public void ExchangeBindNoWait(string destination, string source, string routingKey, IDictionary arguments)
- => InnerChannel.ExchangeBindNoWait(destination, source, routingKey, arguments);
+ public Task ExchangeDeclarePassiveAsync(string exchange)
+ => InnerChannel.ExchangeDeclarePassiveAsync(exchange);
- public void ExchangeDeclare(string exchange, string type, bool durable, bool autoDelete, IDictionary arguments)
+ public async Task ExchangeDeclareAsync(string exchange, string type, bool durable, bool autoDelete,
+ IDictionary arguments, bool passive, bool noWait)
{
- InnerChannel.ExchangeDeclare(exchange, type, durable, autoDelete, arguments);
- var recordedExchange = new RecordedExchange(exchange, type, durable, autoDelete, arguments);
- _connection.RecordExchange(recordedExchange, recordedEntitiesSemaphoreHeld: false);
- }
-
- public async ValueTask ExchangeDeclareAsync(string exchange, string type, bool passive, bool durable, bool autoDelete, IDictionary arguments)
- {
- await InnerChannel.ExchangeDeclareAsync(exchange, type, passive, durable, autoDelete, arguments)
+ await InnerChannel.ExchangeDeclareAsync(exchange, type, durable, autoDelete, arguments, passive, noWait)
.ConfigureAwait(false);
if (false == passive)
{
@@ -425,89 +350,48 @@ await _connection.RecordExchangeAsync(recordedExchange, recordedEntitiesSemaphor
}
}
- public void ExchangeDeclareNoWait(string exchange, string type, bool durable, bool autoDelete, IDictionary arguments)
- {
- InnerChannel.ExchangeDeclareNoWait(exchange, type, durable, autoDelete, arguments);
- var recordedExchange = new RecordedExchange(exchange, type, durable, autoDelete, arguments);
- _connection.RecordExchange(recordedExchange, recordedEntitiesSemaphoreHeld: false);
- }
-
- public void ExchangeDeclarePassive(string exchange)
- => InnerChannel.ExchangeDeclarePassive(exchange);
-
- public void ExchangeDelete(string exchange, bool ifUnused)
+ public async Task ExchangeDeleteAsync(string exchange, bool ifUnused, bool noWait)
{
- InnerChannel.ExchangeDelete(exchange, ifUnused);
- _connection.DeleteRecordedExchange(exchange, recordedEntitiesSemaphoreHeld: false);
- }
-
- public async ValueTask ExchangeDeleteAsync(string exchange, bool ifUnused)
- {
- await InnerChannel.ExchangeDeleteAsync(exchange, ifUnused)
+ await InnerChannel.ExchangeDeleteAsync(exchange, ifUnused, noWait)
.ConfigureAwait(false);
await _connection.DeleteRecordedExchangeAsync(exchange, recordedEntitiesSemaphoreHeld: false)
.ConfigureAwait(false);
}
- public void ExchangeDeleteNoWait(string exchange, bool ifUnused)
- {
- InnerChannel.ExchangeDeleteNoWait(exchange, ifUnused);
- _connection.DeleteRecordedExchange(exchange, recordedEntitiesSemaphoreHeld: false);
- }
-
- public void ExchangeUnbind(string destination, string source, string routingKey, IDictionary arguments)
- {
- ThrowIfDisposed();
- var recordedBinding = new RecordedBinding(false, destination, source, routingKey, arguments);
- _connection.DeleteRecordedBinding(recordedBinding, recordedEntitiesSemaphoreHeld: false);
- _innerChannel.ExchangeUnbind(destination, source, routingKey, arguments);
- _connection.DeleteAutoDeleteExchange(source, recordedEntitiesSemaphoreHeld: false);
- }
-
- public async ValueTask ExchangeUnbindAsync(string destination, string source, string routingKey, IDictionary arguments)
+ public async Task ExchangeUnbindAsync(string destination, string source, string routingKey,
+ IDictionary arguments, bool noWait)
{
ThrowIfDisposed();
var recordedBinding = new RecordedBinding(false, destination, source, routingKey, arguments);
await _connection.DeleteRecordedBindingAsync(recordedBinding, recordedEntitiesSemaphoreHeld: false)
.ConfigureAwait(false);
- await InnerChannel.ExchangeUnbindAsync(destination, source, routingKey, arguments)
+ await InnerChannel.ExchangeUnbindAsync(destination, source, routingKey, arguments, noWait)
.ConfigureAwait(false);
await _connection.DeleteAutoDeleteExchangeAsync(source, recordedEntitiesSemaphoreHeld: false)
.ConfigureAwait(false);
}
- public void ExchangeUnbindNoWait(string destination, string source, string routingKey, IDictionary arguments)
- => InnerChannel.ExchangeUnbind(destination, source, routingKey, arguments);
-
- public void QueueBind(string queue, string exchange, string routingKey, IDictionary arguments)
+ public async Task QueueBindAsync(string queue, string exchange, string routingKey,
+ IDictionary arguments, bool noWait)
{
- ThrowIfDisposed();
+ await InnerChannel.QueueBindAsync(queue, exchange, routingKey, arguments, noWait)
+ .ConfigureAwait(false);
var recordedBinding = new RecordedBinding(true, queue, exchange, routingKey, arguments);
- _connection.RecordBinding(recordedBinding, recordedEntitiesSemaphoreHeld: false);
- _innerChannel.QueueBind(queue, exchange, routingKey, arguments);
- }
-
- public void QueueBindNoWait(string queue, string exchange, string routingKey, IDictionary arguments)
- => InnerChannel.QueueBind(queue, exchange, routingKey, arguments);
-
- public QueueDeclareOk QueueDeclare(string queue, bool durable, bool exclusive, bool autoDelete, IDictionary arguments)
- {
- QueueDeclareOk result = InnerChannel.QueueDeclare(queue, durable, exclusive, autoDelete, arguments);
- var recordedQueue = new RecordedQueue(result.QueueName, queue.Length == 0, durable, exclusive, autoDelete, arguments);
- _connection.RecordQueue(recordedQueue, recordedEntitiesSemaphoreHeld: false);
- return result;
+ await _connection.RecordBindingAsync(recordedBinding, recordedEntitiesSemaphoreHeld: false)
+ .ConfigureAwait(false);
}
- public void QueueDeclareNoWait(string queue, bool durable, bool exclusive, bool autoDelete, IDictionary arguments)
+ public Task QueueDeclarePassiveAsync(string queue)
{
- InnerChannel.QueueDeclareNoWait(queue, durable, exclusive, autoDelete, arguments);
- var recordedQueue = new RecordedQueue(queue, queue.Length == 0, durable, exclusive, autoDelete, arguments);
- _connection.RecordQueue(recordedQueue, recordedEntitiesSemaphoreHeld: false);
+ return QueueDeclareAsync(queue: queue, passive: true,
+ durable: false, exclusive: false, autoDelete: false,
+ arguments: null, noWait: false);
}
- public async ValueTask QueueDeclareAsync(string queue, bool passive, bool durable, bool exclusive, bool autoDelete, IDictionary arguments)
+ public async Task QueueDeclareAsync(string queue, bool durable, bool exclusive, bool autoDelete,
+ IDictionary arguments, bool passive, bool noWait)
{
- QueueDeclareOk result = await InnerChannel.QueueDeclareAsync(queue, passive, durable, exclusive, autoDelete, arguments)
+ QueueDeclareOk result = await InnerChannel.QueueDeclareAsync(queue, durable, exclusive, autoDelete, arguments, passive, noWait)
.ConfigureAwait(false);
if (false == passive)
{
@@ -518,55 +402,24 @@ await _connection.RecordQueueAsync(recordedQueue, recordedEntitiesSemaphoreHeld:
return result;
}
- public ValueTask QueueBindAsync(string queue, string exchange, string routingKey, IDictionary arguments)
- => InnerChannel.QueueBindAsync(queue, exchange, routingKey, arguments);
-
- public QueueDeclareOk QueueDeclarePassive(string queue)
- => InnerChannel.QueueDeclarePassive(queue);
+ public Task MessageCountAsync(string queue)
+ => InnerChannel.MessageCountAsync(queue);
- public uint MessageCount(string queue)
- => InnerChannel.MessageCount(queue);
+ public Task ConsumerCountAsync(string queue)
+ => InnerChannel.ConsumerCountAsync(queue);
- public uint ConsumerCount(string queue)
- => InnerChannel.ConsumerCount(queue);
-
- public uint QueueDelete(string queue, bool ifUnused, bool ifEmpty)
+ public async Task QueueDeleteAsync(string queue, bool ifUnused, bool ifEmpty, bool noWait)
{
- uint result = InnerChannel.QueueDelete(queue, ifUnused, ifEmpty);
- _connection.DeleteRecordedQueue(queue, recordedEntitiesSemaphoreHeld: false);
- return result;
- }
-
- public async ValueTask QueueDeleteAsync(string queue, bool ifUnused, bool ifEmpty)
- {
- uint result = await InnerChannel.QueueDeleteAsync(queue, ifUnused, ifEmpty);
+ uint result = await InnerChannel.QueueDeleteAsync(queue, ifUnused, ifEmpty, noWait);
await _connection.DeleteRecordedQueueAsync(queue, recordedEntitiesSemaphoreHeld: false)
.ConfigureAwait(false);
return result;
}
- public void QueueDeleteNoWait(string queue, bool ifUnused, bool ifEmpty)
- {
- InnerChannel.QueueDeleteNoWait(queue, ifUnused, ifEmpty);
- _connection.DeleteRecordedQueue(queue, recordedEntitiesSemaphoreHeld: false);
- }
-
- public uint QueuePurge(string queue)
- => InnerChannel.QueuePurge(queue);
-
- public ValueTask QueuePurgeAsync(string queue)
+ public Task QueuePurgeAsync(string queue)
=> InnerChannel.QueuePurgeAsync(queue);
- public void QueueUnbind(string queue, string exchange, string routingKey, IDictionary arguments)
- {
- ThrowIfDisposed();
- var recordedBinding = new RecordedBinding(true, queue, exchange, routingKey, arguments);
- _connection.DeleteRecordedBinding(recordedBinding, recordedEntitiesSemaphoreHeld: false);
- _innerChannel.QueueUnbind(queue, exchange, routingKey, arguments);
- _connection.DeleteAutoDeleteExchange(exchange, recordedEntitiesSemaphoreHeld: false);
- }
-
- public async ValueTask QueueUnbindAsync(string queue, string exchange, string routingKey, IDictionary arguments)
+ public async Task QueueUnbindAsync(string queue, string exchange, string routingKey, IDictionary arguments)
{
ThrowIfDisposed();
var recordedBinding = new RecordedBinding(true, queue, exchange, routingKey, arguments);
@@ -578,39 +431,22 @@ await _connection.DeleteAutoDeleteExchangeAsync(exchange, recordedEntitiesSemaph
.ConfigureAwait(false);
}
- public void TxCommit()
- => InnerChannel.TxCommit();
-
- public ValueTask TxCommitAsync()
+ public Task TxCommitAsync()
=> InnerChannel.TxCommitAsync();
- public void TxRollback()
- => InnerChannel.TxRollback();
- public ValueTask TxRollbackAsync()
+ public Task TxRollbackAsync()
=> InnerChannel.TxRollbackAsync();
- public void TxSelect()
- {
- InnerChannel.TxSelect();
- _usesTransactions = true;
- }
-
- public ValueTask TxSelectAsync()
+ public Task TxSelectAsync()
{
_usesTransactions = true;
return InnerChannel.TxSelectAsync();
}
- public bool WaitForConfirms()
- => InnerChannel.WaitForConfirms();
-
public Task WaitForConfirmsAsync(CancellationToken token = default)
=> InnerChannel.WaitForConfirmsAsync(token);
- public void WaitForConfirmsOrDie()
- => InnerChannel.WaitForConfirmsOrDie();
-
public Task WaitForConfirmsOrDieAsync(CancellationToken token = default)
=> InnerChannel.WaitForConfirmsOrDieAsync(token);
diff --git a/projects/RabbitMQ.Client/client/impl/AutorecoveringConnection.Recovery.cs b/projects/RabbitMQ.Client/client/impl/AutorecoveringConnection.Recovery.cs
index 28eab5f41f..d927592472 100644
--- a/projects/RabbitMQ.Client/client/impl/AutorecoveringConnection.Recovery.cs
+++ b/projects/RabbitMQ.Client/client/impl/AutorecoveringConnection.Recovery.cs
@@ -123,12 +123,12 @@ private void StopRecoveryLoop()
private async ValueTask StopRecoveryLoopAsync()
{
Task? task = _recoveryTask;
- if (task is not null)
+ if (task != null)
{
RecoveryCancellationTokenSource.Cancel();
try
{
- await task.TimeoutAfter(_config.RequestedConnectionTimeout)
+ await TaskExtensions.WaitAsync(task, _config.RequestedConnectionTimeout)
.ConfigureAwait(false);
}
catch (TimeoutException)
@@ -173,15 +173,12 @@ await _recordedEntitiesSemaphore.WaitAsync(cancellationToken)
// 2. Recover queues
// 3. Recover bindings
// 4. Recover consumers
- using (var recoveryChannelFactory = new RecoveryChannelFactory(_innerConnection))
- {
- await RecoverExchangesAsync(recoveryChannelFactory, recordedEntitiesSemaphoreHeld: true)
- .ConfigureAwait(false);
- await RecoverQueuesAsync(recoveryChannelFactory, recordedEntitiesSemaphoreHeld: true)
- .ConfigureAwait(false);
- await RecoverBindingsAsync(recoveryChannelFactory, recordedEntitiesSemaphoreHeld: true)
- .ConfigureAwait(false);
- }
+ await RecoverExchangesAsync(_innerConnection, recordedEntitiesSemaphoreHeld: true)
+ .ConfigureAwait(false);
+ await RecoverQueuesAsync(_innerConnection, recordedEntitiesSemaphoreHeld: true)
+ .ConfigureAwait(false);
+ await RecoverBindingsAsync(_innerConnection, recordedEntitiesSemaphoreHeld: true)
+ .ConfigureAwait(false);
}
await RecoverChannelsAndItsConsumersAsync(recordedEntitiesSemaphoreHeld: true)
@@ -214,7 +211,7 @@ await RecoverChannelsAndItsConsumersAsync(recordedEntitiesSemaphoreHeld: true)
*/
if (_innerConnection?.IsOpen == true)
{
- _innerConnection.Abort(Constants.InternalError, "FailedAutoRecovery", _config.RequestedConnectionTimeout);
+ await _innerConnection.AbortAsync(Constants.InternalError, "FailedAutoRecovery", _config.RequestedConnectionTimeout);
}
}
catch (Exception e2)
@@ -253,7 +250,7 @@ await _innerConnection.OpenAsync(cancellationToken)
return false;
}
- private async ValueTask RecoverExchangesAsync(RecoveryChannelFactory recoveryChannelFactory,
+ private async ValueTask RecoverExchangesAsync(IConnection connection,
bool recordedEntitiesSemaphoreHeld = false)
{
if (_disposed)
@@ -270,21 +267,23 @@ await _innerConnection.OpenAsync(cancellationToken)
{
try
{
- using (IChannel ch = await recoveryChannelFactory.CreateRecoveryChannelAsync().ConfigureAwait(false))
+ using (IChannel ch = await connection.CreateChannelAsync().ConfigureAwait(false))
{
await recordedExchange.RecoverAsync(ch)
.ConfigureAwait(false);
+ await ch.CloseAsync()
+ .ConfigureAwait(false);
}
}
catch (Exception ex)
{
- if (_config.TopologyRecoveryExceptionHandler.ExchangeRecoveryExceptionHandler != null
+ if (_config.TopologyRecoveryExceptionHandler.ExchangeRecoveryExceptionHandlerAsync != null
&& _config.TopologyRecoveryExceptionHandler.ExchangeRecoveryExceptionCondition(recordedExchange, ex))
{
try
{
_recordedEntitiesSemaphore.Release();
- _config.TopologyRecoveryExceptionHandler.ExchangeRecoveryExceptionHandler(recordedExchange, ex, this);
+ await _config.TopologyRecoveryExceptionHandler.ExchangeRecoveryExceptionHandlerAsync(recordedExchange, ex, this);
}
finally
{
@@ -300,7 +299,7 @@ await _recordedEntitiesSemaphore.WaitAsync()
}
}
- private async Task RecoverQueuesAsync(RecoveryChannelFactory recoveryChannelFactory,
+ private async Task RecoverQueuesAsync(IConnection connection,
bool recordedEntitiesSemaphoreHeld = false)
{
if (_disposed)
@@ -318,10 +317,12 @@ await _recordedEntitiesSemaphore.WaitAsync()
try
{
string newName = string.Empty;
- using (IChannel ch = await recoveryChannelFactory.CreateRecoveryChannelAsync().ConfigureAwait(false))
+ using (IChannel ch = await connection.CreateChannelAsync().ConfigureAwait(false))
{
newName = await recordedQueue.RecoverAsync(ch)
.ConfigureAwait(false);
+ await ch.CloseAsync()
+ .ConfigureAwait(false);
}
string oldName = recordedQueue.Name;
@@ -360,13 +361,13 @@ await _recordedEntitiesSemaphore.WaitAsync()
}
catch (Exception ex)
{
- if (_config.TopologyRecoveryExceptionHandler.QueueRecoveryExceptionHandler != null
+ if (_config.TopologyRecoveryExceptionHandler.QueueRecoveryExceptionHandlerAsync != null
&& _config.TopologyRecoveryExceptionHandler.QueueRecoveryExceptionCondition(recordedQueue, ex))
{
try
{
_recordedEntitiesSemaphore.Release();
- _config.TopologyRecoveryExceptionHandler.QueueRecoveryExceptionHandler(recordedQueue, ex, this);
+ await _config.TopologyRecoveryExceptionHandler.QueueRecoveryExceptionHandlerAsync(recordedQueue, ex, this);
}
finally
{
@@ -405,7 +406,7 @@ void UpdateConsumerQueue(string oldName, string newName)
}
}
- private async ValueTask RecoverBindingsAsync(RecoveryChannelFactory recoveryChannelFactory,
+ private async ValueTask RecoverBindingsAsync(IConnection connection,
bool recordedEntitiesSemaphoreHeld = false)
{
if (_disposed)
@@ -422,21 +423,23 @@ void UpdateConsumerQueue(string oldName, string newName)
{
try
{
- using (IChannel ch = await recoveryChannelFactory.CreateRecoveryChannelAsync().ConfigureAwait(false))
+ using (IChannel ch = await connection.CreateChannelAsync().ConfigureAwait(false))
{
await binding.RecoverAsync(ch)
.ConfigureAwait(false);
+ await ch.CloseAsync()
+ .ConfigureAwait(false);
}
}
catch (Exception ex)
{
- if (_config.TopologyRecoveryExceptionHandler.BindingRecoveryExceptionHandler != null
+ if (_config.TopologyRecoveryExceptionHandler.BindingRecoveryExceptionHandlerAsync != null
&& _config.TopologyRecoveryExceptionHandler.BindingRecoveryExceptionCondition(binding, ex))
{
try
{
_recordedEntitiesSemaphore.Release();
- _config.TopologyRecoveryExceptionHandler.BindingRecoveryExceptionHandler(binding, ex, this);
+ await _config.TopologyRecoveryExceptionHandler.BindingRecoveryExceptionHandlerAsync(binding, ex, this);
}
finally
{
@@ -506,13 +509,13 @@ await _recordedEntitiesSemaphore.WaitAsync()
}
catch (Exception ex)
{
- if (_config.TopologyRecoveryExceptionHandler.ConsumerRecoveryExceptionHandler != null
+ if (_config.TopologyRecoveryExceptionHandler.ConsumerRecoveryExceptionHandlerAsync != null
&& _config.TopologyRecoveryExceptionHandler.ConsumerRecoveryExceptionCondition(consumer, ex))
{
try
{
_recordedEntitiesSemaphore.Release();
- _config.TopologyRecoveryExceptionHandler.ConsumerRecoveryExceptionHandler(consumer, ex, this);
+ await _config.TopologyRecoveryExceptionHandler.ConsumerRecoveryExceptionHandlerAsync(consumer, ex, this);
}
finally
{
@@ -549,44 +552,5 @@ private async ValueTask RecoverChannelsAndItsConsumersAsync(bool recordedEntitie
.ConfigureAwait(false);
}
}
-
- private sealed class RecoveryChannelFactory : IDisposable
- {
- private readonly IConnection _connection;
- private IChannel? _recoveryChannel;
-
- public RecoveryChannelFactory(IConnection connection)
- {
- _connection = connection;
- }
-
- // TODO cancellation token
- public async ValueTask CreateRecoveryChannelAsync()
- {
- if (_recoveryChannel == null)
- {
- _recoveryChannel = await _connection.CreateChannelAsync()
- .ConfigureAwait(false);
- }
-
- if (_recoveryChannel.IsClosed)
- {
- _recoveryChannel.Dispose();
- _recoveryChannel = await _connection.CreateChannelAsync()
- .ConfigureAwait(false);
- }
-
- return _recoveryChannel;
- }
-
- public void Dispose()
- {
- if (_recoveryChannel != null)
- {
- _recoveryChannel.Close();
- _recoveryChannel.Dispose();
- }
- }
- }
}
}
diff --git a/projects/RabbitMQ.Client/client/impl/AutorecoveringConnection.cs b/projects/RabbitMQ.Client/client/impl/AutorecoveringConnection.cs
index 56962d8edc..fa6a01e0e2 100644
--- a/projects/RabbitMQ.Client/client/impl/AutorecoveringConnection.cs
+++ b/projects/RabbitMQ.Client/client/impl/AutorecoveringConnection.cs
@@ -85,7 +85,7 @@ await _innerConnection.OpenAsync(cancellationToken)
private void CreateInnerConnection(IFrameHandler frameHandler)
{
- _innerConnection = new(_config, frameHandler);
+ _innerConnection = new Connection(_config, frameHandler);
void onException(Exception exception, string context) =>
_innerConnection.OnCallbackException(CallbackExceptionEventArgs.Build(exception, context));
@@ -183,14 +183,6 @@ private void CreateInnerConnection(IFrameHandler frameHandler)
public IProtocol Protocol => Endpoint.Protocol;
- public RecoveryAwareChannel CreateNonRecoveringChannel()
- {
- ISession session = InnerConnection.CreateSession();
- var result = new RecoveryAwareChannel(_config, session);
- result._Private_ChannelOpen();
- return result;
- }
-
public async ValueTask CreateNonRecoveringChannelAsync()
{
ISession session = InnerConnection.CreateSession();
@@ -202,32 +194,21 @@ public async ValueTask CreateNonRecoveringChannelAsync()
public override string ToString()
=> $"AutorecoveringConnection({InnerConnection.Id},{Endpoint},{GetHashCode()})";
- internal void CloseFrameHandler()
+ internal Task CloseFrameHandlerAsync()
{
- InnerConnection.FrameHandler.Close();
+ return InnerConnection.FrameHandler.CloseAsync();
}
///API-side invocation of updating the secret.
- public void UpdateSecret(string newSecret, string reason)
+ public Task UpdateSecretAsync(string newSecret, string reason)
{
ThrowIfDisposed();
EnsureIsOpen();
- _innerConnection.UpdateSecret(newSecret, reason);
- }
-
- ///API-side invocation of connection.close with timeout.
- public void Close(ushort reasonCode, string reasonText, TimeSpan timeout, bool abort)
- {
- ThrowIfDisposed();
- StopRecoveryLoop();
- if (_innerConnection.IsOpen)
- {
- _innerConnection.Close(reasonCode, reasonText, timeout, abort);
- }
+ return _innerConnection.UpdateSecretAsync(newSecret, reason);
}
///Asynchronous API-side invocation of connection.close with timeout.
- public async ValueTask CloseAsync(ushort reasonCode, string reasonText, TimeSpan timeout, bool abort)
+ public async Task CloseAsync(ushort reasonCode, string reasonText, TimeSpan timeout, bool abort)
{
ThrowIfDisposed();
await StopRecoveryLoopAsync()
@@ -239,16 +220,7 @@ await _innerConnection.CloseAsync(reasonCode, reasonText, timeout, abort)
}
}
- public IChannel CreateChannel()
- {
- EnsureIsOpen();
- RecoveryAwareChannel recoveryAwareChannel = CreateNonRecoveringChannel();
- AutorecoveringChannel channel = new AutorecoveringChannel(this, recoveryAwareChannel);
- RecordChannel(channel);
- return channel;
- }
-
- public async ValueTask CreateChannelAsync()
+ public async Task CreateChannelAsync()
{
EnsureIsOpen();
RecoveryAwareChannel recoveryAwareChannel = await CreateNonRecoveringChannelAsync()
@@ -268,7 +240,12 @@ public void Dispose()
try
{
- this.Abort(InternalConstants.DefaultConnectionAbortTimeout);
+ // TODO rabbitmq-dotnet-client-1472
+ // this.Abort(InternalConstants.DefaultConnectionAbortTimeout);
+ if (IsOpen)
+ {
+ throw new InvalidOperationException("Connection must be closed before calling Dispose!");
+ }
}
catch (Exception)
{
diff --git a/projects/RabbitMQ.Client/client/impl/ChannelBase.cs b/projects/RabbitMQ.Client/client/impl/ChannelBase.cs
index 7f54b0eeb3..cadec4ea49 100644
--- a/projects/RabbitMQ.Client/client/impl/ChannelBase.cs
+++ b/projects/RabbitMQ.Client/client/impl/ChannelBase.cs
@@ -70,9 +70,15 @@ internal abstract class ChannelBase : IChannel, IRecoverable
protected ChannelBase(ConnectionConfig config, ISession session)
{
ContinuationTimeout = config.ContinuationTimeout;
- ConsumerDispatcher = config.DispatchConsumersAsync ?
- new AsyncConsumerDispatcher(this, config.DispatchConsumerConcurrency) :
- new ConsumerDispatcher(this, config.DispatchConsumerConcurrency);
+
+ if (config.DispatchConsumersAsync)
+ {
+ ConsumerDispatcher = new AsyncConsumerDispatcher(this, config.DispatchConsumerConcurrency);
+ }
+ else
+ {
+ ConsumerDispatcher = new ConsumerDispatcher(this, config.DispatchConsumerConcurrency);
+ }
Action onException = (exception, context) => OnCallbackException(CallbackExceptionEventArgs.Build(exception, context));
_basicAcksWrapper = new EventingWrapper("OnBasicAck", onException);
@@ -240,13 +246,13 @@ public void Close(ushort replyCode, string replyText, bool abort)
}
}
- public ValueTask CloseAsync(ushort replyCode, string replyText, bool abort)
+ public Task CloseAsync(ushort replyCode, string replyText, bool abort)
{
var args = new ShutdownEventArgs(ShutdownInitiator.Application, replyCode, replyText);
return CloseAsync(args, abort);
}
- public async ValueTask CloseAsync(ShutdownEventArgs args, bool abort)
+ public async Task CloseAsync(ShutdownEventArgs args, bool abort)
{
using var k = new ChannelCloseAsyncRpcContinuation(ContinuationTimeout);
await _rpcSemaphore.WaitAsync()
@@ -383,7 +389,7 @@ protected void Enqueue(IRpcContinuation k)
}
}
- internal async ValueTask OpenAsync()
+ internal async Task OpenAsync()
{
await _rpcSemaphore.WaitAsync()
.ConfigureAwait(false);
@@ -583,7 +589,11 @@ protected virtual void Dispose(bool disposing)
if (disposing)
{
// dispose managed resources
- this.Abort();
+ // TODO exception?
+ if (IsOpen)
+ {
+ throw new InvalidOperationException("Channel must be closed before calling Dispose!");
+ }
ConsumerDispatcher.Dispose();
_rpcSemaphore.Dispose();
}
@@ -967,7 +977,8 @@ protected void HandleConnectionStart(in IncomingCommand cmd)
if (m_connectionStartCell is null)
{
var reason = new ShutdownEventArgs(ShutdownInitiator.Library, Constants.CommandInvalid, "Unexpected Connection.Start");
- Session.Connection.Close(reason, false, InternalConstants.DefaultConnectionCloseTimeout);
+ // TODO async!
+ Session.Connection.CloseAsync(reason, false, InternalConstants.DefaultConnectionCloseTimeout).EnsureCompleted();
}
else
{
@@ -1034,126 +1045,51 @@ protected bool HandleQueueDeclareOk(in IncomingCommand cmd)
}
}
- public abstract void _Private_BasicCancel(string consumerTag, bool nowait);
-
- public abstract void _Private_BasicConsume(string queue, string consumerTag, bool noLocal, bool autoAck, bool exclusive, bool nowait, IDictionary arguments);
-
- public abstract void _Private_BasicGet(string queue, bool autoAck);
-
public abstract void _Private_ChannelClose(ushort replyCode, string replyText, ushort classId, ushort methodId);
public abstract void _Private_ChannelCloseOk();
public abstract void _Private_ChannelFlowOk(bool active);
- public abstract void _Private_ChannelOpen();
-
- public abstract void _Private_ConfirmSelect(bool nowait);
-
public abstract void _Private_ConnectionCloseOk();
- public abstract void _Private_UpdateSecret(byte[] @newSecret, string @reason);
-
- public abstract void _Private_ExchangeBind(string destination, string source, string routingKey, bool nowait, IDictionary arguments);
-
- public abstract void _Private_ExchangeDeclare(string exchange, string type, bool passive, bool durable, bool autoDelete, bool @internal, bool nowait, IDictionary arguments);
-
- public abstract void _Private_ExchangeDelete(string exchange, bool ifUnused, bool nowait);
-
- public abstract void _Private_ExchangeUnbind(string destination, string source, string routingKey, bool nowait, IDictionary arguments);
-
- public abstract void _Private_QueueBind(string queue, string exchange, string routingKey, bool nowait, IDictionary arguments);
-
- public abstract void _Private_QueueDeclare(string queue, bool passive, bool durable, bool exclusive, bool autoDelete, bool nowait, IDictionary arguments);
-
- public abstract uint _Private_QueueDelete(string queue, bool ifUnused, bool ifEmpty, bool nowait);
-
- public abstract uint _Private_QueuePurge(string queue, bool nowait);
-
- public abstract void BasicAck(ulong deliveryTag, bool multiple);
-
public abstract ValueTask BasicAckAsync(ulong deliveryTag, bool multiple);
- public void BasicCancel(string consumerTag)
- {
- var k = new BasicConsumeRpcContinuation { m_consumerTag = consumerTag };
- _rpcSemaphore.Wait();
- try
- {
- Enqueue(k);
- _Private_BasicCancel(consumerTag, false);
- k.GetReply(ContinuationTimeout);
- }
- finally
- {
- _rpcSemaphore.Release();
- }
- }
-
- public async ValueTask BasicCancelAsync(string consumerTag)
+ public async Task BasicCancelAsync(string consumerTag, bool noWait)
{
await _rpcSemaphore.WaitAsync()
.ConfigureAwait(false);
try
{
- using var k = new BasicCancelAsyncRpcContinuation(consumerTag, ConsumerDispatcher, ContinuationTimeout);
- Enqueue(k);
-
- var method = new Client.Framing.Impl.BasicCancel(consumerTag, false);
- await ModelSendAsync(method)
- .ConfigureAwait(false);
+ var method = new Client.Framing.Impl.BasicCancel(consumerTag, noWait);
- bool result = await k;
- Debug.Assert(result);
- return;
- }
- finally
- {
- _rpcSemaphore.Release();
- }
- }
-
- public void BasicCancelNoWait(string consumerTag)
- {
- _Private_BasicCancel(consumerTag, true);
- ConsumerDispatcher.GetAndRemoveConsumer(consumerTag);
- }
-
- public string BasicConsume(string queue, bool autoAck, string consumerTag, bool noLocal, bool exclusive,
- IDictionary arguments, IBasicConsumer consumer)
- {
- // TODO: Replace with flag
- if (ConsumerDispatcher is AsyncConsumerDispatcher)
- {
- if (!(consumer is IAsyncBasicConsumer))
+ if (noWait)
{
- // TODO: Friendly message
- throw new InvalidOperationException("In the async mode you have to use an async consumer");
+ await ModelSendAsync(method)
+ .ConfigureAwait(false);
+ ConsumerDispatcher.GetAndRemoveConsumer(consumerTag);
}
- }
+ else
+ {
+ using var k = new BasicCancelAsyncRpcContinuation(consumerTag, ConsumerDispatcher, ContinuationTimeout);
+ Enqueue(k);
- var k = new BasicConsumeRpcContinuation { m_consumer = consumer };
+ await ModelSendAsync(method)
+ .ConfigureAwait(false);
- _rpcSemaphore.Wait();
- try
- {
- Enqueue(k);
- // Non-nowait. We have an unconventional means of getting
- // the RPC response, but a response is still expected.
- _Private_BasicConsume(queue, consumerTag, noLocal, autoAck, exclusive, false, arguments);
- k.GetReply(ContinuationTimeout);
+ bool result = await k;
+ Debug.Assert(result);
+ }
+
+ return;
}
finally
{
_rpcSemaphore.Release();
}
-
- string actualConsumerTag = k.m_consumerTag;
-
- return actualConsumerTag;
}
- public async ValueTask BasicConsumeAsync(string queue, bool autoAck, string consumerTag, bool noLocal, bool exclusive,
+ public async Task BasicConsumeAsync(string queue, bool autoAck, string consumerTag, bool noLocal, bool exclusive,
IDictionary arguments, IBasicConsumer consumer)
{
// TODO: Replace with flag
@@ -1185,25 +1121,6 @@ await ModelSendAsync(method)
}
}
- public BasicGetResult BasicGet(string queue, bool autoAck)
- {
- var k = new BasicGetRpcContinuation();
-
- _rpcSemaphore.Wait();
- try
- {
- Enqueue(k);
- _Private_BasicGet(queue, autoAck);
- k.GetReply(ContinuationTimeout);
- }
- finally
- {
- _rpcSemaphore.Release();
- }
-
- return k.m_result;
- }
-
public async ValueTask BasicGetAsync(string queue, bool autoAck)
{
await _rpcSemaphore.WaitAsync()
@@ -1225,72 +1142,8 @@ await ModelSendAsync(method)
}
}
- public abstract void BasicNack(ulong deliveryTag, bool multiple, bool requeue);
-
public abstract ValueTask BasicNackAsync(ulong deliveryTag, bool multiple, bool requeue);
- public void BasicPublish(string exchange, string routingKey, in TProperties basicProperties, ReadOnlyMemory body, bool mandatory)
- where TProperties : IReadOnlyBasicProperties, IAmqpHeader
- {
- if (NextPublishSeqNo > 0)
- {
- lock (_confirmLock)
- {
- _pendingDeliveryTags.AddLast(NextPublishSeqNo++);
- }
- }
-
- try
- {
- var cmd = new BasicPublish(exchange, routingKey, mandatory, default);
- ChannelSend(in cmd, in basicProperties, body);
- }
- catch
- {
- if (NextPublishSeqNo > 0)
- {
- lock (_confirmLock)
- {
- NextPublishSeqNo--;
- _pendingDeliveryTags.RemoveLast();
- }
- }
-
- throw;
- }
- }
-
- public void BasicPublish(CachedString exchange, CachedString routingKey, in TProperties basicProperties, ReadOnlyMemory body, bool mandatory)
- where TProperties : IReadOnlyBasicProperties, IAmqpHeader
- {
- if (NextPublishSeqNo > 0)
- {
- lock (_confirmLock)
- {
- _pendingDeliveryTags.AddLast(NextPublishSeqNo++);
- }
- }
-
- try
- {
- var cmd = new BasicPublishMemory(exchange.Bytes, routingKey.Bytes, mandatory, default);
- ChannelSend(in cmd, in basicProperties, body);
- }
- catch
- {
- if (NextPublishSeqNo > 0)
- {
- lock (_confirmLock)
- {
- NextPublishSeqNo--;
- _pendingDeliveryTags.RemoveLast();
- }
- }
-
- throw;
- }
- }
-
public ValueTask BasicPublishAsync(string exchange, string routingKey, in TProperties basicProperties, ReadOnlyMemory body, bool mandatory)
where TProperties : IReadOnlyBasicProperties, IAmqpHeader
{
@@ -1353,7 +1206,7 @@ public ValueTask BasicPublishAsync(CachedString exchange, CachedStr
}
}
- public void UpdateSecret(string newSecret, string reason)
+ public async Task UpdateSecretAsync(string newSecret, string reason)
{
if (newSecret is null)
{
@@ -1365,21 +1218,15 @@ public void UpdateSecret(string newSecret, string reason)
throw new ArgumentNullException(nameof(reason));
}
- _Private_UpdateSecret(Encoding.UTF8.GetBytes(newSecret), reason);
- }
-
- public abstract void BasicQos(uint prefetchSize, ushort prefetchCount, bool global);
-
- public async ValueTask BasicQosAsync(uint prefetchSize, ushort prefetchCount, bool global)
- {
await _rpcSemaphore.WaitAsync()
.ConfigureAwait(false);
try
{
- using var k = new BasicQosAsyncRpcContinuation(ContinuationTimeout);
+ using var k = new SimpleAsyncRpcContinuation(ProtocolCommandId.ConnectionUpdateSecretOk, ContinuationTimeout);
Enqueue(k);
- var method = new BasicQos(prefetchSize, prefetchCount, global);
+ var newSecretBytes = Encoding.UTF8.GetBytes(newSecret);
+ var method = new ConnectionUpdateSecret(newSecretBytes, reason);
await ModelSendAsync(method)
.ConfigureAwait(false);
@@ -1393,22 +1240,32 @@ await ModelSendAsync(method)
}
}
- public abstract void BasicReject(ulong deliveryTag, bool requeue);
+ public async Task BasicQosAsync(uint prefetchSize, ushort prefetchCount, bool global)
+ {
+ await _rpcSemaphore.WaitAsync()
+ .ConfigureAwait(false);
+ try
+ {
+ using var k = new BasicQosAsyncRpcContinuation(ContinuationTimeout);
+ Enqueue(k);
- public abstract ValueTask BasicRejectAsync(ulong deliveryTag, bool requeue);
+ var method = new BasicQos(prefetchSize, prefetchCount, global);
+ await ModelSendAsync(method)
+ .ConfigureAwait(false);
- public void ConfirmSelect()
- {
- if (NextPublishSeqNo == 0UL)
+ bool result = await k;
+ Debug.Assert(result);
+ return;
+ }
+ finally
{
- _confirmsTaskCompletionSources = new List>();
- NextPublishSeqNo = 1;
+ _rpcSemaphore.Release();
}
-
- _Private_ConfirmSelect(false);
}
- public async ValueTask ConfirmSelectAsync()
+ public abstract Task BasicRejectAsync(ulong deliveryTag, bool requeue);
+
+ public async Task ConfirmSelectAsync()
{
await _rpcSemaphore.WaitAsync()
.ConfigureAwait(false);
@@ -1438,26 +1295,32 @@ await ModelSendAsync(method)
}
}
- public void ExchangeBind(string destination, string source, string routingKey, IDictionary arguments)
- {
- _Private_ExchangeBind(destination, source, routingKey, false, arguments);
- }
-
- public async ValueTask ExchangeBindAsync(string destination, string source, string routingKey, IDictionary arguments)
+ public async Task ExchangeBindAsync(string destination, string source, string routingKey,
+ IDictionary arguments, bool noWait)
{
await _rpcSemaphore.WaitAsync()
.ConfigureAwait(false);
try
{
- using var k = new ExchangeBindAsyncRpcContinuation(ContinuationTimeout);
- Enqueue(k);
+ var method = new ExchangeBind(destination, source, routingKey, noWait, arguments);
- var method = new ExchangeBind(destination, source, routingKey, false, arguments);
- await ModelSendAsync(method)
- .ConfigureAwait(false);
+ if (noWait)
+ {
+ await ModelSendAsync(method)
+ .ConfigureAwait(false);
+ }
+ else
+ {
+ using var k = new ExchangeBindAsyncRpcContinuation(ContinuationTimeout);
+ Enqueue(k);
+
+ await ModelSendAsync(method)
+ .ConfigureAwait(false);
+
+ bool result = await k;
+ Debug.Assert(result);
+ }
- bool result = await k;
- Debug.Assert(result);
return;
}
finally
@@ -1466,31 +1329,38 @@ await ModelSendAsync(method)
}
}
- public void ExchangeBindNoWait(string destination, string source, string routingKey, IDictionary arguments)
+ public Task ExchangeDeclarePassiveAsync(string exchange)
{
- _Private_ExchangeBind(destination, source, routingKey, true, arguments);
+ return ExchangeDeclareAsync(exchange: exchange, type: string.Empty, passive: true,
+ durable: false, autoDelete: false, arguments: null, noWait: false);
}
- public void ExchangeDeclare(string exchange, string type, bool durable, bool autoDelete, IDictionary arguments)
- {
- _Private_ExchangeDeclare(exchange, type, false, durable, autoDelete, false, false, arguments);
- }
-
- public async ValueTask ExchangeDeclareAsync(string exchange, string type, bool passive, bool durable, bool autoDelete, IDictionary arguments)
+ public async Task ExchangeDeclareAsync(string exchange, string type, bool durable, bool autoDelete,
+ IDictionary arguments, bool passive, bool noWait)
{
await _rpcSemaphore.WaitAsync()
.ConfigureAwait(false);
try
{
- using var k = new ExchangeDeclareAsyncRpcContinuation(ContinuationTimeout);
- Enqueue(k);
+ var method = new ExchangeDeclare(exchange, type, passive, durable, autoDelete, false, noWait, arguments);
- var method = new ExchangeDeclare(exchange, type, passive, durable, autoDelete, false, false, arguments);
- await ModelSendAsync(method)
- .ConfigureAwait(false);
+ if (noWait)
+ {
+ await ModelSendAsync(method)
+ .ConfigureAwait(false);
+ }
+ else
+ {
+ using var k = new ExchangeDeclareAsyncRpcContinuation(ContinuationTimeout);
+ Enqueue(k);
+
+ await ModelSendAsync(method)
+ .ConfigureAwait(false);
+
+ bool result = await k;
+ Debug.Assert(result);
+ }
- bool result = await k;
- Debug.Assert(result);
return;
}
finally
@@ -1499,36 +1369,31 @@ await ModelSendAsync(method)
}
}
- public void ExchangeDeclareNoWait(string exchange, string type, bool durable, bool autoDelete, IDictionary arguments)
- {
- _Private_ExchangeDeclare(exchange, type, false, durable, autoDelete, false, true, arguments);
- }
-
- public void ExchangeDeclarePassive(string exchange)
+ public async Task ExchangeDeleteAsync(string exchange, bool ifUnused, bool noWait)
{
- _Private_ExchangeDeclare(exchange, "", true, false, false, false, false, null);
- }
-
- public void ExchangeDelete(string exchange, bool ifUnused)
- {
- _Private_ExchangeDelete(exchange, ifUnused, false);
- }
-
- public async ValueTask ExchangeDeleteAsync(string exchange, bool ifUnused)
- {
- using var k = new ExchangeDeleteAsyncRpcContinuation(ContinuationTimeout);
await _rpcSemaphore.WaitAsync()
.ConfigureAwait(false);
try
{
- Enqueue(k);
+ var method = new ExchangeDelete(exchange, ifUnused, Nowait: noWait);
- var method = new ExchangeDelete(exchange, ifUnused, Nowait: false);
- await ModelSendAsync(method)
- .ConfigureAwait(false);
+ if (noWait)
+ {
+ await ModelSendAsync(method)
+ .ConfigureAwait(false);
+ }
+ else
+ {
+ using var k = new ExchangeDeleteAsyncRpcContinuation(ContinuationTimeout);
+ Enqueue(k);
+
+ await ModelSendAsync(method)
+ .ConfigureAwait(false);
+
+ bool result = await k;
+ Debug.Assert(result);
+ }
- bool result = await k;
- Debug.Assert(result);
return;
}
finally
@@ -1537,31 +1402,32 @@ await ModelSendAsync(method)
}
}
- public void ExchangeDeleteNoWait(string exchange, bool ifUnused)
- {
- _Private_ExchangeDelete(exchange, ifUnused, true);
- }
-
- public void ExchangeUnbind(string destination, string source, string routingKey, IDictionary arguments)
- {
- _Private_ExchangeUnbind(destination, source, routingKey, false, arguments);
- }
-
- public async ValueTask ExchangeUnbindAsync(string destination, string source, string routingKey, IDictionary arguments)
+ public async Task ExchangeUnbindAsync(string destination, string source, string routingKey,
+ IDictionary arguments, bool noWait)
{
await _rpcSemaphore.WaitAsync()
.ConfigureAwait(false);
try
{
- using var k = new ExchangeUnbindAsyncRpcContinuation(ContinuationTimeout);
- Enqueue(k);
+ var method = new ExchangeUnbind(destination, source, routingKey, noWait, arguments);
- var method = new ExchangeUnbind(destination, source, routingKey, false, arguments);
- await ModelSendAsync(method)
- .ConfigureAwait(false);
+ if (noWait)
+ {
+ await ModelSendAsync(method)
+ .ConfigureAwait(false);
+ }
+ else
+ {
+ using var k = new ExchangeUnbindAsyncRpcContinuation(ContinuationTimeout);
+ Enqueue(k);
+
+ await ModelSendAsync(method)
+ .ConfigureAwait(false);
+
+ bool result = await k;
+ Debug.Assert(result);
+ }
- bool result = await k;
- Debug.Assert(result);
return;
}
finally
@@ -1570,45 +1436,63 @@ await ModelSendAsync(method)
}
}
- public void ExchangeUnbindNoWait(string destination, string source, string routingKey, IDictionary arguments)
+ public Task QueueDeclarePassiveAsync(string queue)
{
- _Private_ExchangeUnbind(destination, source, routingKey, true, arguments);
+ return QueueDeclareAsync(queue: queue, passive: true,
+ durable: false, exclusive: false, autoDelete: false,
+ noWait: false, arguments: null);
}
- public void QueueBind(string queue, string exchange, string routingKey, IDictionary arguments)
+ public async Task QueueDeclareAsync(string queue, bool durable, bool exclusive, bool autoDelete,
+ IDictionary arguments, bool passive, bool noWait)
{
- _Private_QueueBind(queue, exchange, routingKey, false, arguments);
- }
-
- public void QueueBindNoWait(string queue, string exchange, string routingKey, IDictionary arguments)
- {
- _Private_QueueBind(queue, exchange, routingKey, true, arguments);
- }
+ if (true == noWait)
+ {
+ if (queue == string.Empty)
+ {
+ throw new InvalidOperationException("noWait must not be used with a server-named queue.");
+ }
- public QueueDeclareOk QueueDeclare(string queue, bool durable, bool exclusive, bool autoDelete, IDictionary arguments)
- {
- return DoQueueDeclare(queue, false, durable, exclusive, autoDelete, arguments);
- }
+ if (true == passive)
+ {
+ throw new InvalidOperationException("It does not make sense to use noWait: true and passive: true");
+ }
+ }
- public async ValueTask QueueDeclareAsync(string queue, bool passive, bool durable, bool exclusive, bool autoDelete, IDictionary arguments)
- {
await _rpcSemaphore.WaitAsync()
.ConfigureAwait(false);
try
{
- using var k = new QueueDeclareAsyncRpcContinuation(ContinuationTimeout);
- Enqueue(k);
+ var method = new QueueDeclare(queue, passive, durable, exclusive, autoDelete, noWait, arguments);
- var method = new QueueDeclare(queue, passive, durable, exclusive, autoDelete, false, arguments);
- await ModelSendAsync(method)
- .ConfigureAwait(false);
+ if (noWait)
+ {
+ await ModelSendAsync(method)
+ .ConfigureAwait(false);
+
+ if (false == passive)
+ {
+ CurrentQueue = queue;
+ }
- QueueDeclareOk result = await k;
- if (false == passive)
+ return new QueueDeclareOk(queue, 0, 0);
+ }
+ else
{
- CurrentQueue = result.QueueName;
+ using var k = new QueueDeclareAsyncRpcContinuation(ContinuationTimeout);
+ Enqueue(k);
+
+ await ModelSendAsync(method)
+ .ConfigureAwait(false);
+
+ QueueDeclareOk result = await k;
+ if (false == passive)
+ {
+ CurrentQueue = result.QueueName;
+ }
+
+ return result;
}
- return result;
}
finally
{
@@ -1616,21 +1500,32 @@ await ModelSendAsync(method)
}
}
- public async ValueTask QueueBindAsync(string queue, string exchange, string routingKey, IDictionary arguments)
+ public async Task QueueBindAsync(string queue, string exchange, string routingKey,
+ IDictionary arguments, bool noWait)
{
await _rpcSemaphore.WaitAsync()
.ConfigureAwait(false);
try
{
- using var k = new QueueBindAsyncRpcContinuation(ContinuationTimeout);
- Enqueue(k);
+ var method = new QueueBind(queue, exchange, routingKey, noWait, arguments);
- var method = new QueueBind(queue, exchange, routingKey, false, arguments);
- await ModelSendAsync(method)
- .ConfigureAwait(false);
+ if (noWait)
+ {
+ await ModelSendAsync(method)
+ .ConfigureAwait(false);
+ }
+ else
+ {
+ using var k = new QueueBindAsyncRpcContinuation(ContinuationTimeout);
+ Enqueue(k);
+
+ await ModelSendAsync(method)
+ .ConfigureAwait(false);
+
+ bool result = await k;
+ Debug.Assert(result);
+ }
- bool result = await k;
- Debug.Assert(result);
return;
}
finally
@@ -1639,47 +1534,43 @@ await ModelSendAsync(method)
}
}
- public void QueueDeclareNoWait(string queue, bool durable, bool exclusive, bool autoDelete, IDictionary arguments)
- {
- _Private_QueueDeclare(queue, false, durable, exclusive, autoDelete, true, arguments);
- }
-
- public QueueDeclareOk QueueDeclarePassive(string queue)
+ public async Task MessageCountAsync(string queue)
{
- return DoQueueDeclare(queue, true, false, false, false, null);
- }
-
- public uint MessageCount(string queue)
- {
- QueueDeclareOk ok = QueueDeclarePassive(queue);
+ QueueDeclareOk ok = await QueueDeclarePassiveAsync(queue);
return ok.MessageCount;
}
- public uint ConsumerCount(string queue)
+ public async Task ConsumerCountAsync(string queue)
{
- QueueDeclareOk ok = QueueDeclarePassive(queue);
+ QueueDeclareOk ok = await QueueDeclarePassiveAsync(queue);
return ok.ConsumerCount;
}
- public uint QueueDelete(string queue, bool ifUnused, bool ifEmpty)
- {
- return _Private_QueueDelete(queue, ifUnused, ifEmpty, false);
- }
-
- public async ValueTask QueueDeleteAsync(string queue, bool ifUnused, bool ifEmpty)
+ public async Task QueueDeleteAsync(string queue, bool ifUnused, bool ifEmpty, bool noWait)
{
await _rpcSemaphore.WaitAsync()
.ConfigureAwait(false);
try
{
- var k = new QueueDeleteAsyncRpcContinuation(ContinuationTimeout);
- Enqueue(k);
+ var method = new QueueDelete(queue, ifUnused, ifEmpty, noWait);
- var method = new QueueDelete(queue, ifUnused, ifEmpty, false);
- await ModelSendAsync(method)
- .ConfigureAwait(false);
+ if (noWait)
+ {
+ await ModelSendAsync(method)
+ .ConfigureAwait(false);
- return await k;
+ return 0;
+ }
+ else
+ {
+ var k = new QueueDeleteAsyncRpcContinuation(ContinuationTimeout);
+ Enqueue(k);
+
+ await ModelSendAsync(method)
+ .ConfigureAwait(false);
+
+ return await k;
+ }
}
finally
{
@@ -1687,17 +1578,7 @@ await ModelSendAsync(method)
}
}
- public void QueueDeleteNoWait(string queue, bool ifUnused, bool ifEmpty)
- {
- _Private_QueueDelete(queue, ifUnused, ifEmpty, true);
- }
-
- public uint QueuePurge(string queue)
- {
- return _Private_QueuePurge(queue, false);
- }
-
- public async ValueTask QueuePurgeAsync(string queue)
+ public async Task QueuePurgeAsync(string queue)
{
await _rpcSemaphore.WaitAsync()
.ConfigureAwait(false);
@@ -1718,9 +1599,7 @@ await ModelSendAsync(method)
}
}
- public abstract void QueueUnbind(string queue, string exchange, string routingKey, IDictionary arguments);
-
- public async ValueTask QueueUnbindAsync(string queue, string exchange, string routingKey, IDictionary arguments)
+ public async Task QueueUnbindAsync(string queue, string exchange, string routingKey, IDictionary arguments)
{
await _rpcSemaphore.WaitAsync()
.ConfigureAwait(false);
@@ -1743,9 +1622,7 @@ await ModelSendAsync(method)
}
}
- public abstract void TxCommit();
-
- public async ValueTask TxCommitAsync()
+ public async Task TxCommitAsync()
{
await _rpcSemaphore.WaitAsync()
.ConfigureAwait(false);
@@ -1768,9 +1645,7 @@ await ModelSendAsync(method)
}
}
- public abstract void TxRollback();
-
- public async ValueTask TxRollbackAsync()
+ public async Task TxRollbackAsync()
{
await _rpcSemaphore.WaitAsync()
.ConfigureAwait(false);
@@ -1793,9 +1668,7 @@ await ModelSendAsync(method)
}
}
- public abstract void TxSelect();
-
- public async ValueTask TxSelectAsync()
+ public async Task TxSelectAsync()
{
await _rpcSemaphore.WaitAsync()
.ConfigureAwait(false);
@@ -1820,11 +1693,6 @@ await ModelSendAsync(method)
private List> _confirmsTaskCompletionSources;
- public bool WaitForConfirms()
- {
- return WaitForConfirmsAsync().EnsureCompleted();
- }
-
public Task WaitForConfirmsAsync(CancellationToken token = default)
{
if (NextPublishSeqNo == 0UL)
@@ -1882,11 +1750,6 @@ await tokenRegistration.DisposeAsync()
}
}
- public void WaitForConfirmsOrDie()
- {
- WaitForConfirmsOrDieAsync().EnsureCompleted();
- }
-
public async Task WaitForConfirmsOrDieAsync(CancellationToken token = default)
{
try
@@ -1917,26 +1780,5 @@ await CloseAsync(ea, false)
throw ex;
}
}
-
- private QueueDeclareOk DoQueueDeclare(string queue, bool passive, bool durable, bool exclusive, bool autoDelete, IDictionary arguments)
- {
- var k = new QueueDeclareRpcContinuation();
-
- _rpcSemaphore.Wait();
- try
- {
- Enqueue(k);
- _Private_QueueDeclare(queue, passive, durable, exclusive, autoDelete, false, arguments);
- k.GetReply(ContinuationTimeout);
- }
- finally
- {
- _rpcSemaphore.Release();
- }
-
- QueueDeclareOk result = k.m_result;
- CurrentQueue = result.QueueName;
- return result;
- }
}
}
diff --git a/projects/RabbitMQ.Client/client/impl/Connection.Commands.cs b/projects/RabbitMQ.Client/client/impl/Connection.Commands.cs
index ce92007fff..ae2991945e 100644
--- a/projects/RabbitMQ.Client/client/impl/Connection.Commands.cs
+++ b/projects/RabbitMQ.Client/client/impl/Connection.Commands.cs
@@ -43,9 +43,9 @@ namespace RabbitMQ.Client.Framing.Impl
#nullable enable
internal sealed partial class Connection
{
- public void UpdateSecret(string newSecret, string reason)
+ public Task UpdateSecretAsync(string newSecret, string reason)
{
- _channel0.UpdateSecret(newSecret, reason);
+ return _channel0.UpdateSecretAsync(newSecret, reason);
}
internal void NotifyReceivedCloseOk()
@@ -186,11 +186,15 @@ private void MaybeStartCredentialRefresher()
}
}
- private void NotifyCredentialRefreshed(bool succesfully)
+ private Task NotifyCredentialRefreshed(bool succesfully)
{
if (succesfully)
{
- UpdateSecret(_config.CredentialsProvider.Password, "Token refresh");
+ return UpdateSecretAsync(_config.CredentialsProvider.Password, "Token refresh");
+ }
+ else
+ {
+ return Task.CompletedTask;
}
}
diff --git a/projects/RabbitMQ.Client/client/impl/Connection.cs b/projects/RabbitMQ.Client/client/impl/Connection.cs
index 4417d991e3..0645850342 100644
--- a/projects/RabbitMQ.Client/client/impl/Connection.cs
+++ b/projects/RabbitMQ.Client/client/impl/Connection.cs
@@ -253,16 +253,7 @@ await CloseAsync(ea, true, TimeSpan.FromSeconds(5))
}
}
- public IChannel CreateChannel()
- {
- EnsureIsOpen();
- ISession session = CreateSession();
- var channel = new Channel(_config, session);
- channel._Private_ChannelOpen();
- return channel;
- }
-
- public ValueTask CreateChannelAsync()
+ public Task CreateChannelAsync()
{
EnsureIsOpen();
ISession session = CreateSession();
@@ -290,99 +281,12 @@ internal void EnsureIsOpen()
}
}
- ///API-side invocation of connection.close with timeout.
- public void Close(ushort reasonCode, string reasonText, TimeSpan timeout, bool abort)
- {
- Close(new ShutdownEventArgs(ShutdownInitiator.Application, reasonCode, reasonText), abort, timeout);
- }
-
///Asynchronous API-side invocation of connection.close with timeout.
- public ValueTask CloseAsync(ushort reasonCode, string reasonText, TimeSpan timeout, bool abort)
+ public Task CloseAsync(ushort reasonCode, string reasonText, TimeSpan timeout, bool abort)
{
return CloseAsync(new ShutdownEventArgs(ShutdownInitiator.Application, reasonCode, reasonText), abort, timeout);
}
- ///Try to close connection in a graceful way
- ///
- ///
- ///Shutdown reason contains code and text assigned when closing the connection,
- ///as well as the information about what initiated the close
- ///
- ///
- ///Abort flag, if true, signals to close the ongoing connection immediately
- ///and do not report any errors if it was already closed.
- ///
- ///
- ///Timeout determines how much time internal close operations should be given
- ///to complete.
- ///
- ///
- internal void Close(ShutdownEventArgs reason, bool abort, TimeSpan timeout)
- {
- if (!SetCloseReason(reason))
- {
- if (!abort)
- {
- ThrowAlreadyClosedException(CloseReason!);
- }
- }
- else
- {
- OnShutdown(reason);
- _session0.SetSessionClosing(false);
-
- try
- {
- // Try to send connection.close wait for CloseOk in the MainLoop
- if (!_closed)
- {
- _session0.Transmit(new ConnectionClose(reason.ReplyCode, reason.ReplyText, 0, 0));
- }
- }
- catch (AlreadyClosedException)
- {
- if (!abort)
- {
- throw;
- }
- }
- catch (NotSupportedException)
- {
- // buffered stream had unread data in it and Flush()
- // was called, ignore to not confuse the user
- }
- catch (IOException ioe)
- {
- if (_channel0.CloseReason is null)
- {
- if (!abort)
- {
- throw;
- }
- else
- {
- LogCloseError("Couldn't close connection cleanly. Socket closed unexpectedly", ioe);
- }
- }
- }
- finally
- {
- TerminateMainloop();
- }
- }
-
- try
- {
- if (!_mainLoopTask.Wait(timeout))
- {
- _frameHandler.Close();
- }
- }
- catch (AggregateException) // TODO this could be more than just a timeout
- {
- }
- }
-
///Asychronously try to close connection in a graceful way
///
///
@@ -399,12 +303,12 @@ internal void Close(ShutdownEventArgs reason, bool abort, TimeSpan timeout)
///
///
// TODO cancellation token
- internal async ValueTask CloseAsync(ShutdownEventArgs reason, bool abort, TimeSpan timeout)
+ internal async Task CloseAsync(ShutdownEventArgs reason, bool abort, TimeSpan timeout)
{
- // TODO CloseAsync and Close share a lot of code
- if (!SetCloseReason(reason))
+ if (false == SetCloseReason(reason))
{
- if (!abort)
+ // close reason is already set
+ if (false == abort)
{
ThrowAlreadyClosedException(CloseReason!);
}
@@ -458,7 +362,7 @@ await _session0.TransmitAsync(method)
try
{
- await _mainLoopTask.TimeoutAfter(timeout)
+ await _mainLoopTask.WaitAsync(timeout)
.ConfigureAwait(false);
}
catch (TimeoutException)
@@ -562,8 +466,15 @@ public void Dispose()
try
{
- this.Abort(InternalConstants.DefaultConnectionAbortTimeout);
- _mainLoopTask.Wait();
+ /*
+ * TODO rabbitmq-dotnet-client-1472
+ * this.Abort(InternalConstants.DefaultConnectionAbortTimeout);
+ * _mainLoopTask.Wait();
+ */
+ if (IsOpen)
+ {
+ throw new InvalidOperationException("Connection must be closed before calling Dispose!");
+ }
}
catch (OperationInterruptedException)
{
diff --git a/projects/RabbitMQ.Client/client/impl/ConsumerDispatching/ConsumerDispatcher.cs b/projects/RabbitMQ.Client/client/impl/ConsumerDispatching/ConsumerDispatcher.cs
index 380d95be6c..17ac041d93 100644
--- a/projects/RabbitMQ.Client/client/impl/ConsumerDispatching/ConsumerDispatcher.cs
+++ b/projects/RabbitMQ.Client/client/impl/ConsumerDispatching/ConsumerDispatcher.cs
@@ -29,7 +29,7 @@ protected override async Task ProcessChannelAsync(CancellationToken token)
switch (work.WorkType)
{
case WorkType.Deliver:
- consumer.HandleBasicDeliver(
+ await consumer.HandleBasicDeliverAsync(
consumerTag, work.DeliveryTag, work.Redelivered,
work.Exchange, work.RoutingKey, work.BasicProperties, work.Body.Memory);
break;
diff --git a/projects/RabbitMQ.Client/client/impl/ConsumerDispatching/ConsumerDispatcherBase.cs b/projects/RabbitMQ.Client/client/impl/ConsumerDispatching/ConsumerDispatcherBase.cs
index d61a783544..eb85a04e08 100644
--- a/projects/RabbitMQ.Client/client/impl/ConsumerDispatching/ConsumerDispatcherBase.cs
+++ b/projects/RabbitMQ.Client/client/impl/ConsumerDispatching/ConsumerDispatcherBase.cs
@@ -7,8 +7,8 @@ namespace RabbitMQ.Client.ConsumerDispatching
#nullable enable
internal abstract class ConsumerDispatcherBase
{
- private static readonly FallbackConsumer fallbackConsumer = new();
- private readonly Dictionary _consumers = new();
+ private static readonly FallbackConsumer fallbackConsumer = new FallbackConsumer();
+ private readonly Dictionary _consumers = new Dictionary();
public IBasicConsumer? DefaultConsumer { get; set; }
diff --git a/projects/RabbitMQ.Client/client/impl/ConsumerDispatching/ConsumerDispatcherChannelBase.cs b/projects/RabbitMQ.Client/client/impl/ConsumerDispatching/ConsumerDispatcherChannelBase.cs
index 06682b2c6c..1c5811969a 100644
--- a/projects/RabbitMQ.Client/client/impl/ConsumerDispatching/ConsumerDispatcherChannelBase.cs
+++ b/projects/RabbitMQ.Client/client/impl/ConsumerDispatching/ConsumerDispatcherChannelBase.cs
@@ -1,6 +1,4 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
using System.Threading;
using System.Threading.Channels;
using System.Threading.Tasks;
@@ -13,7 +11,7 @@ namespace RabbitMQ.Client.ConsumerDispatching
#nullable enable
internal abstract class ConsumerDispatcherChannelBase : ConsumerDispatcherBase, IConsumerDispatcher
{
- protected readonly CancellationTokenSource _consumerDispatcherCts = new();
+ protected readonly CancellationTokenSource _consumerDispatcherCts = new CancellationTokenSource();
protected readonly CancellationToken _consumerDispatcherToken;
protected readonly ChannelBase _channel;
@@ -140,13 +138,21 @@ public void WaitForShutdown()
catch (AggregateException aex)
{
AggregateException aexf = aex.Flatten();
- IEnumerable nonTaskCanceled = aexf.InnerExceptions.Where(iex => iex is not TaskCanceledException);
- if (nonTaskCanceled.Any())
+ bool foundUnexpectedException = false;
+ foreach (Exception innerAexf in aexf.InnerExceptions)
+ {
+ if (false == (innerAexf is OperationCanceledException))
+ {
+ foundUnexpectedException = true;
+ break;
+ }
+ }
+ if (foundUnexpectedException)
{
ESLog.Warn("consumer dispatcher task had unexpected exceptions");
}
}
- catch (TaskCanceledException)
+ catch (OperationCanceledException)
{
}
}
@@ -176,13 +182,21 @@ await _worker
catch (AggregateException aex)
{
AggregateException aexf = aex.Flatten();
- IEnumerable nonTaskCanceled = aexf.InnerExceptions.Where(iex => iex is not TaskCanceledException);
- if (nonTaskCanceled.Any())
+ bool foundUnexpectedException = false;
+ foreach (Exception innerAexf in aexf.InnerExceptions)
+ {
+ if (false == (innerAexf is OperationCanceledException))
+ {
+ foundUnexpectedException = true;
+ break;
+ }
+ }
+ if (foundUnexpectedException)
{
ESLog.Warn("consumer dispatcher task had unexpected exceptions (async)");
}
}
- catch (TaskCanceledException)
+ catch (OperationCanceledException)
{
}
}
diff --git a/projects/RabbitMQ.Client/client/impl/ConsumerDispatching/FallbackConsumer.cs b/projects/RabbitMQ.Client/client/impl/ConsumerDispatching/FallbackConsumer.cs
index b901a4ae71..dd9ae73852 100644
--- a/projects/RabbitMQ.Client/client/impl/ConsumerDispatching/FallbackConsumer.cs
+++ b/projects/RabbitMQ.Client/client/impl/ConsumerDispatching/FallbackConsumer.cs
@@ -37,10 +37,11 @@ void IBasicConsumer.HandleBasicConsumeOk(string consumerTag)
ESLog.Info($"Unhandled {nameof(IBasicConsumer.HandleBasicConsumeOk)} for tag {consumerTag}");
}
- void IBasicConsumer.HandleBasicDeliver(string consumerTag, ulong deliveryTag, bool redelivered, string exchange, string routingKey,
- in ReadOnlyBasicProperties properties, ReadOnlyMemory body)
+ Task IBasicConsumer.HandleBasicDeliverAsync(string consumerTag, ulong deliveryTag, bool redelivered, string exchange, string routingKey,
+ ReadOnlyBasicProperties properties, ReadOnlyMemory body)
{
- ESLog.Info($"Unhandled {nameof(IBasicConsumer.HandleBasicDeliver)} for tag {consumerTag}");
+ ESLog.Info($"Unhandled {nameof(IBasicConsumer.HandleBasicDeliverAsync)} for tag {consumerTag}");
+ return Task.CompletedTask;
}
void IBasicConsumer.HandleChannelShutdown(object channel, ShutdownEventArgs reason)
@@ -69,8 +70,7 @@ Task IAsyncBasicConsumer.HandleBasicConsumeOk(string consumerTag)
Task IAsyncBasicConsumer.HandleBasicDeliver(string consumerTag, ulong deliveryTag, bool redelivered, string exchange, string routingKey,
in ReadOnlyBasicProperties properties, ReadOnlyMemory body)
{
- ((IBasicConsumer)this).HandleBasicDeliver(consumerTag, deliveryTag, redelivered, exchange, routingKey, properties, body);
- return Task.CompletedTask;
+ return ((IBasicConsumer)this).HandleBasicDeliverAsync(consumerTag, deliveryTag, redelivered, exchange, routingKey, properties, body);
}
Task IAsyncBasicConsumer.HandleChannelShutdown(object channel, ShutdownEventArgs reason)
diff --git a/projects/RabbitMQ.Client/client/impl/RecordedBinding.cs b/projects/RabbitMQ.Client/client/impl/RecordedBinding.cs
index 1d3ed4221f..d0a861d8fd 100644
--- a/projects/RabbitMQ.Client/client/impl/RecordedBinding.cs
+++ b/projects/RabbitMQ.Client/client/impl/RecordedBinding.cs
@@ -67,15 +67,15 @@ public RecordedBinding(string destination, in RecordedBinding old)
_arguments = old._arguments;
}
- public ValueTask RecoverAsync(IChannel channel)
+ public Task RecoverAsync(IChannel channel)
{
if (_isQueueBinding)
{
- return channel.QueueBindAsync(_destination, _source, _routingKey, _arguments);
+ return channel.QueueBindAsync(_destination, _source, _routingKey, _arguments, false);
}
else
{
- return channel.ExchangeBindAsync(_destination, _source, _routingKey, _arguments);
+ return channel.ExchangeBindAsync(_destination, _source, _routingKey, _arguments, false);
}
}
diff --git a/projects/RabbitMQ.Client/client/impl/RecordedConsumer.cs b/projects/RabbitMQ.Client/client/impl/RecordedConsumer.cs
index 6cb909967f..888635f0a9 100644
--- a/projects/RabbitMQ.Client/client/impl/RecordedConsumer.cs
+++ b/projects/RabbitMQ.Client/client/impl/RecordedConsumer.cs
@@ -105,7 +105,7 @@ public static RecordedConsumer WithNewQueueName(string newQueueName, in Recorded
return new RecordedConsumer(old.Channel, old.Consumer, old.ConsumerTag, newQueueName, old.AutoAck, old.Exclusive, old.Arguments);
}
- public ValueTask RecoverAsync(IChannel channel)
+ public Task RecoverAsync(IChannel channel)
{
return channel.BasicConsumeAsync(Queue, AutoAck, ConsumerTag, false, Exclusive, Arguments, Consumer);
}
diff --git a/projects/RabbitMQ.Client/client/impl/RecordedExchange.cs b/projects/RabbitMQ.Client/client/impl/RecordedExchange.cs
index d5aeeb646d..a7b1c1d946 100644
--- a/projects/RabbitMQ.Client/client/impl/RecordedExchange.cs
+++ b/projects/RabbitMQ.Client/client/impl/RecordedExchange.cs
@@ -58,10 +58,10 @@ public RecordedExchange(string name, string type, bool durable, bool autoDelete,
_arguments = arguments;
}
- public ValueTask RecoverAsync(IChannel channel)
+ public Task RecoverAsync(IChannel channel)
{
return channel.ExchangeDeclareAsync(exchange: Name, type: _type, passive: false,
- durable: _durable, autoDelete: AutoDelete, arguments: _arguments);
+ durable: _durable, autoDelete: AutoDelete, noWait: false, arguments: _arguments);
}
public override string ToString()
diff --git a/projects/RabbitMQ.Client/client/impl/RecordedQueue.cs b/projects/RabbitMQ.Client/client/impl/RecordedQueue.cs
index 43f3f19a9e..d491f98280 100644
--- a/projects/RabbitMQ.Client/client/impl/RecordedQueue.cs
+++ b/projects/RabbitMQ.Client/client/impl/RecordedQueue.cs
@@ -71,7 +71,7 @@ public RecordedQueue(string newName, in RecordedQueue old)
_arguments = old._arguments;
}
- public ValueTask RecoverAsync(IChannel channel)
+ public Task RecoverAsync(IChannel channel)
{
string queueName = IsServerNamed ? string.Empty : Name;
return channel.QueueDeclareAsync(queue: queueName, passive: false,
diff --git a/projects/RabbitMQ.Client/client/impl/RecoveryAwareChannel.cs b/projects/RabbitMQ.Client/client/impl/RecoveryAwareChannel.cs
index 49a3294d0b..7c436e881a 100644
--- a/projects/RabbitMQ.Client/client/impl/RecoveryAwareChannel.cs
+++ b/projects/RabbitMQ.Client/client/impl/RecoveryAwareChannel.cs
@@ -62,15 +62,6 @@ protected override ulong AdjustDeliveryTag(ulong deliveryTag)
return deliveryTag + ActiveDeliveryTagOffset;
}
- public override void BasicAck(ulong deliveryTag, bool multiple)
- {
- ulong realTag = deliveryTag - ActiveDeliveryTagOffset;
- if (realTag > 0 && realTag <= deliveryTag)
- {
- base.BasicAck(realTag, multiple);
- }
- }
-
public override ValueTask BasicAckAsync(ulong deliveryTag, bool multiple)
{
ulong realTag = deliveryTag - ActiveDeliveryTagOffset;
@@ -84,15 +75,6 @@ public override ValueTask BasicAckAsync(ulong deliveryTag, bool multiple)
}
}
- public override void BasicNack(ulong deliveryTag, bool multiple, bool requeue)
- {
- ulong realTag = deliveryTag - ActiveDeliveryTagOffset;
- if (realTag > 0 && realTag <= deliveryTag)
- {
- base.BasicNack(realTag, multiple, requeue);
- }
- }
-
public override ValueTask BasicNackAsync(ulong deliveryTag, bool multiple, bool requeue)
{
ulong realTag = deliveryTag - ActiveDeliveryTagOffset;
@@ -106,16 +88,7 @@ public override ValueTask BasicNackAsync(ulong deliveryTag, bool multiple, bool
}
}
- public override void BasicReject(ulong deliveryTag, bool requeue)
- {
- ulong realTag = deliveryTag - ActiveDeliveryTagOffset;
- if (realTag > 0 && realTag <= deliveryTag)
- {
- base.BasicReject(realTag, requeue);
- }
- }
-
- public override ValueTask BasicRejectAsync(ulong deliveryTag, bool requeue)
+ public override Task BasicRejectAsync(ulong deliveryTag, bool requeue)
{
ulong realTag = deliveryTag - ActiveDeliveryTagOffset;
if (realTag > 0 && realTag <= deliveryTag)
@@ -124,7 +97,7 @@ public override ValueTask BasicRejectAsync(ulong deliveryTag, bool requeue)
}
else
{
- return default;
+ return Task.CompletedTask;
}
}
}
diff --git a/projects/RabbitMQ.Client/client/impl/SocketFrameHandler.cs b/projects/RabbitMQ.Client/client/impl/SocketFrameHandler.cs
index ef922b8c59..b0f9e766a9 100644
--- a/projects/RabbitMQ.Client/client/impl/SocketFrameHandler.cs
+++ b/projects/RabbitMQ.Client/client/impl/SocketFrameHandler.cs
@@ -248,7 +248,7 @@ await _closingSemaphore.WaitAsync()
try
{
_channelWriter.Complete();
- if (_writerTask is not null)
+ if (_writerTask != null)
{
await _writerTask.ConfigureAwait(false);
}
diff --git a/projects/RabbitMQ.Client/client/logging/RabbitMqClientEventSource.cs b/projects/RabbitMQ.Client/client/logging/RabbitMqClientEventSource.cs
index 6266b49aae..2729c9e35e 100644
--- a/projects/RabbitMQ.Client/client/logging/RabbitMqClientEventSource.cs
+++ b/projects/RabbitMQ.Client/client/logging/RabbitMqClientEventSource.cs
@@ -71,12 +71,6 @@ public void Error(string message, RabbitMqExceptionDetail ex)
{
#if NET6_0_OR_GREATER
WriteExceptionEvent(message, ex);
-
- [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The properties are preserved with the DynamicallyAccessedMembers attribute.")]
- void WriteExceptionEvent<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] T>(string message, T ex)
- {
- WriteEvent(3, message, ex);
- }
#else
WriteEvent(3, message, ex);
#endif
@@ -88,5 +82,13 @@ public void Error(string message, Exception ex)
{
Error(message, new RabbitMqExceptionDetail(ex));
}
+
+#if NET6_0_OR_GREATER
+ [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "The properties are preserved with the DynamicallyAccessedMembers attribute.")]
+ private void WriteExceptionEvent<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicProperties)] T>(string message, T ex)
+ {
+ WriteEvent(3, message, ex);
+ }
+#endif
}
}
diff --git a/projects/Test/Applications/CreateChannel/Program.cs b/projects/Test/Applications/CreateChannel/Program.cs
index 7365aca8b9..a490ae0032 100644
--- a/projects/Test/Applications/CreateChannel/Program.cs
+++ b/projects/Test/Applications/CreateChannel/Program.cs
@@ -15,24 +15,24 @@ public static class Program
private static int channelsOpened;
private static AutoResetEvent doneEvent;
- public static void Main()
+ public static async Task Main()
{
ThreadPool.SetMinThreads(16 * Environment.ProcessorCount, 16 * Environment.ProcessorCount);
doneEvent = new AutoResetEvent(false);
var connectionFactory = new ConnectionFactory { DispatchConsumersAsync = true };
- var connection = connectionFactory.CreateConnection();
+ IConnection connection = await connectionFactory.CreateConnectionAsync();
var watch = Stopwatch.StartNew();
- _ = Task.Run(() =>
+ _ = Task.Run(async () =>
{
var channels = new IChannel[ChannelsToOpen];
for (int i = 0; i < Repeats; i++)
{
for (int j = 0; j < channels.Length; j++)
{
- channels[j] = connection.CreateChannel();
+ channels[j] = await connection.CreateChannelAsync();
channelsOpened++;
}
diff --git a/projects/Test/Applications/MassPublish/MassPublish.csproj b/projects/Test/Applications/MassPublish/MassPublish.csproj
index b57323cb5a..63d513a986 100644
--- a/projects/Test/Applications/MassPublish/MassPublish.csproj
+++ b/projects/Test/Applications/MassPublish/MassPublish.csproj
@@ -9,8 +9,8 @@
- latest
Exe
+ 9.0
diff --git a/projects/Test/Applications/MassPublish/Program.cs b/projects/Test/Applications/MassPublish/Program.cs
index 78a31f00fd..a3938b69a8 100644
--- a/projects/Test/Applications/MassPublish/Program.cs
+++ b/projects/Test/Applications/MassPublish/Program.cs
@@ -76,7 +76,7 @@ static async Task Main()
await consumeChannel.BasicQosAsync(prefetchSize: 0, prefetchCount: 128, global: false);
await consumeChannel.ExchangeDeclareAsync(exchange: ExchangeName,
- type: ExchangeType.Direct, passive: false, durable: false, autoDelete: false, arguments: null);
+ type: ExchangeType.Direct, passive: false, durable: false, autoDelete: false, noWait: false, arguments: null);
await consumeChannel.QueueDeclareAsync(queue: QueueName,
passive: false, durable: false, exclusive: false, autoDelete: false, arguments: null);
@@ -125,6 +125,8 @@ static async Task Main()
{
Console.WriteLine("[DEBUG] channel {0} done publishing and waiting for confirms", publishChannel.ChannelNumber);
}
+
+ await publishChannel.CloseAsync();
}));
}
@@ -152,6 +154,8 @@ static async Task Main()
await c.CloseAsync();
}
+
+ await consumeChannel.CloseAsync();
}
private static void PublishChannel_BasicNacks(object sender, BasicNackEventArgs e)
diff --git a/projects/Test/AsyncIntegration/AsyncIntegration.csproj b/projects/Test/AsyncIntegration/AsyncIntegration.csproj
index c7521605d9..c724726a05 100644
--- a/projects/Test/AsyncIntegration/AsyncIntegration.csproj
+++ b/projects/Test/AsyncIntegration/AsyncIntegration.csproj
@@ -11,9 +11,8 @@
../../rabbit.snk
true
- latest
- 7.0
true
+ 7.3
@@ -41,8 +40,8 @@
-
-
+
+
diff --git a/projects/Test/AsyncIntegration/AsyncIntegrationFixture.cs b/projects/Test/AsyncIntegration/AsyncIntegrationFixture.cs
index 508b9b96ad..23398f6147 100644
--- a/projects/Test/AsyncIntegration/AsyncIntegrationFixture.cs
+++ b/projects/Test/AsyncIntegration/AsyncIntegrationFixture.cs
@@ -53,11 +53,6 @@ public class AsyncIntegrationFixture : IntegrationFixtureBase, IAsyncLifetime
_openChannel = openChannel;
}
- protected override void SetUp()
- {
- // InitializeAsync
- }
-
protected static Task AssertRanToCompletion(params Task[] tasks)
{
return DoAssertRanToCompletion(tasks);
@@ -68,7 +63,7 @@ protected static Task AssertRanToCompletion(IEnumerable tasks)
return DoAssertRanToCompletion(tasks);
}
- public virtual async Task InitializeAsync()
+ public override async Task InitializeAsync()
{
_connFactory = CreateConnectionFactory();
_connFactory.DispatchConsumersAsync = _dispatchConsumersAsync;
@@ -92,33 +87,11 @@ public virtual async Task InitializeAsync()
base.AddCallbackHandlers();
}
- public virtual async Task DisposeAsync()
- {
- try
- {
- if (_channel != null)
- {
- await _channel.CloseAsync();
- }
- await _conn.CloseAsync();
- }
- finally
- {
- if (_channel != null)
- {
- _channel.Dispose();
- }
- _conn.Dispose();
- _channel = null;
- _conn = null;
- }
- }
-
private static async Task DoAssertRanToCompletion(IEnumerable tasks)
{
Task whenAllTask = Task.WhenAll(tasks);
await whenAllTask;
- Assert.Equal(TaskStatus.RanToCompletion, whenAllTask.Status);
+ Assert.True(whenAllTask.IsCompletedSuccessfully());
}
}
}
diff --git a/projects/Test/AsyncIntegration/TestAsyncConsumer.cs b/projects/Test/AsyncIntegration/TestAsyncConsumer.cs
index 3ce42591e2..49c77aedb5 100644
--- a/projects/Test/AsyncIntegration/TestAsyncConsumer.cs
+++ b/projects/Test/AsyncIntegration/TestAsyncConsumer.cs
@@ -173,22 +173,25 @@ public async Task TestBasicRoundtripConcurrentManyMessages()
Task publishTask = Task.Run(async () =>
{
- using (IChannel m = await _conn.CreateChannelAsync())
+ using (IChannel publishChannel = await _conn.CreateChannelAsync())
{
- QueueDeclareOk q = _channel.QueueDeclare(queue: queueName, exclusive: false, durable: true);
+ QueueDeclareOk pubQ = await publishChannel.QueueDeclareAsync(queue: queueName, exclusive: false, durable: true);
+ Assert.Equal(queueName, pubQ.QueueName);
for (int i = 0; i < publish_total; i++)
{
- await _channel.BasicPublishAsync(string.Empty, queueName, body1);
- await _channel.BasicPublishAsync(string.Empty, queueName, body2);
+ await publishChannel.BasicPublishAsync(string.Empty, queueName, body1);
+ await publishChannel.BasicPublishAsync(string.Empty, queueName, body2);
}
+
+ await publishChannel.CloseAsync();
}
});
Task consumeTask = Task.Run(async () =>
{
- using (IChannel m = await _conn.CreateChannelAsync())
+ using (IChannel consumeChannel = await _conn.CreateChannelAsync())
{
- var consumer = new AsyncEventingBasicConsumer(m);
+ var consumer = new AsyncEventingBasicConsumer(consumeChannel);
int publish1_count = 0;
int publish2_count = 0;
@@ -214,7 +217,7 @@ public async Task TestBasicRoundtripConcurrentManyMessages()
}
};
- await _channel.BasicConsumeAsync(queueName, true, string.Empty, false, false, null, consumer);
+ await consumeChannel.BasicConsumeAsync(queueName, true, string.Empty, false, false, null, consumer);
// ensure we get a delivery
await AssertRanToCompletion(publish1SyncSource.Task, publish2SyncSource.Task);
@@ -224,6 +227,8 @@ public async Task TestBasicRoundtripConcurrentManyMessages()
bool result2 = await publish2SyncSource.Task;
Assert.True(result2, $"Non concurrent dispatch lead to deadlock after {maximumWaitTime}");
+
+ await consumeChannel.CloseAsync();
}
});
@@ -235,93 +240,95 @@ public async Task TestBasicRejectAsync()
{
var publishSyncSource = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
- using var cancellationTokenSource = new CancellationTokenSource(TestTimeout);
-
- cancellationTokenSource.Token.Register(() =>
+ using (var cancellationTokenSource = new CancellationTokenSource(TestTimeout))
{
- publishSyncSource.SetCanceled();
- });
-
- _conn.ConnectionShutdown += (o, ea) =>
- {
- HandleConnectionShutdown(_conn, ea, (args) =>
+ cancellationTokenSource.Token.Register(() =>
{
- if (args.Initiator == ShutdownInitiator.Peer)
- {
- publishSyncSource.TrySetResult(false);
- }
+ publishSyncSource.SetCanceled();
});
- };
- _channel.ChannelShutdown += (o, ea) =>
- {
- HandleChannelShutdown(_channel, ea, (args) =>
+ _conn.ConnectionShutdown += (o, ea) =>
{
- if (args.Initiator == ShutdownInitiator.Peer)
+ HandleConnectionShutdown(_conn, ea, (args) =>
{
- publishSyncSource.TrySetResult(false);
- }
- });
- };
-
- var consumer = new AsyncEventingBasicConsumer(_channel);
- consumer.Received += async (object sender, BasicDeliverEventArgs args) =>
- {
- var c = sender as AsyncEventingBasicConsumer;
- Assert.Same(c, consumer);
- await _channel.BasicCancelAsync(c.ConsumerTags[0]);
- /*
- * https://github.com/rabbitmq/rabbitmq-dotnet-client/actions/runs/7450578332/attempts/1
- * That job failed with a bizarre error where the delivery tag ack timed out:
- *
- * AI.TestAsyncConsumer.TestBasicRejectAsync channel 1 shut down:
- * AMQP close-reason, initiated by Peer, code=406, text=
- * 'PRECONDITION_FAILED - delivery acknowledgement on channel 1 timed out. Timeout value used: 1800000 ms ...', classId=0, methodId=0
- *
- * Added Task.Yield() to see if it ever happens again.
- */
- await Task.Yield();
- await _channel.BasicRejectAsync(args.DeliveryTag, true);
- publishSyncSource.TrySetResult(true);
- };
-
- QueueDeclareOk q = await _channel.QueueDeclareAsync(string.Empty, false, false, true, false, null);
- string queueName = q.QueueName;
- const string publish1 = "sync-hi-1";
- byte[] _body = _encoding.GetBytes(publish1);
- await _channel.BasicPublishAsync(string.Empty, queueName, _body);
+ if (args.Initiator == ShutdownInitiator.Peer)
+ {
+ publishSyncSource.TrySetResult(false);
+ }
+ });
+ };
- await _channel.BasicConsumeAsync(queue: queueName, autoAck: false,
- consumerTag: string.Empty, noLocal: false, exclusive: false,
- arguments: null, consumer);
+ _channel.ChannelShutdown += (o, ea) =>
+ {
+ HandleChannelShutdown(_channel, ea, (args) =>
+ {
+ if (args.Initiator == ShutdownInitiator.Peer)
+ {
+ publishSyncSource.TrySetResult(false);
+ }
+ });
+ };
- Assert.True(await publishSyncSource.Task);
+ var consumer = new AsyncEventingBasicConsumer(_channel);
+ consumer.Received += async (object sender, BasicDeliverEventArgs args) =>
+ {
+ var c = sender as AsyncEventingBasicConsumer;
+ Assert.Same(c, consumer);
+ await _channel.BasicCancelAsync(c.ConsumerTags[0]);
+ /*
+ * https://github.com/rabbitmq/rabbitmq-dotnet-client/actions/runs/7450578332/attempts/1
+ * That job failed with a bizarre error where the delivery tag ack timed out:
+ *
+ * AI.TestAsyncConsumer.TestBasicRejectAsync channel 1 shut down:
+ * AMQP close-reason, initiated by Peer, code=406, text=
+ * 'PRECONDITION_FAILED - delivery acknowledgement on channel 1 timed out. Timeout value used: 1800000 ms ...', classId=0, methodId=0
+ *
+ * Added Task.Yield() to see if it ever happens again.
+ */
+ await Task.Yield();
+ await _channel.BasicRejectAsync(args.DeliveryTag, true);
+ publishSyncSource.TrySetResult(true);
+ };
+
+ QueueDeclareOk q = await _channel.QueueDeclareAsync(queue: string.Empty,
+ durable: false, exclusive: true, autoDelete: false);
+ string queueName = q.QueueName;
+ const string publish1 = "sync-hi-1";
+ byte[] _body = _encoding.GetBytes(publish1);
+ await _channel.BasicPublishAsync(string.Empty, queueName, _body);
+
+ await _channel.BasicConsumeAsync(queue: queueName, autoAck: false,
+ consumerTag: string.Empty, noLocal: false, exclusive: false,
+ arguments: null, consumer);
+
+ Assert.True(await publishSyncSource.Task);
+
+ uint messageCount, consumerCount = 0;
+ ushort tries = 5;
+ do
+ {
+ QueueDeclareOk result = await _channel.QueueDeclarePassiveAsync(queue: queueName);
+ consumerCount = result.ConsumerCount;
+ messageCount = result.MessageCount;
+ if (consumerCount == 0 && messageCount > 0)
+ {
+ break;
+ }
+ else
+ {
+ await Task.Delay(500);
+ }
+ } while (tries-- > 0);
- uint messageCount, consumerCount = 0;
- ushort tries = 5;
- do
- {
- QueueDeclareOk result = await _channel.QueueDeclareAsync(queue: queueName, passive: true, false, false, false, null);
- consumerCount = result.ConsumerCount;
- messageCount = result.MessageCount;
- if (consumerCount == 0 && messageCount > 0)
+ if (tries == 0)
{
- break;
+ Assert.Fail("[ERROR] failed waiting for MessageCount > 0 && ConsumerCount == 0");
}
else
{
- await Task.Delay(500);
+ Assert.Equal((uint)1, messageCount);
+ Assert.Equal((uint)0, consumerCount);
}
- } while (tries-- > 0);
-
- if (tries == 0)
- {
- Assert.Fail("[ERROR] failed waiting for MessageCount > 0 && ConsumerCount == 0");
- }
- else
- {
- Assert.Equal((uint)1, messageCount);
- Assert.Equal((uint)0, consumerCount);
}
}
@@ -333,15 +340,9 @@ public async Task TestBasicAckAsync()
var publishSyncSource = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
- var cf = CreateConnectionFactory();
- cf.DispatchConsumersAsync = true;
-
- using IConnection connection = await cf.CreateConnectionAsync();
- using IChannel channel = await connection.CreateChannelAsync();
-
- connection.ConnectionShutdown += (o, ea) =>
+ _conn.ConnectionShutdown += (o, ea) =>
{
- HandleConnectionShutdown(connection, ea, (args) =>
+ HandleConnectionShutdown(_conn, ea, (args) =>
{
if (args.Initiator == ShutdownInitiator.Peer)
{
@@ -350,9 +351,9 @@ public async Task TestBasicAckAsync()
});
};
- channel.ChannelShutdown += (o, ea) =>
+ _channel.ChannelShutdown += (o, ea) =>
{
- HandleChannelShutdown(channel, ea, (args) =>
+ HandleChannelShutdown(_channel, ea, (args) =>
{
if (args.Initiator == ShutdownInitiator.Peer)
{
@@ -361,14 +362,14 @@ public async Task TestBasicAckAsync()
});
};
- await channel.ConfirmSelectAsync();
+ await _channel.ConfirmSelectAsync();
- var consumer = new AsyncEventingBasicConsumer(channel);
+ var consumer = new AsyncEventingBasicConsumer(_channel);
consumer.Received += async (object sender, BasicDeliverEventArgs args) =>
{
var c = sender as AsyncEventingBasicConsumer;
Assert.NotNull(c);
- await channel.BasicAckAsync(args.DeliveryTag, false);
+ await _channel.BasicAckAsync(args.DeliveryTag, false);
messagesReceived++;
if (messagesReceived == messageCount)
{
@@ -376,11 +377,11 @@ public async Task TestBasicAckAsync()
}
};
- QueueDeclareOk q = await channel.QueueDeclareAsync(string.Empty, false, false, true, false, null);
+ QueueDeclareOk q = await _channel.QueueDeclareAsync(string.Empty, false, false, true);
string queueName = q.QueueName;
- await channel.BasicQosAsync(0, 1, false);
- await channel.BasicConsumeAsync(queue: queueName, autoAck: false,
+ await _channel.BasicQosAsync(0, 1, false);
+ await _channel.BasicConsumeAsync(queue: queueName, autoAck: false,
consumerTag: string.Empty, noLocal: false, exclusive: false,
arguments: null, consumer);
@@ -389,17 +390,16 @@ public async Task TestBasicAckAsync()
for (int i = 0; i < messageCount; i++)
{
byte[] _body = _encoding.GetBytes(Guid.NewGuid().ToString());
- await channel.BasicPublishAsync(string.Empty, queueName, _body);
+ await _channel.BasicPublishAsync(string.Empty, queueName, _body);
}
});
- await channel.WaitForConfirmsOrDieAsync();
+ await _channel.WaitForConfirmsOrDieAsync();
Assert.True(await publishSyncSource.Task);
Assert.Equal(messageCount, messagesReceived);
- // Note: closing channel explicitly just to test it.
- await channel.CloseAsync(_closeArgs, false);
+ await _channel.CloseAsync(_closeArgs, false);
}
[Fact]
@@ -407,15 +407,9 @@ public async Task TestBasicNackAsync()
{
var publishSyncSource = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
- var cf = CreateConnectionFactory();
- cf.DispatchConsumersAsync = true;
-
- using IConnection connection = await cf.CreateConnectionAsync();
- using IChannel channel = await connection.CreateChannelAsync();
-
- connection.ConnectionShutdown += (o, ea) =>
+ _conn.ConnectionShutdown += (o, ea) =>
{
- HandleConnectionShutdown(connection, ea, (args) =>
+ HandleConnectionShutdown(_conn, ea, (args) =>
{
if (args.Initiator == ShutdownInitiator.Peer)
{
@@ -424,9 +418,9 @@ public async Task TestBasicNackAsync()
});
};
- channel.ChannelShutdown += (o, ea) =>
+ _channel.ChannelShutdown += (o, ea) =>
{
- HandleChannelShutdown(channel, ea, (args) =>
+ HandleChannelShutdown(_channel, ea, (args) =>
{
if (args.Initiator == ShutdownInitiator.Peer)
{
@@ -435,23 +429,23 @@ public async Task TestBasicNackAsync()
});
};
- var consumer = new AsyncEventingBasicConsumer(channel);
+ var consumer = new AsyncEventingBasicConsumer(_channel);
consumer.Received += async (object sender, BasicDeliverEventArgs args) =>
{
var c = sender as AsyncEventingBasicConsumer;
Assert.NotNull(c);
- await channel.BasicCancelAsync(c.ConsumerTags[0]);
- await channel.BasicNackAsync(args.DeliveryTag, false, true);
+ await _channel.BasicCancelAsync(c.ConsumerTags[0]);
+ await _channel.BasicNackAsync(args.DeliveryTag, false, true);
publishSyncSource.SetResult(true);
};
- QueueDeclareOk q = await channel.QueueDeclareAsync(string.Empty, false, false, false, false, null);
+ QueueDeclareOk q = await _channel.QueueDeclareAsync(string.Empty, false, false, false);
string queueName = q.QueueName;
const string publish1 = "sync-hi-1";
byte[] _body = _encoding.GetBytes(publish1);
- await channel.BasicPublishAsync(string.Empty, queueName, _body);
+ await _channel.BasicPublishAsync(string.Empty, queueName, _body);
- await channel.BasicConsumeAsync(queue: queueName, autoAck: false,
+ await _channel.BasicConsumeAsync(queue: queueName, autoAck: false,
consumerTag: string.Empty, noLocal: false, exclusive: false,
arguments: null, consumer);
@@ -461,7 +455,7 @@ public async Task TestBasicNackAsync()
ushort tries = 5;
do
{
- QueueDeclareOk result = await channel.QueueDeclareAsync(queue: queueName, passive: true, false, false, false, null);
+ QueueDeclareOk result = await _channel.QueueDeclarePassiveAsync(queue: queueName);
consumerCount = result.ConsumerCount;
messageCount = result.MessageCount;
if (consumerCount == 0 && messageCount > 0)
@@ -484,15 +478,14 @@ public async Task TestBasicNackAsync()
Assert.Equal((uint)0, consumerCount);
}
- // Note: closing channel explicitly just to test it.
- await channel.CloseAsync(_closeArgs, false);
+ await _channel.CloseAsync(_closeArgs, false);
}
[Fact]
public async Task NonAsyncConsumerShouldThrowInvalidOperationException()
{
bool sawException = false;
- QueueDeclareOk q = await _channel.QueueDeclareAsync(string.Empty, false, false, false, false, null);
+ QueueDeclareOk q = await _channel.QueueDeclareAsync(string.Empty, false, false, false);
await _channel.BasicPublishAsync(string.Empty, q.QueueName, GetRandomBody(1024));
var consumer = new EventingBasicConsumer(_channel);
try
diff --git a/projects/Test/AsyncIntegration/TestAsyncConsumerExceptions.cs b/projects/Test/AsyncIntegration/TestAsyncConsumerExceptions.cs
index d26b85fd68..dc1051d002 100644
--- a/projects/Test/AsyncIntegration/TestAsyncConsumerExceptions.cs
+++ b/projects/Test/AsyncIntegration/TestAsyncConsumerExceptions.cs
@@ -84,18 +84,18 @@ public Task TestDeliveryExceptionHandling()
{
IBasicConsumer consumer = new ConsumerFailingOnDelivery(_channel);
return TestExceptionHandlingWith(consumer, (ch, q, c, ct) =>
- ch.BasicPublishAsync("", q, _encoding.GetBytes("msg")));
+ ch.BasicPublishAsync("", q, _encoding.GetBytes("msg")).AsTask());
}
protected async Task TestExceptionHandlingWith(IBasicConsumer consumer,
- Func action)
+ Func action)
{
var waitSpan = TimeSpan.FromSeconds(5);
var tcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously);
var cts = new CancellationTokenSource(waitSpan);
cts.Token.Register(() => tcs.TrySetResult(false));
- string q = await _channel.QueueDeclareAsync(string.Empty, false, false, true, false, null);
+ string q = await _channel.QueueDeclareAsync(string.Empty, false, true, false);
_channel.CallbackException += (ch, evt) =>
{
if (evt.Exception == TestException)
diff --git a/projects/Test/AsyncIntegration/TestBasicGetAsync.cs b/projects/Test/AsyncIntegration/TestBasicGetAsync.cs
index 6d43ebd0a3..48309660df 100644
--- a/projects/Test/AsyncIntegration/TestBasicGetAsync.cs
+++ b/projects/Test/AsyncIntegration/TestBasicGetAsync.cs
@@ -47,7 +47,7 @@ public async Task TestBasicGet()
{
const string msg = "for async basic.get";
- QueueDeclareOk queueResult = await _channel.QueueDeclareAsync(string.Empty, false, true, true, true, null);
+ QueueDeclareOk queueResult = await _channel.QueueDeclareAsync(string.Empty, false, true, true);
string queueName = queueResult.QueueName;
await _channel.BasicPublishAsync(string.Empty, queueName, _encoding.GetBytes(msg), true);
@@ -55,7 +55,7 @@ public async Task TestBasicGet()
BasicGetResult getResult = await _channel.BasicGetAsync(queueName, true);
Assert.Equal(msg, _encoding.GetString(getResult.Body.ToArray()));
- QueueDeclareOk queueResultPassive = await _channel.QueueDeclareAsync(queueName, true, true, true, true, null);
+ QueueDeclareOk queueResultPassive = await _channel.QueueDeclarePassiveAsync(queue: queueName);
Assert.Equal((uint)0, queueResultPassive.MessageCount);
Assert.Null(await _channel.BasicGetAsync(queueName, true));
diff --git a/projects/Test/AsyncIntegration/TestBasicPublishAsync.cs b/projects/Test/AsyncIntegration/TestBasicPublishAsync.cs
index e6a526a130..6c58fb3f2f 100644
--- a/projects/Test/AsyncIntegration/TestBasicPublishAsync.cs
+++ b/projects/Test/AsyncIntegration/TestBasicPublishAsync.cs
@@ -51,7 +51,7 @@ public async Task TestQueuePurgeAsync()
await _channel.ConfirmSelectAsync();
- QueueDeclareOk q = await _channel.QueueDeclareAsync(string.Empty, false, false, true, false, null);
+ QueueDeclareOk q = await _channel.QueueDeclareAsync(string.Empty, false, false, true);
var publishTask = Task.Run(async () =>
{
diff --git a/projects/Test/AsyncIntegration/TestConcurrentAccessWithSharedConnectionAsync.cs b/projects/Test/AsyncIntegration/TestConcurrentAccessWithSharedConnectionAsync.cs
index 9626bf4fa8..32a16dc546 100644
--- a/projects/Test/AsyncIntegration/TestConcurrentAccessWithSharedConnectionAsync.cs
+++ b/projects/Test/AsyncIntegration/TestConcurrentAccessWithSharedConnectionAsync.cs
@@ -132,6 +132,7 @@ private Task TestConcurrentChannelOpenAndPublishingWithBodyAsync(byte[] body, in
}
Assert.True(await tcs.Task);
+ await ch.CloseAsync();
}
}, iterations);
}
diff --git a/projects/Test/AsyncIntegration/TestConnectionFactory.cs b/projects/Test/AsyncIntegration/TestConnectionFactory.cs
index 459e0ae0e8..15763a6d1d 100644
--- a/projects/Test/AsyncIntegration/TestConnectionFactory.cs
+++ b/projects/Test/AsyncIntegration/TestConnectionFactory.cs
@@ -45,53 +45,61 @@ public TestConnectionFactory(ITestOutputHelper output) : base(output)
{
}
- protected override void SetUp()
+ public override Task InitializeAsync()
{
// NB: nothing to do here since each test creates its own factory,
// connections and channels
Assert.Null(_connFactory);
Assert.Null(_conn);
Assert.Null(_channel);
+ return Task.CompletedTask;
}
[Fact]
public async Task TestCreateConnectionAsync_WithAlreadyCanceledToken()
{
- using var cts = new CancellationTokenSource();
- cts.Cancel();
+ using (var cts = new CancellationTokenSource())
+ {
+ cts.Cancel();
- ConnectionFactory cf = CreateConnectionFactory();
+ ConnectionFactory cf = CreateConnectionFactory();
- bool passed = false;
- /*
- * If anyone wonders why TaskCanceledException is explicitly checked,
- * even though it's a subclass of OperationCanceledException:
- * https://github.com/rabbitmq/rabbitmq-dotnet-client/commit/383ca5c5f161edb717cf8fae7bf143c13143f634#r135400615
- */
- try
- {
- await cf.CreateConnectionAsync(cts.Token);
- }
- catch (TaskCanceledException)
- {
- passed = true;
- }
- catch (OperationCanceledException)
- {
- passed = true;
- }
+ bool passed = false;
+ /*
+ * If anyone wonders why TaskCanceledException is explicitly checked,
+ * even though it's a subclass of OperationCanceledException:
+ * https://github.com/rabbitmq/rabbitmq-dotnet-client/commit/383ca5c5f161edb717cf8fae7bf143c13143f634#r135400615
+ */
+ try
+ {
+ await cf.CreateConnectionAsync(cts.Token);
+ }
+ catch (TaskCanceledException)
+ {
+ passed = true;
+ }
+ catch (OperationCanceledException)
+ {
+ passed = true;
+ }
- Assert.True(passed, "FAIL did not see TaskCanceledException nor OperationCanceledException");
+ Assert.True(passed, "FAIL did not see TaskCanceledException nor OperationCanceledException");
+ }
}
[Fact]
public async Task TestCreateConnectionAsync_UsesValidEndpointWhenMultipleSupplied()
{
- using var cts = new CancellationTokenSource(WaitSpan);
- ConnectionFactory cf = CreateConnectionFactory();
- var invalidEp = new AmqpTcpEndpoint("not_localhost");
- var ep = new AmqpTcpEndpoint("localhost");
- using IConnection conn = await cf.CreateConnectionAsync(new List { invalidEp, ep }, cts.Token);
+ using (var cts = new CancellationTokenSource(WaitSpan))
+ {
+ ConnectionFactory cf = CreateConnectionFactory();
+ var invalidEp = new AmqpTcpEndpoint("not_localhost");
+ var ep = new AmqpTcpEndpoint("localhost");
+ using (IConnection conn = await cf.CreateConnectionAsync(new List { invalidEp, ep }, cts.Token))
+ {
+ await conn.CloseAsync();
+ }
+ }
}
}
}
diff --git a/projects/Test/AsyncIntegration/TestExchangeDeclareAsync.cs b/projects/Test/AsyncIntegration/TestExchangeDeclareAsync.cs
index 6fee43ebf4..cb72ad6dbb 100644
--- a/projects/Test/AsyncIntegration/TestExchangeDeclareAsync.cs
+++ b/projects/Test/AsyncIntegration/TestExchangeDeclareAsync.cs
@@ -58,8 +58,8 @@ async Task f()
{
await Task.Delay(S_Random.Next(5, 50));
string exchangeName = GenerateExchangeName();
- await _channel.ExchangeDeclareAsync(exchange: exchangeName, type: "fanout", passive: false, false, false, null);
- await _channel.ExchangeBindAsync(destination: "amq.fanout", source: exchangeName, routingKey: "unused", null);
+ await _channel.ExchangeDeclareAsync(exchange: exchangeName, type: "fanout", false, false);
+ await _channel.ExchangeBindAsync(destination: "amq.fanout", source: exchangeName, routingKey: "unused");
exchangeNames.Add(exchangeName);
}
catch (NotSupportedException e)
@@ -82,7 +82,8 @@ async Task f()
try
{
await Task.Delay(S_Random.Next(5, 50));
- await _channel.ExchangeUnbindAsync(destination: "amq.fanout", source: exchangeName, routingKey: "unused", null);
+ await _channel.ExchangeUnbindAsync(destination: "amq.fanout", source: exchangeName, routingKey: "unused",
+ noWait: false, arguments: null);
await _channel.ExchangeDeleteAsync(exchange: exchangeName, ifUnused: false);
}
catch (NotSupportedException e)
diff --git a/projects/Test/AsyncIntegration/TestExtensionsAsync.cs b/projects/Test/AsyncIntegration/TestExtensionsAsync.cs
index 91cb8e9107..22a8ec1ff4 100644
--- a/projects/Test/AsyncIntegration/TestExtensionsAsync.cs
+++ b/projects/Test/AsyncIntegration/TestExtensionsAsync.cs
@@ -55,9 +55,9 @@ public async Task TestConfirmBarrier()
}
[Fact]
- public Task TestConfirmBeforeWait()
+ public async Task TestConfirmBeforeWait()
{
- return Assert.ThrowsAsync(() => _channel.WaitForConfirmsAsync());
+ await Assert.ThrowsAsync(() => _channel.WaitForConfirmsAsync());
}
[Fact]
@@ -65,18 +65,18 @@ public async Task TestExchangeBindingAsync()
{
await _channel.ConfirmSelectAsync();
- await _channel.ExchangeDeclareAsync("src", ExchangeType.Direct, false, false, false, null);
- await _channel.ExchangeDeclareAsync("dest", ExchangeType.Direct, false, false, false, null);
- string queue = await _channel.QueueDeclareAsync(string.Empty, false, false, true, false, null);
+ await _channel.ExchangeDeclareAsync("src", ExchangeType.Direct, false, false);
+ await _channel.ExchangeDeclareAsync("dest", ExchangeType.Direct, false, false);
+ string queue = await _channel.QueueDeclareAsync(string.Empty, false, false, true);
- await _channel.ExchangeBindAsync("dest", "src", string.Empty, null);
- await _channel.QueueBindAsync(queue, "dest", string.Empty, null);
+ await _channel.ExchangeBindAsync("dest", "src", string.Empty);
+ await _channel.QueueBindAsync(queue, "dest", string.Empty);
await _channel.BasicPublishAsync("src", string.Empty);
await _channel.WaitForConfirmsAsync();
Assert.NotNull(await _channel.BasicGetAsync(queue, true));
- await _channel.ExchangeUnbindAsync("dest", "src", string.Empty, null);
+ await _channel.ExchangeUnbindAsync("dest", "src", string.Empty);
await _channel.BasicPublishAsync("src", string.Empty);
await _channel.WaitForConfirmsAsync();
diff --git a/projects/Test/AsyncIntegration/TestFloodPublishingAsync.cs b/projects/Test/AsyncIntegration/TestFloodPublishingAsync.cs
index ce845b5294..e196ea063a 100644
--- a/projects/Test/AsyncIntegration/TestFloodPublishingAsync.cs
+++ b/projects/Test/AsyncIntegration/TestFloodPublishingAsync.cs
@@ -185,6 +185,7 @@ public async Task TestMultithreadFloodPublishingAsync()
}
await pubCh.WaitForConfirmsOrDieAsync();
+ await pubCh.CloseAsync();
}
});
@@ -224,6 +225,7 @@ public async Task TestMultithreadFloodPublishingAsync()
arguments: null, consumer: consumer);
Assert.True(await tcs.Task);
+ await consumeCh.CloseAsync();
}
await pub;
diff --git a/projects/Test/AsyncIntegration/TestMessageCountAsync.cs b/projects/Test/AsyncIntegration/TestMessageCountAsync.cs
index 55417d0732..e40dc79200 100644
--- a/projects/Test/AsyncIntegration/TestMessageCountAsync.cs
+++ b/projects/Test/AsyncIntegration/TestMessageCountAsync.cs
@@ -48,11 +48,11 @@ public async Task TestMessageCountMethod()
await _channel.ConfirmSelectAsync();
string q = GenerateQueueName();
await _channel.QueueDeclareAsync(queue: q, passive: false, durable: false, exclusive: true, autoDelete: false, arguments: null);
- Assert.Equal(0u, _channel.MessageCount(q));
+ Assert.Equal(0u, await _channel.MessageCountAsync(q));
await _channel.BasicPublishAsync("", q, _encoding.GetBytes("msg"));
await _channel.WaitForConfirmsAsync();
- Assert.Equal(1u, _channel.MessageCount(q));
+ Assert.Equal(1u, await _channel.MessageCountAsync(q));
}
}
}
diff --git a/projects/Test/AsyncIntegration/TestPassiveDeclareAsync.cs b/projects/Test/AsyncIntegration/TestPassiveDeclareAsync.cs
index 54eb1fc032..43fd9a24e2 100644
--- a/projects/Test/AsyncIntegration/TestPassiveDeclareAsync.cs
+++ b/projects/Test/AsyncIntegration/TestPassiveDeclareAsync.cs
@@ -49,8 +49,8 @@ public Task TestPassiveExchangeDeclareWhenExchangeDoesNotExist()
{
return Assert.ThrowsAsync(() =>
{
- ValueTask r = _channel.ExchangeDeclareAsync(Guid.NewGuid().ToString(), ExchangeType.Fanout, true, false, false, null);
- return r.AsTask();
+ return _channel.ExchangeDeclareAsync(exchange: Guid.NewGuid().ToString(), type: ExchangeType.Fanout,
+ passive: true, durable: true, autoDelete: false);
});
}
@@ -59,8 +59,8 @@ public Task TestPassiveQueueDeclareWhenQueueDoesNotExist()
{
return Assert.ThrowsAsync(() =>
{
- ValueTask r = _channel.QueueDeclareAsync(Guid.NewGuid().ToString(), true, false, false, false, null);
- return r.AsTask();
+ return _channel.QueueDeclareAsync(queue: Guid.NewGuid().ToString(), passive: true,
+ durable: true, exclusive: true, autoDelete: false);
});
}
}
diff --git a/projects/Test/AsyncIntegration/TestPublishSharedChannelAsync.cs b/projects/Test/AsyncIntegration/TestPublishSharedChannelAsync.cs
index eb25891339..067a097800 100644
--- a/projects/Test/AsyncIntegration/TestPublishSharedChannelAsync.cs
+++ b/projects/Test/AsyncIntegration/TestPublishSharedChannelAsync.cs
@@ -75,30 +75,42 @@ public async Task MultiThreadPublishOnSharedChannel()
using (IConnection conn = await cf.CreateConnectionAsync())
{
- Assert.IsNotType(conn);
- conn.ConnectionShutdown += HandleConnectionShutdown;
-
- using (IChannel channel = await conn.CreateChannelAsync())
+ try
{
- channel.ChannelShutdown += HandleChannelShutdown;
- await channel.ExchangeDeclareAsync(ExchangeName.Value, ExchangeType.Topic, passive: false, durable: false, autoDelete: true, arguments: null);
- await channel.QueueDeclareAsync(QueueName, false, false, false, true, null);
- await channel.QueueBindAsync(QueueName, ExchangeName.Value, PublishKey.Value, null);
+ Assert.IsNotType(conn);
+ conn.ConnectionShutdown += HandleConnectionShutdown;
- try
+ using (IChannel channel = await conn.CreateChannelAsync())
{
- for (int i = 0; i < Loops; i++)
+ try
{
- for (int j = 0; j < Repeats; j++)
+ channel.ChannelShutdown += HandleChannelShutdown;
+ await channel.ExchangeDeclareAsync(ExchangeName.Value, ExchangeType.Topic, passive: false, durable: false, autoDelete: true,
+ noWait: false, arguments: null);
+ await channel.QueueDeclareAsync(QueueName, exclusive: false, autoDelete: true);
+ await channel.QueueBindAsync(QueueName, ExchangeName.Value, PublishKey.Value);
+
+ for (int i = 0; i < Loops; i++)
{
- await channel.BasicPublishAsync(ExchangeName, PublishKey, _body, false);
+ for (int j = 0; j < Repeats; j++)
+ {
+ await channel.BasicPublishAsync(ExchangeName, PublishKey, _body, false);
+ }
}
}
+ catch (Exception e)
+ {
+ _raisedException = e;
+ }
+ finally
+ {
+ await channel.CloseAsync();
+ }
}
- catch (Exception e)
- {
- _raisedException = e;
- }
+ }
+ finally
+ {
+ await conn.CloseAsync();
}
}
diff --git a/projects/Test/AsyncIntegration/TestPublisherConfirmsAsync.cs b/projects/Test/AsyncIntegration/TestPublisherConfirmsAsync.cs
index 45cebdcb4c..8385a5ea7b 100644
--- a/projects/Test/AsyncIntegration/TestPublisherConfirmsAsync.cs
+++ b/projects/Test/AsyncIntegration/TestPublisherConfirmsAsync.cs
@@ -154,6 +154,7 @@ public async Task TestWaitForConfirmsWithEventsAsync()
finally
{
await ch.QueueDeleteAsync(queue: queueName, ifUnused: false, ifEmpty: false);
+ await ch.CloseAsync();
}
}
}
@@ -180,6 +181,7 @@ private async Task TestWaitForConfirmsAsync(int numberOfMessagesToPublish, Func<
finally
{
await ch.QueueDeleteAsync(queue: queueName, ifUnused: false, ifEmpty: false);
+ await ch.CloseAsync();
}
}
}
diff --git a/projects/Test/AsyncIntegration/TestQueueDeclareAsync.cs b/projects/Test/AsyncIntegration/TestQueueDeclareAsync.cs
index f7ca9367d4..e8092e00ca 100644
--- a/projects/Test/AsyncIntegration/TestQueueDeclareAsync.cs
+++ b/projects/Test/AsyncIntegration/TestQueueDeclareAsync.cs
@@ -50,10 +50,10 @@ public async void TestQueueDeclare()
{
string q = GenerateQueueName();
- QueueDeclareOk declareResult = await _channel.QueueDeclareAsync(q, passive: false, false, false, false, null);
+ QueueDeclareOk declareResult = await _channel.QueueDeclareAsync(q, false, false, false);
Assert.Equal(q, declareResult.QueueName);
- QueueDeclareOk passiveDeclareResult = await _channel.QueueDeclareAsync(q, passive: true, false, false, false, null);
+ QueueDeclareOk passiveDeclareResult = await _channel.QueueDeclarePassiveAsync(q);
Assert.Equal(q, passiveDeclareResult.QueueName);
}
@@ -97,9 +97,9 @@ async Task f()
// sleep for a random amount of time to increase the chances
// of thread interleaving. MK.
await Task.Delay(S_Random.Next(5, 50));
- QueueDeclareOk r = await _channel.QueueDeclareAsync(queue: string.Empty, passive: false, false, false, false, null);
+ QueueDeclareOk r = await _channel.QueueDeclareAsync(queue: string.Empty, false, false, false);
string queueName = r.QueueName;
- await _channel.QueueBindAsync(queue: queueName, exchange: "amq.fanout", routingKey: queueName, null);
+ await _channel.QueueBindAsync(queue: queueName, exchange: "amq.fanout", routingKey: queueName);
queues.Add(queueName);
}
catch (NotSupportedException e)
@@ -125,7 +125,7 @@ async Task f()
{
await Task.Delay(S_Random.Next(5, 50));
- QueueDeclareOk r = await _channel.QueueDeclareAsync(qname, passive: true, false, false, false, null);
+ QueueDeclareOk r = await _channel.QueueDeclarePassiveAsync(qname);
Assert.Equal(qname, r.QueueName);
await _channel.QueueUnbindAsync(queue: qname, exchange: "amq.fanout", routingKey: qname, null);
diff --git a/projects/Test/Common/Common.csproj b/projects/Test/Common/Common.csproj
index 500a0b669d..39917eeea9 100644
--- a/projects/Test/Common/Common.csproj
+++ b/projects/Test/Common/Common.csproj
@@ -11,9 +11,8 @@
../../rabbit.snk
true
- latest
- 7.0
false
+ 7.3
@@ -27,7 +26,7 @@
-
+
diff --git a/projects/Test/Common/IntegrationFixtureBase.cs b/projects/Test/Common/IntegrationFixtureBase.cs
index 7e3b172baa..53f25680e9 100644
--- a/projects/Test/Common/IntegrationFixtureBase.cs
+++ b/projects/Test/Common/IntegrationFixtureBase.cs
@@ -38,6 +38,7 @@
using System.Reflection;
using System.Text;
using System.Threading;
+using System.Threading.Tasks;
using RabbitMQ.Client;
using RabbitMQ.Client.Exceptions;
using RabbitMQ.Client.Framing.Impl;
@@ -46,7 +47,7 @@
namespace Test
{
- public abstract class IntegrationFixtureBase : IDisposable
+ public abstract class IntegrationFixtureBase : IAsyncLifetime
{
private static bool s_isRunningInCI = false;
private static bool s_isWindows = false;
@@ -105,53 +106,64 @@ public IntegrationFixtureBase(ITestOutputHelper output)
.Replace("AsyncIntegration.", "AI.")
.Replace("Integration.", "I.")
.Replace("SequentialI.", "SI.");
-
- SetUp();
}
- protected virtual void SetUp()
+ public virtual async Task InitializeAsync()
{
+ /*
+ * https://github.com/rabbitmq/rabbitmq-dotnet-client/commit/120f9bfce627f704956e1008d095b853b459d45b#r135400345
+ *
+ * Integration tests must use CreateConnectionFactory so that ClientProvidedName is set for the connection.
+ * Tests that close connections via `rabbitmqctl` depend on finding the connection PID via its name.
+ */
if (_connFactory == null)
{
- /*
- * https://github.com/rabbitmq/rabbitmq-dotnet-client/commit/120f9bfce627f704956e1008d095b853b459d45b#r135400345
- *
- * Integration tests must use CreateConnectionFactory so that ClientProvidedName is set for the connection.
- * Tests that close connections via `rabbitmqctl` depend on finding the connection PID via its name.
- */
_connFactory = CreateConnectionFactory();
}
if (_conn == null)
{
- _conn = CreateConnectionWithRetries(_connFactory);
- _channel = _conn.CreateChannel();
+ _conn = await CreateConnectionAsyncWithRetries(_connFactory);
+ _channel = await _conn.CreateChannelAsync();
AddCallbackHandlers();
}
- }
- public virtual void Dispose()
- {
- if (_channel != null)
+ if (_connFactory.AutomaticRecoveryEnabled)
{
- _channel.Dispose();
+ Assert.IsType(_conn);
}
-
- if (_conn != null)
+ else
{
- _conn.Dispose();
+ Assert.IsType(_conn);
}
-
- TearDown();
}
- protected virtual void TearDown()
+ public virtual async Task DisposeAsync()
{
+ try
+ {
+ if (_channel != null)
+ {
+ await _channel.CloseAsync();
+ }
+
+ if (_conn != null)
+ {
+ await _conn.CloseAsync();
+ }
+ }
+ finally
+ {
+ _channel?.Dispose();
+ _conn?.Dispose();
+ _channel = null;
+ _conn = null;
+ }
}
protected virtual void AddCallbackHandlers()
{
- if (IntegrationFixtureBase.IsVerbose)
+ if (IsVerbose)
{
if (_conn != null)
{
@@ -206,13 +218,12 @@ protected static bool IsVerbose
get { return s_isVerbose; }
}
- internal AutorecoveringConnection CreateAutorecoveringConnection(IEnumerable hostnames, bool expectException = false)
+ internal Task CreateAutorecoveringConnectionAsync(IEnumerable hostnames, bool expectException = false)
{
-
- return CreateAutorecoveringConnection(hostnames, RequestedConnectionTimeout, RecoveryInterval, expectException);
+ return CreateAutorecoveringConnectionAsync(hostnames, RequestedConnectionTimeout, RecoveryInterval, expectException);
}
- internal AutorecoveringConnection CreateAutorecoveringConnection(IEnumerable hostnames,
+ internal async Task CreateAutorecoveringConnectionAsync(IEnumerable hostnames,
TimeSpan requestedConnectionTimeout, TimeSpan networkRecoveryInterval, bool expectException = false)
{
if (hostnames is null)
@@ -228,10 +239,11 @@ internal AutorecoveringConnection CreateAutorecoveringConnection(IEnumerable CreateConnectionAsyncWithRetries(ConnectionFactory connectionFactory,
IEnumerable hostnames = null, bool expectException = false)
{
bool shouldRetry = IsWindows;
@@ -243,11 +255,11 @@ internal AutorecoveringConnection CreateAutorecoveringConnection(IEnumerable ex is IOException).FirstOrDefault() as IOException;
+ ioex = agex1.InnerExceptions.Where(iex => iex is IOException).FirstOrDefault() as IOException;
}
- ioex ??= ex.InnerException as IOException;
+ if (ioex == null)
+ {
+ ioex = ex.InnerException as IOException;
+ }
if (ioex is null)
{
@@ -277,7 +292,7 @@ internal AutorecoveringConnection CreateAutorecoveringConnection(IEnumerable action)
+ protected async Task WithTemporaryChannelAsync(Func action)
{
- IChannel channel = _conn.CreateChannel();
-
+ IChannel channel = await _conn.CreateChannelAsync();
try
{
- action(channel);
+ await action(channel);
}
finally
{
- channel.Abort();
+ await channel.AbortAsync();
}
}
@@ -317,58 +331,69 @@ protected string GenerateQueueName()
return $"{_testDisplayName}-queue-{Guid.NewGuid()}";
}
- protected void WithTemporaryNonExclusiveQueue(Action action)
+ protected Task WithTemporaryNonExclusiveQueueAsync(Func action)
{
- WithTemporaryNonExclusiveQueue(_channel, action);
+ return WithTemporaryNonExclusiveQueueAsync(_channel, action);
}
- protected void WithTemporaryNonExclusiveQueue(IChannel channel, Action action)
+ protected Task WithTemporaryNonExclusiveQueueAsync(IChannel channel, Func action)
{
- WithTemporaryNonExclusiveQueue(channel, action, GenerateQueueName());
+ return WithTemporaryNonExclusiveQueueAsync(channel, action, GenerateQueueName());
}
- protected void WithTemporaryNonExclusiveQueue(IChannel channel, Action action, string queue)
+ protected async Task WithTemporaryNonExclusiveQueueAsync(IChannel channel, Func action, string queue)
{
try
{
- channel.QueueDeclare(queue, false, false, false, null);
- action(channel, queue);
+ await channel.QueueDeclareAsync(queue, false, false, false);
+ await action(channel, queue);
}
finally
{
- WithTemporaryChannel(tm => tm.QueueDelete(queue));
+ await WithTemporaryChannelAsync(ch =>
+ {
+ return ch.QueueDeleteAsync(queue);
+ });
}
}
- protected void AssertMessageCount(string q, uint count)
+ protected Task AssertMessageCountAsync(string q, uint count)
{
- WithTemporaryChannel((m) =>
+ return WithTemporaryChannelAsync(async ch =>
{
- RabbitMQ.Client.QueueDeclareOk ok = m.QueueDeclarePassive(q);
+ RabbitMQ.Client.QueueDeclareOk ok = await ch.QueueDeclarePassiveAsync(q);
Assert.Equal(count, ok.MessageCount);
});
}
- protected void AssertShutdownError(ShutdownEventArgs args, int code)
+ protected static void AssertShutdownError(ShutdownEventArgs args, int code)
{
Assert.Equal(args.ReplyCode, code);
}
- protected void AssertPreconditionFailed(ShutdownEventArgs args)
+ protected static void AssertPreconditionFailed(ShutdownEventArgs args)
{
AssertShutdownError(args, Constants.PreconditionFailed);
}
- protected void Wait(ManualResetEventSlim latch, string desc)
+ protected static Task WaitAsync(TaskCompletionSource tcs, string desc)
{
- Assert.True(latch.Wait(WaitSpan),
- $"waiting {WaitSpan.TotalSeconds} seconds on a latch for '{desc}' timed out");
+ return WaitAsync(tcs, WaitSpan, desc);
}
- protected void Wait(ManualResetEventSlim latch, TimeSpan timeSpan, string desc)
+ protected static async Task WaitAsync(TaskCompletionSource tcs, TimeSpan timeSpan, string desc)
{
- Assert.True(latch.Wait(timeSpan),
- $"waiting {timeSpan.TotalSeconds} seconds on a latch for '{desc}' timed out");
+ try
+ {
+ await tcs.Task.WaitAsync(timeSpan);
+ bool result = await tcs.Task;
+ Assert.True((true == result) && (tcs.Task.IsCompletedSuccessfully()),
+ $"waiting {timeSpan.TotalSeconds} seconds on a tcs for '{desc}' timed out");
+ }
+ catch (TimeoutException)
+ {
+ Assert.Fail($"waiting {timeSpan.TotalSeconds} seconds on a tcs for '{desc}' timed out");
+ }
}
protected ConnectionFactory CreateConnectionFactory()
diff --git a/projects/Test/Common/ProcessUtil.cs b/projects/Test/Common/ProcessUtil.cs
new file mode 100644
index 0000000000..7eb9196f68
--- /dev/null
+++ b/projects/Test/Common/ProcessUtil.cs
@@ -0,0 +1,190 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Test
+{
+ ///
+ /// Process helper with asynchronous interface
+ /// https://gist.github.com/Indigo744/b5f3bd50df4b179651c876416bf70d0a
+ /// - Based on https://gist.github.com/georg-jung/3a8703946075d56423e418ea76212745
+ /// - And on https://stackoverflow.com/questions/470256/process-waitforexit-asynchronously
+ ///
+ public static class ProcessUtil
+ {
+ ///
+ /// Run a process asynchronously
+ /// To capture STDOUT, set StartInfo.RedirectStandardOutput to TRUE
+ /// To capture STDERR, set StartInfo.RedirectStandardError to TRUE
+ ///
+ /// ProcessStartInfo object
+ /// The timeout in milliseconds (null for no timeout)
+ /// Result object
+ public static async Task RunAsync(ProcessStartInfo startInfo)
+ {
+ var result = new Result();
+
+ using (var process = new Process { StartInfo = startInfo, EnableRaisingEvents = true })
+ {
+ // List of tasks to wait for a whole process exit
+ var processTasks = new List();
+
+ // === EXITED Event handling ===
+ var processExitEvent = new TaskCompletionSource();
+
+ process.Exited += (sender, args) =>
+ {
+ processExitEvent.TrySetResult(true);
+ };
+
+ processTasks.Add(processExitEvent.Task);
+
+ // === STDOUT handling ===
+ var stdOutBuilder = new StringBuilder();
+
+ if (process.StartInfo.RedirectStandardOutput)
+ {
+ var stdOutCloseEvent = new TaskCompletionSource();
+
+ process.OutputDataReceived += (s, e) =>
+ {
+ if (e.Data == null)
+ {
+ stdOutCloseEvent.TrySetResult(true);
+ }
+ else
+ {
+ stdOutBuilder.AppendLine(e.Data);
+ }
+ };
+
+ processTasks.Add(stdOutCloseEvent.Task);
+ }
+ else
+ {
+ // STDOUT is not redirected, so we won't look for it
+ }
+
+ // === STDERR handling ===
+ var stdErrBuilder = new StringBuilder();
+
+ if (process.StartInfo.RedirectStandardError)
+ {
+ var stdErrCloseEvent = new TaskCompletionSource();
+
+ process.ErrorDataReceived += (s, e) =>
+ {
+ if (e.Data == null)
+ {
+ stdErrCloseEvent.TrySetResult(true);
+ }
+ else
+ {
+ stdErrBuilder.AppendLine(e.Data);
+ }
+ };
+
+ processTasks.Add(stdErrCloseEvent.Task);
+ }
+ else
+ {
+ // STDERR is not redirected, so we won't look for it
+ }
+
+ // === START OF PROCESS ===
+ if (false == process.Start())
+ {
+ result.ExitCode = process.ExitCode;
+ return result;
+ }
+
+ // Reads the output stream first as needed and then waits because deadlocks are possible
+ if (process.StartInfo.RedirectStandardOutput)
+ {
+ process.BeginOutputReadLine();
+ }
+ else
+ {
+ // No STDOUT
+ }
+
+ if (process.StartInfo.RedirectStandardError)
+ {
+ process.BeginErrorReadLine();
+ }
+ else
+ {
+ // No STDERR
+ }
+
+ // === ASYNC WAIT OF PROCESS ===
+
+ // Process completion = exit AND stdout (if defined) AND stderr (if defined)
+ Task processCompletionTask = Task.WhenAll(processTasks);
+
+ try
+ {
+ // Task to wait for exit OR timeout (if defined)
+ await processCompletionTask.WaitAsync(TimeSpan.FromSeconds(30));
+
+ // -> Process exited cleanly
+ result.ExitCode = process.ExitCode;
+ }
+ catch (OperationCanceledException)
+ {
+ // -> Timeout, let's kill the process
+ KillProcess(process);
+ throw;
+ }
+ catch (TimeoutException)
+ {
+ // -> Timeout, let's kill the process
+ KillProcess(process);
+ throw;
+ }
+
+ // Read stdout/stderr
+ result.StdOut = stdOutBuilder.ToString();
+ result.StdErr = stdErrBuilder.ToString();
+ }
+
+ return result;
+ }
+
+ private static void KillProcess(Process process)
+ {
+ try
+ {
+ process.Kill();
+ }
+ catch
+ {
+ // ignored
+ }
+ }
+
+ ///
+ /// Run process result
+ ///
+ public class Result
+ {
+ ///
+ /// Exit code
+ /// If NULL, process exited due to timeout
+ ///
+ public int? ExitCode { get; set; } = null;
+
+ ///
+ /// Standard error stream
+ ///
+ public string StdErr { get; set; } = "";
+
+ ///
+ /// Standard output stream
+ ///
+ public string StdOut { get; set; } = "";
+ }
+ }
+}
diff --git a/projects/Test/Common/RabbitMQCtl.cs b/projects/Test/Common/RabbitMQCtl.cs
index 4c57652a8f..994b92e9c1 100644
--- a/projects/Test/Common/RabbitMQCtl.cs
+++ b/projects/Test/Common/RabbitMQCtl.cs
@@ -33,6 +33,7 @@
using System.Diagnostics;
using System.IO;
using System.Text.RegularExpressions;
+using System.Threading.Tasks;
using RabbitMQ.Client;
using Xunit.Abstractions;
@@ -42,8 +43,10 @@ public class RabbitMQCtl
{
private static readonly char[] newLine = new char[] { '\n' };
private static readonly Func s_invokeRabbitMqCtl = GetRabbitMqCtlInvokeAction();
+ // NOTE: \r?
+ // https://learn.microsoft.com/en-us/dotnet/standard/base-types/regular-expression-options#multiline-mode
private static readonly Regex s_getConnectionProperties =
- new Regex(@"^(?<[^>]*>)\s\[.*""connection_name"",""(?[^""]*)"".*\]$", RegexOptions.Multiline | RegexOptions.Compiled);
+ new Regex(@"^(?<[^>]*>)\s\[.*""connection_name"",""(?[^""]*)"".*\]\r?$", RegexOptions.Multiline | RegexOptions.Compiled);
private readonly ITestOutputHelper _output;
@@ -52,47 +55,39 @@ public RabbitMQCtl(ITestOutputHelper output)
_output = output;
}
- public void CloseConnection(IConnection conn)
+ public async Task CloseConnectionAsync(IConnection conn)
{
- CloseConnection(GetConnectionPid(conn.ClientProvidedName));
+ string pid = await GetConnectionPidAsync(conn.ClientProvidedName);
+ await CloseConnectionAsync(pid);
}
- public void AddUser(string username, string password)
+ public Task AddUserAsync(string username, string password)
{
- ExecRabbitMQCtl($"add_user {username} {password}");
+ return ExecRabbitMQCtlAsync($"add_user {username} {password}");
}
- public void ChangePassword(string username, string password)
+ public Task ChangePasswordAsync(string username, string password)
{
- ExecRabbitMQCtl($"change_password {username} {password}");
+ return ExecRabbitMQCtlAsync($"change_password {username} {password}");
}
- public void SetPermissions(string username, string conf, string write, string read)
+ public Task SetPermissionsAsync(string username, string conf, string write, string read)
{
- ExecRabbitMQCtl($"set_permissions {username} \"{conf}\" \"{write}\" \"${read}\" ");
+ return ExecRabbitMQCtlAsync($"set_permissions {username} \"{conf}\" \"{write}\" \"${read}\" ");
}
- public void DeleteUser(string username)
+ public Task DeleteUserAsync(string username)
{
- ExecRabbitMQCtl($"delete_user {username}");
+ return ExecRabbitMQCtlAsync($"delete_user {username}");
}
- public string ExecRabbitMQCtl(string args)
+ public async Task ExecRabbitMQCtlAsync(string args)
{
try
{
- using var process = s_invokeRabbitMqCtl(args);
- process.Start();
- process.WaitForExit();
- string stderr = process.StandardError.ReadToEnd();
- string stdout = process.StandardOutput.ReadToEnd();
-
- if (stderr.Length > 0 || process.ExitCode > 0)
- {
- ReportExecFailure("rabbitmqctl", args, $"{stderr}\n{stdout}");
- }
-
- return stdout;
+ ProcessStartInfo rabbitmqCtlStartInfo = GetRabbitMqCtlStartInfo(args);
+ ProcessUtil.Result result = await ProcessUtil.RunAsync(rabbitmqCtlStartInfo);
+ return result.StdOut;
}
catch (Exception e)
{
@@ -106,6 +101,54 @@ private void ReportExecFailure(string cmd, string args, string msg)
_output.WriteLine($"Failure while running {cmd} {args}:\n{msg}");
}
+ private static ProcessStartInfo GetRabbitMqCtlStartInfo(string args)
+ {
+ string envVariable = Environment.GetEnvironmentVariable("RABBITMQ_RABBITMQCTL_PATH");
+
+ if (false == string.IsNullOrWhiteSpace(envVariable))
+ {
+ const string DockerPrefix = "DOCKER:";
+ if (envVariable.StartsWith(DockerPrefix))
+ {
+ // Call docker
+ return CreateProcessStartInfo("docker",
+ $"exec {envVariable.Substring(DockerPrefix.Length)} rabbitmqctl {args}");
+ }
+ else
+ {
+ // call the path from the env var
+ return CreateProcessStartInfo(envVariable, args);
+ }
+ }
+
+ // Try default
+ string umbrellaRabbitmqctlPath;
+ string providedRabbitmqctlPath;
+
+ if (IsRunningOnMonoOrDotNetCore())
+ {
+ umbrellaRabbitmqctlPath = "../../../../../../rabbit/scripts/rabbitmqctl";
+ providedRabbitmqctlPath = "rabbitmqctl";
+ }
+ else
+ {
+ umbrellaRabbitmqctlPath = @"..\..\..\..\..\..\rabbit\scripts\rabbitmqctl.bat";
+ providedRabbitmqctlPath = "rabbitmqctl.bat";
+ }
+
+ string path = File.Exists(umbrellaRabbitmqctlPath) ? umbrellaRabbitmqctlPath : providedRabbitmqctlPath;
+
+ if (IsRunningOnMonoOrDotNetCore())
+ {
+ return CreateProcessStartInfo(path, args);
+ }
+ else
+ {
+ // TODO is cmd.exe really necessary?
+ return CreateProcessStartInfo("cmd.exe", $"/c \"\"{path}\" {args}");
+ }
+ }
+
private static Func GetRabbitMqCtlInvokeAction()
{
string precomputedArguments;
@@ -155,11 +198,11 @@ private void ReportExecFailure(string cmd, string args, string msg)
}
}
- private string GetConnectionPid(string connectionName)
+ private async Task GetConnectionPidAsync(string connectionName)
{
- string stdout = ExecRabbitMQCtl("list_connections --silent pid client_properties");
+ string stdout = await ExecRabbitMQCtlAsync("list_connections --silent pid client_properties");
- var match = s_getConnectionProperties.Match(stdout);
+ Match match = s_getConnectionProperties.Match(stdout);
while (match.Success)
{
if (match.Groups["connection_name"].Value == connectionName)
@@ -173,9 +216,9 @@ private string GetConnectionPid(string connectionName)
throw new Exception($"No connection found with name: {connectionName}");
}
- private void CloseConnection(string pid)
+ private Task CloseConnectionAsync(string pid)
{
- ExecRabbitMQCtl($"close_connection \"{pid}\" \"Closed via rabbitmqctl\"");
+ return ExecRabbitMQCtlAsync($"close_connection \"{pid}\" \"Closed via rabbitmqctl\"");
}
private static bool IsRunningOnMonoOrDotNetCore()
@@ -187,6 +230,20 @@ private static bool IsRunningOnMonoOrDotNetCore()
#endif
}
+ private static ProcessStartInfo CreateProcessStartInfo(string cmd, string arguments, string workDirectory = null)
+ {
+ return new ProcessStartInfo
+ {
+ CreateNoWindow = true,
+ UseShellExecute = false,
+ RedirectStandardError = true,
+ RedirectStandardOutput = true,
+ FileName = cmd,
+ Arguments = arguments,
+ WorkingDirectory = workDirectory
+ };
+ }
+
private static Process CreateProcess(string cmd, string arguments, string workDirectory = null)
{
return new Process
diff --git a/projects/Test/Common/TaskExtensions.cs b/projects/Test/Common/TaskExtensions.cs
new file mode 100644
index 0000000000..f67222a448
--- /dev/null
+++ b/projects/Test/Common/TaskExtensions.cs
@@ -0,0 +1,105 @@
+// This source code is dual-licensed under the Apache License, version
+// 2.0, and the Mozilla Public License, version 2.0.
+//
+// The APL v2.0:
+//
+//---------------------------------------------------------------------------
+// Copyright (c) 2007-2020 VMware, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//---------------------------------------------------------------------------
+//
+// The MPL v2.0:
+//
+//---------------------------------------------------------------------------
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at https://mozilla.org/MPL/2.0/.
+//
+// Copyright (c) 2007-2020 VMware, Inc. All rights reserved.
+//---------------------------------------------------------------------------
+
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Test
+{
+ internal static class TaskExtensions
+ {
+#if NET6_0_OR_GREATER
+ public static Task WaitAsync(this Task task, TimeSpan timeout)
+ {
+ if (task.IsCompletedSuccessfully)
+ {
+ return task;
+ }
+
+ return task.WaitAsync(timeout);
+ }
+#else
+ private static readonly TaskContinuationOptions s_tco = TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.ExecuteSynchronously;
+ private static void IgnoreTaskContinuation(Task t, object s) => t.Exception.Handle(e => true);
+
+ public static Task WaitAsync(this Task task, TimeSpan timeout)
+ {
+ if (task.Status == TaskStatus.RanToCompletion)
+ {
+ return task;
+ }
+
+ return DoTimeoutAfter(task, timeout);
+ }
+
+ // https://github.com/davidfowl/AspNetCoreDiagnosticScenarios/blob/master/AsyncGuidance.md#using-a-timeout
+ private static async Task DoTimeoutAfter(Task task, TimeSpan timeout)
+ {
+ using (var cts = new CancellationTokenSource())
+ {
+ Task delayTask = Task.Delay(timeout, cts.Token);
+ Task resultTask = await Task.WhenAny(task, delayTask).ConfigureAwait(false);
+ if (resultTask == delayTask)
+ {
+ task.Ignore();
+ throw new TimeoutException();
+ }
+ else
+ {
+ cts.Cancel();
+ }
+
+ await task.ConfigureAwait(false);
+ }
+ }
+
+ // https://github.com/dotnet/runtime/issues/23878
+ // https://github.com/dotnet/runtime/issues/23878#issuecomment-1398958645
+ private static void Ignore(this Task task)
+ {
+ if (task.IsCompleted)
+ {
+ _ = task.Exception;
+ }
+ else
+ {
+ _ = task.ContinueWith(
+ continuationAction: IgnoreTaskContinuation,
+ state: null,
+ cancellationToken: CancellationToken.None,
+ continuationOptions: s_tco,
+ scheduler: TaskScheduler.Default);
+ }
+ }
+#endif
+ }
+}
diff --git a/projects/Test/Integration/Integration.csproj b/projects/Test/Integration/Integration.csproj
index 47ac180a0e..1eca77ebcc 100644
--- a/projects/Test/Integration/Integration.csproj
+++ b/projects/Test/Integration/Integration.csproj
@@ -11,9 +11,8 @@
../../rabbit.snk
true
- latest
- 7.0
true
+ 7.3
@@ -37,8 +36,8 @@
-
-
+
+
diff --git a/projects/Test/Integration/TestAuth.cs b/projects/Test/Integration/TestAuth.cs
index 790de61041..637c9490b3 100644
--- a/projects/Test/Integration/TestAuth.cs
+++ b/projects/Test/Integration/TestAuth.cs
@@ -29,6 +29,8 @@
// Copyright (c) 2007-2020 VMware, Inc. All rights reserved.
//---------------------------------------------------------------------------
+using System.Threading.Tasks;
+using RabbitMQ.Client;
using RabbitMQ.Client.Exceptions;
using Xunit;
using Xunit.Abstractions;
@@ -41,23 +43,26 @@ public TestAuth(ITestOutputHelper output) : base(output)
{
}
- protected override void SetUp()
+ public override Task InitializeAsync()
{
+ // NB: nothing to do here since each test creates its own factory,
+ // connections and channels
Assert.Null(_connFactory);
Assert.Null(_conn);
Assert.Null(_channel);
+ return Task.CompletedTask;
}
[Fact]
- public void TestAuthFailure()
+ public async Task TestAuthFailure()
{
- var connFactory = CreateConnectionFactory();
+ ConnectionFactory connFactory = CreateConnectionFactory();
connFactory.UserName = "guest";
connFactory.Password = "incorrect-password";
try
{
- connFactory.CreateConnection();
+ await connFactory.CreateConnectionAsync();
Assert.Fail("Exception caused by authentication failure expected");
}
catch (BrokerUnreachableException bue)
diff --git a/projects/Test/Integration/TestBasicGet.cs b/projects/Test/Integration/TestBasicGet.cs
index 1bb486b9b9..254b42e547 100644
--- a/projects/Test/Integration/TestBasicGet.cs
+++ b/projects/Test/Integration/TestBasicGet.cs
@@ -30,6 +30,7 @@
//---------------------------------------------------------------------------
using System;
+using System.Threading.Tasks;
using RabbitMQ.Client;
using RabbitMQ.Client.Exceptions;
using Xunit;
@@ -44,71 +45,77 @@ public TestBasicGet(ITestOutputHelper output) : base(output)
}
[Fact]
- public void TestBasicGetWithClosedChannel()
+ public Task TestBasicGetWithClosedChannel()
{
- WithNonEmptyQueue((_, q) =>
- {
- WithClosedChannel(cm =>
- {
- Assert.Throws(() => cm.BasicGet(q, true));
- });
- });
+ return WithNonEmptyQueueAsync((_, q) =>
+ {
+ return WithClosedChannelAsync(ch =>
+ {
+ return Assert.ThrowsAsync(() =>
+ {
+ return ch.BasicGetAsync(q, true).AsTask();
+ });
+ });
+ });
}
[Fact]
- public void TestBasicGetWithEmptyResponse()
+ public Task TestBasicGetWithEmptyResponse()
{
- WithEmptyQueue((channel, queue) =>
+ return WithEmptyQueueAsync(async (channel, queue) =>
{
- BasicGetResult res = channel.BasicGet(queue, false);
+ BasicGetResult res = await channel.BasicGetAsync(queue, false);
Assert.Null(res);
});
}
[Fact]
- public void TestBasicGetWithNonEmptyResponseAndAutoAckMode()
+ public Task TestBasicGetWithNonEmptyResponseAndAutoAckMode()
{
const string msg = "for basic.get";
- WithNonEmptyQueue((channel, queue) =>
+ return WithNonEmptyQueueAsync(async (channel, queue) =>
{
- BasicGetResult res = channel.BasicGet(queue, true);
+ BasicGetResult res = await channel.BasicGetAsync(queue, true);
Assert.Equal(msg, _encoding.GetString(res.Body.ToArray()));
- AssertMessageCount(queue, 0);
+ await AssertMessageCountAsync(queue, 0);
}, msg);
}
- private void EnsureNotEmpty(string q, string body)
+ private Task EnsureNotEmptyAsync(string q, string body)
{
- WithTemporaryChannel(x => x.BasicPublish("", q, _encoding.GetBytes(body)));
+ return WithTemporaryChannelAsync(ch =>
+ {
+ return ch.BasicPublishAsync("", q, _encoding.GetBytes(body)).AsTask();
+ });
}
- private void WithClosedChannel(Action action)
+ private async Task WithClosedChannelAsync(Func action)
{
- IChannel channel = _conn.CreateChannel();
- channel.Close();
- action(channel);
+ IChannel channel = await _conn.CreateChannelAsync();
+ await channel.CloseAsync();
+ await action(channel);
}
- private void WithNonEmptyQueue(Action action)
+ private Task WithNonEmptyQueueAsync(Func action)
{
- WithNonEmptyQueue(action, "msg");
+ return WithNonEmptyQueueAsync(action, "msg");
}
- private void WithNonEmptyQueue(Action action, string msg)
+ private Task WithNonEmptyQueueAsync(Func action, string msg)
{
- WithTemporaryNonExclusiveQueue((m, q) =>
+ return WithTemporaryNonExclusiveQueueAsync(async (ch, q) =>
{
- EnsureNotEmpty(q, msg);
- action(m, q);
+ await EnsureNotEmptyAsync(q, msg);
+ await action(ch, q);
});
}
- private void WithEmptyQueue(Action action)
+ private Task WithEmptyQueueAsync(Func action)
{
- WithTemporaryNonExclusiveQueue((channel, queue) =>
+ return WithTemporaryNonExclusiveQueueAsync(async (channel, queue) =>
{
- channel.QueuePurge(queue);
- action(channel, queue);
+ await channel.QueuePurgeAsync(queue);
+ await action(channel, queue);
});
}
}
diff --git a/projects/Test/Integration/TestBasicPublish.cs b/projects/Test/Integration/TestBasicPublish.cs
index 78287d61e0..7bab6cfb41 100644
--- a/projects/Test/Integration/TestBasicPublish.cs
+++ b/projects/Test/Integration/TestBasicPublish.cs
@@ -32,6 +32,7 @@
using System;
using System.Collections.Generic;
using System.Threading;
+using System.Threading.Tasks;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using Xunit;
@@ -46,125 +47,134 @@ public TestBasicPublish(ITestOutputHelper output) : base(output)
{
}
- protected override void SetUp()
+ public override Task InitializeAsync()
{
_connFactory = CreateConnectionFactory();
Assert.Null(_conn);
Assert.Null(_channel);
+ return Task.CompletedTask;
}
[Fact]
- public void TestBasicRoundtripArray()
+ public async Task TestBasicRoundtripArray()
{
- _conn = _connFactory.CreateConnection();
- _channel = _conn.CreateChannel();
+ _conn = await _connFactory.CreateConnectionAsync();
+ _channel = await _conn.CreateChannelAsync();
- QueueDeclareOk q = _channel.QueueDeclare();
+ QueueDeclareOk q = await _channel.QueueDeclareAsync();
var bp = new BasicProperties();
byte[] sendBody = _encoding.GetBytes("hi");
byte[] consumeBody = null;
var consumer = new EventingBasicConsumer(_channel);
- var are = new AutoResetEvent(false);
- consumer.Received += (o, a) =>
+ using (var consumerReceivedSemaphore = new SemaphoreSlim(0, 1))
{
- consumeBody = a.Body.ToArray();
- are.Set();
- };
- string tag = _channel.BasicConsume(q.QueueName, true, consumer);
+ consumer.Received += (o, a) =>
+ {
+ consumeBody = a.Body.ToArray();
+ consumerReceivedSemaphore.Release();
+ };
+ string tag = await _channel.BasicConsumeAsync(q.QueueName, true, consumer);
- _channel.BasicPublish("", q.QueueName, bp, sendBody);
- bool waitResFalse = are.WaitOne(5000);
- _channel.BasicCancel(tag);
+ await _channel.BasicPublishAsync("", q.QueueName, bp, sendBody);
+ bool waitRes = await consumerReceivedSemaphore.WaitAsync(TimeSpan.FromSeconds(5));
+ await _channel.BasicCancelAsync(tag);
- Assert.True(waitResFalse);
- Assert.Equal(sendBody, consumeBody);
+ Assert.True(waitRes);
+ Assert.Equal(sendBody, consumeBody);
+ }
}
[Fact]
- public void TestBasicRoundtripCachedString()
+ public async Task TestBasicRoundtripCachedString()
{
- _conn = _connFactory.CreateConnection();
- _channel = _conn.CreateChannel();
+ _conn = await _connFactory.CreateConnectionAsync();
+ _channel = await _conn.CreateChannelAsync();
CachedString exchangeName = new CachedString(string.Empty);
- CachedString queueName = new CachedString(_channel.QueueDeclare().QueueName);
+ CachedString queueName = new CachedString((await _channel.QueueDeclareAsync()).QueueName);
byte[] sendBody = _encoding.GetBytes("hi");
byte[] consumeBody = null;
var consumer = new EventingBasicConsumer(_channel);
- var are = new AutoResetEvent(false);
- consumer.Received += (o, a) =>
+ using (var consumerReceivedSemaphore = new SemaphoreSlim(0, 1))
{
- consumeBody = a.Body.ToArray();
- are.Set();
- };
- string tag = _channel.BasicConsume(queueName.Value, true, consumer);
+ consumer.Received += (o, a) =>
+ {
+ consumeBody = a.Body.ToArray();
+ consumerReceivedSemaphore.Release();
+ };
+ string tag = await _channel.BasicConsumeAsync(queueName.Value, true, consumer);
- _channel.BasicPublish(exchangeName, queueName, sendBody);
- bool waitResFalse = are.WaitOne(2000);
- _channel.BasicCancel(tag);
+ await _channel.BasicPublishAsync(exchangeName, queueName, sendBody);
+ bool waitResFalse = await consumerReceivedSemaphore.WaitAsync(TimeSpan.FromSeconds(2));
+ await _channel.BasicCancelAsync(tag);
- Assert.True(waitResFalse);
- Assert.Equal(sendBody, consumeBody);
+ Assert.True(waitResFalse);
+ Assert.Equal(sendBody, consumeBody);
+ }
}
[Fact]
- public void TestBasicRoundtripReadOnlyMemory()
+ public async Task TestBasicRoundtripReadOnlyMemory()
{
- _conn = _connFactory.CreateConnection();
- _channel = _conn.CreateChannel();
+ _conn = await _connFactory.CreateConnectionAsync();
+ _channel = await _conn.CreateChannelAsync();
- QueueDeclareOk q = _channel.QueueDeclare();
+ QueueDeclareOk q = await _channel.QueueDeclareAsync();
byte[] sendBody = _encoding.GetBytes("hi");
byte[] consumeBody = null;
var consumer = new EventingBasicConsumer(_channel);
- var are = new AutoResetEvent(false);
- consumer.Received += (o, a) =>
+ using (var consumerReceivedSemaphore = new SemaphoreSlim(0, 1))
{
- consumeBody = a.Body.ToArray();
- are.Set();
- };
- string tag = _channel.BasicConsume(q.QueueName, true, consumer);
+ consumer.Received += (o, a) =>
+ {
+ consumeBody = a.Body.ToArray();
+ consumerReceivedSemaphore.Release();
+ };
+ string tag = await _channel.BasicConsumeAsync(q.QueueName, true, consumer);
- _channel.BasicPublish("", q.QueueName, new ReadOnlyMemory(sendBody));
- bool waitResFalse = are.WaitOne(2000);
- _channel.BasicCancel(tag);
+ await _channel.BasicPublishAsync("", q.QueueName, new ReadOnlyMemory(sendBody));
+ bool waitRes = await consumerReceivedSemaphore.WaitAsync(TimeSpan.FromSeconds(2));
+ await _channel.BasicCancelAsync(tag);
- Assert.True(waitResFalse);
- Assert.Equal(sendBody, consumeBody);
+ Assert.True(waitRes);
+ Assert.Equal(sendBody, consumeBody);
+ }
}
[Fact]
- public void CanNotModifyPayloadAfterPublish()
+ public async Task CanNotModifyPayloadAfterPublish()
{
- _conn = _connFactory.CreateConnection();
- _channel = _conn.CreateChannel();
+ _conn = await _connFactory.CreateConnectionAsync();
+ _channel = await _conn.CreateChannelAsync();
- QueueDeclareOk q = _channel.QueueDeclare();
+ QueueDeclareOk q = await _channel.QueueDeclareAsync();
byte[] sendBody = new byte[1000];
var consumer = new EventingBasicConsumer(_channel);
- var receivedMessage = new AutoResetEvent(false);
- bool modified = true;
- consumer.Received += (o, a) =>
+ using (var consumerReceivedSemaphore = new SemaphoreSlim(0, 1))
{
- if (a.Body.Span.IndexOf((byte)1) < 0)
+ bool modified = true;
+ consumer.Received += (o, a) =>
{
- modified = false;
- }
- receivedMessage.Set();
- };
- string tag = _channel.BasicConsume(q.QueueName, true, consumer);
+ if (a.Body.Span.IndexOf((byte)1) < 0)
+ {
+ modified = false;
+ }
+ consumerReceivedSemaphore.Release();
+ };
+ string tag = await _channel.BasicConsumeAsync(q.QueueName, true, consumer);
- _channel.BasicPublish("", q.QueueName, sendBody);
- sendBody.AsSpan().Fill(1);
+ await _channel.BasicPublishAsync("", q.QueueName, sendBody);
+ sendBody.AsSpan().Fill(1);
- Assert.True(receivedMessage.WaitOne(5000));
- Assert.False(modified, "Payload was modified after the return of BasicPublish");
+ Assert.True(await consumerReceivedSemaphore.WaitAsync(TimeSpan.FromSeconds(5)));
+ Assert.False(modified, "Payload was modified after the return of BasicPublish");
- _channel.BasicCancel(tag);
+ await _channel.BasicCancelAsync(tag);
+ }
}
[Fact]
- public void TestMaxMessageSize()
+ public async Task TestMaxMessageSize()
{
var re = new ManualResetEventSlim();
const ushort maxMsgSize = 1024;
@@ -183,7 +193,7 @@ public void TestMaxMessageSize()
bool sawConsumerRegistered = false;
bool sawConsumerCancelled = false;
- using (IConnection c = cf.CreateConnection())
+ using (IConnection c = await cf.CreateConnectionAsync())
{
c.ConnectionShutdown += (o, a) =>
{
@@ -194,7 +204,7 @@ public void TestMaxMessageSize()
Assert.Equal(maxMsgSize, cf.Endpoint.MaxMessageSize);
Assert.Equal(maxMsgSize, c.Endpoint.MaxMessageSize);
- using (IChannel channel = c.CreateChannel())
+ using (IChannel channel = await c.CreateChannelAsync())
{
channel.ChannelShutdown += (o, a) =>
{
@@ -206,7 +216,7 @@ public void TestMaxMessageSize()
throw new XunitException("Unexpected channel.CallbackException");
};
- QueueDeclareOk q = channel.QueueDeclare();
+ QueueDeclareOk q = await channel.QueueDeclareAsync();
var consumer = new EventingBasicConsumer(channel);
@@ -235,10 +245,10 @@ public void TestMaxMessageSize()
Interlocked.Increment(ref count);
};
- string tag = channel.BasicConsume(q.QueueName, true, consumer);
+ string tag = await channel.BasicConsumeAsync(q.QueueName, true, consumer);
- channel.BasicPublish("", q.QueueName, msg0);
- channel.BasicPublish("", q.QueueName, msg1);
+ await channel.BasicPublishAsync("", q.QueueName, msg0);
+ await channel.BasicPublishAsync("", q.QueueName, msg1);
Assert.True(re.Wait(TimeSpan.FromSeconds(5)));
Assert.Equal(1, count);
@@ -246,43 +256,47 @@ public void TestMaxMessageSize()
Assert.True(sawChannelShutdown);
Assert.True(sawConsumerRegistered);
Assert.True(sawConsumerCancelled);
+
+ await channel.CloseAsync();
}
}
}
[Fact]
- public void TestPropertiesRoundtrip_Headers()
+ public async Task TestPropertiesRoundtrip_Headers()
{
- _conn = _connFactory.CreateConnection();
- _channel = _conn.CreateChannel();
+ _conn = await _connFactory.CreateConnectionAsync();
+ _channel = await _conn.CreateChannelAsync();
var subject = new BasicProperties
{
Headers = new Dictionary()
};
- QueueDeclareOk q = _channel.QueueDeclare();
+ QueueDeclareOk q = await _channel.QueueDeclareAsync();
var bp = new BasicProperties() { Headers = new Dictionary() };
bp.Headers["Hello"] = "World";
byte[] sendBody = _encoding.GetBytes("hi");
byte[] consumeBody = null;
var consumer = new EventingBasicConsumer(_channel);
- var are = new AutoResetEvent(false);
- string response = null;
- consumer.Received += (o, a) =>
+ using (var consumerReceivedSemaphore = new SemaphoreSlim(0, 1))
{
- response = _encoding.GetString(a.BasicProperties.Headers["Hello"] as byte[]);
- consumeBody = a.Body.ToArray();
- are.Set();
- };
+ string response = null;
+ consumer.Received += (o, a) =>
+ {
+ response = _encoding.GetString(a.BasicProperties.Headers["Hello"] as byte[]);
+ consumeBody = a.Body.ToArray();
+ consumerReceivedSemaphore.Release();
+ };
- string tag = _channel.BasicConsume(q.QueueName, true, consumer);
- _channel.BasicPublish("", q.QueueName, bp, sendBody);
- bool waitResFalse = are.WaitOne(5000);
- _channel.BasicCancel(tag);
- Assert.True(waitResFalse);
- Assert.Equal(sendBody, consumeBody);
- Assert.Equal("World", response);
+ string tag = await _channel.BasicConsumeAsync(q.QueueName, true, consumer);
+ await _channel.BasicPublishAsync("", q.QueueName, bp, sendBody);
+ bool waitResFalse = await consumerReceivedSemaphore.WaitAsync(TimeSpan.FromSeconds(5));
+ await _channel.BasicCancelAsync(tag);
+ Assert.True(waitResFalse);
+ Assert.Equal(sendBody, consumeBody);
+ Assert.Equal("World", response);
+ }
}
}
}
diff --git a/projects/Test/Integration/TestChannelAllocation.cs b/projects/Test/Integration/TestChannelAllocation.cs
index bdb3f71a37..a553ac1791 100644
--- a/projects/Test/Integration/TestChannelAllocation.cs
+++ b/projects/Test/Integration/TestChannelAllocation.cs
@@ -29,7 +29,6 @@
// Copyright (c) 2007-2020 VMware, Inc. All rights reserved.
//---------------------------------------------------------------------------
-using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using RabbitMQ.Client;
@@ -38,13 +37,12 @@
namespace Test.Integration
{
- public class TestChannelAllocation : IDisposable
+ public class TestChannelAllocation : IAsyncLifetime
{
- public const int CHANNEL_COUNT = 100;
+ private IConnection _c;
+ private const int CHANNEL_COUNT = 100;
- IConnection _c;
-
- public TestChannelAllocation()
+ public async Task InitializeAsync()
{
var cf = new ConnectionFactory
{
@@ -52,70 +50,67 @@ public TestChannelAllocation()
HandshakeContinuationTimeout = IntegrationFixture.WaitSpan,
ClientProvidedName = nameof(TestChannelAllocation)
};
- _c = cf.CreateConnection();
+
+ _c = await cf.CreateConnectionAsync();
}
- public void Dispose() => _c.Close();
+ public async Task DisposeAsync()
+ {
+ await _c.CloseAsync();
+ }
[Fact]
- public void AllocateInOrder()
+ public async Task AllocateInOrder()
{
var channels = new List();
for (int i = 1; i <= CHANNEL_COUNT; i++)
{
- IChannel channel = _c.CreateChannel();
+ IChannel channel = await _c.CreateChannelAsync();
channels.Add(channel);
Assert.Equal(i, ChannelNumber(channel));
}
foreach (IChannel channel in channels)
{
+ await channel.CloseAsync();
channel.Dispose();
}
}
[Fact]
- public void AllocateAfterFreeingLast()
- {
- using IChannel ch0 = _c.CreateChannel();
- Assert.Equal(1, ChannelNumber(ch0));
- ch0.Close();
-
- using IChannel ch1 = _c.CreateChannel();
- Assert.Equal(1, ChannelNumber(ch1));
- }
-
- [Fact]
- public async Task AllocateAfterFreeingLastAsync()
+ public async Task AllocateAfterFreeingLast()
{
- using IChannel ch0 = _c.CreateChannel();
+ IChannel ch0 = await _c.CreateChannelAsync();
Assert.Equal(1, ChannelNumber(ch0));
await ch0.CloseAsync();
+ ch0.Dispose();
- using IChannel ch1 = _c.CreateChannel();
+ IChannel ch1 = await _c.CreateChannelAsync();
Assert.Equal(1, ChannelNumber(ch1));
+ await ch1.CloseAsync();
+ ch1.Dispose();
}
[Fact]
- public void AllocateAfterFreeingMany()
+ public async Task AllocateAfterFreeingMany()
{
var channels = new List();
for (int i = 1; i <= CHANNEL_COUNT; i++)
{
- channels.Add(_c.CreateChannel());
+ channels.Add(await _c.CreateChannelAsync());
}
foreach (IChannel channel in channels)
{
- channel.Close();
+ await channel.CloseAsync();
}
channels.Clear();
for (int j = 1; j <= CHANNEL_COUNT; j++)
{
- channels.Add(_c.CreateChannel());
+ channels.Add(await _c.CreateChannelAsync());
}
// In the current implementation the list should actually
@@ -126,7 +121,7 @@ public void AllocateAfterFreeingMany()
foreach (IChannel channel in channels)
{
Assert.Equal(k++, ChannelNumber(channel));
- channel.Close();
+ await channel.CloseAsync();
}
}
diff --git a/projects/Test/Integration/TestChannelShutdown.cs b/projects/Test/Integration/TestChannelShutdown.cs
index ceb4639b2b..8a190a1749 100644
--- a/projects/Test/Integration/TestChannelShutdown.cs
+++ b/projects/Test/Integration/TestChannelShutdown.cs
@@ -30,7 +30,7 @@
//---------------------------------------------------------------------------
using System;
-using System.Threading;
+using System.Threading.Tasks;
using RabbitMQ.Client;
using RabbitMQ.Client.Impl;
using Xunit;
@@ -45,20 +45,20 @@ public TestChannelShutdown(ITestOutputHelper output) : base(output)
}
[Fact]
- public void TestConsumerDispatcherShutdown()
+ public async Task TestConsumerDispatcherShutdown()
{
- var m = (AutorecoveringChannel)_channel;
- var latch = new ManualResetEventSlim(false);
+ var autorecoveringChannel = (AutorecoveringChannel)_channel;
+ var tcs = new TaskCompletionSource();
_channel.ChannelShutdown += (channel, args) =>
{
- latch.Set();
+ tcs.SetResult(true);
};
- Assert.False(m.ConsumerDispatcher.IsShutdown, "dispatcher should NOT be shut down before Close");
- _channel.Close();
- Wait(latch, TimeSpan.FromSeconds(5), "channel shutdown");
- Assert.True(m.ConsumerDispatcher.IsShutdown, "dispatcher should be shut down after Close");
+ Assert.False(autorecoveringChannel.ConsumerDispatcher.IsShutdown, "dispatcher should NOT be shut down before Close");
+ await _channel.CloseAsync();
+ await WaitAsync(tcs, TimeSpan.FromSeconds(5), "channel shutdown");
+ Assert.True(autorecoveringChannel.ConsumerDispatcher.IsShutdown, "dispatcher should be shut down after Close");
}
}
}
diff --git a/projects/Test/Integration/TestChannelSoftErrors.cs b/projects/Test/Integration/TestChannelSoftErrors.cs
index b369c6a048..81fb062130 100644
--- a/projects/Test/Integration/TestChannelSoftErrors.cs
+++ b/projects/Test/Integration/TestChannelSoftErrors.cs
@@ -29,6 +29,7 @@
// Copyright (c) 2007-2020 VMware, Inc. All rights reserved.
//---------------------------------------------------------------------------
+using System.Threading.Tasks;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using RabbitMQ.Client.Exceptions;
@@ -44,29 +45,30 @@ public TestChannelSoftErrors(ITestOutputHelper output) : base(output)
}
[Fact]
- public void TestBindOnNonExistingQueue()
+ public async Task TestBindOnNonExistingQueue()
{
- OperationInterruptedException exception = Assert.Throws(() => _channel.QueueBind("NonExistingQueue", "", string.Empty));
+ OperationInterruptedException exception = await Assert.ThrowsAsync(() => _channel.QueueBindAsync("NonExistingQueue", "", string.Empty));
Assert.True(exception.Message.Contains("403"), $"Message doesn't contain the expected 403 part: {exception.Message}");
Assert.False(_channel.IsOpen, "Channel should be closed due to the soft error");
Assert.True(_conn.IsOpen, "Connection should still be open due to the soft error only closing the channel");
}
[Fact]
- public void TestBindOnNonExistingExchange()
+ public async Task TestBindOnNonExistingExchange()
{
- OperationInterruptedException exception = Assert.Throws(() => _channel.ExchangeBind("NonExistingQueue", "", string.Empty));
+ OperationInterruptedException exception = await Assert.ThrowsAsync(() => _channel.ExchangeBindAsync("NonExistingQueue", "", string.Empty));
Assert.True(exception.Message.Contains("403"), $"Message doesn't contain the expected 403 part: {exception.Message}");
Assert.False(_channel.IsOpen, "Channel should be closed due to the soft error");
Assert.True(_conn.IsOpen, "Connection should still be open due to the soft error only closing the channel");
}
[Fact]
- public void TestConsumeOnNonExistingQueue()
+ public async Task TestConsumeOnNonExistingQueue()
{
- OperationInterruptedException exception = Assert.Throws(() =>
+ OperationInterruptedException exception = await Assert.ThrowsAsync(() =>
{
- var consumer = new EventingBasicConsumer(_channel); _channel.BasicConsume("NonExistingQueue", true, consumer);
+ var consumer = new EventingBasicConsumer(_channel);
+ return _channel.BasicConsumeAsync("NonExistingQueue", true, consumer);
});
Assert.True(exception.Message.Contains("404"), $"Message doesn't contain the expected 404 part: {exception.Message}");
diff --git a/projects/Test/Integration/TestConcurrentAccessWithSharedConnection.cs b/projects/Test/Integration/TestConcurrentAccessWithSharedConnection.cs
index c1384bf383..db2f0a1d3b 100644
--- a/projects/Test/Integration/TestConcurrentAccessWithSharedConnection.cs
+++ b/projects/Test/Integration/TestConcurrentAccessWithSharedConnection.cs
@@ -31,7 +31,6 @@
using System;
using System.Collections.Generic;
-using System.Threading;
using System.Threading.Tasks;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
@@ -42,119 +41,122 @@ namespace Test.Integration
{
public class TestConcurrentAccessWithSharedConnection : IntegrationFixture
{
- private const ushort _messageCount = 200;
+ private const ushort MessageCount = 256;
- public TestConcurrentAccessWithSharedConnection(ITestOutputHelper output) : base(output)
+ public TestConcurrentAccessWithSharedConnection(ITestOutputHelper output)
+ : base(output)
{
}
- protected override void SetUp()
+ public override async Task InitializeAsync()
{
_connFactory = CreateConnectionFactory();
- _conn = _connFactory.CreateConnection();
+ _conn = await _connFactory.CreateConnectionAsync();
// NB: not creating _channel because this test suite doesn't use it.
Assert.Null(_channel);
}
[Fact]
- public void TestConcurrentChannelOpenAndPublishingWithBlankMessages()
+ public async Task TestConcurrentChannelOpenAndPublishingWithBlankMessages()
{
- TestConcurrentChannelOpenAndPublishingWithBody(Array.Empty(), 30);
+ await TestConcurrentChannelOpenAndPublishingWithBodyAsync(Array.Empty(), 30);
}
[Fact]
- public void TestConcurrentChannelOpenAndPublishingSize64()
+ public async Task TestConcurrentChannelOpenAndPublishingSize64()
{
- TestConcurrentChannelOpenAndPublishingWithBodyOfSize(64);
+ await TestConcurrentChannelOpenAndPublishingWithBodyOfSizeAsync(64);
}
[Fact]
- public void TestConcurrentChannelOpenAndPublishingSize256()
+ public async Task TestConcurrentChannelOpenAndPublishingSize256()
{
- TestConcurrentChannelOpenAndPublishingWithBodyOfSize(256);
+ await TestConcurrentChannelOpenAndPublishingWithBodyOfSizeAsync(256);
}
[Fact]
- public void TestConcurrentChannelOpenAndPublishingSize1024()
+ public Task TestConcurrentChannelOpenAndPublishingSize1024()
{
- TestConcurrentChannelOpenAndPublishingWithBodyOfSize(1024);
+ return TestConcurrentChannelOpenAndPublishingWithBodyOfSizeAsync(1024);
}
[Fact]
- public void TestConcurrentChannelOpenCloseLoop()
+ public async Task TestConcurrentChannelOpenCloseLoop()
{
- TestConcurrentChannelOperations((conn) =>
+ await TestConcurrentChannelOperationsAsync(async (conn) =>
{
- using (IChannel ch = conn.CreateChannel())
+ using (IChannel ch = await conn.CreateChannelAsync())
{
- ch.Close();
+ await ch.CloseAsync();
}
}, 50);
}
- private void TestConcurrentChannelOpenAndPublishingWithBodyOfSize(ushort length, int iterations = 30)
+ private Task TestConcurrentChannelOpenAndPublishingWithBodyOfSizeAsync(ushort length, int iterations = 30)
{
byte[] body = GetRandomBody(length);
- TestConcurrentChannelOpenAndPublishingWithBody(body, iterations);
+ return TestConcurrentChannelOpenAndPublishingWithBodyAsync(body, iterations);
}
- private void TestConcurrentChannelOpenAndPublishingWithBody(byte[] body, int iterations)
+ private Task TestConcurrentChannelOpenAndPublishingWithBodyAsync(byte[] body, int iterations)
{
- TestConcurrentChannelOperations((conn) =>
+ return TestConcurrentChannelOperationsAsync(async (conn) =>
{
- using (var localLatch = new ManualResetEvent(false))
- {
- // publishing on a shared channel is not supported
- // and would missing the point of this test anyway
- using (IChannel ch = _conn.CreateChannel())
- {
- ch.ConfirmSelect();
-
- ch.BasicAcks += (object sender, BasicAckEventArgs e) =>
- {
- if (e.DeliveryTag >= _messageCount)
- {
- localLatch.Set();
- }
- };
+ var tcs = new TaskCompletionSource();
- ch.BasicNacks += (object sender, BasicNackEventArgs e) =>
- {
- localLatch.Set();
- Assert.Fail("should never see a nack");
- };
+ // publishing on a shared channel is not supported
+ // and would missing the point of this test anyway
+ using (IChannel ch = await _conn.CreateChannelAsync())
+ {
+ await ch.ConfirmSelectAsync();
- QueueDeclareOk q = ch.QueueDeclare(queue: string.Empty, exclusive: true, autoDelete: true);
- for (ushort j = 0; j < _messageCount; j++)
+ ch.BasicAcks += (object sender, BasicAckEventArgs e) =>
+ {
+ if (e.DeliveryTag >= MessageCount)
{
- ch.BasicPublish("", q.QueueName, body, true);
+ tcs.SetResult(true);
}
+ };
+
+ ch.BasicNacks += (object sender, BasicNackEventArgs e) =>
+ {
+ tcs.SetResult(false);
+ Assert.Fail("should never see a nack");
+ };
- Assert.True(localLatch.WaitOne(WaitSpan));
+ QueueDeclareOk q = await ch.QueueDeclareAsync(queue: string.Empty, exclusive: true, autoDelete: true);
+ for (ushort j = 0; j < MessageCount; j++)
+ {
+ await ch.BasicPublishAsync("", q.QueueName, body, true);
}
+
+ Assert.True(await tcs.Task);
+
+ // NOTE: this is very important before a Dispose();
+ await ch.CloseAsync();
}
}, iterations);
}
- private void TestConcurrentChannelOperations(Action actions, int iterations)
- {
- TestConcurrentChannelOperations(actions, iterations, LongWaitSpan);
- }
-
- private void TestConcurrentChannelOperations(Action action, int iterations, TimeSpan timeout)
+ private async Task TestConcurrentChannelOperationsAsync(Func action, int iterations)
{
var tasks = new List();
for (int i = 0; i < _processorCount; i++)
{
- tasks.Add(Task.Run(() =>
+ tasks.Add(Task.Run(async () =>
{
for (int j = 0; j < iterations; j++)
{
- action(_conn);
+ await action(_conn);
}
}));
}
- Assert.True(Task.WaitAll(tasks.ToArray(), timeout));
+
+ Task whenTask = Task.WhenAll(tasks);
+ await whenTask.WaitAsync(LongWaitSpan);
+ Assert.True(whenTask.IsCompleted);
+ Assert.False(whenTask.IsCanceled);
+ Assert.False(whenTask.IsFaulted);
// incorrect frame interleaving in these tests will result
// in an unrecoverable connection-level exception, thus
diff --git a/projects/Test/Integration/TestConfirmSelect.cs b/projects/Test/Integration/TestConfirmSelect.cs
index cf2374805d..4adaf31d06 100644
--- a/projects/Test/Integration/TestConfirmSelect.cs
+++ b/projects/Test/Integration/TestConfirmSelect.cs
@@ -29,6 +29,7 @@
// Copyright (c) 2007-2020 VMware, Inc. All rights reserved.
//---------------------------------------------------------------------------
+using System.Threading.Tasks;
using RabbitMQ.Client;
using Xunit;
using Xunit.Abstractions;
@@ -42,44 +43,44 @@ public TestConfirmSelect(ITestOutputHelper output) : base(output)
}
[Fact]
- public void TestConfirmSelectIdempotency()
+ public async Task TestConfirmSelectIdempotency()
{
- void Publish()
+ ValueTask PublishAsync()
{
- _channel.BasicPublish("", "amq.fanout", _encoding.GetBytes("message"));
+ return _channel.BasicPublishAsync("", "amq.fanout", _encoding.GetBytes("message"));
}
- _channel.ConfirmSelect();
+ await _channel.ConfirmSelectAsync();
Assert.Equal(1ul, _channel.NextPublishSeqNo);
- Publish();
+ await PublishAsync();
Assert.Equal(2ul, _channel.NextPublishSeqNo);
- Publish();
+ await PublishAsync();
Assert.Equal(3ul, _channel.NextPublishSeqNo);
- _channel.ConfirmSelect();
- Publish();
+ await _channel.ConfirmSelectAsync();
+ await PublishAsync();
Assert.Equal(4ul, _channel.NextPublishSeqNo);
- Publish();
+ await PublishAsync();
Assert.Equal(5ul, _channel.NextPublishSeqNo);
- Publish();
+ await PublishAsync();
Assert.Equal(6ul, _channel.NextPublishSeqNo);
}
[Theory]
[InlineData(255)]
[InlineData(256)]
- public void TestDeliveryTagDiverged_GH1043(ushort correlationIdLength)
+ public async Task TestDeliveryTagDiverged_GH1043(ushort correlationIdLength)
{
byte[] body = GetRandomBody(16);
- _channel.ExchangeDeclare("sample", "fanout", autoDelete: true);
+ await _channel.ExchangeDeclareAsync("sample", "fanout", autoDelete: true);
// _channel.BasicAcks += (s, e) => _output.WriteLine("Acked {0}", e.DeliveryTag);
- _channel.ConfirmSelect();
+ await _channel.ConfirmSelectAsync();
var properties = new BasicProperties();
// _output.WriteLine("Client delivery tag {0}", _channel.NextPublishSeqNo);
- _channel.BasicPublish(exchange: "sample", routingKey: string.Empty, in properties, body);
- _channel.WaitForConfirmsOrDie();
+ await _channel.BasicPublishAsync(exchange: "sample", routingKey: string.Empty, in properties, body);
+ await _channel.WaitForConfirmsOrDieAsync();
try
{
@@ -88,8 +89,8 @@ public void TestDeliveryTagDiverged_GH1043(ushort correlationIdLength)
CorrelationId = new string('o', correlationIdLength)
};
// _output.WriteLine("Client delivery tag {0}", _channel.NextPublishSeqNo);
- _channel.BasicPublish("sample", string.Empty, in properties, body);
- _channel.WaitForConfirmsOrDie();
+ await _channel.BasicPublishAsync("sample", string.Empty, in properties, body);
+ await _channel.WaitForConfirmsOrDieAsync();
}
catch
{
@@ -98,8 +99,8 @@ public void TestDeliveryTagDiverged_GH1043(ushort correlationIdLength)
properties = new BasicProperties();
// _output.WriteLine("Client delivery tag {0}", _channel.NextPublishSeqNo);
- _channel.BasicPublish("sample", string.Empty, in properties, body);
- _channel.WaitForConfirmsOrDie();
+ await _channel.BasicPublishAsync("sample", string.Empty, in properties, body);
+ await _channel.WaitForConfirmsOrDieAsync();
// _output.WriteLine("I'm done...");
}
}
diff --git a/projects/Test/Integration/TestConnectionFactory.cs b/projects/Test/Integration/TestConnectionFactory.cs
index 8362a78c95..71d4ca0d3a 100644
--- a/projects/Test/Integration/TestConnectionFactory.cs
+++ b/projects/Test/Integration/TestConnectionFactory.cs
@@ -31,6 +31,7 @@
using System.Collections.Generic;
using System.Net.Sockets;
+using System.Threading.Tasks;
using RabbitMQ.Client;
using RabbitMQ.Client.Exceptions;
using Xunit;
@@ -44,13 +45,14 @@ public TestConnectionFactory(ITestOutputHelper output) : base(output)
{
}
- protected override void SetUp()
+ public override Task InitializeAsync()
{
// NB: nothing to do here since each test creates its own factory,
// connections and channels
Assert.Null(_connFactory);
Assert.Null(_conn);
Assert.Null(_channel);
+ return Task.CompletedTask;
}
[Fact]
@@ -97,7 +99,7 @@ public void TestConnectionFactoryWithCustomSocketFactory()
defaultSendBufsz = defaultSocket.SendBufferSize;
}
- ConnectionFactory cf = new()
+ var cf = new ConnectionFactory
{
SocketFactory = (AddressFamily af) =>
{
@@ -121,246 +123,271 @@ public void TestConnectionFactoryWithCustomSocketFactory()
}
[Fact]
- public void TestCreateConnectionUsesSpecifiedPort()
+ public async Task TestCreateConnectionUsesSpecifiedPort()
{
- var cf = CreateConnectionFactory();
+ ConnectionFactory cf = CreateConnectionFactory();
cf.AutomaticRecoveryEnabled = true;
cf.HostName = "localhost";
cf.Port = 1234;
- Assert.Throws(() =>
+ await Assert.ThrowsAsync(() =>
{
- using IConnection conn = cf.CreateConnection();
+ return cf.CreateConnectionAsync();
});
}
[Fact]
- public void TestCreateConnectionWithClientProvidedNameUsesSpecifiedPort()
+ public async Task TestCreateConnectionWithClientProvidedNameUsesSpecifiedPort()
{
- var cf = CreateConnectionFactory();
+ ConnectionFactory cf = CreateConnectionFactory();
cf.AutomaticRecoveryEnabled = true;
cf.HostName = "localhost";
cf.Port = 123;
- Assert.Throws(() =>
+ await Assert.ThrowsAsync(() =>
{
- using IConnection conn = cf.CreateConnection();
+ return cf.CreateConnectionAsync();
});
}
[Fact]
- public void TestCreateConnectionWithClientProvidedNameUsesDefaultName()
+ public async Task TestCreateConnectionWithClientProvidedNameUsesDefaultName()
{
- var cf = CreateConnectionFactory();
+ ConnectionFactory cf = CreateConnectionFactory();
cf.AutomaticRecoveryEnabled = false;
string expectedName = cf.ClientProvidedName;
- using (IConnection conn = cf.CreateConnection())
+ using (IConnection conn = await cf.CreateConnectionAsync())
{
Assert.Equal(expectedName, conn.ClientProvidedName);
Assert.Equal(expectedName, conn.ClientProperties["connection_name"]);
+ await conn.CloseAsync();
}
}
[Fact]
- public void TestCreateConnectionWithClientProvidedNameUsesNameArgumentValue()
+ public async Task TestCreateConnectionWithClientProvidedNameUsesNameArgumentValue()
{
- var cf = CreateConnectionFactory();
+ ConnectionFactory cf = CreateConnectionFactory();
cf.AutomaticRecoveryEnabled = false;
string expectedName = cf.ClientProvidedName;
- using (IConnection conn = cf.CreateConnection(expectedName))
+ using (IConnection conn = await cf.CreateConnectionAsync(expectedName))
{
Assert.Equal(expectedName, conn.ClientProvidedName);
Assert.Equal(expectedName, conn.ClientProperties["connection_name"]);
+ await conn.CloseAsync();
}
}
[Fact]
- public void TestCreateConnectionWithClientProvidedNameAndAutorecoveryUsesNameArgumentValue()
+ public async Task TestCreateConnectionWithClientProvidedNameAndAutorecoveryUsesNameArgumentValue()
{
- var cf = CreateConnectionFactory();
+ ConnectionFactory cf = CreateConnectionFactory();
cf.AutomaticRecoveryEnabled = true;
string expectedName = cf.ClientProvidedName;
- using (IConnection conn = cf.CreateConnection(expectedName))
+ using (IConnection conn = await cf.CreateConnectionAsync(expectedName))
{
Assert.Equal(expectedName, conn.ClientProvidedName);
Assert.Equal(expectedName, conn.ClientProperties["connection_name"]);
+ await conn.CloseAsync();
}
}
[Fact]
- public void TestCreateConnectionAmqpTcpEndpointListAndClientProvidedName()
+ public async Task TestCreateConnectionAmqpTcpEndpointListAndClientProvidedName()
{
- var cf = CreateConnectionFactory();
+ ConnectionFactory cf = CreateConnectionFactory();
cf.AutomaticRecoveryEnabled = true;
string expectedName = cf.ClientProvidedName;
var xs = new List { new AmqpTcpEndpoint("localhost") };
- using (IConnection conn = cf.CreateConnection(xs, expectedName))
+ using (IConnection conn = await cf.CreateConnectionAsync(xs, expectedName))
{
Assert.Equal(expectedName, conn.ClientProvidedName);
Assert.Equal(expectedName, conn.ClientProperties["connection_name"]);
+ await conn.CloseAsync();
}
}
[Fact]
- public void TestCreateConnectionUsesDefaultPort()
+ public async Task TestCreateConnectionUsesDefaultPort()
{
- var cf = CreateConnectionFactory();
+ ConnectionFactory cf = CreateConnectionFactory();
cf.AutomaticRecoveryEnabled = true;
cf.HostName = "localhost";
- using (IConnection conn = cf.CreateConnection())
+ using (IConnection conn = await cf.CreateConnectionAsync())
{
Assert.Equal(5672, conn.Endpoint.Port);
+ await conn.CloseAsync();
}
}
[Fact]
- public void TestCreateConnectionUsesDefaultMaxMessageSize()
+ public async Task TestCreateConnectionUsesDefaultMaxMessageSize()
{
- var cf = CreateConnectionFactory();
+ ConnectionFactory cf = CreateConnectionFactory();
cf.AutomaticRecoveryEnabled = true;
cf.HostName = "localhost";
Assert.Equal(ConnectionFactory.DefaultMaxMessageSize, cf.MaxMessageSize);
Assert.Equal(ConnectionFactory.DefaultMaxMessageSize, cf.Endpoint.MaxMessageSize);
- using (IConnection conn = cf.CreateConnection())
+ using (IConnection conn = await cf.CreateConnectionAsync())
{
Assert.Equal(ConnectionFactory.DefaultMaxMessageSize, conn.Endpoint.MaxMessageSize);
+ await conn.CloseAsync();
}
}
[Fact]
- public void TestCreateConnectionWithoutAutoRecoverySelectsAHostFromTheList()
+ public async Task TestCreateConnectionWithoutAutoRecoverySelectsAHostFromTheList()
{
- var cf = CreateConnectionFactory();
+ ConnectionFactory cf = CreateConnectionFactory();
cf.AutomaticRecoveryEnabled = false;
cf.HostName = "not_localhost";
- IConnection conn = cf.CreateConnection(new List { "localhost" });
- conn.Close();
+ IConnection conn = await cf.CreateConnectionAsync(new List { "localhost" });
+ await conn.CloseAsync();
conn.Dispose();
Assert.Equal("not_localhost", cf.HostName);
Assert.Equal("localhost", conn.Endpoint.HostName);
}
[Fact]
- public void TestCreateConnectionWithAutoRecoveryUsesAmqpTcpEndpoint()
+ public async Task TestCreateConnectionWithAutoRecoveryUsesAmqpTcpEndpoint()
{
- var cf = CreateConnectionFactory();
+ ConnectionFactory cf = CreateConnectionFactory();
cf.AutomaticRecoveryEnabled = true;
cf.HostName = "not_localhost";
cf.Port = 1234;
var ep = new AmqpTcpEndpoint("localhost");
- using (IConnection conn = cf.CreateConnection(new List { ep })) { }
+ using (IConnection conn = await cf.CreateConnectionAsync(new List { ep }))
+ {
+ await conn.CloseAsync();
+ }
}
[Fact]
- public void TestCreateConnectionWithAutoRecoveryUsesInvalidAmqpTcpEndpoint()
+ public async Task TestCreateConnectionWithAutoRecoveryUsesInvalidAmqpTcpEndpoint()
{
- var cf = CreateConnectionFactory();
+ ConnectionFactory cf = CreateConnectionFactory();
cf.AutomaticRecoveryEnabled = true;
var ep = new AmqpTcpEndpoint("localhost", 1234);
- Assert.Throws(() => { using IConnection conn = cf.CreateConnection(new List { ep }); });
+ await Assert.ThrowsAsync(() =>
+ {
+ return cf.CreateConnectionAsync(new List { ep });
+ });
}
[Fact]
- public void TestCreateConnectionUsesAmqpTcpEndpoint()
+ public async Task TestCreateConnectionUsesAmqpTcpEndpoint()
{
- var cf = CreateConnectionFactory();
+ ConnectionFactory cf = CreateConnectionFactory();
cf.HostName = "not_localhost";
cf.Port = 1234;
var ep = new AmqpTcpEndpoint("localhost");
- using (IConnection conn = cf.CreateConnection(new List { ep })) { }
+ using (IConnection conn = await cf.CreateConnectionAsync(new List { ep }))
+ {
+ await conn.CloseAsync();
+ }
}
[Fact]
- public void TestCreateConnectionWithForcedAddressFamily()
+ public async Task TestCreateConnectionWithForcedAddressFamily()
{
- var cf = CreateConnectionFactory();
+ ConnectionFactory cf = CreateConnectionFactory();
cf.HostName = "not_localhost";
var ep = new AmqpTcpEndpoint("localhost")
{
AddressFamily = System.Net.Sockets.AddressFamily.InterNetwork
};
cf.Endpoint = ep;
- using IConnection conn = cf.CreateConnection();
+ using (IConnection conn = await cf.CreateConnectionAsync())
+ {
+ await conn.CloseAsync();
+ }
}
[Fact]
- public void TestCreateConnectionUsesInvalidAmqpTcpEndpoint()
+ public async Task TestCreateConnectionUsesInvalidAmqpTcpEndpoint()
{
- var cf = CreateConnectionFactory();
+ ConnectionFactory cf = CreateConnectionFactory();
var ep = new AmqpTcpEndpoint("localhost", 1234);
- Assert.Throws(() =>
+ await Assert.ThrowsAsync(() =>
{
- using IConnection conn = cf.CreateConnection(new List { ep });
+ return cf.CreateConnectionAsync(new List { ep });
});
}
[Fact]
- public void TestCreateConnectionUsesValidEndpointWhenMultipleSupplied()
+ public async Task TestCreateConnectionUsesValidEndpointWhenMultipleSupplied()
{
- var cf = CreateConnectionFactory();
+ ConnectionFactory cf = CreateConnectionFactory();
var invalidEp = new AmqpTcpEndpoint("not_localhost");
var ep = new AmqpTcpEndpoint("localhost");
- using IConnection conn = cf.CreateConnection(new List { invalidEp, ep });
+ using (IConnection conn = await cf.CreateConnectionAsync(new List { invalidEp, ep }))
+ {
+ await conn.CloseAsync();
+ }
}
[Fact]
public void TestCreateAmqpTCPEndPointOverridesMaxMessageSizeWhenGreaterThanMaximumAllowed()
{
- var ep = new AmqpTcpEndpoint("localhost", -1, new SslOption(), ConnectionFactory.MaximumMaxMessageSize);
+ _ = new AmqpTcpEndpoint("localhost", -1, new SslOption(), ConnectionFactory.MaximumMaxMessageSize);
}
[Fact]
- public void TestCreateConnectionUsesConfiguredMaxMessageSize()
+ public async Task TestCreateConnectionUsesConfiguredMaxMessageSize()
{
- var cf = CreateConnectionFactory();
+ ConnectionFactory cf = CreateConnectionFactory();
cf.MaxMessageSize = 1500;
- using (IConnection conn = cf.CreateConnection())
+ using (IConnection conn = await cf.CreateConnectionAsync())
{
Assert.Equal(cf.MaxMessageSize, conn.Endpoint.MaxMessageSize);
- };
+ await conn.CloseAsync();
+ }
}
[Fact]
- public void TestCreateConnectionWithAmqpEndpointListUsesAmqpTcpEndpointMaxMessageSize()
+ public async Task TestCreateConnectionWithAmqpEndpointListUsesAmqpTcpEndpointMaxMessageSize()
{
- var cf = CreateConnectionFactory();
+ ConnectionFactory cf = CreateConnectionFactory();
cf.MaxMessageSize = 1500;
var ep = new AmqpTcpEndpoint("localhost");
Assert.Equal(ConnectionFactory.DefaultMaxMessageSize, ep.MaxMessageSize);
- using (IConnection conn = cf.CreateConnection(new List { ep }))
+ using (IConnection conn = await cf.CreateConnectionAsync(new List { ep }))
{
Assert.Equal(ConnectionFactory.DefaultMaxMessageSize, conn.Endpoint.MaxMessageSize);
- };
+ await conn.CloseAsync();
+ }
}
[Fact]
- public void TestCreateConnectionWithAmqpEndpointResolverUsesAmqpTcpEndpointMaxMessageSize()
+ public async Task TestCreateConnectionWithAmqpEndpointResolverUsesAmqpTcpEndpointMaxMessageSize()
{
- var cf = CreateConnectionFactory();
+ ConnectionFactory cf = CreateConnectionFactory();
cf.MaxMessageSize = 1500;
var ep = new AmqpTcpEndpoint("localhost", -1, new SslOption(), 1200);
- using (IConnection conn = cf.CreateConnection(new List { ep }))
+ using (IConnection conn = await cf.CreateConnectionAsync(new List { ep }))
{
Assert.Equal(ep.MaxMessageSize, conn.Endpoint.MaxMessageSize);
- };
+ await conn.CloseAsync();
+ }
}
[Fact]
- public void TestCreateConnectionWithHostnameListUsesConnectionFactoryMaxMessageSize()
+ public async Task TestCreateConnectionWithHostnameListUsesConnectionFactoryMaxMessageSize()
{
- var cf = CreateConnectionFactory();
+ ConnectionFactory cf = CreateConnectionFactory();
cf.MaxMessageSize = 1500;
- using (IConnection conn = cf.CreateConnection(new List { "localhost" }))
+ using (IConnection conn = await cf.CreateConnectionAsync(new List { "localhost" }))
{
Assert.Equal(cf.MaxMessageSize, conn.Endpoint.MaxMessageSize);
- };
+ await conn.CloseAsync();
+ }
}
}
}
diff --git a/projects/Test/Integration/TestConnectionFactoryContinuationTimeout.cs b/projects/Test/Integration/TestConnectionFactoryContinuationTimeout.cs
index 23022e8d8b..8d9d4890e9 100644
--- a/projects/Test/Integration/TestConnectionFactoryContinuationTimeout.cs
+++ b/projects/Test/Integration/TestConnectionFactoryContinuationTimeout.cs
@@ -30,6 +30,7 @@
//---------------------------------------------------------------------------
using System;
+using System.Threading.Tasks;
using RabbitMQ.Client;
using Xunit;
using Xunit.Abstractions;
@@ -42,39 +43,54 @@ public TestConnectionFactoryContinuationTimeout(ITestOutputHelper output) : base
{
}
- protected override void SetUp()
+ public override Task InitializeAsync()
{
+ // NB: nothing to do here since each test creates its own factory,
+ // connections and channels
+ Assert.Null(_connFactory);
+ Assert.Null(_conn);
+ Assert.Null(_channel);
+ return Task.CompletedTask;
}
[Fact]
- public void TestConnectionFactoryContinuationTimeoutOnRecoveringConnection()
+ public async Task TestConnectionFactoryContinuationTimeoutOnRecoveringConnection()
{
var continuationTimeout = TimeSpan.FromSeconds(777);
- using (IConnection c = CreateConnectionWithContinuationTimeout(true, continuationTimeout))
+ using (IConnection c = await CreateConnectionWithContinuationTimeoutAsync(true, continuationTimeout))
{
- Assert.Equal(continuationTimeout, c.CreateChannel().ContinuationTimeout);
+ using (IChannel ch = await c.CreateChannelAsync())
+ {
+ Assert.Equal(continuationTimeout, ch.ContinuationTimeout);
+ await ch.CloseAsync();
+ }
+
+ await c.CloseAsync();
}
}
[Fact]
- public void TestConnectionFactoryContinuationTimeoutOnNonRecoveringConnection()
+ public async Task TestConnectionFactoryContinuationTimeoutOnNonRecoveringConnection()
{
var continuationTimeout = TimeSpan.FromSeconds(777);
- using (IConnection c = CreateConnectionWithContinuationTimeout(false, continuationTimeout))
+ using (IConnection c = await CreateConnectionWithContinuationTimeoutAsync(false, continuationTimeout))
{
- using (IChannel ch = c.CreateChannel())
+ using (IChannel ch = await c.CreateChannelAsync())
{
Assert.Equal(continuationTimeout, ch.ContinuationTimeout);
+ await ch.CloseAsync();
}
+
+ await c.CloseAsync();
}
}
- private IConnection CreateConnectionWithContinuationTimeout(bool automaticRecoveryEnabled, TimeSpan continuationTimeout)
+ private Task CreateConnectionWithContinuationTimeoutAsync(bool automaticRecoveryEnabled, TimeSpan continuationTimeout)
{
- var cf = CreateConnectionFactory();
+ ConnectionFactory cf = CreateConnectionFactory();
cf.AutomaticRecoveryEnabled = automaticRecoveryEnabled;
cf.ContinuationTimeout = continuationTimeout;
- return cf.CreateConnection();
+ return cf.CreateConnectionAsync();
}
}
}
diff --git a/projects/Test/Integration/TestConnectionShutdown.cs b/projects/Test/Integration/TestConnectionShutdown.cs
index 5489ec4611..d38b3d3ee1 100644
--- a/projects/Test/Integration/TestConnectionShutdown.cs
+++ b/projects/Test/Integration/TestConnectionShutdown.cs
@@ -30,7 +30,7 @@
//---------------------------------------------------------------------------
using System;
-using System.Threading;
+using System.Threading.Tasks;
using RabbitMQ.Client;
using RabbitMQ.Client.Framing.Impl;
using RabbitMQ.Client.Impl;
@@ -46,81 +46,88 @@ public TestConnectionShutdown(ITestOutputHelper output) : base(output)
}
[Fact]
- public void TestCleanClosureWithSocketClosedOutOfBand()
+ public async Task TestCleanClosureWithSocketClosedOutOfBand()
{
- var latch = new ManualResetEventSlim(false);
+ var tcs = new TaskCompletionSource();
_channel.ChannelShutdown += (channel, args) =>
{
- latch.Set();
+ tcs.SetResult(true);
};
var c = (AutorecoveringConnection)_conn;
- c.CloseFrameHandler();
+ await c.CloseFrameHandlerAsync();
- _conn.Close(TimeSpan.FromSeconds(4));
- Wait(latch, TimeSpan.FromSeconds(5), "channel shutdown");
+ await _conn.CloseAsync(TimeSpan.FromSeconds(4));
+ await WaitAsync(tcs, TimeSpan.FromSeconds(5), "channel shutdown");
}
[Fact]
- public void TestAbortWithSocketClosedOutOfBand()
+ public async Task TestAbortWithSocketClosedOutOfBand()
{
- var latch = new ManualResetEventSlim(false);
+ var tcs = new TaskCompletionSource();
_channel.ChannelShutdown += (channel, args) =>
{
- latch.Set();
+ tcs.SetResult(true);
};
var c = (AutorecoveringConnection)_conn;
- c.CloseFrameHandler();
+ await c.CloseFrameHandlerAsync();
+
+ await _conn.AbortAsync();
- _conn.Abort();
// default Connection.Abort() timeout and then some
- Wait(latch, TimeSpan.FromSeconds(6), "channel shutdown");
+ await WaitAsync(tcs, TimeSpan.FromSeconds(6), "channel shutdown");
}
[Fact]
- public void TestDisposedWithSocketClosedOutOfBand()
+ public async Task TestDisposedWithSocketClosedOutOfBand()
{
- var latch = new ManualResetEventSlim(false);
+ var tcs = new TaskCompletionSource();
+
_channel.ChannelShutdown += (channel, args) =>
{
- latch.Set();
+ tcs.SetResult(true);
};
var c = (AutorecoveringConnection)_conn;
- c.CloseFrameHandler();
+ await c.CloseFrameHandlerAsync();
+ // TODO this fails due to a race condition caused by abrupt closure of the
+ // socket frame handler
+ // await _conn.CloseAsync();
_conn.Dispose();
- Wait(latch, TimeSpan.FromSeconds(3), "channel shutdown");
+ _conn = null;
+ await WaitAsync(tcs, TimeSpan.FromSeconds(3), "channel shutdown");
}
[Fact]
- public void TestShutdownSignalPropagationToChannels()
+ public async Task TestShutdownSignalPropagationToChannels()
{
- var latch = new ManualResetEventSlim(false);
+ var tcs = new TaskCompletionSource();
_channel.ChannelShutdown += (channel, args) =>
{
- latch.Set();
+ tcs.SetResult(true);
};
- _conn.Close();
- Wait(latch, TimeSpan.FromSeconds(3), "channel shutdown");
+ await _conn.CloseAsync();
+
+ await WaitAsync(tcs, TimeSpan.FromSeconds(3), "channel shutdown");
}
[Fact]
- public void TestConsumerDispatcherShutdown()
+ public async Task TestConsumerDispatcherShutdown()
{
var m = (AutorecoveringChannel)_channel;
- var latch = new ManualResetEventSlim(false);
+ var tcs = new TaskCompletionSource();
_channel.ChannelShutdown += (channel, args) =>
{
- latch.Set();
+ tcs.SetResult(true);
};
Assert.False(m.ConsumerDispatcher.IsShutdown, "dispatcher should NOT be shut down before Close");
- _conn.Close();
- Wait(latch, TimeSpan.FromSeconds(3), "channel shutdown");
+ await _conn.CloseAsync();
+ await WaitAsync(tcs, TimeSpan.FromSeconds(3), "channel shutdown");
Assert.True(m.ConsumerDispatcher.IsShutdown, "dispatcher should be shut down after Close");
}
}
diff --git a/projects/Test/Integration/TestConsumer.cs b/projects/Test/Integration/TestConsumer.cs
index 9aa3082eb4..681969bc0a 100644
--- a/projects/Test/Integration/TestConsumer.cs
+++ b/projects/Test/Integration/TestConsumer.cs
@@ -30,6 +30,7 @@
//---------------------------------------------------------------------------
using System;
+using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using RabbitMQ.Client;
@@ -49,65 +50,72 @@ public TestConsumer(ITestOutputHelper output) : base(output)
}
[Fact]
- public void TestBasicRoundtrip()
+ public async Task TestBasicRoundtrip()
{
- QueueDeclareOk q = _channel.QueueDeclare();
- _channel.BasicPublish("", q.QueueName, _body);
+ TimeSpan waitSpan = TimeSpan.FromSeconds(2);
+ QueueDeclareOk q = await _channel.QueueDeclareAsync();
+ await _channel.BasicPublishAsync("", q.QueueName, _body);
var consumer = new EventingBasicConsumer(_channel);
- var are = new AutoResetEvent(false);
- consumer.Received += (o, a) =>
+ using (var consumerReceivedSemaphore = new SemaphoreSlim(0, 1))
+ {
+ consumer.Received += (o, a) =>
{
- are.Set();
+ consumerReceivedSemaphore.Release();
};
- string tag = _channel.BasicConsume(q.QueueName, true, consumer);
- // ensure we get a delivery
- bool waitRes = are.WaitOne(2000);
- Assert.True(waitRes);
- // unsubscribe and ensure no further deliveries
- _channel.BasicCancel(tag);
- _channel.BasicPublish("", q.QueueName, _body);
- bool waitResFalse = are.WaitOne(2000);
- Assert.False(waitResFalse);
+ string tag = await _channel.BasicConsumeAsync(q.QueueName, true, consumer);
+ // ensure we get a delivery
+ bool waitRes = await consumerReceivedSemaphore.WaitAsync(waitSpan);
+ Assert.True(waitRes);
+ // unsubscribe and ensure no further deliveries
+ await _channel.BasicCancelAsync(tag);
+ await _channel.BasicPublishAsync("", q.QueueName, _body);
+ bool waitResFalse = await consumerReceivedSemaphore.WaitAsync(waitSpan);
+ Assert.False(waitResFalse);
+ }
}
[Fact]
- public void TestBasicRoundtripNoWait()
+ public async Task TestBasicRoundtripNoWait()
{
- QueueDeclareOk q = _channel.QueueDeclare();
- _channel.BasicPublish("", q.QueueName, _body);
+ QueueDeclareOk q = await _channel.QueueDeclareAsync();
+ await _channel.BasicPublishAsync("", q.QueueName, _body);
var consumer = new EventingBasicConsumer(_channel);
- var are = new AutoResetEvent(false);
- consumer.Received += (o, a) =>
+ using (var consumerReceivedSemaphore = new SemaphoreSlim(0, 1))
+ {
+ consumer.Received += (o, a) =>
{
- are.Set();
+ consumerReceivedSemaphore.Release();
};
- string tag = _channel.BasicConsume(q.QueueName, true, consumer);
- // ensure we get a delivery
- bool waitRes = are.WaitOne(2000);
- Assert.True(waitRes);
- // unsubscribe and ensure no further deliveries
- _channel.BasicCancelNoWait(tag);
- _channel.BasicPublish("", q.QueueName, _body);
- bool waitResFalse = are.WaitOne(2000);
- Assert.False(waitResFalse);
+ string tag = await _channel.BasicConsumeAsync(q.QueueName, true, consumer);
+ // ensure we get a delivery
+ bool waitRes0 = await consumerReceivedSemaphore.WaitAsync(TimeSpan.FromSeconds(2));
+ Assert.True(waitRes0);
+ // unsubscribe and ensure no further deliveries
+ await _channel.BasicCancelAsync(tag, noWait: true);
+ await _channel.BasicPublishAsync("", q.QueueName, _body);
+ bool waitRes1 = await consumerReceivedSemaphore.WaitAsync(TimeSpan.FromSeconds(2));
+ Assert.False(waitRes1);
+ }
}
[Fact]
- public void ConcurrentEventingTestForReceived()
+ public async Task ConcurrentEventingTestForReceived()
{
const int NumberOfThreads = 4;
const int NumberOfRegistrations = 5000;
- var called = new byte[NumberOfThreads * NumberOfRegistrations];
+ byte[] called = new byte[NumberOfThreads * NumberOfRegistrations];
- QueueDeclareOk q = _channel.QueueDeclare();
+ QueueDeclareOk q = await _channel.QueueDeclareAsync();
var consumer = new EventingBasicConsumer(_channel);
- _channel.BasicConsume(q.QueueName, true, consumer);
+ await _channel.BasicConsumeAsync(q.QueueName, true, consumer);
var countdownEvent = new CountdownEvent(NumberOfThreads);
+
+ var tasks = new List();
for (int i = 0; i < NumberOfThreads; i++)
{
int threadIndex = i;
- Task.Run(() =>
+ tasks.Add(Task.Run(() =>
{
int start = threadIndex * NumberOfRegistrations;
for (int j = start; j < start + NumberOfRegistrations; j++)
@@ -119,21 +127,23 @@ public void ConcurrentEventingTestForReceived()
};
}
countdownEvent.Signal();
- });
+ }));
}
countdownEvent.Wait();
// Add last receiver
- var are = new AutoResetEvent(false);
+ var lastConsumerReceivedTcs = new TaskCompletionSource();
consumer.Received += (o, a) =>
{
- are.Set();
+ lastConsumerReceivedTcs.SetResult(true);
};
// Send message
- _channel.BasicPublish("", q.QueueName, ReadOnlyMemory.Empty);
- are.WaitOne(TimingFixture.TestTimeout);
+ await _channel.BasicPublishAsync("", q.QueueName, ReadOnlyMemory.Empty);
+
+ await lastConsumerReceivedTcs.Task.WaitAsync(TimingFixture.TestTimeout);
+ Assert.True(await lastConsumerReceivedTcs.Task);
// Check received messages
Assert.Equal(-1, called.AsSpan().IndexOf((byte)0));
diff --git a/projects/Test/Integration/TestConsumerCancelNotify.cs b/projects/Test/Integration/TestConsumerCancelNotify.cs
index 630a3e6035..68a64bf1f6 100644
--- a/projects/Test/Integration/TestConsumerCancelNotify.cs
+++ b/projects/Test/Integration/TestConsumerCancelNotify.cs
@@ -30,7 +30,7 @@
//---------------------------------------------------------------------------
using System.Linq;
-using System.Threading;
+using System.Threading.Tasks;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using Xunit;
@@ -40,9 +40,7 @@ namespace Test.Integration
{
public class TestConsumerCancelNotify : IntegrationFixture
{
- private readonly ManualResetEventSlim _latch = new ManualResetEventSlim();
- private bool _notifiedCallback;
- private bool _notifiedEvent;
+ private readonly TaskCompletionSource _tcs = new TaskCompletionSource();
private string _consumerTag;
public TestConsumerCancelNotify(ITestOutputHelper output) : base(output)
@@ -50,53 +48,52 @@ public TestConsumerCancelNotify(ITestOutputHelper output) : base(output)
}
[Fact]
- public void TestConsumerCancelNotification()
+ public Task TestConsumerCancelNotification()
{
- TestConsumerCancel("queue_consumer_cancel_notify", false, ref _notifiedCallback);
+ return TestConsumerCancelAsync("queue_consumer_cancel_notify", false);
}
[Fact]
- public void TestConsumerCancelEvent()
+ public Task TestConsumerCancelEvent()
{
- TestConsumerCancel("queue_consumer_cancel_event", true, ref _notifiedEvent);
+ return TestConsumerCancelAsync("queue_consumer_cancel_event", true);
}
[Fact]
- public void TestCorrectConsumerTag()
+ public async Task TestCorrectConsumerTag()
{
string q1 = GenerateQueueName();
string q2 = GenerateQueueName();
- _channel.QueueDeclare(q1, false, false, false, null);
- _channel.QueueDeclare(q2, false, false, false, null);
+ await _channel.QueueDeclareAsync(q1, false, false, false);
+ await _channel.QueueDeclareAsync(q2, false, false, false);
EventingBasicConsumer consumer = new EventingBasicConsumer(_channel);
- string consumerTag1 = _channel.BasicConsume(q1, true, consumer);
- string consumerTag2 = _channel.BasicConsume(q2, true, consumer);
+ string consumerTag1 = await _channel.BasicConsumeAsync(q1, true, consumer);
+ string consumerTag2 = await _channel.BasicConsumeAsync(q2, true, consumer);
string notifiedConsumerTag = null;
consumer.ConsumerCancelled += (sender, args) =>
{
notifiedConsumerTag = args.ConsumerTags.First();
- _latch.Set();
+ _tcs.SetResult(true);
};
- _channel.QueueDelete(q1);
- Wait(_latch, "ConsumerCancelled event");
+ await _channel.QueueDeleteAsync(q1);
+ await WaitAsync(_tcs, "ConsumerCancelled event");
Assert.Equal(consumerTag1, notifiedConsumerTag);
- _channel.QueueDelete(q2);
+ await _channel.QueueDeleteAsync(q2);
}
- private void TestConsumerCancel(string queue, bool EventMode, ref bool notified)
+ private async Task TestConsumerCancelAsync(string queue, bool eventMode)
{
- _channel.QueueDeclare(queue, false, true, false, null);
- IBasicConsumer consumer = new CancelNotificationConsumer(_channel, this, EventMode);
- string actualConsumerTag = _channel.BasicConsume(queue, false, consumer);
+ await _channel.QueueDeclareAsync(queue, false, true, false);
+ IBasicConsumer consumer = new CancelNotificationConsumer(_channel, this, eventMode);
+ string actualConsumerTag = await _channel.BasicConsumeAsync(queue, false, consumer);
- _channel.QueueDelete(queue);
- Wait(_latch, "HandleBasicCancel / Cancelled event");
- Assert.True(notified);
+ await _channel.QueueDeleteAsync(queue);
+ await WaitAsync(_tcs, "HandleBasicCancel / Cancelled event");
Assert.Equal(actualConsumerTag, _consumerTag);
}
@@ -105,12 +102,12 @@ private class CancelNotificationConsumer : DefaultBasicConsumer
private readonly TestConsumerCancelNotify _testClass;
private readonly bool _eventMode;
- public CancelNotificationConsumer(IChannel channel, TestConsumerCancelNotify tc, bool EventMode)
+ public CancelNotificationConsumer(IChannel channel, TestConsumerCancelNotify tc, bool eventMode)
: base(channel)
{
_testClass = tc;
- _eventMode = EventMode;
- if (EventMode)
+ _eventMode = eventMode;
+ if (eventMode)
{
ConsumerCancelled += Cancelled;
}
@@ -120,18 +117,17 @@ public override void HandleBasicCancel(string consumerTag)
{
if (!_eventMode)
{
- _testClass._notifiedCallback = true;
_testClass._consumerTag = consumerTag;
- _testClass._latch.Set();
+ _testClass._tcs.SetResult(true);
}
+
base.HandleBasicCancel(consumerTag);
}
private void Cancelled(object sender, ConsumerEventArgs arg)
{
- _testClass._notifiedEvent = true;
_testClass._consumerTag = arg.ConsumerTags[0];
- _testClass._latch.Set();
+ _testClass._tcs.SetResult(true);
}
}
}
diff --git a/projects/Test/Integration/TestConsumerCount.cs b/projects/Test/Integration/TestConsumerCount.cs
index 8b38ea0360..ab4bb3703f 100644
--- a/projects/Test/Integration/TestConsumerCount.cs
+++ b/projects/Test/Integration/TestConsumerCount.cs
@@ -29,6 +29,7 @@
// Copyright (c) 2007-2020 VMware, Inc. All rights reserved.
//---------------------------------------------------------------------------
+using System.Threading.Tasks;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using Xunit;
@@ -43,17 +44,17 @@ public TestConsumerCount(ITestOutputHelper output) : base(output)
}
[Fact]
- public void TestConsumerCountMethod()
+ public async Task TestConsumerCountMethod()
{
string q = GenerateQueueName();
- _channel.QueueDeclare(queue: q, durable: false, exclusive: true, autoDelete: false, arguments: null);
- Assert.Equal(0u, _channel.ConsumerCount(q));
+ await _channel.QueueDeclareAsync(queue: q, durable: false, exclusive: true, autoDelete: false, arguments: null);
+ Assert.Equal(0u, await _channel.ConsumerCountAsync(q));
- string tag = _channel.BasicConsume(q, true, new EventingBasicConsumer(_channel));
- Assert.Equal(1u, _channel.ConsumerCount(q));
+ string tag = await _channel.BasicConsumeAsync(q, true, new EventingBasicConsumer(_channel));
+ Assert.Equal(1u, await _channel.ConsumerCountAsync(q));
- _channel.BasicCancel(tag);
- Assert.Equal(0u, _channel.ConsumerCount(q));
+ await _channel.BasicCancelAsync(tag);
+ Assert.Equal(0u, await _channel.ConsumerCountAsync(q));
}
}
}
diff --git a/projects/Test/Integration/TestConsumerExceptions.cs b/projects/Test/Integration/TestConsumerExceptions.cs
index d8ec356e68..d119eba2c4 100644
--- a/projects/Test/Integration/TestConsumerExceptions.cs
+++ b/projects/Test/Integration/TestConsumerExceptions.cs
@@ -30,7 +30,7 @@
//---------------------------------------------------------------------------
using System;
-using System.Threading;
+using System.Threading.Tasks;
using RabbitMQ.Client;
using Xunit;
using Xunit.Abstractions;
@@ -45,12 +45,12 @@ public ConsumerFailingOnDelivery(IChannel channel) : base(channel)
{
}
- public override void HandleBasicDeliver(string consumerTag,
+ public override Task HandleBasicDeliverAsync(string consumerTag,
ulong deliveryTag,
bool redelivered,
string exchange,
string routingKey,
- in ReadOnlyBasicProperties properties,
+ ReadOnlyBasicProperties properties,
ReadOnlyMemory body)
{
throw new Exception("oops");
@@ -105,22 +105,22 @@ public override void HandleBasicCancelOk(string consumerTag)
}
}
- protected void TestExceptionHandlingWith(IBasicConsumer consumer,
- Action action)
+ protected async Task TestExceptionHandlingWithAsync(IBasicConsumer consumer,
+ Func action)
{
- var mre = new ManualResetEventSlim(false);
+ var tcs = new TaskCompletionSource();
bool notified = false;
- string q = _channel.QueueDeclare();
+ string q = await _channel.QueueDeclareAsync();
_channel.CallbackException += (m, evt) =>
{
notified = true;
- mre.Set();
+ tcs.SetResult(true);
};
- string tag = _channel.BasicConsume(q, true, consumer);
- action(_channel, q, consumer, tag);
- Wait(mre, "callback exception");
+ string tag = await _channel.BasicConsumeAsync(q, true, consumer);
+ await action(_channel, q, consumer, tag);
+ await WaitAsync(tcs, "callback exception");
Assert.True(notified);
}
@@ -130,38 +130,42 @@ public TestConsumerExceptions(ITestOutputHelper output) : base(output)
}
[Fact]
- public void TestCancelNotificationExceptionHandling()
+ public Task TestCancelNotificationExceptionHandling()
{
IBasicConsumer consumer = new ConsumerFailingOnCancel(_channel);
- TestExceptionHandlingWith(consumer, (m, q, c, ct) => m.QueueDelete(q));
+ return TestExceptionHandlingWithAsync(consumer, (ch, q, c, ct) =>
+ {
+ return ch.QueueDeleteAsync(q);
+ });
}
[Fact]
- public void TestConsumerCancelOkExceptionHandling()
+ public Task TestConsumerCancelOkExceptionHandling()
{
IBasicConsumer consumer = new ConsumerFailingOnCancelOk(_channel);
- TestExceptionHandlingWith(consumer, (m, q, c, ct) => m.BasicCancel(ct));
+ return TestExceptionHandlingWithAsync(consumer, (ch, q, c, ct) => ch.BasicCancelAsync(ct));
}
[Fact]
- public void TestConsumerConsumeOkExceptionHandling()
+ public Task TestConsumerConsumeOkExceptionHandling()
{
IBasicConsumer consumer = new ConsumerFailingOnConsumeOk(_channel);
- TestExceptionHandlingWith(consumer, (m, q, c, ct) => { });
+ return TestExceptionHandlingWithAsync(consumer, (ch, q, c, ct) => Task.CompletedTask);
}
[Fact]
- public void TestConsumerShutdownExceptionHandling()
+ public Task TestConsumerShutdownExceptionHandling()
{
IBasicConsumer consumer = new ConsumerFailingOnShutdown(_channel);
- TestExceptionHandlingWith(consumer, (m, q, c, ct) => m.Close());
+ return TestExceptionHandlingWithAsync(consumer, (ch, q, c, ct) => ch.CloseAsync());
}
[Fact]
- public void TestDeliveryExceptionHandling()
+ public Task TestDeliveryExceptionHandling()
{
IBasicConsumer consumer = new ConsumerFailingOnDelivery(_channel);
- TestExceptionHandlingWith(consumer, (m, q, c, ct) => m.BasicPublish("", q, _encoding.GetBytes("msg")));
+ return TestExceptionHandlingWithAsync(consumer, (ch, q, c, ct) =>
+ ch.BasicPublishAsync("", q, _encoding.GetBytes("msg")).AsTask());
}
}
}
diff --git a/projects/Test/Integration/TestConsumerOperationDispatch.cs b/projects/Test/Integration/TestConsumerOperationDispatch.cs
index 3e2588aa88..c90f2e9871 100644
--- a/projects/Test/Integration/TestConsumerOperationDispatch.cs
+++ b/projects/Test/Integration/TestConsumerOperationDispatch.cs
@@ -32,6 +32,7 @@
using System;
using System.Collections.Generic;
using System.Threading;
+using System.Threading.Tasks;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using Xunit;
@@ -58,17 +59,19 @@ public TestConsumerOperationDispatch(ITestOutputHelper output) : base(output)
{
}
- protected override void TearDown()
+ public override async Task DisposeAsync()
{
foreach (IChannel ch in _channels)
{
if (ch.IsOpen)
{
- ch.Close();
+ await ch.CloseAsync();
}
}
s_counter.Reset();
+
+ await base.DisposeAsync();
}
private class CollectingConsumer : DefaultBasicConsumer
@@ -81,9 +84,9 @@ public CollectingConsumer(IChannel channel)
DeliveryTags = new List();
}
- public override void HandleBasicDeliver(string consumerTag,
+ public override Task HandleBasicDeliverAsync(string consumerTag,
ulong deliveryTag, bool redelivered, string exchange, string routingKey,
- in ReadOnlyBasicProperties properties, ReadOnlyMemory body)
+ ReadOnlyBasicProperties properties, ReadOnlyMemory body)
{
// we test concurrent dispatch from the moment basic.delivery is returned.
// delivery tags have guaranteed ordering and we verify that it is preserved
@@ -95,32 +98,32 @@ public CollectingConsumer(IChannel channel)
s_counter.Signal();
}
- Channel.BasicAck(deliveryTag: deliveryTag, multiple: false);
+ return Channel.BasicAckAsync(deliveryTag: deliveryTag, multiple: false).AsTask();
}
}
[SkippableFact]
- public void TestDeliveryOrderingWithSingleChannel()
+ public async Task TestDeliveryOrderingWithSingleChannel()
{
Skip.If(IntegrationFixture.IsRunningInCI && IntegrationFixtureBase.IsWindows, "TODO - test is slow in CI on Windows");
- _channel.ExchangeDeclare(_x, "fanout", durable: false);
+ await _channel.ExchangeDeclareAsync(_x, "fanout", durable: false);
for (int i = 0; i < Y; i++)
{
- IChannel ch = _conn.CreateChannel();
- QueueDeclareOk q = ch.QueueDeclare("", durable: false, exclusive: true, autoDelete: true, arguments: null);
- ch.QueueBind(queue: q, exchange: _x, routingKey: "");
+ IChannel ch = await _conn.CreateChannelAsync();
+ QueueDeclareOk q = await ch.QueueDeclareAsync("", durable: false, exclusive: true, autoDelete: true, arguments: null);
+ await ch.QueueBindAsync(queue: q, exchange: _x, routingKey: "");
_channels.Add(ch);
_queues.Add(q);
var cons = new CollectingConsumer(ch);
_consumers.Add(cons);
- ch.BasicConsume(queue: q, autoAck: false, consumer: cons);
+ await ch.BasicConsumeAsync(queue: q, autoAck: false, consumer: cons);
}
for (int i = 0; i < N; i++)
{
- _channel.BasicPublish(_x, "", _encoding.GetBytes("msg"));
+ await _channel.BasicPublishAsync(_x, "", _encoding.GetBytes("msg"));
}
if (IntegrationFixture.IsRunningInCI)
@@ -150,68 +153,75 @@ public void TestDeliveryOrderingWithSingleChannel()
// see rabbitmq/rabbitmq-dotnet-client#61
[Fact]
- public void TestChannelShutdownDoesNotShutDownDispatcher()
+ public async Task TestChannelShutdownDoesNotShutDownDispatcher()
{
- _channel.ExchangeDeclare(_x, "fanout", durable: false);
+ await _channel.ExchangeDeclareAsync(_x, "fanout", durable: false);
- IChannel ch1 = _conn.CreateChannel();
- IChannel ch2 = _conn.CreateChannel();
+ IChannel ch1 = await _conn.CreateChannelAsync();
+ IChannel ch2 = await _conn.CreateChannelAsync();
- string q1 = ch1.QueueDeclare().QueueName;
- string q2 = ch2.QueueDeclare().QueueName;
- ch2.QueueBind(queue: q2, exchange: _x, routingKey: "");
+ string q1 = (await ch1.QueueDeclareAsync()).QueueName;
+ string q2 = (await ch2.QueueDeclareAsync()).QueueName;
+ await ch2.QueueBindAsync(queue: q2, exchange: _x, routingKey: "");
- var latch = new ManualResetEventSlim(false);
- ch1.BasicConsume(q1, true, new EventingBasicConsumer(ch1));
+ var tcs = new TaskCompletionSource();
+ await ch1.BasicConsumeAsync(q1, true, new EventingBasicConsumer(ch1));
var c2 = new EventingBasicConsumer(ch2);
c2.Received += (object sender, BasicDeliverEventArgs e) =>
{
- latch.Set();
+ tcs.SetResult(true);
};
- ch2.BasicConsume(q2, true, c2);
+ await ch2.BasicConsumeAsync(q2, true, c2);
// closing this channel must not affect ch2
- ch1.Close();
+ await ch1.CloseAsync();
- ch2.BasicPublish(_x, "", _encoding.GetBytes("msg"));
- Wait(latch, "received event");
+ await ch2.BasicPublishAsync(_x, "", _encoding.GetBytes("msg"));
+ await WaitAsync(tcs, "received event");
}
private class ShutdownLatchConsumer : DefaultBasicConsumer
{
public ShutdownLatchConsumer()
{
- Latch = new();
- DuplicateLatch = new();
+ Latch = new TaskCompletionSource();
+ DuplicateLatch = new TaskCompletionSource();
}
- public readonly ManualResetEventSlim Latch;
- public readonly ManualResetEventSlim DuplicateLatch;
+ public readonly TaskCompletionSource Latch;
+ public readonly TaskCompletionSource DuplicateLatch;
public override void HandleChannelShutdown(object channel, ShutdownEventArgs reason)
{
// keep track of duplicates
- if (Latch.Wait(0))
+ if (Latch.Task.IsCompletedSuccessfully())
{
- DuplicateLatch.Set();
+ DuplicateLatch.SetResult(true);
}
else
{
- Latch.Set();
+ Latch.SetResult(true);
}
}
}
[Fact]
- public void TestChannelShutdownHandler()
+ public async Task TestChannelShutdownHandler()
{
- string q = _channel.QueueDeclare();
+ string q = await _channel.QueueDeclareAsync();
var c = new ShutdownLatchConsumer();
- _channel.BasicConsume(queue: q, autoAck: true, consumer: c);
- _channel.Close();
+ await _channel.BasicConsumeAsync(queue: q, autoAck: true, consumer: c);
+ await _channel.CloseAsync();
+
+ await c.Latch.Task.WaitAsync(TimeSpan.FromSeconds(5));
+ Assert.True(c.Latch.Task.IsCompletedSuccessfully());
+
+ await Assert.ThrowsAsync(() =>
+ {
+ return c.DuplicateLatch.Task.WaitAsync(TimeSpan.FromSeconds(5));
+ });
- Wait(c.Latch, TimeSpan.FromSeconds(5), "channel shutdown");
- Assert.False(c.DuplicateLatch.Wait(TimeSpan.FromSeconds(5)), "event handler fired more than once");
+ Assert.False(c.DuplicateLatch.Task.IsCompletedSuccessfully());
}
}
}
diff --git a/projects/Test/Integration/TestEventingConsumer.cs b/projects/Test/Integration/TestEventingConsumer.cs
index f3e33f1908..4ee805dd2f 100644
--- a/projects/Test/Integration/TestEventingConsumer.cs
+++ b/projects/Test/Integration/TestEventingConsumer.cs
@@ -29,7 +29,7 @@
// Copyright (c) 2007-2020 VMware, Inc. All rights reserved.
//---------------------------------------------------------------------------
-using System.Threading;
+using System.Threading.Tasks;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using Xunit;
@@ -44,47 +44,49 @@ public TestEventingConsumer(ITestOutputHelper output) : base(output)
}
[Fact]
- public void TestEventingConsumerRegistrationEvents()
+ public async Task TestEventingConsumerRegistrationEvents()
{
- string q = _channel.QueueDeclare();
+ string q = await _channel.QueueDeclareAsync();
- var registeredLatch = new ManualResetEventSlim(false);
+ var registeredTcs = new TaskCompletionSource();
object registeredSender = null;
- var unregisteredLatch = new ManualResetEventSlim(false);
+
+ var unregisteredTcs = new TaskCompletionSource();
object unregisteredSender = null;
EventingBasicConsumer ec = new EventingBasicConsumer(_channel);
ec.Registered += (s, args) =>
{
registeredSender = s;
- registeredLatch.Set();
+ registeredTcs.SetResult(true);
};
ec.Unregistered += (s, args) =>
{
unregisteredSender = s;
- unregisteredLatch.Set();
+ unregisteredTcs.SetResult(true);
};
- string tag = _channel.BasicConsume(q, false, ec);
- Wait(registeredLatch, "consumer registered");
+ string tag = await _channel.BasicConsumeAsync(q, false, ec);
+ await WaitAsync(registeredTcs, "consumer registered");
Assert.NotNull(registeredSender);
Assert.Equal(ec, registeredSender);
Assert.Equal(_channel, ((EventingBasicConsumer)registeredSender).Channel);
- _channel.BasicCancel(tag);
- Wait(unregisteredLatch, "consumer unregistered");
+ await _channel.BasicCancelAsync(tag);
+
+ await WaitAsync(unregisteredTcs, "consumer unregistered");
Assert.NotNull(unregisteredSender);
Assert.Equal(ec, unregisteredSender);
Assert.Equal(_channel, ((EventingBasicConsumer)unregisteredSender).Channel);
}
[Fact]
- public void TestEventingConsumerDeliveryEvents()
+ public async Task TestEventingConsumerDeliveryEvents()
{
- var mre = new ManualResetEventSlim(false);
- string q = _channel.QueueDeclare();
+ var tcs0 = new TaskCompletionSource();
+ string q = await _channel.QueueDeclareAsync();
bool receivedInvoked = false;
object receivedSender = null;
@@ -94,14 +96,14 @@ public void TestEventingConsumerDeliveryEvents()
{
receivedInvoked = true;
receivedSender = s;
- mre.Set();
+ tcs0.SetResult(true);
};
- _channel.BasicConsume(q, true, ec);
- _channel.BasicPublish("", q, _encoding.GetBytes("msg"));
+ await _channel.BasicConsumeAsync(q, true, ec);
+ await _channel.BasicPublishAsync("", q, _encoding.GetBytes("msg"));
- Wait(mre, "received event");
- mre.Reset();
+ await WaitAsync(tcs0, "received event");
+ var tcs1 = new TaskCompletionSource();
Assert.True(receivedInvoked);
Assert.NotNull(receivedSender);
@@ -115,12 +117,12 @@ public void TestEventingConsumerDeliveryEvents()
{
shutdownInvoked = true;
shutdownSender = s;
- mre.Set();
+ tcs1.SetResult(true);
};
- _channel.Close();
+ await _channel.CloseAsync();
- Wait(mre, "shutdown event");
+ await WaitAsync(tcs1, "shutdown event");
Assert.True(shutdownInvoked);
Assert.NotNull(shutdownSender);
diff --git a/projects/Test/Integration/TestExceptionMessages.cs b/projects/Test/Integration/TestExceptionMessages.cs
index 7901096f54..fdf3a55785 100644
--- a/projects/Test/Integration/TestExceptionMessages.cs
+++ b/projects/Test/Integration/TestExceptionMessages.cs
@@ -30,6 +30,7 @@
//---------------------------------------------------------------------------
using System;
+using System.Threading.Tasks;
using RabbitMQ.Client.Exceptions;
using Xunit;
using Xunit.Abstractions;
@@ -43,12 +44,12 @@ public TestExceptionMessages(ITestOutputHelper output) : base(output)
}
[Fact]
- public void TestAlreadyClosedExceptionMessage()
+ public async Task TestAlreadyClosedExceptionMessage()
{
- string uuid = System.Guid.NewGuid().ToString();
+ string uuid = Guid.NewGuid().ToString();
try
{
- _channel.QueueDeclarePassive(uuid);
+ await _channel.QueueDeclarePassiveAsync(uuid);
}
catch (Exception e)
{
@@ -59,7 +60,7 @@ public void TestAlreadyClosedExceptionMessage()
try
{
- _channel.QueueDeclarePassive(uuid);
+ await _channel.QueueDeclarePassiveAsync(uuid);
}
catch (AlreadyClosedException e)
{
diff --git a/projects/Test/Integration/TestExchangeDeclare.cs b/projects/Test/Integration/TestExchangeDeclare.cs
index 47056d76ed..3fdbb45462 100644
--- a/projects/Test/Integration/TestExchangeDeclare.cs
+++ b/projects/Test/Integration/TestExchangeDeclare.cs
@@ -31,8 +31,7 @@
using System;
using System.Collections.Generic;
-using System.Threading;
-using RabbitMQ.Client;
+using System.Threading.Tasks;
using Xunit;
using Xunit.Abstractions;
@@ -47,22 +46,22 @@ public TestExchangeDeclare(ITestOutputHelper output) : base(output)
}
[Fact]
- public void TestConcurrentExchangeDeclareAndDelete()
+ public async Task TestConcurrentExchangeDeclareAndDelete()
{
var exchangeNames = new List();
- var ts = new List();
+ var tasks = new List();
NotSupportedException nse = null;
for (int i = 0; i < 256; i++)
{
- var t = new Thread(() =>
+ var t = Task.Run(async () =>
{
try
{
// sleep for a random amount of time to increase the chances
// of thread interleaving. MK.
- Thread.Sleep(_rnd.Next(5, 500));
+ await Task.Delay(_rnd.Next(5, 500));
string exchangeName = GenerateExchangeName();
- _channel.ExchangeDeclare(exchange: exchangeName, "fanout", false, false, null);
+ await _channel.ExchangeDeclareAsync(exchange: exchangeName, "fanout", false, false);
exchangeNames.Add(exchangeName);
}
catch (NotSupportedException e)
@@ -70,42 +69,35 @@ public void TestConcurrentExchangeDeclareAndDelete()
nse = e;
}
});
- ts.Add(t);
- t.Start();
+ tasks.Add(t);
}
- foreach (Thread t in ts)
- {
- t.Join();
- }
+ await Task.WhenAll(tasks);
Assert.Null(nse);
- ts.Clear();
+ tasks.Clear();
foreach (string exchangeName in exchangeNames)
{
- var t = new Thread((object ex) =>
+ string ex = exchangeName;
+ var t = Task.Run(async () =>
{
try
{
// sleep for a random amount of time to increase the chances
// of thread interleaving. MK.
- Thread.Sleep(_rnd.Next(5, 500));
- _channel.ExchangeDelete((string)ex);
+ await Task.Delay(_rnd.Next(5, 500));
+ await _channel.ExchangeDeleteAsync(ex);
}
catch (NotSupportedException e)
{
nse = e;
}
});
- ts.Add(t);
- t.Start(exchangeName);
+ tasks.Add(t);
}
- foreach (Thread t in ts)
- {
- t.Join();
- }
+ await Task.WhenAll(tasks);
Assert.Null(nse);
}
diff --git a/projects/Test/Integration/TestHeartbeats.cs b/projects/Test/Integration/TestHeartbeats.cs
index 9d2bba292c..93f29bed39 100644
--- a/projects/Test/Integration/TestHeartbeats.cs
+++ b/projects/Test/Integration/TestHeartbeats.cs
@@ -32,6 +32,7 @@
using System;
using System.Collections.Generic;
using System.Threading;
+using System.Threading.Tasks;
using RabbitMQ.Client;
using Xunit;
using Xunit.Abstractions;
@@ -46,36 +47,39 @@ public TestHeartbeats(ITestOutputHelper output) : base(output)
{
}
- protected override void SetUp()
+ public override Task InitializeAsync()
{
+ // NB: nothing to do here since each test creates its own factory,
+ // connections and channels
Assert.Null(_connFactory);
Assert.Null(_conn);
Assert.Null(_channel);
+ return Task.CompletedTask;
}
[SkippableFact(Timeout = 35000)]
[Trait("Category", "LongRunning")]
- public void TestThatHeartbeatWriterUsesConfigurableInterval()
+ public async Task TestThatHeartbeatWriterUsesConfigurableInterval()
{
Skip.IfNot(LongRunningTestsEnabled(), "RABBITMQ_LONG_RUNNING_TESTS is not set, skipping test");
- var cf = CreateConnectionFactory();
+ ConnectionFactory cf = CreateConnectionFactory();
cf.RequestedHeartbeat = _heartbeatTimeout;
cf.AutomaticRecoveryEnabled = false;
- RunSingleConnectionTest(cf);
+ await RunSingleConnectionTestAsync(cf);
}
[SkippableFact]
[Trait("Category", "LongRunning")]
- public void TestThatHeartbeatWriterWithTLSEnabled()
+ public async Task TestThatHeartbeatWriterWithTLSEnabled()
{
Skip.IfNot(LongRunningTestsEnabled(), "RABBITMQ_LONG_RUNNING_TESTS is not set, skipping test");
var sslEnv = new SslEnv();
Skip.IfNot(sslEnv.IsSslConfigured, "SSL_CERTS_DIR and/or PASSWORD are not configured, skipping test");
- var cf = CreateConnectionFactory();
+ ConnectionFactory cf = CreateConnectionFactory();
cf.Port = 5671;
cf.RequestedHeartbeat = _heartbeatTimeout;
cf.AutomaticRecoveryEnabled = false;
@@ -85,12 +89,12 @@ public void TestThatHeartbeatWriterWithTLSEnabled()
cf.Ssl.CertPassphrase = sslEnv.CertPassphrase;
cf.Ssl.Enabled = true;
- RunSingleConnectionTest(cf);
+ await RunSingleConnectionTestAsync(cf);
}
[SkippableFact(Timeout = 90000)]
[Trait("Category", "LongRunning")]
- public void TestHundredsOfConnectionsWithRandomHeartbeatInterval()
+ public async Task TestHundredsOfConnectionsWithRandomHeartbeatInterval()
{
Skip.IfNot(LongRunningTestsEnabled(), "RABBITMQ_LONG_RUNNING_TESTS is not set, skipping test");
@@ -110,25 +114,26 @@ public void TestHundredsOfConnectionsWithRandomHeartbeatInterval()
for (int i = 0; i < connectionCount; i++)
{
ushort n = Convert.ToUInt16(rnd.Next(2, 6));
- var cf = CreateConnectionFactory();
+ ConnectionFactory cf = CreateConnectionFactory();
cf.RequestedHeartbeat = TimeSpan.FromSeconds(n);
cf.AutomaticRecoveryEnabled = false;
- IConnection conn = cf.CreateConnection($"{_testDisplayName}:{i}");
+ IConnection conn = await cf.CreateConnectionAsync($"{_testDisplayName}:{i}");
conns.Add(conn);
- IChannel ch = conn.CreateChannel();
+ IChannel ch = await conn.CreateChannelAsync();
conn.ConnectionShutdown += (sender, evt) =>
{
CheckInitiator(evt);
};
}
- SleepFor(60);
+
+ await SleepFor(60);
}
finally
{
foreach (IConnection conn in conns)
{
- conn.Close();
+ await conn.CloseAsync();
}
}
}
@@ -138,11 +143,11 @@ public void TestHundredsOfConnectionsWithRandomHeartbeatInterval()
}
}
- private void RunSingleConnectionTest(ConnectionFactory cf)
+ private async Task RunSingleConnectionTestAsync(ConnectionFactory cf)
{
- using (IConnection conn = cf.CreateConnection(_testDisplayName))
+ using (IConnection conn = await cf.CreateConnectionAsync(_testDisplayName))
{
- using (IChannel ch = conn.CreateChannel())
+ using (IChannel ch = await conn.CreateChannelAsync())
{
bool wasShutdown = false;
@@ -157,11 +162,16 @@ private void RunSingleConnectionTest(ConnectionFactory cf)
}
}
};
- SleepFor(30);
+
+ await SleepFor(30);
Assert.False(wasShutdown, "shutdown event should not have been fired");
Assert.True(conn.IsOpen, "connection should be open");
+
+ await ch.CloseAsync();
}
+
+ await conn.CloseAsync();
}
}
@@ -182,10 +192,10 @@ private bool LongRunningTestsEnabled()
return false;
}
- private void SleepFor(int t)
+ private Task SleepFor(int t)
{
_output.WriteLine("Testing heartbeats, sleeping for {0} seconds", t);
- Thread.Sleep(t * 1000);
+ return Task.Delay(t * 1000);
}
private bool InitiatedByPeerOrLibrary(ShutdownEventArgs evt)
diff --git a/projects/Test/Integration/TestInitialConnection.cs b/projects/Test/Integration/TestInitialConnection.cs
index c141baa8f5..267d0b61c8 100644
--- a/projects/Test/Integration/TestInitialConnection.cs
+++ b/projects/Test/Integration/TestInitialConnection.cs
@@ -30,8 +30,10 @@
//---------------------------------------------------------------------------
using System.Collections.Generic;
+using System.Threading.Tasks;
using RabbitMQ.Client;
using RabbitMQ.Client.Exceptions;
+using RabbitMQ.Client.Framing.Impl;
using Xunit;
using Xunit.Abstractions;
@@ -44,27 +46,27 @@ public TestInitialConnection(ITestOutputHelper output) : base(output)
}
[Fact]
- public void TestBasicConnectionRecoveryWithHostnameList()
+ public async Task TestBasicConnectionRecoveryWithHostnameList()
{
- var c = CreateAutorecoveringConnection(new List() { "127.0.0.1", "localhost" });
+ AutorecoveringConnection c = await CreateAutorecoveringConnectionAsync(new List() { "127.0.0.1", "localhost" });
Assert.True(c.IsOpen);
- c.Close();
+ await c.CloseAsync();
}
[Fact]
- public void TestBasicConnectionRecoveryWithHostnameListAndUnreachableHosts()
+ public async Task TestBasicConnectionRecoveryWithHostnameListAndUnreachableHosts()
{
- var c = CreateAutorecoveringConnection(new List() { "191.72.44.22", "127.0.0.1", "localhost" });
+ AutorecoveringConnection c = await CreateAutorecoveringConnectionAsync(new List() { "191.72.44.22", "127.0.0.1", "localhost" });
Assert.True(c.IsOpen);
- c.Close();
+ await c.CloseAsync();
}
[Fact]
- public void TestBasicConnectionRecoveryWithHostnameListWithOnlyUnreachableHosts()
+ public async Task TestBasicConnectionRecoveryWithHostnameListWithOnlyUnreachableHosts()
{
- Assert.Throws(() =>
+ await Assert.ThrowsAsync(() =>
{
- CreateAutorecoveringConnection(new List() {
+ return CreateAutorecoveringConnectionAsync(new List() {
"191.72.44.22",
"145.23.22.18",
"192.255.255.255"
diff --git a/projects/Test/Integration/TestInvalidAck.cs b/projects/Test/Integration/TestInvalidAck.cs
index d2f2888e88..1eb5d735a8 100644
--- a/projects/Test/Integration/TestInvalidAck.cs
+++ b/projects/Test/Integration/TestInvalidAck.cs
@@ -29,7 +29,7 @@
// Copyright (c) 2007-2020 VMware, Inc. All rights reserved.
//---------------------------------------------------------------------------
-using System.Threading;
+using System.Threading.Tasks;
using RabbitMQ.Client;
using Xunit;
using Xunit.Abstractions;
@@ -43,20 +43,20 @@ public TestInvalidAck(ITestOutputHelper output) : base(output)
}
[Fact]
- public void TestAckWithUnknownConsumerTagAndMultipleFalse()
+ public async Task TestAckWithUnknownConsumerTagAndMultipleFalse()
{
- var mre = new ManualResetEventSlim();
+ var tcs = new TaskCompletionSource();
bool shutdownFired = false;
ShutdownEventArgs shutdownArgs = null;
_channel.ChannelShutdown += (s, args) =>
{
shutdownFired = true;
shutdownArgs = args;
- mre.Set();
+ tcs.SetResult(true);
};
- _channel.BasicAck(123456, false);
- Wait(mre, "ChannelShutdown");
+ await _channel.BasicAckAsync(123456, false);
+ await WaitAsync(tcs, "ChannelShutdown");
Assert.True(shutdownFired);
AssertPreconditionFailed(shutdownArgs);
}
diff --git a/projects/Test/Integration/TestMainLoop.cs b/projects/Test/Integration/TestMainLoop.cs
index c01f385d92..eda581fc37 100644
--- a/projects/Test/Integration/TestMainLoop.cs
+++ b/projects/Test/Integration/TestMainLoop.cs
@@ -30,7 +30,7 @@
//---------------------------------------------------------------------------
using System;
-using System.Threading;
+using System.Threading.Tasks;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using Xunit;
@@ -48,12 +48,12 @@ private sealed class FaultyConsumer : DefaultBasicConsumer
{
public FaultyConsumer(IChannel channel) : base(channel) { }
- public override void HandleBasicDeliver(string consumerTag,
+ public override Task HandleBasicDeliverAsync(string consumerTag,
ulong deliveryTag,
bool redelivered,
string exchange,
string routingKey,
- in ReadOnlyBasicProperties properties,
+ ReadOnlyBasicProperties properties,
ReadOnlyMemory body)
{
throw new Exception("I am a bad consumer");
@@ -61,23 +61,23 @@ private sealed class FaultyConsumer : DefaultBasicConsumer
}
[Fact]
- public void TestCloseWithFaultyConsumer()
+ public async Task TestCloseWithFaultyConsumer()
{
- var mre = new ManualResetEventSlim();
- QueueDeclareOk q = _channel.QueueDeclare(string.Empty, false, false, false, null);
+ var tcs = new TaskCompletionSource();
+ QueueDeclareOk q = await _channel.QueueDeclareAsync(string.Empty, false, false, false);
CallbackExceptionEventArgs ea = null;
- _channel.CallbackException += (_, evt) =>
+ _channel.CallbackException += async (_, evt) =>
{
ea = evt;
- _channel.Close();
- mre.Set();
+ await _channel.CloseAsync();
+ tcs.SetResult(true);
};
- _channel.BasicConsume(q, true, new FaultyConsumer(_channel));
- _channel.BasicPublish(string.Empty, q, _encoding.GetBytes("message"));
+ await _channel.BasicConsumeAsync(q, true, new FaultyConsumer(_channel));
+ await _channel.BasicPublishAsync(string.Empty, q, _encoding.GetBytes("message"));
- Wait(mre, "CallbackException");
+ await WaitAsync(tcs, "CallbackException");
Assert.NotNull(ea);
Assert.False(_channel.IsOpen);
diff --git a/projects/Test/Integration/TestNowait.cs b/projects/Test/Integration/TestNowait.cs
index 4fa6f06b30..e865ede5ea 100644
--- a/projects/Test/Integration/TestNowait.cs
+++ b/projects/Test/Integration/TestNowait.cs
@@ -29,7 +29,9 @@
// Copyright (c) 2007-2020 VMware, Inc. All rights reserved.
//---------------------------------------------------------------------------
-using RabbitMQ.Client;
+using System;
+using System.Threading.Tasks;
+using RabbitMQ.Client.Exceptions;
using Xunit;
using Xunit.Abstractions;
@@ -42,81 +44,95 @@ public TestNoWait(ITestOutputHelper output) : base(output)
}
[Fact]
- public void TestQueueDeclareNoWait()
+ public async Task TestQueueDeclareNoWait()
{
string q = GenerateQueueName();
- _channel.QueueDeclareNoWait(q, false, true, false, null);
- _channel.QueueDeclarePassive(q);
+ await _channel.QueueDeclareAsync(q, false, true, false, noWait: true, arguments: null);
+ await _channel.QueueDeclarePassiveAsync(q);
}
[Fact]
- public void TestQueueBindNoWait()
+ public Task TestQueueDeclareServerNamedNoWait()
+ {
+ return Assert.ThrowsAsync(() =>
+ {
+ return _channel.QueueDeclareAsync("", false, true, false, noWait: true);
+ });
+ }
+
+ [Fact]
+ public async Task TestQueueBindNoWait()
{
string q = GenerateQueueName();
- _channel.QueueDeclareNoWait(q, false, true, false, null);
- _channel.QueueBindNoWait(q, "amq.fanout", "", null);
+ await _channel.QueueDeclareAsync(q, false, true, false, noWait: true);
+ await _channel.QueueBindAsync(q, "amq.fanout", "", noWait: true);
}
[Fact]
- public void TestQueueDeleteNoWait()
+ public async Task TestQueueDeleteNoWait()
{
string q = GenerateQueueName();
- _channel.QueueDeclareNoWait(q, false, true, false, null);
- _channel.QueueDeleteNoWait(q, false, false);
+ await _channel.QueueDeclareAsync(q, false, true, false, noWait: true);
+ await _channel.QueueDeleteAsync(q, false, false, noWait: true);
+ await Assert.ThrowsAsync(() =>
+ {
+ return _channel.QueueDeclarePassiveAsync(q);
+ });
}
[Fact]
- public void TestExchangeDeclareNoWait()
+ public async Task TestExchangeDeclareNoWaitAsync()
{
string x = GenerateExchangeName();
try
{
- _channel.ExchangeDeclareNoWait(x, "fanout", false, true, null);
- _channel.ExchangeDeclarePassive(x);
+ await _channel.ExchangeDeclareAsync(x, "fanout", false, true);
+ await _channel.ExchangeDeclarePassiveAsync(x);
}
finally
{
- _channel.ExchangeDelete(x);
+ await _channel.ExchangeDeleteAsync(x);
}
}
[Fact]
- public void TestExchangeBindNoWait()
+ public async Task TestExchangeBindNoWait()
{
string x = GenerateExchangeName();
try
{
- _channel.ExchangeDeclareNoWait(x, "fanout", false, true, null);
- _channel.ExchangeBindNoWait(x, "amq.fanout", "", null);
+ await _channel.ExchangeDeclareAsync(x, "fanout", false, true, noWait: true);
+ await _channel.ExchangeBindAsync(x, "amq.fanout", "", noWait: true);
}
finally
{
- _channel.ExchangeDelete(x);
+ await _channel.ExchangeDeleteAsync(x);
}
}
[Fact]
- public void TestExchangeUnbindNoWait()
+ public async Task TestExchangeUnbindNoWait()
{
string x = GenerateExchangeName();
try
{
- _channel.ExchangeDeclare(x, "fanout", false, true, null);
- _channel.ExchangeBind(x, "amq.fanout", "", null);
- _channel.ExchangeUnbindNoWait(x, "amq.fanout", "", null);
+ await _channel.ExchangeDeclareAsync(x, "fanout", false, true);
+ await _channel.ExchangeBindAsync(x, "amq.fanout", "", noWait: true);
+ await _channel.ExchangeUnbindAsync(x, "amq.fanout", "", noWait: true);
}
finally
{
- _channel.ExchangeDelete(x);
+ await _channel.ExchangeDeleteAsync(x);
}
}
[Fact]
- public void TestExchangeDeleteNoWait()
+ public async Task TestExchangeDeleteNoWait()
{
string x = GenerateExchangeName();
- _channel.ExchangeDeclareNoWait(x, "fanout", false, true, null);
- _channel.ExchangeDeleteNoWait(x, false);
+ await _channel.ExchangeDeclareAsync(x, "fanout", false, true,
+ noWait: true, arguments: null);
+ await _channel.ExchangeDeleteAsync(x, false, noWait: true);
}
}
}
diff --git a/projects/Test/Integration/TestPassiveDeclare.cs b/projects/Test/Integration/TestPassiveDeclare.cs
index 6063697159..3f62505d22 100644
--- a/projects/Test/Integration/TestPassiveDeclare.cs
+++ b/projects/Test/Integration/TestPassiveDeclare.cs
@@ -30,6 +30,7 @@
//---------------------------------------------------------------------------
using System;
+using System.Threading.Tasks;
using RabbitMQ.Client.Exceptions;
using Xunit;
using Xunit.Abstractions;
@@ -43,15 +44,21 @@ public TestPassiveDeclare(ITestOutputHelper output) : base(output)
}
[Fact]
- public void TestPassiveExchangeDeclareWhenExchangeDoesNotExist()
+ public Task TestPassiveExchangeDeclareWhenExchangeDoesNotExist()
{
- Assert.Throws(() => _channel.ExchangeDeclarePassive(Guid.NewGuid().ToString()));
+ return Assert.ThrowsAsync(() =>
+ {
+ return _channel.ExchangeDeclarePassiveAsync(Guid.NewGuid().ToString());
+ });
}
[Fact]
- public void TestPassiveQueueDeclareWhenQueueDoesNotExist()
+ public Task TestPassiveQueueDeclareWhenQueueDoesNotExist()
{
- Assert.Throws(() => _channel.QueueDeclarePassive(Guid.NewGuid().ToString()));
+ return Assert.ThrowsAsync(() =>
+ {
+ return _channel.QueueDeclarePassiveAsync(Guid.NewGuid().ToString());
+ });
}
}
}
diff --git a/projects/Test/Integration/TestQueueDeclare.cs b/projects/Test/Integration/TestQueueDeclare.cs
index d068993c63..9d461873ea 100644
--- a/projects/Test/Integration/TestQueueDeclare.cs
+++ b/projects/Test/Integration/TestQueueDeclare.cs
@@ -31,7 +31,7 @@
using System;
using System.Collections.Generic;
-using System.Threading;
+using System.Threading.Tasks;
using RabbitMQ.Client;
using Xunit;
using Xunit.Abstractions;
@@ -45,22 +45,22 @@ public TestQueueDeclare(ITestOutputHelper output) : base(output)
}
[Fact]
- public void TestConcurrentQueueDeclare()
+ public async Task TestConcurrentQueueDeclare()
{
var qs = new List();
- var ts = new List();
+ var tasks = new List();
NotSupportedException nse = null;
for (int i = 0; i < 256; i++)
{
- var t = new Thread(() =>
+ var t = Task.Run(async () =>
{
try
{
// sleep for a random amount of time to increase the chances
// of thread interleaving. MK.
- Thread.Sleep(S_Random.Next(5, 50));
+ await Task.Delay(S_Random.Next(5, 50));
string q = GenerateQueueName();
- _channel.QueueDeclare(q, false, false, false, null);
+ await _channel.QueueDeclareAsync(q, false, false, false);
qs.Add(q);
}
catch (NotSupportedException e)
@@ -68,40 +68,33 @@ public void TestConcurrentQueueDeclare()
nse = e;
}
});
- ts.Add(t);
- t.Start();
+ tasks.Add(t);
}
- foreach (Thread t in ts)
- {
- t.Join();
- }
+ await Task.WhenAll(tasks);
Assert.Null(nse);
- ts.Clear();
+ tasks.Clear();
foreach (string queueName in qs)
{
- var t = new Thread(() =>
+ string q = queueName;
+ var t = Task.Run(async () =>
{
try
{
- Thread.Sleep(S_Random.Next(5, 50));
- _channel.QueueDelete(queueName);
+ await Task.Delay(S_Random.Next(5, 50));
+ await _channel.QueueDeleteAsync(queueName);
}
catch (NotSupportedException e)
{
nse = e;
}
});
- ts.Add(t);
- t.Start();
+ tasks.Add(t);
}
- foreach (Thread t in ts)
- {
- t.Join();
- }
+ await Task.WhenAll(tasks);
Assert.Null(nse);
}
diff --git a/projects/Test/Integration/TestSsl.cs b/projects/Test/Integration/TestSsl.cs
index 58ce7fb561..aa7f8ed965 100644
--- a/projects/Test/Integration/TestSsl.cs
+++ b/projects/Test/Integration/TestSsl.cs
@@ -32,6 +32,7 @@
using System.IO;
using System.Net.Security;
using System.Security.Authentication;
+using System.Threading.Tasks;
using RabbitMQ.Client;
using Xunit;
using Xunit.Abstractions;
@@ -47,15 +48,16 @@ public TestSsl(ITestOutputHelper output) : base(output)
_sslEnv = new SslEnv();
}
- protected override void SetUp()
+ public override Task InitializeAsync()
{
Assert.Null(_connFactory);
Assert.Null(_conn);
Assert.Null(_channel);
+ return Task.CompletedTask;
}
[SkippableFact]
- public void TestServerVerifiedIgnoringNameMismatch()
+ public async Task TestServerVerifiedIgnoringNameMismatch()
{
Skip.IfNot(_sslEnv.IsSslConfigured, "SSL_CERTS_DIR and/or PASSWORD are not configured, skipping test");
@@ -65,11 +67,11 @@ public void TestServerVerifiedIgnoringNameMismatch()
cf.Ssl.AcceptablePolicyErrors = SslPolicyErrors.RemoteCertificateNameMismatch;
cf.Ssl.Enabled = true;
- SendReceive(cf);
+ await SendReceiveAsync(cf);
}
[SkippableFact]
- public void TestServerVerified()
+ public async Task TestServerVerified()
{
Skip.IfNot(_sslEnv.IsSslConfigured, "SSL_CERTS_DIR and/or PASSWORD are not configured, skipping test");
@@ -78,11 +80,11 @@ public void TestServerVerified()
cf.Ssl.ServerName = _sslEnv.Hostname;
cf.Ssl.Enabled = true;
- SendReceive(cf);
+ await SendReceiveAsync(cf);
}
[SkippableFact]
- public void TestClientAndServerVerified()
+ public async Task TestClientAndServerVerified()
{
Skip.IfNot(_sslEnv.IsSslConfigured, "SSL_CERTS_DIR and/or PASSWORD are not configured, skipping test");
@@ -96,12 +98,12 @@ public void TestClientAndServerVerified()
cf.Ssl.CertPassphrase = _sslEnv.CertPassphrase;
cf.Ssl.Enabled = true;
- SendReceive(cf);
+ await SendReceiveAsync(cf);
}
// rabbitmq/rabbitmq-dotnet-client#46, also #44 and #45
[SkippableFact]
- public void TestNoClientCertificate()
+ public async Task TestNoClientCertificate()
{
Skip.IfNot(_sslEnv.IsSslConfigured, "SSL_CERTS_DIR and/or PASSWORD are not configured, skipping test");
@@ -118,29 +120,32 @@ public void TestNoClientCertificate()
SslPolicyErrors.RemoteCertificateNameMismatch
};
- SendReceive(cf);
+ await SendReceiveAsync(cf);
}
- private void SendReceive(ConnectionFactory connectionFactory)
+ private async Task SendReceiveAsync(ConnectionFactory connectionFactory)
{
- using (IConnection conn = CreateConnectionWithRetries(connectionFactory))
+ using (IConnection conn = await CreateConnectionAsyncWithRetries(connectionFactory))
{
- using (IChannel ch = conn.CreateChannel())
+ using (IChannel ch = await conn.CreateChannelAsync())
{
- ch.ExchangeDeclare("Exchange_TestSslEndPoint", ExchangeType.Direct);
- string qName = ch.QueueDeclare();
- ch.QueueBind(qName, "Exchange_TestSslEndPoint", "Key_TestSslEndpoint", null);
+ await ch.ExchangeDeclareAsync("Exchange_TestSslEndPoint", ExchangeType.Direct);
+
+ string qName = await ch.QueueDeclareAsync();
+ await ch.QueueBindAsync(qName, "Exchange_TestSslEndPoint", "Key_TestSslEndpoint");
string message = "Hello C# SSL Client World";
byte[] msgBytes = _encoding.GetBytes(message);
- ch.BasicPublish("Exchange_TestSslEndPoint", "Key_TestSslEndpoint", msgBytes);
+ await ch.BasicPublishAsync("Exchange_TestSslEndPoint", "Key_TestSslEndpoint", msgBytes);
bool autoAck = false;
- BasicGetResult result = ch.BasicGet(qName, autoAck);
+ BasicGetResult result = await ch.BasicGetAsync(qName, autoAck);
byte[] body = result.Body.ToArray();
string resultMessage = _encoding.GetString(body);
Assert.Equal(message, resultMessage);
+
+ await ch.CloseAsync();
}
}
}
diff --git a/projects/Test/Integration/TestUpdateSecret.cs b/projects/Test/Integration/TestUpdateSecret.cs
index d2396ca831..3f65d79d64 100644
--- a/projects/Test/Integration/TestUpdateSecret.cs
+++ b/projects/Test/Integration/TestUpdateSecret.cs
@@ -29,6 +29,8 @@
// Copyright (c) 2007-2020 VMware, Inc. All rights reserved.
//---------------------------------------------------------------------------
+using System.Threading.Tasks;
+using Xunit;
using Xunit.Abstractions;
namespace Test.Integration
@@ -39,9 +41,10 @@ public TestUpdateSecret(ITestOutputHelper output) : base(output)
{
}
- public void TestUpdatingConnectionSecret()
+ [Fact]
+ public Task TestUpdatingConnectionSecret()
{
- _conn.UpdateSecret("new-secret", "Test Case");
+ return _conn.UpdateSecretAsync("new-secret", "Test Case");
}
}
}
diff --git a/projects/Test/OAuth2/OAuth2.csproj b/projects/Test/OAuth2/OAuth2.csproj
index f7f9b8d2fa..aea8b6d1ba 100644
--- a/projects/Test/OAuth2/OAuth2.csproj
+++ b/projects/Test/OAuth2/OAuth2.csproj
@@ -11,8 +11,8 @@
../../rabbit.snk
true
- latest
- 7.0
+ true
+ 7.3
@@ -23,11 +23,11 @@
-
-
+
+
-
-
+
+
diff --git a/projects/Test/OAuth2/TestOAuth2.cs b/projects/Test/OAuth2/TestOAuth2.cs
index a44700356a..6357e173c2 100644
--- a/projects/Test/OAuth2/TestOAuth2.cs
+++ b/projects/Test/OAuth2/TestOAuth2.cs
@@ -25,35 +25,71 @@ public OAuth2Options(Mode mode)
_mode = mode;
}
- public string Name => _mode switch
+ public string Name
{
- Mode.uaa => "uaa",
- Mode.keycloak => "keycloak",
- _ => throw new InvalidOperationException(),
- };
+ get
+ {
+ switch (_mode)
+ {
+ case Mode.uaa:
+ return "uaa";
+ case Mode.keycloak:
+ return "keycloak";
+ default:
+ throw new InvalidOperationException();
+ }
+ }
+ }
public string ClientId => "producer";
- public string ClientSecret => _mode switch
+ public string ClientSecret
{
- Mode.uaa => "producer_secret",
- Mode.keycloak => "kbOFBXI9tANgKUq8vXHLhT6YhbivgXxn",
- _ => throw new InvalidOperationException(),
- };
+ get
+ {
+ switch (_mode)
+ {
+ case Mode.uaa:
+ return "producer_secret";
+ case Mode.keycloak:
+ return "kbOFBXI9tANgKUq8vXHLhT6YhbivgXxn";
+ default:
+ throw new InvalidOperationException();
+ }
+ }
+ }
- public string Scope => _mode switch
+ public string Scope
{
- Mode.uaa => "",
- Mode.keycloak => "rabbitmq:configure:*/* rabbitmq:read:*/* rabbitmq:write:*/*",
- _ => throw new InvalidOperationException(),
- };
+ get
+ {
+ switch (_mode)
+ {
+ case Mode.uaa:
+ return string.Empty;
+ case Mode.keycloak:
+ return "rabbitmq:configure:*/* rabbitmq:read:*/* rabbitmq:write:*/*";
+ default:
+ throw new InvalidOperationException();
+ }
+ }
+ }
- public string TokenEndpoint => _mode switch
+ public string TokenEndpoint // => _mode switch
{
- Mode.uaa => "http://localhost:8080/oauth/token",
- Mode.keycloak => "http://localhost:8080/realms/test/protocol/openid-connect/token",
- _ => throw new InvalidOperationException(),
- };
+ get
+ {
+ switch (_mode)
+ {
+ case Mode.uaa:
+ return "http://localhost:8080/oauth/token";
+ case Mode.keycloak:
+ return "http://localhost:8080/realms/test/protocol/openid-connect/token";
+ default:
+ throw new InvalidOperationException();
+ }
+ }
+ }
public int TokenExpiresInSeconds => 60;
}
@@ -62,7 +98,7 @@ public class TestOAuth2 : IAsyncLifetime
{
private const string Exchange = "test_direct";
- private readonly AutoResetEvent _doneEvent = new AutoResetEvent(false);
+ private readonly SemaphoreSlim _doneEvent = new SemaphoreSlim(0, 1);
private readonly ITestOutputHelper _testOutputHelper;
private readonly IConnectionFactory _connectionFactory;
private IConnection _connection;
@@ -95,38 +131,49 @@ public async Task InitializeAsync()
public async Task DisposeAsync()
{
- await _connection.CloseAsync();
- _connection.Dispose();
+ try
+ {
+ await _connection.CloseAsync();
+ }
+ finally
+ {
+ _doneEvent.Dispose();
+ _connection.Dispose();
+ }
}
[Fact]
public async void IntegrationTest()
{
using (IChannel publishChannel = await DeclarePublisherAsync())
- using (IChannel consumeChannel = await DeclareConsumerAsync())
{
- await PublishAsync(publishChannel);
- Consume(consumeChannel);
-
- if (_tokenExpiresInSeconds > 0)
+ using (IChannel consumeChannel = await DeclareConsumerAsync())
{
- for (int i = 0; i < 4; i++)
- {
- _testOutputHelper.WriteLine("Wait until Token expires. Attempt #" + (i + 1));
+ await PublishAsync(publishChannel);
+ await ConsumeAsync(consumeChannel);
- await Task.Delay(TimeSpan.FromSeconds(_tokenExpiresInSeconds + 10));
- _testOutputHelper.WriteLine("Resuming ..");
+ if (_tokenExpiresInSeconds > 0)
+ {
+ for (int i = 0; i < 4; i++)
+ {
+ _testOutputHelper.WriteLine("Wait until Token expires. Attempt #" + (i + 1));
- await PublishAsync(publishChannel);
- _doneEvent.Reset();
+ await Task.Delay(TimeSpan.FromSeconds(_tokenExpiresInSeconds + 10));
+ _testOutputHelper.WriteLine("Resuming ..");
- Consume(consumeChannel);
+ await PublishAsync(publishChannel);
+ await ConsumeAsync(consumeChannel);
+ }
}
+ else
+ {
+ Assert.Fail("_tokenExpiresInSeconds is NOT greater than 0");
+ }
+
+ await consumeChannel.CloseAsync();
}
- else
- {
- Assert.Fail("_tokenExpiresInSeconds is NOT greater than 0");
- }
+
+ await publishChannel.CloseAsync();
}
}
@@ -134,7 +181,8 @@ public async void IntegrationTest()
public async void SecondConnectionCrashes_GH1429()
{
// https://github.com/rabbitmq/rabbitmq-dotnet-client/issues/1429
- using IConnection secondConnection = await _connectionFactory.CreateConnectionAsync(CancellationToken.None);
+ IConnection secondConnection = await _connectionFactory.CreateConnectionAsync(CancellationToken.None);
+ secondConnection.Dispose();
}
private async Task DeclarePublisherAsync()
@@ -164,20 +212,20 @@ private async Task PublishAsync(IChannel publisher)
private async ValueTask DeclareConsumerAsync()
{
- IChannel subscriber = _connection.CreateChannel();
- await subscriber.QueueDeclareAsync(queue: "testqueue", passive: false, true, false, false, arguments: null);
- subscriber.QueueBind("testqueue", Exchange, "hello");
+ IChannel subscriber = await _connection.CreateChannelAsync();
+ await subscriber.QueueDeclareAsync(queue: "testqueue", true, false, false);
+ await subscriber.QueueBindAsync("testqueue", Exchange, "hello");
return subscriber;
}
- private void Consume(IChannel subscriber)
+ private async Task ConsumeAsync(IChannel subscriber)
{
var asyncListener = new AsyncEventingBasicConsumer(subscriber);
asyncListener.Received += AsyncListener_Received;
- string consumerTag = subscriber.BasicConsume("testqueue", true, "testconsumer", asyncListener);
- _doneEvent.WaitOne(1);
+ string consumerTag = await subscriber.BasicConsumeAsync("testqueue", true, "testconsumer", asyncListener);
+ await _doneEvent.WaitAsync(TimeSpan.FromMilliseconds(500));
_testOutputHelper.WriteLine("Received message");
- subscriber.BasicCancel(consumerTag);
+ await subscriber.BasicCancelAsync(consumerTag);
}
private OAuth2ClientCredentialsProvider GetCredentialsProvider(OAuth2Options opts)
@@ -195,7 +243,7 @@ private OAuth2ClientCredentialsProvider GetCredentialsProvider(OAuth2Options opt
private Task AsyncListener_Received(object sender, BasicDeliverEventArgs @event)
{
- _doneEvent.Set();
+ _doneEvent.Release();
return Task.CompletedTask;
}
diff --git a/projects/Test/SequentialIntegration/SequentialIntegration.csproj b/projects/Test/SequentialIntegration/SequentialIntegration.csproj
index 2820689e79..1020dddbbd 100644
--- a/projects/Test/SequentialIntegration/SequentialIntegration.csproj
+++ b/projects/Test/SequentialIntegration/SequentialIntegration.csproj
@@ -11,9 +11,8 @@
../../rabbit.snk
true
- latest
- 7.0
true
+ 7.3
@@ -37,8 +36,8 @@
-
-
+
+
diff --git a/projects/Test/SequentialIntegration/SequentialIntegrationFixture.cs b/projects/Test/SequentialIntegration/SequentialIntegrationFixture.cs
index 4f8dd82a3e..960ac0d6ad 100644
--- a/projects/Test/SequentialIntegration/SequentialIntegrationFixture.cs
+++ b/projects/Test/SequentialIntegration/SequentialIntegrationFixture.cs
@@ -30,7 +30,7 @@
//---------------------------------------------------------------------------
using System;
-using System.Threading;
+using System.Threading.Tasks;
using RabbitMQ.Client;
using Xunit.Abstractions;
@@ -42,48 +42,40 @@ public SequentialIntegrationFixture(ITestOutputHelper output) : base(output)
{
}
- public void Block()
+ public async Task BlockAsync(IChannel channel)
{
- _rabbitMQCtl.ExecRabbitMQCtl("set_vm_memory_high_watermark 0.000000001");
+ await _rabbitMQCtl.ExecRabbitMQCtlAsync("set_vm_memory_high_watermark 0.000000001");
// give rabbitmqctl some time to do its job
- Thread.Sleep(TimeSpan.FromSeconds(2));
- Publish();
+ await Task.Delay(TimeSpan.FromSeconds(5));
+ await channel.BasicPublishAsync("amq.fanout", "", _encoding.GetBytes("message"));
}
- public void Unblock()
+ public Task UnblockAsync()
{
- _rabbitMQCtl.ExecRabbitMQCtl("set_vm_memory_high_watermark 0.4");
+ return _rabbitMQCtl.ExecRabbitMQCtlAsync("set_vm_memory_high_watermark 0.4");
}
- public void RestartRabbitMQ()
+ public async Task RestartRabbitMqAsync()
{
- StopRabbitMQ();
- Thread.Sleep(TimeSpan.FromMilliseconds(500));
- StartRabbitMQ();
- AwaitRabbitMQ();
+ await StopRabbitMqAsync();
+ await Task.Delay(TimeSpan.FromSeconds(1));
+ await StartRabbitMqAsync();
+ await AwaitRabbitMqAsync();
}
- public void StopRabbitMQ()
+ public Task StopRabbitMqAsync()
{
- _rabbitMQCtl.ExecRabbitMQCtl("stop_app");
+ return _rabbitMQCtl.ExecRabbitMQCtlAsync("stop_app");
}
- public void StartRabbitMQ()
+ public Task StartRabbitMqAsync()
{
- _rabbitMQCtl.ExecRabbitMQCtl("start_app");
+ return _rabbitMQCtl.ExecRabbitMQCtlAsync("start_app");
}
- private void AwaitRabbitMQ()
+ private Task AwaitRabbitMqAsync()
{
- _rabbitMQCtl.ExecRabbitMQCtl("await_startup");
- }
-
- private void Publish()
- {
- using (IChannel ch = _conn.CreateChannel())
- {
- ch.BasicPublish("amq.fanout", "", _encoding.GetBytes("message"));
- }
+ return _rabbitMQCtl.ExecRabbitMQCtlAsync("await_startup");
}
}
}
diff --git a/projects/Test/SequentialIntegration/TestConnectionBlocked.cs b/projects/Test/SequentialIntegration/TestConnectionBlocked.cs
index 232a83b954..f9e3eaf2d4 100644
--- a/projects/Test/SequentialIntegration/TestConnectionBlocked.cs
+++ b/projects/Test/SequentialIntegration/TestConnectionBlocked.cs
@@ -30,8 +30,8 @@
//---------------------------------------------------------------------------
using System;
-using System.Threading;
using System.Threading.Tasks;
+using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using Xunit;
using Xunit.Abstractions;
@@ -40,89 +40,54 @@ namespace Test.SequentialIntegration
{
public class TestConnectionBlocked : SequentialIntegrationFixture
{
- private readonly ManualResetEventSlim _connDisposed = new ManualResetEventSlim(false);
- private readonly object _lockObject = new object();
- private bool _notified;
-
public TestConnectionBlocked(ITestOutputHelper output) : base(output)
{
}
- [Fact]
- public void TestConnectionBlockedNotification()
+ public override async Task DisposeAsync()
{
- _notified = false;
- _conn.ConnectionBlocked += HandleBlocked;
- _conn.ConnectionUnblocked += HandleUnblocked;
-
- try
- {
- Block();
-
- lock (_lockObject)
- {
- if (!_notified)
- {
- Monitor.Wait(_lockObject, TimeSpan.FromSeconds(15));
- }
- }
-
- if (!_notified)
- {
- Assert.Fail("Unblock notification not received.");
- }
- }
- finally
- {
- Unblock();
- }
+ await UnblockAsync();
+ await base.DisposeAsync();
}
[Fact]
- public void TestDisposeOnBlockedConnectionDoesNotHang()
+ public async Task TestConnectionBlockedNotification()
{
- _notified = false;
-
- try
+ var tcs = new TaskCompletionSource();
+ _conn.ConnectionBlocked += (object sender, ConnectionBlockedEventArgs args) =>
{
- Block();
-
- Task.Factory.StartNew(DisposeConnection);
+ UnblockAsync();
+ };
- if (!_connDisposed.Wait(TimeSpan.FromSeconds(20)))
- {
- Assert.Fail("Dispose must have finished within 20 seconds after starting");
- }
- }
- finally
+ _conn.ConnectionUnblocked += (object sender, EventArgs ea) =>
{
- Unblock();
- }
- }
+ tcs.SetResult(true);
+ };
- protected override void TearDown()
- {
- Unblock();
+ await BlockAsync(_channel);
+ await tcs.Task.WaitAsync(TimeSpan.FromSeconds(15));
+ Assert.True(await tcs.Task, "Unblock notification not received.");
}
- private void HandleBlocked(object sender, ConnectionBlockedEventArgs args)
+ [Fact]
+ public async Task TestDisposeOnBlockedConnectionDoesNotHang()
{
- Unblock();
- }
+ var tcs = new TaskCompletionSource();
- private void HandleUnblocked(object sender, EventArgs ea)
- {
- lock (_lockObject)
+ await BlockAsync(_channel);
+
+ Task disposeTask = Task.Run(async () =>
{
- _notified = true;
- Monitor.PulseAll(_lockObject);
- }
- }
+ await _conn.AbortAsync();
+ _conn.Dispose();
+ _conn = null;
+ tcs.SetResult(true);
+ });
- private void DisposeConnection()
- {
- _conn.Dispose();
- _connDisposed.Set();
+ Task anyTask = Task.WhenAny(tcs.Task, disposeTask);
+ await anyTask.WaitAsync(LongWaitSpan);
+ bool disposeSuccess = await tcs.Task;
+ Assert.True(disposeSuccess, "Dispose must have finished within 20 seconds after starting");
}
}
}
diff --git a/projects/Test/SequentialIntegration/TestConnectionRecovery.cs b/projects/Test/SequentialIntegration/TestConnectionRecovery.cs
index a2abcb0a1e..a31ac8603d 100644
--- a/projects/Test/SequentialIntegration/TestConnectionRecovery.cs
+++ b/projects/Test/SequentialIntegration/TestConnectionRecovery.cs
@@ -40,6 +40,7 @@
using RabbitMQ.Client.Impl;
using Xunit;
using Xunit.Abstractions;
+using QueueDeclareOk = RabbitMQ.Client.QueueDeclareOk;
namespace Test.SequentialIntegration
{
@@ -52,145 +53,158 @@ public TestConnectionRecovery(ITestOutputHelper output) : base(output)
_queueName = $"{nameof(TestConnectionRecovery)}-{Guid.NewGuid()}";
}
- protected override void TearDown()
+ public override async Task DisposeAsync()
{
- var cf = CreateConnectionFactory();
- cf.ClientProvidedName = cf.ClientProvidedName + "-TearDown";
- using IConnection conn = cf.CreateConnection();
- using IChannel ch = conn.CreateChannel();
- ch.QueueDelete(_queueName);
- base.TearDown();
+ ConnectionFactory cf = CreateConnectionFactory();
+ cf.ClientProvidedName += "-TearDown";
+ using (IConnection conn = await cf.CreateConnectionAsync())
+ {
+ using (IChannel ch = await conn.CreateChannelAsync())
+ {
+ await ch.QueueDeleteAsync(_queueName);
+ await ch.CloseAsync();
+ }
+ await conn.CloseAsync();
+ }
+
+ await base.DisposeAsync();
}
[Fact]
- public void TestBasicAckAfterChannelRecovery()
+ public async Task TestBasicAckAfterChannelRecovery()
{
- var allMessagesSeenLatch = new ManualResetEventSlim(false);
- var cons = new AckingBasicConsumer(_channel, _totalMessageCount, allMessagesSeenLatch);
+ var allMessagesSeenTcs = new TaskCompletionSource();
+ var cons = new AckingBasicConsumer(_channel, _totalMessageCount, allMessagesSeenTcs);
- string queueName = _channel.QueueDeclare(_queueName, false, false, false, null).QueueName;
+ QueueDeclareOk q = await _channel.QueueDeclareAsync(_queueName, false, false, false);
+ string queueName = q.QueueName;
Assert.Equal(queueName, _queueName);
- _channel.BasicQos(0, 1, false);
- _channel.BasicConsume(queueName, false, cons);
+ await _channel.BasicQosAsync(0, 1, false);
+ await _channel.BasicConsumeAsync(queueName, false, cons);
- ManualResetEventSlim sl = PrepareForShutdown(_conn);
- ManualResetEventSlim rl = PrepareForRecovery(_conn);
+ TaskCompletionSource sl = PrepareForShutdown(_conn);
+ TaskCompletionSource rl = PrepareForRecovery(_conn);
- PublishMessagesWhileClosingConn(queueName);
+ await PublishMessagesWhileClosingConnAsync(queueName);
- Wait(sl, "connection shutdown");
- Wait(rl, "connection recovery");
- Wait(allMessagesSeenLatch, "all messages seen");
+ await WaitAsync(sl, "connection shutdown");
+ await WaitAsync(rl, "connection recovery");
+ await WaitAsync(allMessagesSeenTcs, "all messages seen");
}
[Fact]
- public void TestBasicNackAfterChannelRecovery()
+ public async Task TestBasicNackAfterChannelRecovery()
{
- var allMessagesSeenLatch = new ManualResetEventSlim(false);
- var cons = new NackingBasicConsumer(_channel, _totalMessageCount, allMessagesSeenLatch);
+ var allMessagesSeenTcs = new TaskCompletionSource();
+ var cons = new NackingBasicConsumer(_channel, _totalMessageCount, allMessagesSeenTcs);
- string queueName = _channel.QueueDeclare(_queueName, false, false, false, null).QueueName;
+ QueueDeclareOk q = await _channel.QueueDeclareAsync(_queueName, false, false, false);
+ string queueName = q.QueueName;
Assert.Equal(queueName, _queueName);
- _channel.BasicQos(0, 1, false);
- _channel.BasicConsume(queueName, false, cons);
+ await _channel.BasicQosAsync(0, 1, false);
+ await _channel.BasicConsumeAsync(queueName, false, cons);
- ManualResetEventSlim sl = PrepareForShutdown(_conn);
- ManualResetEventSlim rl = PrepareForRecovery(_conn);
+ TaskCompletionSource sl = PrepareForShutdown(_conn);
+ TaskCompletionSource rl = PrepareForRecovery(_conn);
- PublishMessagesWhileClosingConn(queueName);
+ await PublishMessagesWhileClosingConnAsync(queueName);
- Wait(sl, "connection shutdown");
- Wait(rl, "connection recovery");
- Wait(allMessagesSeenLatch, "all messages seen");
+ await WaitAsync(sl, "connection shutdown");
+ await WaitAsync(rl, "connection recovery");
+ await WaitAsync(allMessagesSeenTcs, "all messages seen");
}
[Fact]
- public void TestBasicRejectAfterChannelRecovery()
+ public async Task TestBasicRejectAfterChannelRecovery()
{
- var allMessagesSeenLatch = new ManualResetEventSlim(false);
- var cons = new RejectingBasicConsumer(_channel, _totalMessageCount, allMessagesSeenLatch);
+ var allMessagesSeenTcs = new TaskCompletionSource();
+ var cons = new RejectingBasicConsumer(_channel, _totalMessageCount, allMessagesSeenTcs);
- string queueName = _channel.QueueDeclare(_queueName, false, false, false, null).QueueName;
+ string queueName = (await _channel.QueueDeclareAsync(_queueName, false, false, false)).QueueName;
Assert.Equal(queueName, _queueName);
- _channel.BasicQos(0, 1, false);
- _channel.BasicConsume(queueName, false, cons);
+ await _channel.BasicQosAsync(0, 1, false);
+ await _channel.BasicConsumeAsync(queueName, false, cons);
- ManualResetEventSlim sl = PrepareForShutdown(_conn);
- ManualResetEventSlim rl = PrepareForRecovery(_conn);
+ TaskCompletionSource sl = PrepareForShutdown(_conn);
+ TaskCompletionSource rl = PrepareForRecovery(_conn);
- PublishMessagesWhileClosingConn(queueName);
+ await PublishMessagesWhileClosingConnAsync(queueName);
- Wait(sl, "connection shutdown");
- Wait(rl, "connection recovery");
- Wait(allMessagesSeenLatch, "all messages seen");
+ await WaitAsync(sl, "connection shutdown");
+ await WaitAsync(rl, "connection recovery");
+ await WaitAsync(allMessagesSeenTcs, "all messages seen");
}
[Fact]
- public void TestBasicAckAfterBasicGetAndChannelRecovery()
+ public async Task TestBasicAckAfterBasicGetAndChannelRecovery()
{
string q = GenerateQueueName();
- _channel.QueueDeclare(q, false, false, false, null);
+ await _channel.QueueDeclareAsync(q, false, false, false);
// create an offset
- _channel.BasicPublish("", q, _messageBody);
- Thread.Sleep(50);
- BasicGetResult g = _channel.BasicGet(q, false);
- CloseAndWaitForRecovery();
+ await _channel.BasicPublishAsync("", q, _messageBody);
+ await Task.Delay(50);
+ BasicGetResult g = await _channel.BasicGetAsync(q, false);
+ await CloseAndWaitForRecoveryAsync();
Assert.True(_conn.IsOpen);
Assert.True(_channel.IsOpen);
// ack the message after recovery - this should be out of range and ignored
- _channel.BasicAck(g.DeliveryTag, false);
+ await _channel.BasicAckAsync(g.DeliveryTag, false);
// do a sync operation to 'check' there is no channel exception
- _channel.BasicGet(q, false);
+ await _channel.BasicGetAsync(q, false);
}
[Fact]
- public void TestBasicAckEventHandlerRecovery()
+ public async Task TestBasicAckEventHandlerRecovery()
{
- _channel.ConfirmSelect();
- var latch = new ManualResetEventSlim(false);
- ((AutorecoveringChannel)_channel).BasicAcks += (m, args) => latch.Set();
- ((AutorecoveringChannel)_channel).BasicNacks += (m, args) => latch.Set();
+ await _channel.ConfirmSelectAsync();
+ var tcs = new TaskCompletionSource();
+ ((AutorecoveringChannel)_channel).BasicAcks += (m, args) => tcs.SetResult(true);
+ ((AutorecoveringChannel)_channel).BasicNacks += (m, args) => tcs.SetResult(true);
- CloseAndWaitForRecovery();
- CloseAndWaitForRecovery();
+ await CloseAndWaitForRecoveryAsync();
+ await CloseAndWaitForRecoveryAsync();
Assert.True(_channel.IsOpen);
- WithTemporaryNonExclusiveQueue(_channel, (m, q) => m.BasicPublish("", q, _messageBody));
- Wait(latch, "basic acks/nacks");
+ await WithTemporaryNonExclusiveQueueAsync(_channel, (ch, q) =>
+ {
+ return ch.BasicPublishAsync("", q, _messageBody).AsTask();
+ });
+
+ await WaitAsync(tcs, "basic acks/nacks");
}
[Fact]
- public void TestBasicConnectionRecovery()
+ public async Task TestBasicConnectionRecovery()
{
Assert.True(_conn.IsOpen);
- CloseAndWaitForRecovery();
+ await CloseAndWaitForRecoveryAsync();
Assert.True(_conn.IsOpen);
}
[Fact]
- public void TestBasicConnectionRecoveryOnBrokerRestart()
+ public async Task BasicConnectionRecoveryOnBrokerRestart()
{
Assert.True(_conn.IsOpen);
- RestartServerAndWaitForRecovery();
+ await RestartServerAndWaitForRecoveryAsync();
Assert.True(_conn.IsOpen);
}
[Fact]
- public void TestBasicChannelRecovery()
+ public async Task TestBasicChannelRecovery()
{
Assert.True(_channel.IsOpen);
- CloseAndWaitForRecovery();
+ await CloseAndWaitForRecoveryAsync();
Assert.True(_channel.IsOpen);
}
[Fact]
- public void TestBasicChannelRecoveryOnServerRestart()
+ public async Task TestBasicChannelRecoveryOnServerRestart()
{
Assert.True(_channel.IsOpen);
- RestartServerAndWaitForRecovery();
+ await RestartServerAndWaitForRecoveryAsync();
Assert.True(_channel.IsOpen);
}
@@ -215,7 +229,7 @@ void _channel_ChannelShutdown(object sender, ShutdownEventArgs e)
byte[] body = GetRandomBody(64);
- RestartServerAndWaitForRecovery();
+ await RestartServerAndWaitForRecoveryAsync();
Task publishTask = Task.Run(async () =>
{
@@ -242,307 +256,323 @@ void _channel_ChannelShutdown(object sender, ShutdownEventArgs e)
// This is false because the channel has been recovered
Assert.False(_channel.IsClosed);
+ await _channel.CloseAsync();
_channel.Dispose();
Assert.True(_channel.IsClosed);
+ _channel = null;
await publishTask;
}
[Fact]
- public void TestBlockedListenersRecovery()
+ public async Task TestBlockedListenersRecovery()
{
- var latch = new ManualResetEventSlim(false);
- _conn.ConnectionBlocked += (c, reason) => latch.Set();
- CloseAndWaitForRecovery();
- CloseAndWaitForRecovery();
-
- Block();
- Wait(latch, "connection blocked");
-
- Unblock();
+ try
+ {
+ var tcs = new TaskCompletionSource();
+ _conn.ConnectionBlocked += (c, reason) => tcs.SetResult(true);
+ await CloseAndWaitForRecoveryAsync();
+ await CloseAndWaitForRecoveryAsync();
+ await BlockAsync(_channel);
+ await WaitAsync(tcs, "connection blocked");
+ }
+ finally
+ {
+ await UnblockAsync();
+ }
}
[Fact]
- public void TestClientNamedQueueRecovery()
+ public Task TestClientNamedQueueRecovery()
{
string s = "dotnet-client.test.recovery.q1";
- WithTemporaryNonExclusiveQueue(_channel, (m, q) =>
+ return WithTemporaryNonExclusiveQueueAsync(_channel, async (m, q) =>
{
- CloseAndWaitForRecovery();
- AssertQueueRecovery(m, q, false);
- _channel.QueueDelete(q);
+ await CloseAndWaitForRecoveryAsync();
+ await AssertQueueRecoveryAsync(m, q, false);
+ await _channel.QueueDeleteAsync(q);
}, s);
}
[Fact]
- public void TestClientNamedQueueRecoveryNoWait()
+ public Task TestClientNamedQueueRecoveryNoWait()
{
string s = "dotnet-client.test.recovery.q1-nowait";
- WithTemporaryQueueNoWait(_channel, (m, q) =>
+ return WithTemporaryExclusiveQueueNoWaitAsync(_channel, async (ch, q) =>
{
- CloseAndWaitForRecovery();
- AssertQueueRecovery(m, q);
+ await CloseAndWaitForRecoveryAsync();
+ await AssertExclusiveQueueRecoveryAsync(ch, q);
}, s);
}
[Fact]
- public void TestClientNamedQueueRecoveryOnServerRestart()
+ public Task TestClientNamedQueueRecoveryOnServerRestart()
{
string s = "dotnet-client.test.recovery.q1";
- WithTemporaryNonExclusiveQueue(_channel, (m, q) =>
+ return WithTemporaryNonExclusiveQueueAsync(_channel, async (m, q) =>
{
- RestartServerAndWaitForRecovery();
- AssertQueueRecovery(m, q, false);
- _channel.QueueDelete(q);
+ await RestartServerAndWaitForRecoveryAsync();
+ await AssertQueueRecoveryAsync(m, q, false);
+ await _channel.QueueDeleteAsync(q);
}, s);
}
[Fact]
- public void TestConsumerRecoveryWithManyConsumers()
+ public async Task TestConsumerRecoveryWithManyConsumers()
{
- string q = _channel.QueueDeclare(GenerateQueueName(), false, false, false, null).QueueName;
+ string q = (await _channel.QueueDeclareAsync(GenerateQueueName(), false, false, false)).QueueName;
int n = 1024;
for (int i = 0; i < n; i++)
{
var cons = new EventingBasicConsumer(_channel);
- _channel.BasicConsume(q, true, cons);
+ await _channel.BasicConsumeAsync(q, true, cons);
}
- var latch = new ManualResetEventSlim(false);
- ((AutorecoveringConnection)_conn).ConsumerTagChangeAfterRecovery += (prev, current) => latch.Set();
+ var tcs = new TaskCompletionSource();
+ ((AutorecoveringConnection)_conn).ConsumerTagChangeAfterRecovery += (prev, current) => tcs.SetResult(true);
- CloseAndWaitForRecovery();
- Wait(latch, "consumer tag change after recovery");
+ await CloseAndWaitForRecoveryAsync();
+ await WaitAsync(tcs, "consumer tag change after recovery");
Assert.True(_channel.IsOpen);
- AssertConsumerCount(q, n);
+ await AssertConsumerCountAsync(q, n);
}
[Fact]
- public void TestDeclarationOfManyAutoDeleteExchangesWithTransientExchangesThatAreDeleted()
+ public async Task TestDeclarationOfManyAutoDeleteExchangesWithTransientExchangesThatAreDeleted()
{
AssertRecordedExchanges((AutorecoveringConnection)_conn, 0);
for (int i = 0; i < 3; i++)
{
string x1 = $"source-{Guid.NewGuid()}";
- _channel.ExchangeDeclare(x1, "fanout", false, true, null);
+ await _channel.ExchangeDeclareAsync(x1, "fanout", false, true);
+
string x2 = $"destination-{Guid.NewGuid()}";
- _channel.ExchangeDeclare(x2, "fanout", false, false, null);
- _channel.ExchangeBind(x2, x1, "");
- _channel.ExchangeDelete(x2);
+ await _channel.ExchangeDeclareAsync(x2, "fanout", false, false);
+
+ await _channel.ExchangeBindAsync(x2, x1, "");
+ await _channel.ExchangeDeleteAsync(x2);
}
AssertRecordedExchanges((AutorecoveringConnection)_conn, 0);
}
[Fact]
- public void TestDeclarationOfManyAutoDeleteExchangesWithTransientExchangesThatAreUnbound()
+ public async Task TestDeclarationOfManyAutoDeleteExchangesWithTransientExchangesThatAreUnbound()
{
AssertRecordedExchanges((AutorecoveringConnection)_conn, 0);
for (int i = 0; i < 1000; i++)
{
string x1 = $"source-{Guid.NewGuid()}";
- _channel.ExchangeDeclare(x1, "fanout", false, true, null);
+ await _channel.ExchangeDeclareAsync(x1, "fanout", false, true);
string x2 = $"destination-{Guid.NewGuid()}";
- _channel.ExchangeDeclare(x2, "fanout", false, false, null);
- _channel.ExchangeBind(x2, x1, "");
- _channel.ExchangeUnbind(x2, x1, "");
- _channel.ExchangeDelete(x2);
+ await _channel.ExchangeDeclareAsync(x2, "fanout", false, false);
+ await _channel.ExchangeBindAsync(x2, x1, "");
+ await _channel.ExchangeUnbindAsync(x2, x1, "");
+ await _channel.ExchangeDeleteAsync(x2);
}
AssertRecordedExchanges((AutorecoveringConnection)_conn, 0);
}
[Fact]
- public void TestDeclarationOfManyAutoDeleteExchangesWithTransientQueuesThatAreDeleted()
+ public async Task TestDeclarationOfManyAutoDeleteExchangesWithTransientQueuesThatAreDeleted()
{
AssertRecordedExchanges((AutorecoveringConnection)_conn, 0);
for (int i = 0; i < 1000; i++)
{
string x = Guid.NewGuid().ToString();
- _channel.ExchangeDeclare(x, "fanout", false, true, null);
- RabbitMQ.Client.QueueDeclareOk q = _channel.QueueDeclare();
- _channel.QueueBind(q, x, "");
- _channel.QueueDelete(q);
+ await _channel.ExchangeDeclareAsync(x, "fanout", false, true);
+ RabbitMQ.Client.QueueDeclareOk q = await _channel.QueueDeclareAsync();
+ await _channel.QueueBindAsync(q, x, "");
+ await _channel.QueueDeleteAsync(q);
}
AssertRecordedExchanges((AutorecoveringConnection)_conn, 0);
}
[Fact]
- public void TestDeclarationOfManyAutoDeleteExchangesWithTransientQueuesThatAreUnbound()
+ public async Task TestDeclarationOfManyAutoDeleteExchangesWithTransientQueuesThatAreUnbound()
{
AssertRecordedExchanges((AutorecoveringConnection)_conn, 0);
for (int i = 0; i < 1000; i++)
{
string x = Guid.NewGuid().ToString();
- _channel.ExchangeDeclare(x, "fanout", false, true, null);
- RabbitMQ.Client.QueueDeclareOk q = _channel.QueueDeclare();
- _channel.QueueBind(q, x, "");
- _channel.QueueUnbind(q, x, "", null);
+ await _channel.ExchangeDeclareAsync(x, "fanout", false, true);
+ RabbitMQ.Client.QueueDeclareOk q = await _channel.QueueDeclareAsync();
+ await _channel.QueueBindAsync(q, x, "");
+ await _channel.QueueUnbindAsync(q, x, "", null);
}
AssertRecordedExchanges((AutorecoveringConnection)_conn, 0);
}
[Fact]
- public void TestDeclarationOfManyAutoDeleteQueuesWithTransientConsumer()
+ public async Task TestDeclarationOfManyAutoDeleteQueuesWithTransientConsumer()
{
AssertRecordedQueues((AutorecoveringConnection)_conn, 0);
for (int i = 0; i < 1000; i++)
{
string q = Guid.NewGuid().ToString();
- _channel.QueueDeclare(q, false, false, true, null);
+ await _channel.QueueDeclareAsync(q, false, false, true);
var dummy = new EventingBasicConsumer(_channel);
- string tag = _channel.BasicConsume(q, true, dummy);
- _channel.BasicCancel(tag);
+ string tag = await _channel.BasicConsumeAsync(q, true, dummy);
+ await _channel.BasicCancelAsync(tag);
}
AssertRecordedQueues((AutorecoveringConnection)_conn, 0);
}
[Fact]
- public void TestExchangeRecovery()
+ public async Task TestExchangeRecovery()
{
string x = "dotnet-client.test.recovery.x1";
- DeclareNonDurableExchange(_channel, x);
- CloseAndWaitForRecovery();
- AssertExchangeRecovery(_channel, x);
- _channel.ExchangeDelete(x);
+ await DeclareNonDurableExchangeAsync(_channel, x);
+ await CloseAndWaitForRecoveryAsync();
+ await AssertExchangeRecoveryAsync(_channel, x);
+ await _channel.ExchangeDeleteAsync(x);
}
[Fact]
- public void TestExchangeRecoveryWithNoWait()
+ public async Task TestExchangeToExchangeBindingRecovery()
{
- string x = "dotnet-client.test.recovery.x1-nowait";
- DeclareNonDurableExchangeNoWait(_channel, x);
- CloseAndWaitForRecovery();
- AssertExchangeRecovery(_channel, x);
- _channel.ExchangeDelete(x);
- }
-
- [Fact]
- public void TestExchangeToExchangeBindingRecovery()
- {
- string q = _channel.QueueDeclare("", false, false, false, null).QueueName;
+ string q = (await _channel.QueueDeclareAsync("", false, false, false)).QueueName;
string x1 = "amq.fanout";
string x2 = GenerateExchangeName();
- _channel.ExchangeDeclare(x2, "fanout");
- _channel.ExchangeBind(x1, x2, "");
- _channel.QueueBind(q, x1, "");
+ await _channel.ExchangeDeclareAsync(x2, "fanout");
+ await _channel.ExchangeBindAsync(x1, x2, "");
+ await _channel.QueueBindAsync(q, x1, "");
try
{
- CloseAndWaitForRecovery();
+ await CloseAndWaitForRecoveryAsync();
Assert.True(_channel.IsOpen);
- _channel.BasicPublish(x2, "", _encoding.GetBytes("msg"));
- AssertMessageCount(q, 1);
+ await _channel.BasicPublishAsync(x2, "", _encoding.GetBytes("msg"));
+ await AssertMessageCountAsync(q, 1);
}
finally
{
- WithTemporaryChannel(m =>
+ await WithTemporaryChannelAsync(async ch =>
{
- m.ExchangeDelete(x2);
- m.QueueDelete(q);
+ await ch.ExchangeDeleteAsync(x2);
+ await ch.QueueDeleteAsync(q);
});
}
}
[Fact]
- public void TestQueueRecoveryWithManyQueues()
+ public async Task TestQueueRecoveryWithManyQueues()
{
var qs = new List();
int n = 1024;
for (int i = 0; i < n; i++)
{
- qs.Add(_channel.QueueDeclare(GenerateQueueName(), false, false, false, null).QueueName);
+ QueueDeclareOk q = await _channel.QueueDeclareAsync(GenerateQueueName(), false, false, false);
+ qs.Add(q.QueueName);
}
- CloseAndWaitForRecovery();
+ await CloseAndWaitForRecoveryAsync();
Assert.True(_channel.IsOpen);
foreach (string q in qs)
{
- AssertQueueRecovery(_channel, q, false);
- _channel.QueueDelete(q);
+ await AssertQueueRecoveryAsync(_channel, q, false);
+ await _channel.QueueDeleteAsync(q);
}
}
// rabbitmq/rabbitmq-dotnet-client#43
[Fact]
- public void TestClientNamedTransientAutoDeleteQueueAndBindingRecovery()
+ public async Task TestClientNamedTransientAutoDeleteQueueAndBindingRecovery()
{
- string q = Guid.NewGuid().ToString();
- string x = "tmp-fanout";
- IChannel ch = _conn.CreateChannel();
- ch.QueueDelete(q);
- ch.ExchangeDelete(x);
- ch.ExchangeDeclare(exchange: x, type: "fanout");
- ch.QueueDeclare(queue: q, durable: false, exclusive: false, autoDelete: true, arguments: null);
- ch.QueueBind(queue: q, exchange: x, routingKey: "");
- RestartServerAndWaitForRecovery();
- Assert.True(ch.IsOpen);
- ch.ConfirmSelect();
- ch.QueuePurge(q);
- ch.ExchangeDeclare(exchange: x, type: "fanout");
- ch.BasicPublish(exchange: x, routingKey: "", body: _encoding.GetBytes("msg"));
- WaitForConfirms(ch);
- RabbitMQ.Client.QueueDeclareOk ok = ch.QueueDeclare(queue: q, durable: false, exclusive: false, autoDelete: true, arguments: null);
- Assert.Equal(1u, ok.MessageCount);
- ch.QueueDelete(q);
- ch.ExchangeDelete(x);
+ string queueName = GenerateQueueName();
+ string exchangeName = GenerateExchangeName();
+ try
+ {
+ await _channel.QueueDeleteAsync(queueName);
+ await _channel.ExchangeDeleteAsync(exchangeName);
+
+ await _channel.ExchangeDeclareAsync(exchange: exchangeName, type: "fanout");
+ await _channel.QueueDeclareAsync(queue: queueName, durable: false, exclusive: false, autoDelete: true, arguments: null);
+ await _channel.QueueBindAsync(queue: queueName, exchange: exchangeName, routingKey: "");
+
+ await RestartServerAndWaitForRecoveryAsync();
+ Assert.True(_channel.IsOpen);
+
+ await _channel.ConfirmSelectAsync();
+ QueueDeclareOk ok0 = await _channel.QueueDeclarePassiveAsync(queue: queueName);
+ Assert.Equal(queueName, ok0.QueueName);
+ await _channel.QueuePurgeAsync(queueName);
+ await _channel.ExchangeDeclarePassiveAsync(exchange: exchangeName);
+ await _channel.BasicPublishAsync(exchange: exchangeName, routingKey: "", body: _encoding.GetBytes("msg"));
+
+ await WaitForConfirmsWithCancellationAsync(_channel);
+
+ QueueDeclareOk ok1 = await _channel.QueueDeclarePassiveAsync(queue: queueName);
+ Assert.Equal(1u, ok1.MessageCount);
+ }
+ finally
+ {
+ await _channel.QueueDeleteAsync(queueName);
+ await _channel.ExchangeDeleteAsync(exchangeName);
+ }
}
// rabbitmq/rabbitmq-dotnet-client#43
[Fact]
- public void TestServerNamedTransientAutoDeleteQueueAndBindingRecovery()
+ public async Task TestServerNamedTransientAutoDeleteQueueAndBindingRecovery()
{
string x = "tmp-fanout";
- _channel.ExchangeDelete(x);
- _channel.ExchangeDeclare(exchange: x, type: "fanout");
- string q = _channel.QueueDeclare(queue: "", durable: false, exclusive: false, autoDelete: true, arguments: null).QueueName;
+ await _channel.ExchangeDeleteAsync(x);
+ await _channel.ExchangeDeclareAsync(exchange: x, type: "fanout");
+ string q = (await _channel.QueueDeclareAsync(queue: "", durable: false, exclusive: false, autoDelete: true, arguments: null)).QueueName;
string nameBefore = q;
string nameAfter = null;
- var latch = new ManualResetEventSlim(false);
+ var tcs = new TaskCompletionSource();
+
((AutorecoveringConnection)_conn).QueueNameChangedAfterRecovery += (source, ea) =>
{
nameBefore = ea.NameBefore;
nameAfter = ea.NameAfter;
- latch.Set();
+ tcs.SetResult(true);
};
- _channel.QueueBind(queue: nameBefore, exchange: x, routingKey: "");
- RestartServerAndWaitForRecovery();
- Wait(latch, "queue name change after recovery");
+
+ await _channel.QueueBindAsync(queue: nameBefore, exchange: x, routingKey: "");
+ await RestartServerAndWaitForRecoveryAsync();
+
+ await WaitAsync(tcs, "queue name change after recovery");
Assert.True(_channel.IsOpen);
Assert.NotEqual(nameBefore, nameAfter);
- _channel.ConfirmSelect();
- _channel.ExchangeDeclare(exchange: x, type: "fanout");
- _channel.BasicPublish(exchange: x, routingKey: "", body: _encoding.GetBytes("msg"));
- WaitForConfirms(_channel);
- RabbitMQ.Client.QueueDeclareOk ok = _channel.QueueDeclarePassive(nameAfter);
+
+ await _channel.ConfirmSelectAsync();
+ await _channel.ExchangeDeclareAsync(exchange: x, type: "fanout");
+ await _channel.BasicPublishAsync(exchange: x, routingKey: "", body: _encoding.GetBytes("msg"));
+ await WaitForConfirmsWithCancellationAsync(_channel);
+
+ QueueDeclareOk ok = await _channel.QueueDeclarePassiveAsync(nameAfter);
Assert.Equal(1u, ok.MessageCount);
- _channel.QueueDelete(q);
- _channel.ExchangeDelete(x);
+ await _channel.QueueDeleteAsync(q);
+ await _channel.ExchangeDeleteAsync(x);
}
[Fact]
- public void TestRecoveryEventHandlersOnConnection()
+ public async Task TestRecoveryEventHandlersOnConnection()
{
int counter = 0;
((AutorecoveringConnection)_conn).RecoverySucceeded += (source, ea) => Interlocked.Increment(ref counter);
- CloseAndWaitForRecovery();
- CloseAndWaitForRecovery();
- CloseAndWaitForRecovery();
- CloseAndWaitForRecovery();
+ await CloseAndWaitForRecoveryAsync();
+ await CloseAndWaitForRecoveryAsync();
+ await CloseAndWaitForRecoveryAsync();
+ await CloseAndWaitForRecoveryAsync();
Assert.True(_conn.IsOpen);
Assert.True(counter >= 3);
}
[Fact]
- public void TestRecoveryEventHandlersOnChannel()
+ public async Task TestRecoveryEventHandlersOnChannel()
{
int counter = 0;
((AutorecoveringChannel)_channel).Recovery += (source, ea) => Interlocked.Increment(ref counter);
- CloseAndWaitForRecovery();
- CloseAndWaitForRecovery();
- CloseAndWaitForRecovery();
- CloseAndWaitForRecovery();
+ await CloseAndWaitForRecoveryAsync();
+ await CloseAndWaitForRecoveryAsync();
+ await CloseAndWaitForRecoveryAsync();
+ await CloseAndWaitForRecoveryAsync();
Assert.True(_channel.IsOpen);
Assert.True(counter >= 3);
}
@@ -550,30 +580,30 @@ public void TestRecoveryEventHandlersOnChannel()
[Theory]
[InlineData(1)]
[InlineData(3)]
- public void TestRecoveringConsumerHandlerOnConnection(int iterations)
+ public async Task TestRecoveringConsumerHandlerOnConnection(int iterations)
{
- string q = _channel.QueueDeclare(GenerateQueueName(), false, false, false, null).QueueName;
+ string q = (await _channel.QueueDeclareAsync(GenerateQueueName(), false, false, false)).QueueName;
var cons = new EventingBasicConsumer(_channel);
- _channel.BasicConsume(q, true, cons);
+ await _channel.BasicConsumeAsync(q, true, cons);
int counter = 0;
((AutorecoveringConnection)_conn).RecoveringConsumer += (sender, args) => Interlocked.Increment(ref counter);
for (int i = 0; i < iterations; i++)
{
- CloseAndWaitForRecovery();
+ await CloseAndWaitForRecoveryAsync();
}
Assert.Equal(iterations, counter);
}
[Fact]
- public void TestRecoveringConsumerHandlerOnConnection_EventArgumentsArePassedDown()
+ public async Task TestRecoveringConsumerHandlerOnConnection_EventArgumentsArePassedDown()
{
var myArgs = new Dictionary { { "first-argument", "some-value" } };
- string q = _channel.QueueDeclare(GenerateQueueName(), false, false, false, null).QueueName;
+ string q = (await _channel.QueueDeclareAsync(GenerateQueueName(), false, false, false)).QueueName;
var cons = new EventingBasicConsumer(_channel);
- string expectedCTag = _channel.BasicConsume(cons, q, arguments: myArgs);
+ string expectedCTag = await _channel.BasicConsumeAsync(cons, q, arguments: myArgs);
bool ctagMatches = false;
bool consumerArgumentMatches = false;
@@ -587,7 +617,7 @@ public void TestRecoveringConsumerHandlerOnConnection_EventArgumentsArePassedDow
args.ConsumerArguments["first-argument"] = "event-handler-set-this-value";
};
- CloseAndWaitForRecovery();
+ await CloseAndWaitForRecoveryAsync();
Assert.True(ctagMatches, "expected consumer tag to match");
Assert.True(consumerArgumentMatches, "expected consumer arguments to match");
string actualVal = (string)Assert.Contains("first-argument", myArgs as IDictionary);
@@ -595,151 +625,152 @@ public void TestRecoveringConsumerHandlerOnConnection_EventArgumentsArePassedDow
}
[Fact]
- public void TestServerNamedQueueRecovery()
+ public async Task TestServerNamedQueueRecovery()
{
- string q = _channel.QueueDeclare("", false, false, false, null).QueueName;
+ string q = (await _channel.QueueDeclareAsync("", false, false, false)).QueueName;
string x = "amq.fanout";
- _channel.QueueBind(q, x, "");
+ await _channel.QueueBindAsync(q, x, "");
string nameBefore = q;
string nameAfter = null;
- var latch = new ManualResetEventSlim(false);
+ var tcs = new TaskCompletionSource();
var connection = (AutorecoveringConnection)_conn;
- connection.RecoverySucceeded += (source, ea) => latch.Set();
+ connection.RecoverySucceeded += (source, ea) => tcs.SetResult(true);
connection.QueueNameChangedAfterRecovery += (source, ea) => { nameAfter = ea.NameAfter; };
- CloseAndWaitForRecovery();
- Wait(latch, "recovery succeeded");
+ await CloseAndWaitForRecoveryAsync();
+ await WaitAsync(tcs, "recovery succeeded");
Assert.NotNull(nameAfter);
Assert.StartsWith("amq.", nameBefore);
Assert.StartsWith("amq.", nameAfter);
Assert.NotEqual(nameBefore, nameAfter);
- _channel.QueueDeclarePassive(nameAfter);
+ await _channel.QueueDeclarePassiveAsync(nameAfter);
}
[Fact]
- public void TestShutdownEventHandlersRecoveryOnConnection()
+ public async Task TestShutdownEventHandlersRecoveryOnConnection()
{
int counter = 0;
_conn.ConnectionShutdown += (c, args) => Interlocked.Increment(ref counter);
Assert.True(_conn.IsOpen);
- CloseAndWaitForRecovery();
- CloseAndWaitForRecovery();
- CloseAndWaitForRecovery();
- CloseAndWaitForRecovery();
+ await CloseAndWaitForRecoveryAsync();
+ await CloseAndWaitForRecoveryAsync();
+ await CloseAndWaitForRecoveryAsync();
+ await CloseAndWaitForRecoveryAsync();
Assert.True(_conn.IsOpen);
Assert.True(counter >= 3);
}
[Fact]
- public void TestShutdownEventHandlersRecoveryOnConnectionAfterDelayedServerRestart()
+ public async Task TestShutdownEventHandlersRecoveryOnConnectionAfterDelayedServerRestart()
{
int counter = 0;
_conn.ConnectionShutdown += (c, args) => Interlocked.Increment(ref counter);
- ManualResetEventSlim shutdownLatch = PrepareForShutdown(_conn);
- ManualResetEventSlim recoveryLatch = PrepareForRecovery((AutorecoveringConnection)_conn);
+ TaskCompletionSource shutdownLatch = PrepareForShutdown(_conn);
+ TaskCompletionSource recoveryLatch = PrepareForRecovery((AutorecoveringConnection)_conn);
Assert.True(_conn.IsOpen);
try
{
- StopRabbitMQ();
- Thread.Sleep(7000);
+ await StopRabbitMqAsync();
+ await Task.Delay(TimeSpan.FromSeconds(7));
}
finally
{
- StartRabbitMQ();
+ await StartRabbitMqAsync();
}
- Wait(shutdownLatch, WaitSpan, "connection shutdown");
- Wait(recoveryLatch, WaitSpan, "connection recovery");
+ await WaitAsync(shutdownLatch, WaitSpan, "connection shutdown");
+ await WaitAsync(recoveryLatch, WaitSpan, "connection recovery");
Assert.True(_conn.IsOpen);
Assert.True(counter >= 1);
}
[Fact]
- public void TestShutdownEventHandlersRecoveryOnChannel()
+ public async Task TestShutdownEventHandlersRecoveryOnChannel()
{
int counter = 0;
_channel.ChannelShutdown += (c, args) => Interlocked.Increment(ref counter);
Assert.True(_channel.IsOpen);
- CloseAndWaitForRecovery();
- CloseAndWaitForRecovery();
- CloseAndWaitForRecovery();
- CloseAndWaitForRecovery();
+ await CloseAndWaitForRecoveryAsync();
+ await CloseAndWaitForRecoveryAsync();
+ await CloseAndWaitForRecoveryAsync();
+ await CloseAndWaitForRecoveryAsync();
Assert.True(_channel.IsOpen);
Assert.True(counter >= 3);
}
[Fact]
- public void TestRecoverTopologyOnDisposedChannel()
+ public async Task TestRecoverTopologyOnDisposedChannel()
{
string x = GenerateExchangeName();
string q = GenerateQueueName();
const string rk = "routing-key";
- using (IChannel ch = _conn.CreateChannel())
+ using (IChannel ch = await _conn.CreateChannelAsync())
{
- ch.ExchangeDeclare(exchange: x, type: "fanout");
- ch.QueueDeclare(q, false, false, false, null);
- ch.QueueBind(q, x, rk);
+ await ch.ExchangeDeclareAsync(exchange: x, type: "fanout");
+ await ch.QueueDeclareAsync(q, false, false, false);
+ await ch.QueueBindAsync(q, x, rk);
+ await ch.CloseAsync();
}
var cons = new EventingBasicConsumer(_channel);
- _channel.BasicConsume(q, true, cons);
- AssertConsumerCount(_channel, q, 1);
+ await _channel.BasicConsumeAsync(q, true, cons);
+ await AssertConsumerCountAsync(_channel, q, 1);
- CloseAndWaitForRecovery();
- AssertConsumerCount(_channel, q, 1);
+ await CloseAndWaitForRecoveryAsync();
+ await AssertConsumerCountAsync(_channel, q, 1);
- var latch = new ManualResetEventSlim(false);
- cons.Received += (s, args) => latch.Set();
+ var tcs = new TaskCompletionSource();
+ cons.Received += (s, args) => tcs.SetResult(true);
- _channel.BasicPublish("", q, _messageBody);
- Wait(latch, "received event");
+ await _channel.BasicPublishAsync("", q, _messageBody);
+ await WaitAsync(tcs, "received event");
- _channel.QueueUnbind(q, x, rk);
- _channel.ExchangeDelete(x);
- _channel.QueueDelete(q);
+ await _channel.QueueUnbindAsync(q, x, rk);
+ await _channel.ExchangeDeleteAsync(x);
+ await _channel.QueueDeleteAsync(q);
}
- [Fact(Skip = "TODO-FLAKY")]
- public void TestPublishRpcRightAfterReconnect()
+ [Fact]
+ public async Task TestPublishRpcRightAfterReconnect()
{
string testQueueName = $"dotnet-client.test.{nameof(TestPublishRpcRightAfterReconnect)}";
- _channel.QueueDeclare(testQueueName, false, false, false, null);
+ await _channel.QueueDeclareAsync(testQueueName, false, false, false);
var replyConsumer = new EventingBasicConsumer(_channel);
- _channel.BasicConsume("amq.rabbitmq.reply-to", true, replyConsumer);
+ await _channel.BasicConsumeAsync("amq.rabbitmq.reply-to", true, replyConsumer);
var properties = new BasicProperties();
properties.ReplyTo = "amq.rabbitmq.reply-to";
TimeSpan doneSpan = TimeSpan.FromMilliseconds(100);
- var done = new ManualResetEventSlim(false);
- Task.Run(() =>
+ var doneTcs = new TaskCompletionSource();
+ Task closeTask = Task.Run(async () =>
{
try
{
- CloseAndWaitForRecovery();
+ await CloseAndWaitForRecoveryAsync();
}
finally
{
- done.Set();
+ doneTcs.SetResult(true);
}
});
- while (!done.IsSet)
+ while (false == doneTcs.Task.IsCompletedSuccessfully())
{
try
{
- _channel.BasicPublish(string.Empty, testQueueName, properties, _messageBody);
+ await _channel.BasicPublishAsync(string.Empty, testQueueName, properties, _messageBody);
}
catch (Exception e)
{
@@ -749,68 +780,77 @@ public void TestPublishRpcRightAfterReconnect()
Assert.NotEqual(406, a.ShutdownReason.ReplyCode);
}
}
- done.Wait(doneSpan);
+
+ try
+ {
+ await doneTcs.Task.WaitAsync(doneSpan);
+ }
+ catch (TimeoutException)
+ {
+ }
}
+
+ await closeTask;
}
[Fact]
- public void TestThatCancelledConsumerDoesNotReappearOnRecovery()
+ public async Task TestThatCancelledConsumerDoesNotReappearOnRecovery()
{
- string q = _channel.QueueDeclare(GenerateQueueName(), false, false, false, null).QueueName;
+ string q = (await _channel.QueueDeclareAsync(GenerateQueueName(), false, false, false)).QueueName;
int n = 1024;
for (int i = 0; i < n; i++)
{
var cons = new EventingBasicConsumer(_channel);
- string tag = _channel.BasicConsume(q, true, cons);
- _channel.BasicCancel(tag);
+ string tag = await _channel.BasicConsumeAsync(q, true, cons);
+ await _channel.BasicCancelAsync(tag);
}
- CloseAndWaitForRecovery();
+ await CloseAndWaitForRecoveryAsync();
Assert.True(_channel.IsOpen);
- AssertConsumerCount(q, 0);
+ await AssertConsumerCountAsync(q, 0);
}
[Fact]
- public void TestThatDeletedExchangeBindingsDontReappearOnRecovery()
+ public async Task TestThatDeletedExchangeBindingsDontReappearOnRecovery()
{
- string q = _channel.QueueDeclare("", false, false, false, null).QueueName;
+ string q = (await _channel.QueueDeclareAsync("", false, false, false)).QueueName;
string x1 = "amq.fanout";
string x2 = GenerateExchangeName();
- _channel.ExchangeDeclare(x2, "fanout");
- _channel.ExchangeBind(x1, x2, "");
- _channel.QueueBind(q, x1, "");
- _channel.ExchangeUnbind(x1, x2, "", null);
+ await _channel.ExchangeDeclareAsync(x2, "fanout");
+ await _channel.ExchangeBindAsync(x1, x2, "");
+ await _channel.QueueBindAsync(q, x1, "");
+ await _channel.ExchangeUnbindAsync(x1, x2, "");
try
{
- CloseAndWaitForRecovery();
+ await CloseAndWaitForRecoveryAsync();
Assert.True(_channel.IsOpen);
- _channel.BasicPublish(x2, "", _encoding.GetBytes("msg"));
- AssertMessageCount(q, 0);
+ await _channel.BasicPublishAsync(x2, "", _encoding.GetBytes("msg"));
+ await AssertMessageCountAsync(q, 0);
}
finally
{
- WithTemporaryChannel(m =>
+ await WithTemporaryChannelAsync(async ch =>
{
- m.ExchangeDelete(x2);
- m.QueueDelete(q);
+ await ch.ExchangeDeleteAsync(x2);
+ await ch.QueueDeleteAsync(q);
});
}
}
[Fact]
- public void TestThatDeletedExchangesDontReappearOnRecovery()
+ public async Task TestThatDeletedExchangesDontReappearOnRecovery()
{
string x = GenerateExchangeName();
- _channel.ExchangeDeclare(x, "fanout");
- _channel.ExchangeDelete(x);
+ await _channel.ExchangeDeclareAsync(x, "fanout");
+ await _channel.ExchangeDeleteAsync(x);
try
{
- CloseAndWaitForRecovery();
+ await CloseAndWaitForRecoveryAsync();
Assert.True(_channel.IsOpen);
- _channel.ExchangeDeclarePassive(x);
+ await _channel.ExchangeDeclarePassiveAsync(x);
Assert.Fail("Expected an exception");
}
catch (OperationInterruptedException e)
@@ -821,46 +861,46 @@ public void TestThatDeletedExchangesDontReappearOnRecovery()
}
[Fact]
- public void TestThatDeletedQueueBindingsDontReappearOnRecovery()
+ public async Task TestThatDeletedQueueBindingsDontReappearOnRecovery()
{
- string q = _channel.QueueDeclare("", false, false, false, null).QueueName;
+ string q = (await _channel.QueueDeclareAsync("", false, false, false)).QueueName;
string x1 = "amq.fanout";
string x2 = GenerateExchangeName();
- _channel.ExchangeDeclare(x2, "fanout");
- _channel.ExchangeBind(x1, x2, "");
- _channel.QueueBind(q, x1, "");
- _channel.QueueUnbind(q, x1, "", null);
+ await _channel.ExchangeDeclareAsync(x2, "fanout");
+ await _channel.ExchangeBindAsync(x1, x2, "");
+ await _channel.QueueBindAsync(q, x1, "");
+ await _channel.QueueUnbindAsync(q, x1, "", null);
try
{
- CloseAndWaitForRecovery();
+ await CloseAndWaitForRecoveryAsync();
Assert.True(_channel.IsOpen);
- _channel.BasicPublish(x2, "", _encoding.GetBytes("msg"));
- AssertMessageCount(q, 0);
+ await _channel.BasicPublishAsync(x2, "", _encoding.GetBytes("msg"));
+ await AssertMessageCountAsync(q, 0);
}
finally
{
- WithTemporaryChannel(m =>
+ await WithTemporaryChannelAsync(async ch =>
{
- m.ExchangeDelete(x2);
- m.QueueDelete(q);
+ await ch.ExchangeDeleteAsync(x2);
+ await ch.QueueDeleteAsync(q);
});
}
}
[Fact]
- public void TestThatDeletedQueuesDontReappearOnRecovery()
+ public async Task TestThatDeletedQueuesDontReappearOnRecovery()
{
string q = "dotnet-client.recovery.q1";
- _channel.QueueDeclare(q, false, false, false, null);
- _channel.QueueDelete(q);
+ await _channel.QueueDeclareAsync(q, false, false, false);
+ await _channel.QueueDeleteAsync(q);
try
{
- CloseAndWaitForRecovery();
+ await CloseAndWaitForRecoveryAsync();
Assert.True(_channel.IsOpen);
- _channel.QueueDeclarePassive(q);
+ await _channel.QueueDeclarePassiveAsync(q);
Assert.Fail("Expected an exception");
}
catch (OperationInterruptedException e)
@@ -871,75 +911,78 @@ public void TestThatDeletedQueuesDontReappearOnRecovery()
}
[Fact]
- public void TestUnblockedListenersRecovery()
+ public async Task TestUnblockedListenersRecovery()
{
- var latch = new ManualResetEventSlim(false);
- _conn.ConnectionUnblocked += (source, ea) => latch.Set();
- CloseAndWaitForRecovery();
- CloseAndWaitForRecovery();
-
- Block();
- Unblock();
- Wait(latch, "connection unblocked");
+ var tcs = new TaskCompletionSource();
+ _conn.ConnectionUnblocked += (source, ea) => tcs.SetResult(true);
+ await CloseAndWaitForRecoveryAsync();
+ await CloseAndWaitForRecoveryAsync();
+ await BlockAsync(_channel);
+ await UnblockAsync();
+ await WaitAsync(tcs, "connection unblocked");
}
[Fact]
- public void TestBindingRecovery_GH1035()
+ public async Task TestBindingRecovery_GH1035()
{
const string routingKey = "unused";
byte[] body = GetRandomBody();
- using var receivedMessageEvent = new AutoResetEvent(initialState: false);
+ var receivedMessageSemaphore = new SemaphoreSlim(0, 1);
void MessageReceived(object sender, BasicDeliverEventArgs e)
{
- receivedMessageEvent.Set();
+ receivedMessageSemaphore.Release();
}
string exchangeName = $"ex-gh-1035-{Guid.NewGuid()}";
string queueName = $"q-gh-1035-{Guid.NewGuid()}";
- _channel.ExchangeDeclare(exchange: exchangeName,
+ await _channel.ExchangeDeclareAsync(exchange: exchangeName,
type: "fanout", durable: false, autoDelete: true,
arguments: null);
- RabbitMQ.Client.QueueDeclareOk q0 = _channel.QueueDeclare(queue: queueName, exclusive: true);
+ QueueDeclareOk q0 = await _channel.QueueDeclareAsync(queue: queueName, exclusive: true);
Assert.Equal(queueName, q0);
- _channel.QueueBind(queue: queueName, exchange: exchangeName, routingKey: routingKey);
+ await _channel.QueueBindAsync(queue: queueName, exchange: exchangeName, routingKey: routingKey);
+ await _channel.CloseAsync();
_channel.Dispose();
+ _channel = null;
- _channel = _conn.CreateChannel();
+ _channel = await _conn.CreateChannelAsync();
- _channel.ExchangeDeclare(exchange: exchangeName,
+ await _channel.ExchangeDeclareAsync(exchange: exchangeName,
type: "fanout", durable: false, autoDelete: true,
arguments: null);
- RabbitMQ.Client.QueueDeclareOk q1 = _channel.QueueDeclare(queue: queueName, exclusive: true);
+ QueueDeclareOk q1 = await _channel.QueueDeclareAsync(queue: queueName, exclusive: true);
Assert.Equal(queueName, q1.QueueName);
- _channel.QueueBind(queue: queueName, exchange: exchangeName, routingKey: routingKey);
+ await _channel.QueueBindAsync(queue: queueName, exchange: exchangeName, routingKey: routingKey);
var c = new EventingBasicConsumer(_channel);
c.Received += MessageReceived;
- _channel.BasicConsume(queue: queueName, autoAck: true, consumer: c);
+ await _channel.BasicConsumeAsync(queue: queueName, autoAck: true, consumer: c);
- using (IChannel pubCh = _conn.CreateChannel())
+ using (IChannel pubCh = await _conn.CreateChannelAsync())
{
- pubCh.BasicPublish(exchange: exchangeName, routingKey: routingKey, body: body);
+ await pubCh.BasicPublishAsync(exchange: exchangeName, routingKey: routingKey, body: body);
+ await pubCh.CloseAsync();
}
- Assert.True(receivedMessageEvent.WaitOne(WaitSpan));
+ Assert.True(await receivedMessageSemaphore.WaitAsync(WaitSpan));
- CloseAndWaitForRecovery();
+ await CloseAndWaitForRecoveryAsync();
- using (IChannel pubCh = _conn.CreateChannel())
+ using (IChannel pubCh = await _conn.CreateChannelAsync())
{
- pubCh.BasicPublish(exchange: exchangeName, routingKey: "unused", body: body);
+ await pubCh.BasicPublishAsync(exchange: exchangeName, routingKey: "unused", body: body);
+ await pubCh.CloseAsync();
}
- Assert.True(receivedMessageEvent.WaitOne(WaitSpan));
+ Assert.True(await receivedMessageSemaphore.WaitAsync(WaitSpan));
}
}
}
diff --git a/projects/Test/SequentialIntegration/TestConnectionRecoveryBase.cs b/projects/Test/SequentialIntegration/TestConnectionRecoveryBase.cs
index 117a1717db..5d7d495136 100644
--- a/projects/Test/SequentialIntegration/TestConnectionRecoveryBase.cs
+++ b/projects/Test/SequentialIntegration/TestConnectionRecoveryBase.cs
@@ -32,6 +32,7 @@
using System;
using System.Collections.Generic;
using System.Threading;
+using System.Threading.Tasks;
using RabbitMQ.Client;
using RabbitMQ.Client.Framing.Impl;
using Xunit;
@@ -42,7 +43,7 @@ namespace Test.SequentialIntegration
public class TestConnectionRecoveryBase : SequentialIntegrationFixture
{
protected readonly byte[] _messageBody;
- protected const ushort _totalMessageCount = 8192;
+ protected const ushort _totalMessageCount = 16384;
protected const ushort _closeAtCount = 16;
public TestConnectionRecoveryBase(ITestOutputHelper output) : base(output)
@@ -50,54 +51,60 @@ public TestConnectionRecoveryBase(ITestOutputHelper output) : base(output)
_messageBody = GetRandomBody(4096);
}
- protected override void TearDown()
+ public override async Task DisposeAsync()
{
- Unblock();
+ await UnblockAsync();
+ await base.DisposeAsync();
}
- protected void AssertConsumerCount(string q, int count)
+ protected Task AssertConsumerCountAsync(string q, int count)
{
- WithTemporaryChannel((m) =>
+ return WithTemporaryChannelAsync(async ch =>
{
- RabbitMQ.Client.QueueDeclareOk ok = m.QueueDeclarePassive(q);
+ RabbitMQ.Client.QueueDeclareOk ok = await ch.QueueDeclarePassiveAsync(q);
Assert.Equal((uint)count, ok.ConsumerCount);
});
}
- protected void AssertConsumerCount(IChannel m, string q, uint count)
+ protected async Task AssertConsumerCountAsync(IChannel ch, string q, uint count)
{
- RabbitMQ.Client.QueueDeclareOk ok = m.QueueDeclarePassive(q);
+ RabbitMQ.Client.QueueDeclareOk ok = await ch.QueueDeclarePassiveAsync(q);
Assert.Equal(count, ok.ConsumerCount);
}
- protected void AssertExchangeRecovery(IChannel m, string x)
+ protected async Task AssertExchangeRecoveryAsync(IChannel m, string x)
{
- m.ConfirmSelect();
- WithTemporaryNonExclusiveQueue(m, (_, q) =>
+ await m.ConfirmSelectAsync();
+ await WithTemporaryNonExclusiveQueueAsync(m, async (_, q) =>
{
string rk = "routing-key";
- m.QueueBind(q, x, rk);
- m.BasicPublish(x, rk, _messageBody);
+ await m.QueueBindAsync(q, x, rk);
+ await m.BasicPublishAsync(x, rk, _messageBody);
- Assert.True(WaitForConfirms(m));
- m.ExchangeDeclarePassive(x);
+ Assert.True(await TestConnectionRecoveryBase.WaitForConfirmsWithCancellationAsync(m));
+ await m.ExchangeDeclarePassiveAsync(x);
});
}
- protected void AssertQueueRecovery(IChannel m, string q)
+ protected Task AssertExclusiveQueueRecoveryAsync(IChannel m, string q)
{
- AssertQueueRecovery(m, q, true);
+ return AssertQueueRecoveryAsync(m, q, true);
}
- protected void AssertQueueRecovery(IChannel m, string q, bool exclusive, IDictionary arguments = null)
+ protected async Task AssertQueueRecoveryAsync(IChannel ch, string q, bool exclusive, IDictionary arguments = null)
{
- m.ConfirmSelect();
- m.QueueDeclarePassive(q);
- RabbitMQ.Client.QueueDeclareOk ok1 = m.QueueDeclare(q, false, exclusive, false, arguments);
+ await ch.ConfirmSelectAsync();
+ await ch.QueueDeclareAsync(queue: q, passive: true, durable: false, exclusive: false, autoDelete: false, arguments: null);
+
+ RabbitMQ.Client.QueueDeclareOk ok1 = await ch.QueueDeclareAsync(queue: q, passive: false,
+ durable: false, exclusive: exclusive, autoDelete: false, arguments: arguments);
Assert.Equal(0u, ok1.MessageCount);
- m.BasicPublish("", q, _messageBody);
- Assert.True(WaitForConfirms(m));
- RabbitMQ.Client.QueueDeclareOk ok2 = m.QueueDeclare(q, false, exclusive, false, arguments);
+
+ await ch.BasicPublishAsync("", q, _messageBody);
+ Assert.True(await WaitForConfirmsWithCancellationAsync(ch));
+
+ RabbitMQ.Client.QueueDeclareOk ok2 = await ch.QueueDeclareAsync(queue: q, passive: false,
+ durable: false, exclusive: exclusive, autoDelete: false, arguments: arguments);
Assert.Equal(1u, ok2.MessageCount);
}
@@ -111,20 +118,21 @@ internal void AssertRecordedQueues(AutorecoveringConnection c, int n)
Assert.Equal(n, c.RecordedQueuesCount);
}
- internal AutorecoveringConnection CreateAutorecoveringConnection()
+ internal Task CreateAutorecoveringConnectionAsync()
{
- return CreateAutorecoveringConnection(RecoveryInterval);
+ return CreateAutorecoveringConnectionAsync(RecoveryInterval);
}
- internal AutorecoveringConnection CreateAutorecoveringConnection(TimeSpan networkRecoveryInterval)
+ internal async Task CreateAutorecoveringConnectionAsync(TimeSpan networkRecoveryInterval)
{
var cf = CreateConnectionFactory();
cf.AutomaticRecoveryEnabled = true;
cf.NetworkRecoveryInterval = networkRecoveryInterval;
- return (AutorecoveringConnection)cf.CreateConnection();
+ IConnection conn = await cf.CreateConnectionAsync();
+ return (AutorecoveringConnection)conn;
}
- internal AutorecoveringConnection CreateAutorecoveringConnection(IList endpoints)
+ internal async Task CreateAutorecoveringConnectionAsync(IList endpoints)
{
var cf = CreateConnectionFactory();
cf.AutomaticRecoveryEnabled = true;
@@ -132,257 +140,282 @@ internal AutorecoveringConnection CreateAutorecoveringConnection(IList CreateAutorecoveringConnectionWithTopologyRecoveryDisabledAsync()
{
var cf = CreateConnectionFactory();
cf.AutomaticRecoveryEnabled = true;
cf.TopologyRecoveryEnabled = false;
cf.NetworkRecoveryInterval = RecoveryInterval;
- return (AutorecoveringConnection)cf.CreateConnection();
+ IConnection conn = await cf.CreateConnectionAsync();
+ return (AutorecoveringConnection)conn;
}
- internal AutorecoveringConnection CreateAutorecoveringConnectionWithTopologyRecoveryFilter(TopologyRecoveryFilter filter)
+ internal async Task CreateAutorecoveringConnectionWithTopologyRecoveryFilterAsync(TopologyRecoveryFilter filter)
{
var cf = CreateConnectionFactory();
cf.AutomaticRecoveryEnabled = true;
cf.TopologyRecoveryEnabled = true;
cf.TopologyRecoveryFilter = filter;
- return (AutorecoveringConnection)cf.CreateConnection();
+ IConnection conn = await cf.CreateConnectionAsync();
+ return (AutorecoveringConnection)conn;
}
- internal AutorecoveringConnection CreateAutorecoveringConnectionWithTopologyRecoveryExceptionHandler(TopologyRecoveryExceptionHandler handler)
+ internal async Task CreateAutorecoveringConnectionWithTopologyRecoveryExceptionHandlerAsync(TopologyRecoveryExceptionHandler handler)
{
var cf = CreateConnectionFactory();
cf.AutomaticRecoveryEnabled = true;
cf.TopologyRecoveryEnabled = true;
cf.TopologyRecoveryExceptionHandler = handler;
- return (AutorecoveringConnection)cf.CreateConnection();
+ IConnection conn = await cf.CreateConnectionAsync();
+ return (AutorecoveringConnection)conn;
}
- protected void CloseConnection(IConnection conn)
+ protected Task CloseConnectionAsync(IConnection conn)
{
- _rabbitMQCtl.CloseConnection(conn);
+ return _rabbitMQCtl.CloseConnectionAsync(conn);
}
- protected void CloseAndWaitForRecovery()
+ protected Task CloseAndWaitForRecoveryAsync()
{
- CloseAndWaitForRecovery((AutorecoveringConnection)_conn);
+ return CloseAndWaitForRecoveryAsync((AutorecoveringConnection)_conn);
}
- internal void CloseAndWaitForRecovery(AutorecoveringConnection conn)
+ internal async Task CloseAndWaitForRecoveryAsync(AutorecoveringConnection conn)
{
- ManualResetEventSlim sl = PrepareForShutdown(conn);
- ManualResetEventSlim rl = PrepareForRecovery(conn);
- CloseConnection(conn);
- Wait(sl, "connection shutdown");
- Wait(rl, "connection recovery");
+ TaskCompletionSource sl = PrepareForShutdown(conn);
+ TaskCompletionSource rl = PrepareForRecovery(conn);
+ await CloseConnectionAsync(conn);
+ await WaitAsync(sl, "connection shutdown");
+ await WaitAsync(rl, "connection recovery");
}
- internal void CloseAndWaitForShutdown(AutorecoveringConnection conn)
+ internal async Task CloseAndWaitForShutdownAsync(AutorecoveringConnection conn)
{
- ManualResetEventSlim sl = PrepareForShutdown(conn);
- CloseConnection(conn);
- Wait(sl, "connection shutdown");
+ TaskCompletionSource sl = PrepareForShutdown(conn);
+ await CloseConnectionAsync(conn);
+ await WaitAsync(sl, "connection shutdown");
}
- protected string DeclareNonDurableExchange(IChannel m, string x)
+ protected static async Task DeclareNonDurableExchangeAsync(IChannel ch, string exchangeName)
{
- m.ExchangeDeclare(x, "fanout", false);
- return x;
+ await ch.ExchangeDeclareAsync(exchangeName, "fanout", false);
+ return exchangeName;
}
- protected string DeclareNonDurableExchangeNoWait(IChannel m, string x)
+ protected async Task PublishMessagesWhileClosingConnAsync(string queueName)
{
- m.ExchangeDeclareNoWait(x, "fanout", false, false, null);
- return x;
- }
-
- protected ManualResetEventSlim PrepareForRecovery(IConnection conn)
- {
- var latch = new ManualResetEventSlim(false);
-
- AutorecoveringConnection aconn = conn as AutorecoveringConnection;
- aconn.RecoverySucceeded += (source, ea) => latch.Set();
-
- return latch;
- }
-
- protected void PublishMessagesWhileClosingConn(string queueName)
- {
- using (AutorecoveringConnection publishingConn = CreateAutorecoveringConnection())
+ using (AutorecoveringConnection publishingConn = await CreateAutorecoveringConnectionAsync())
{
- using (IChannel publishingChannel = publishingConn.CreateChannel())
+ using (IChannel publishingChannel = await publishingConn.CreateChannelAsync())
{
for (ushort i = 0; i < _totalMessageCount; i++)
{
if (i == _closeAtCount)
{
- CloseConnection(_conn);
+ await CloseConnectionAsync(_conn);
}
- publishingChannel.BasicPublish(string.Empty, queueName, _messageBody);
+
+ await publishingChannel.BasicPublishAsync(string.Empty, queueName, _messageBody);
}
+
+ await publishingChannel.CloseAsync();
}
}
}
- protected static ManualResetEventSlim PrepareForShutdown(IConnection conn)
+ protected static TaskCompletionSource PrepareForShutdown(IConnection conn)
+ {
+ var tcs = new TaskCompletionSource();
+
+ AutorecoveringConnection aconn = conn as AutorecoveringConnection;
+ aconn.ConnectionShutdown += (c, args) => tcs.SetResult(true);
+
+ return tcs;
+ }
+
+ protected static TaskCompletionSource PrepareForRecovery(IConnection conn)
{
- var latch = new ManualResetEventSlim(false);
+ var tcs = new TaskCompletionSource();
AutorecoveringConnection aconn = conn as AutorecoveringConnection;
- aconn.ConnectionShutdown += (c, args) => latch.Set();
+ aconn.RecoverySucceeded += (source, ea) => tcs.SetResult(true);
- return latch;
+ return tcs;
}
- protected void RestartServerAndWaitForRecovery()
+ protected Task RestartServerAndWaitForRecoveryAsync()
{
- RestartServerAndWaitForRecovery((AutorecoveringConnection)_conn);
+ return RestartServerAndWaitForRecoveryAsync((AutorecoveringConnection)_conn);
}
- internal void RestartServerAndWaitForRecovery(AutorecoveringConnection conn)
+ private async Task RestartServerAndWaitForRecoveryAsync(AutorecoveringConnection conn)
{
- ManualResetEventSlim sl = PrepareForShutdown(conn);
- ManualResetEventSlim rl = PrepareForRecovery(conn);
- RestartRabbitMQ();
- Wait(sl, "connection shutdown");
- Wait(rl, "connection recovery");
+ TaskCompletionSource sl = PrepareForShutdown(conn);
+ TaskCompletionSource rl = PrepareForRecovery(conn);
+ await RestartRabbitMqAsync();
+ await WaitAsync(sl, "connection shutdown");
+ await WaitAsync(rl, "connection recovery");
}
- protected bool WaitForConfirms(IChannel m)
+ protected static Task WaitForConfirmsWithCancellationAsync(IChannel m)
{
- using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(4));
- return m.WaitForConfirmsAsync(cts.Token).EnsureCompleted();
+ using (var cts = new CancellationTokenSource(TimeSpan.FromSeconds(4)))
+ {
+ return m.WaitForConfirmsAsync(cts.Token);
+ }
}
- protected void WaitForRecovery()
+ protected Task WaitForRecoveryAsync()
{
- Wait(PrepareForRecovery((AutorecoveringConnection)_conn), "recovery succeded");
+ TaskCompletionSource tcs = PrepareForRecovery((AutorecoveringConnection)_conn);
+ return WaitAsync(tcs, "recovery succeded");
}
- internal void WaitForRecovery(AutorecoveringConnection conn)
+ internal Task WaitForRecoveryAsync(AutorecoveringConnection conn)
{
- Wait(PrepareForRecovery(conn), "recovery succeeded");
+ TaskCompletionSource tcs = PrepareForRecovery(conn);
+ return WaitAsync(tcs, "recovery succeeded");
}
- protected void WaitForShutdown()
+ protected Task WaitForShutdownAsync()
{
- Wait(PrepareForShutdown(_conn), "connection shutdown");
+ TaskCompletionSource tcs = PrepareForShutdown(_conn);
+ return WaitAsync(tcs, "connection shutdown");
}
- protected void WaitForShutdown(IConnection conn)
+ protected static Task WaitForShutdownAsync(IConnection conn)
{
- Wait(PrepareForShutdown(conn), "connection shutdown");
+ TaskCompletionSource tcs = PrepareForShutdown(conn);
+ return WaitAsync(tcs, "connection shutdown");
}
- protected void WithTemporaryQueueNoWait(IChannel channel, Action action, string queue)
+ protected async Task WithTemporaryExclusiveQueueNoWaitAsync(IChannel channel, Func action, string queue)
{
try
{
- channel.QueueDeclareNoWait(queue, false, true, false, null);
- action(channel, queue);
+ await channel.QueueDeclareAsync(queue: queue, durable: false, exclusive: true, autoDelete: false, noWait: true);
+ await action(channel, queue);
}
finally
{
- WithTemporaryChannel(x => x.QueueDelete(queue));
+ await WithTemporaryChannelAsync((ch) => ch.QueueDeleteAsync(queue));
}
}
public class AckingBasicConsumer : TestBasicConsumer
{
- public AckingBasicConsumer(IChannel channel, ushort totalMessageCount, ManualResetEventSlim allMessagesSeenLatch)
+ public AckingBasicConsumer(IChannel channel, ushort totalMessageCount, TaskCompletionSource allMessagesSeenLatch)
: base(channel, totalMessageCount, allMessagesSeenLatch)
{
}
- public override void PostHandleDelivery(ulong deliveryTag)
+ public override Task PostHandleDeliveryAsync(ulong deliveryTag)
{
- Channel.BasicAck(deliveryTag, false);
+ return Channel.BasicAckAsync(deliveryTag, false).AsTask();
}
}
public class NackingBasicConsumer : TestBasicConsumer
{
- public NackingBasicConsumer(IChannel channel, ushort totalMessageCount, ManualResetEventSlim allMessagesSeenLatch)
- : base(channel, totalMessageCount, allMessagesSeenLatch)
+ public NackingBasicConsumer(IChannel channel, ushort totalMessageCount, TaskCompletionSource allMessagesSeenTcs)
+ : base(channel, totalMessageCount, allMessagesSeenTcs)
{
}
- public override void PostHandleDelivery(ulong deliveryTag)
+ public override Task PostHandleDeliveryAsync(ulong deliveryTag)
{
- Channel.BasicNack(deliveryTag, false, false);
+ return Channel.BasicNackAsync(deliveryTag, false, false).AsTask();
}
}
public class RejectingBasicConsumer : TestBasicConsumer
{
- public RejectingBasicConsumer(IChannel channel, ushort totalMessageCount, ManualResetEventSlim allMessagesSeenLatch)
- : base(channel, totalMessageCount, allMessagesSeenLatch)
+ public RejectingBasicConsumer(IChannel channel, ushort totalMessageCount, TaskCompletionSource allMessagesSeenTcs)
+ : base(channel, totalMessageCount, allMessagesSeenTcs)
{
}
- public override void PostHandleDelivery(ulong deliveryTag)
+ public override Task PostHandleDeliveryAsync(ulong deliveryTag)
{
- Channel.BasicReject(deliveryTag, false);
+ return Channel.BasicRejectAsync(deliveryTag, false);
}
}
public class TestBasicConsumer : DefaultBasicConsumer
{
- protected readonly ManualResetEventSlim _allMessagesSeenLatch;
+ protected readonly TaskCompletionSource _allMessagesSeenTcs;
protected readonly ushort _totalMessageCount;
protected ushort _counter = 0;
- public TestBasicConsumer(IChannel channel, ushort totalMessageCount, ManualResetEventSlim allMessagesSeenLatch)
+ public TestBasicConsumer(IChannel channel, ushort totalMessageCount, TaskCompletionSource allMessagesSeenTcs)
: base(channel)
{
_totalMessageCount = totalMessageCount;
- _allMessagesSeenLatch = allMessagesSeenLatch;
+ _allMessagesSeenTcs = allMessagesSeenTcs;
}
- public override void HandleBasicDeliver(string consumerTag,
+ public override Task HandleBasicDeliverAsync(string consumerTag,
ulong deliveryTag,
bool redelivered,
string exchange,
string routingKey,
- in ReadOnlyBasicProperties properties,
+ ReadOnlyBasicProperties properties,
ReadOnlyMemory body)
{
try
{
- PostHandleDelivery(deliveryTag);
+ return PostHandleDeliveryAsync(deliveryTag);
}
finally
{
++_counter;
if (_counter >= _totalMessageCount)
{
- _allMessagesSeenLatch.Set();
+ _allMessagesSeenTcs.SetResult(true);
}
}
}
- public virtual void PostHandleDelivery(ulong deliveryTag)
+ public virtual Task PostHandleDeliveryAsync(ulong deliveryTag)
{
+ return Task.CompletedTask;
}
}
- protected bool SendAndConsumeMessage(IConnection conn, string queue, string exchange, string routingKey)
+ protected static async Task SendAndConsumeMessageAsync(IConnection conn, string queue, string exchange, string routingKey)
{
- using (IChannel ch = conn.CreateChannel())
+ using (IChannel ch = await conn.CreateChannelAsync())
{
- var latch = new ManualResetEventSlim(false);
+ await ch.ConfirmSelectAsync();
+
+ var tcs = new TaskCompletionSource();
+
+ var consumer = new AckingBasicConsumer(ch, 1, tcs);
- var consumer = new AckingBasicConsumer(ch, 1, latch);
+ await ch.BasicConsumeAsync(queue, false, consumer);
- ch.BasicConsume(queue, false, consumer);
+ await ch.BasicPublishAsync(exchange: exchange, routingKey: routingKey,
+ body: _encoding.GetBytes("test message"), mandatory: true);
- ch.BasicPublish(exchange, routingKey, _encoding.GetBytes("test message"));
+ await ch.WaitForConfirmsOrDieAsync();
- return latch.Wait(TimeSpan.FromSeconds(5));
+ try
+ {
+ await tcs.Task.WaitAsync(TimeSpan.FromSeconds(5));
+ return tcs.Task.IsCompletedSuccessfully();
+ }
+ catch (TimeoutException)
+ {
+ return false;
+ }
+ finally
+ {
+ await ch.CloseAsync();
+ }
}
}
}
diff --git a/projects/Test/SequentialIntegration/TestConnectionRecoveryWithoutSetup.cs b/projects/Test/SequentialIntegration/TestConnectionRecoveryWithoutSetup.cs
index b88c90451f..57690db17b 100644
--- a/projects/Test/SequentialIntegration/TestConnectionRecoveryWithoutSetup.cs
+++ b/projects/Test/SequentialIntegration/TestConnectionRecoveryWithoutSetup.cs
@@ -31,7 +31,7 @@
using System;
using System.Collections.Generic;
-using System.Threading;
+using System.Threading.Tasks;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using RabbitMQ.Client.Exceptions;
@@ -47,39 +47,44 @@ public TestConnectionRecoveryWithoutSetup(ITestOutputHelper output) : base(outpu
{
}
- protected override void SetUp()
+ public override Task InitializeAsync()
{
+ // NB: nothing to do here since each test creates its own factory,
+ // connections and channels
Assert.Null(_connFactory);
Assert.Null(_conn);
Assert.Null(_channel);
+ return Task.CompletedTask;
}
[Fact]
- public void TestBasicConnectionRecoveryWithHostnameList()
+ public async Task TestBasicConnectionRecoveryWithHostnameList()
{
- using (AutorecoveringConnection c = CreateAutorecoveringConnection(new List { "127.0.0.1", "localhost" }))
+ using (AutorecoveringConnection c = await CreateAutorecoveringConnectionAsync(new List { "127.0.0.1", "localhost" }))
{
Assert.True(c.IsOpen);
- CloseAndWaitForRecovery(c);
+ await CloseAndWaitForRecoveryAsync(c);
Assert.True(c.IsOpen);
+ await c.CloseAsync();
}
}
[Fact]
- public void TestBasicConnectionRecoveryWithHostnameListAndUnreachableHosts()
+ public async Task TestBasicConnectionRecoveryWithHostnameListAndUnreachableHosts()
{
- using (AutorecoveringConnection c = CreateAutorecoveringConnection(new List { "191.72.44.22", "127.0.0.1", "localhost" }))
+ using (AutorecoveringConnection c = await CreateAutorecoveringConnectionAsync(new List { "191.72.44.22", "127.0.0.1", "localhost" }))
{
Assert.True(c.IsOpen);
- CloseAndWaitForRecovery(c);
+ await CloseAndWaitForRecoveryAsync(c);
Assert.True(c.IsOpen);
+ await c.CloseAsync();
}
}
[Fact]
- public void TestBasicConnectionRecoveryWithEndpointList()
+ public async Task TestBasicConnectionRecoveryWithEndpointList()
{
- using (AutorecoveringConnection c = CreateAutorecoveringConnection(
+ using (AutorecoveringConnection c = await CreateAutorecoveringConnectionAsync(
new List
{
new AmqpTcpEndpoint("127.0.0.1"),
@@ -87,15 +92,16 @@ public void TestBasicConnectionRecoveryWithEndpointList()
}))
{
Assert.True(c.IsOpen);
- CloseAndWaitForRecovery(c);
+ await CloseAndWaitForRecoveryAsync(c);
Assert.True(c.IsOpen);
+ await c.CloseAsync();
}
}
[Fact]
- public void TestBasicConnectionRecoveryWithEndpointListAndUnreachableHosts()
+ public async Task TestBasicConnectionRecoveryWithEndpointListAndUnreachableHosts()
{
- using (AutorecoveringConnection c = CreateAutorecoveringConnection(
+ using (AutorecoveringConnection c = await CreateAutorecoveringConnectionAsync(
new List
{
new AmqpTcpEndpoint("191.72.44.22"),
@@ -104,229 +110,273 @@ public void TestBasicConnectionRecoveryWithEndpointListAndUnreachableHosts()
}))
{
Assert.True(c.IsOpen);
- CloseAndWaitForRecovery(c);
+ await CloseAndWaitForRecoveryAsync(c);
Assert.True(c.IsOpen);
+ await c.CloseAsync();
}
}
[Fact]
- public void TestConsumerWorkServiceRecovery()
+ public async Task TestConsumerWorkServiceRecovery()
{
- using (AutorecoveringConnection c = CreateAutorecoveringConnection())
+ using (AutorecoveringConnection c = await CreateAutorecoveringConnectionAsync())
{
- IChannel m = c.CreateChannel();
- string q = m.QueueDeclare("dotnet-client.recovery.consumer_work_pool1",
- false, false, false, null).QueueName;
- var cons = new EventingBasicConsumer(m);
- m.BasicConsume(q, true, cons);
- AssertConsumerCount(m, q, 1);
+ using (IChannel ch = await c.CreateChannelAsync())
+ {
+ string q = (await ch.QueueDeclareAsync("dotnet-client.recovery.consumer_work_pool1",
+ false, false, false)).QueueName;
+ var cons = new EventingBasicConsumer(ch);
+ await ch.BasicConsumeAsync(q, true, cons);
+ await AssertConsumerCountAsync(ch, q, 1);
+
+ await CloseAndWaitForRecoveryAsync(c);
- CloseAndWaitForRecovery(c);
+ Assert.True(ch.IsOpen);
+ var tcs = new TaskCompletionSource();
+ cons.Received += (s, args) => tcs.SetResult(true);
- Assert.True(m.IsOpen);
- var latch = new ManualResetEventSlim(false);
- cons.Received += (s, args) => latch.Set();
+ await ch.BasicPublishAsync("", q, _encoding.GetBytes("msg"));
+ await WaitAsync(tcs, "received event");
- m.BasicPublish("", q, _encoding.GetBytes("msg"));
- Wait(latch, "received event");
+ await ch.QueueDeleteAsync(q);
+ await ch.CloseAsync();
+ }
- m.QueueDelete(q);
+ await c.CloseAsync();
}
}
[Fact]
- public void TestConsumerRecoveryOnClientNamedQueueWithOneRecovery()
+ public async Task TestConsumerRecoveryOnClientNamedQueueWithOneRecovery()
{
string q0 = "dotnet-client.recovery.queue1";
- using (AutorecoveringConnection c = CreateAutorecoveringConnection())
+ using (AutorecoveringConnection c = await CreateAutorecoveringConnectionAsync())
{
- IChannel m = c.CreateChannel();
- string q1 = m.QueueDeclare(q0, false, false, false, null).QueueName;
- Assert.Equal(q0, q1);
+ using (IChannel ch = await c.CreateChannelAsync())
+ {
+ string q1 = (await ch.QueueDeclareAsync(q0, false, false, false)).QueueName;
+ Assert.Equal(q0, q1);
+
+ var cons = new EventingBasicConsumer(ch);
+ await ch.BasicConsumeAsync(q1, true, cons);
+ await AssertConsumerCountAsync(ch, q1, 1);
- var cons = new EventingBasicConsumer(m);
- m.BasicConsume(q1, true, cons);
- AssertConsumerCount(m, q1, 1);
+ bool queueNameChangeAfterRecoveryCalled = false;
- bool queueNameChangeAfterRecoveryCalled = false;
+ c.QueueNameChangedAfterRecovery += (source, ea) => { queueNameChangeAfterRecoveryCalled = true; };
- c.QueueNameChangedAfterRecovery += (source, ea) => { queueNameChangeAfterRecoveryCalled = true; };
+ await CloseAndWaitForRecoveryAsync(c);
+ await AssertConsumerCountAsync(ch, q1, 1);
+ Assert.False(queueNameChangeAfterRecoveryCalled);
- CloseAndWaitForRecovery(c);
- AssertConsumerCount(m, q1, 1);
- Assert.False(queueNameChangeAfterRecoveryCalled);
+ await CloseAndWaitForRecoveryAsync(c);
+ await AssertConsumerCountAsync(ch, q1, 1);
+ Assert.False(queueNameChangeAfterRecoveryCalled);
- CloseAndWaitForRecovery(c);
- AssertConsumerCount(m, q1, 1);
- Assert.False(queueNameChangeAfterRecoveryCalled);
+ await CloseAndWaitForRecoveryAsync(c);
+ await AssertConsumerCountAsync(ch, q1, 1);
+ Assert.False(queueNameChangeAfterRecoveryCalled);
- CloseAndWaitForRecovery(c);
- AssertConsumerCount(m, q1, 1);
- Assert.False(queueNameChangeAfterRecoveryCalled);
+ var tcs = new TaskCompletionSource();
+ cons.Received += (s, args) => tcs.SetResult(true);
- var latch = new ManualResetEventSlim(false);
- cons.Received += (s, args) => latch.Set();
+ await ch.BasicPublishAsync("", q1, _encoding.GetBytes("msg"));
+ await WaitAsync(tcs, "received event");
- m.BasicPublish("", q1, _encoding.GetBytes("msg"));
- Wait(latch, "received event");
+ await ch.QueueDeleteAsync(q1);
+ await ch.CloseAsync();
+ }
- m.QueueDelete(q1);
+ await c.CloseAsync();
}
}
[Fact]
- public void TestConsumerRecoveryWithServerNamedQueue()
+ public async Task TestConsumerRecoveryWithServerNamedQueue()
{
// https://github.com/rabbitmq/rabbitmq-dotnet-client/issues/1238
- using (AutorecoveringConnection c = CreateAutorecoveringConnection())
+ using (AutorecoveringConnection c = await CreateAutorecoveringConnectionAsync())
{
- IChannel ch = c.CreateChannel();
- RabbitMQ.Client.QueueDeclareOk queueDeclareResult = ch.QueueDeclare(queue: string.Empty, durable: false, exclusive: true, autoDelete: true, arguments: null);
- string qname = queueDeclareResult.QueueName;
- Assert.False(string.IsNullOrEmpty(qname));
-
- var cons = new EventingBasicConsumer(ch);
- ch.BasicConsume(string.Empty, true, cons);
- AssertConsumerCount(ch, qname, 1);
-
- bool queueNameBeforeIsEqual = false;
- bool queueNameChangeAfterRecoveryCalled = false;
- string qnameAfterRecovery = null;
- c.QueueNameChangedAfterRecovery += (source, ea) =>
+ using (IChannel ch = await c.CreateChannelAsync())
{
- queueNameChangeAfterRecoveryCalled = true;
- queueNameBeforeIsEqual = qname.Equals(ea.NameBefore);
- qnameAfterRecovery = ea.NameAfter;
- };
-
- CloseAndWaitForRecovery(c);
+ RabbitMQ.Client.QueueDeclareOk queueDeclareResult =
+ await ch.QueueDeclareAsync(queue: string.Empty, durable: false, exclusive: true, autoDelete: true, arguments: null);
+ string qname = queueDeclareResult.QueueName;
+ Assert.False(string.IsNullOrEmpty(qname));
+
+ var cons = new EventingBasicConsumer(ch);
+ await ch.BasicConsumeAsync(string.Empty, true, cons);
+ await AssertConsumerCountAsync(ch, qname, 1);
+
+ bool queueNameBeforeIsEqual = false;
+ bool queueNameChangeAfterRecoveryCalled = false;
+ string qnameAfterRecovery = null;
+ c.QueueNameChangedAfterRecovery += (source, ea) =>
+ {
+ queueNameChangeAfterRecoveryCalled = true;
+ queueNameBeforeIsEqual = qname.Equals(ea.NameBefore);
+ qnameAfterRecovery = ea.NameAfter;
+ };
+
+ await CloseAndWaitForRecoveryAsync(c);
+
+ await AssertConsumerCountAsync(ch, qnameAfterRecovery, 1);
+ Assert.True(queueNameChangeAfterRecoveryCalled);
+ Assert.True(queueNameBeforeIsEqual);
+
+ await ch.CloseAsync();
+ }
- AssertConsumerCount(ch, qnameAfterRecovery, 1);
- Assert.True(queueNameChangeAfterRecoveryCalled);
- Assert.True(queueNameBeforeIsEqual);
+ await c.CloseAsync();
}
}
[Fact]
- public void TestCreateChannelOnClosedAutorecoveringConnectionDoesNotHang()
+ public async Task TestCreateChannelOnClosedAutorecoveringConnectionDoesNotHang()
{
// we don't want this to recover quickly in this test
- AutorecoveringConnection c = CreateAutorecoveringConnection(TimeSpan.FromSeconds(20));
-
- try
- {
- c.Close();
- WaitForShutdown(c);
- Assert.False(c.IsOpen);
- c.CreateChannel();
- Assert.Fail("Expected an exception");
- }
- catch (AlreadyClosedException)
+ using (AutorecoveringConnection conn = await CreateAutorecoveringConnectionAsync(TimeSpan.FromSeconds(20)))
{
- // expected
- }
- finally
- {
- StartRabbitMQ();
- if (c.IsOpen)
+ try
+ {
+ await conn.CloseAsync();
+ await WaitForShutdownAsync(conn);
+ Assert.False(conn.IsOpen);
+ await conn.CreateChannelAsync();
+ Assert.Fail("Expected an exception");
+ }
+ catch (AlreadyClosedException)
+ {
+ // expected
+ }
+ finally
{
- c.Abort();
+ await StartRabbitMqAsync();
+ await conn.CloseAsync();
}
}
}
[Fact]
- public void TestTopologyRecoveryConsumerFilter()
+ public async Task TestTopologyRecoveryConsumerFilter()
{
var filter = new TopologyRecoveryFilter
{
ConsumerFilter = consumer => !consumer.ConsumerTag.Contains("filtered")
};
- var latch = new ManualResetEventSlim(false);
- AutorecoveringConnection conn = CreateAutorecoveringConnectionWithTopologyRecoveryFilter(filter);
- conn.RecoverySucceeded += (source, ea) => latch.Set();
- IChannel ch = conn.CreateChannel();
- ch.ConfirmSelect();
-
- var exchange = "topology.recovery.exchange";
- var queueWithRecoveredConsumer = "topology.recovery.queue.1";
- var queueWithIgnoredConsumer = "topology.recovery.queue.2";
- var binding1 = "recovered.binding.1";
- var binding2 = "recovered.binding.2";
-
- ch.ExchangeDeclare(exchange, "direct");
- ch.QueueDeclare(queueWithRecoveredConsumer, false, false, false, null);
- ch.QueueDeclare(queueWithIgnoredConsumer, false, false, false, null);
- ch.QueueBind(queueWithRecoveredConsumer, exchange, binding1);
- ch.QueueBind(queueWithIgnoredConsumer, exchange, binding2);
- ch.QueuePurge(queueWithRecoveredConsumer);
- ch.QueuePurge(queueWithIgnoredConsumer);
-
- var recoverLatch = new ManualResetEventSlim(false);
- var consumerToRecover = new EventingBasicConsumer(ch);
- consumerToRecover.Received += (source, ea) => recoverLatch.Set();
- ch.BasicConsume(queueWithRecoveredConsumer, true, "recovered.consumer", consumerToRecover);
-
- var ignoredLatch = new ManualResetEventSlim(false);
- var consumerToIgnore = new EventingBasicConsumer(ch);
- consumerToIgnore.Received += (source, ea) => ignoredLatch.Set();
- ch.BasicConsume(queueWithIgnoredConsumer, true, "filtered.consumer", consumerToIgnore);
-
- try
- {
- CloseAndWaitForRecovery(conn);
- Wait(latch, "recovery succeeded");
-
- Assert.True(ch.IsOpen);
- ch.BasicPublish(exchange, binding1, _encoding.GetBytes("test message"));
- ch.BasicPublish(exchange, binding2, _encoding.GetBytes("test message"));
- Assert.True(recoverLatch.Wait(TimeSpan.FromSeconds(5)));
- Assert.False(ignoredLatch.Wait(TimeSpan.FromSeconds(5)));
+ var connectionRecoveryTcs = new TaskCompletionSource();
- ch.BasicConsume(queueWithIgnoredConsumer, true, "filtered.consumer", consumerToIgnore);
+ using (AutorecoveringConnection conn = await CreateAutorecoveringConnectionWithTopologyRecoveryFilterAsync(filter))
+ {
+ conn.RecoverySucceeded += (source, ea) => connectionRecoveryTcs.SetResult(true);
- try
- {
- ch.BasicConsume(queueWithRecoveredConsumer, true, "recovered.consumer", consumerToRecover);
- Assert.Fail("Expected an exception");
- }
- catch (OperationInterruptedException e)
+ using (IChannel ch = await conn.CreateChannelAsync())
{
- AssertShutdownError(e.ShutdownReason, 530); // NOT_ALLOWED - not allowed to reuse consumer tag
+ await ch.ConfirmSelectAsync();
+
+ string exchange = "topology.recovery.exchange";
+ string queueWithRecoveredConsumer = "topology.recovery.queue.1";
+ string queueWithIgnoredConsumer = "topology.recovery.queue.2";
+ string binding1 = "recovered.binding.1";
+ string binding2 = "recovered.binding.2";
+
+ await ch.ExchangeDeclareAsync(exchange, "direct");
+ await ch.QueueDeclareAsync(queueWithRecoveredConsumer, false, false, false);
+ await ch.QueueDeclareAsync(queueWithIgnoredConsumer, false, false, false);
+ await ch.QueueBindAsync(queueWithRecoveredConsumer, exchange, binding1);
+ await ch.QueueBindAsync(queueWithIgnoredConsumer, exchange, binding2);
+ await ch.QueuePurgeAsync(queueWithRecoveredConsumer);
+ await ch.QueuePurgeAsync(queueWithIgnoredConsumer);
+
+ var consumerRecoveryTcs = new TaskCompletionSource();
+ var consumerToRecover = new EventingBasicConsumer(ch);
+ consumerToRecover.Received += (source, ea) => consumerRecoveryTcs.SetResult(true);
+ await ch.BasicConsumeAsync(queueWithRecoveredConsumer, true, "recovered.consumer", consumerToRecover);
+
+ var ignoredTcs = new TaskCompletionSource();
+ var consumerToIgnore = new EventingBasicConsumer(ch);
+ consumerToIgnore.Received += (source, ea) => ignoredTcs.SetResult(true);
+ await ch.BasicConsumeAsync(queueWithIgnoredConsumer, true, "filtered.consumer", consumerToIgnore);
+
+ try
+ {
+ await CloseAndWaitForRecoveryAsync(conn);
+ await WaitAsync(connectionRecoveryTcs, "recovery succeeded");
+
+ Assert.True(ch.IsOpen);
+ await ch.BasicPublishAsync(exchange, binding1, _encoding.GetBytes("test message"));
+ await ch.BasicPublishAsync(exchange, binding2, _encoding.GetBytes("test message"));
+
+ await consumerRecoveryTcs.Task.WaitAsync(TimeSpan.FromSeconds(5));
+ Assert.True(await consumerRecoveryTcs.Task);
+
+ bool sawTimeout = false;
+ try
+ {
+ await ignoredTcs.Task.WaitAsync(TimeSpan.FromSeconds(5));
+ }
+ catch (TimeoutException)
+ {
+ sawTimeout = true;
+ }
+ Assert.True(sawTimeout);
+
+ await ch.BasicConsumeAsync(queueWithIgnoredConsumer, true, "filtered.consumer", consumerToIgnore);
+
+ try
+ {
+ await ch.BasicConsumeAsync(queueWithRecoveredConsumer, true, "recovered.consumer", consumerToRecover);
+ Assert.Fail("Expected an exception");
+ }
+ catch (OperationInterruptedException e)
+ {
+ AssertShutdownError(e.ShutdownReason, 530); // NOT_ALLOWED - not allowed to reuse consumer tag
+ }
+ }
+ finally
+ {
+ await ch.CloseAsync();
+ }
}
- }
- finally
- {
- conn.Abort();
+
+ await conn.CloseAsync();
}
}
[Fact]
- public void TestRecoveryWithTopologyDisabled()
+ public async Task TestRecoveryWithTopologyDisabled()
{
- AutorecoveringConnection conn = CreateAutorecoveringConnectionWithTopologyRecoveryDisabled();
- IChannel ch = conn.CreateChannel();
- string s = "dotnet-client.test.recovery.q2";
- ch.QueueDelete(s);
- ch.QueueDeclare(s, false, true, false, null);
- ch.QueueDeclarePassive(s);
- Assert.True(ch.IsOpen);
-
- try
- {
- CloseAndWaitForRecovery(conn);
- Assert.True(ch.IsOpen);
- ch.QueueDeclarePassive(s);
- Assert.Fail("Expected an exception");
- }
- catch (OperationInterruptedException)
+ using (AutorecoveringConnection conn = await CreateAutorecoveringConnectionWithTopologyRecoveryDisabledAsync())
{
- // expected
- }
- finally
- {
- conn.Abort();
+ using (IChannel ch = await conn.CreateChannelAsync())
+ {
+ try
+ {
+ string s = "dotnet-client.test.recovery.q2";
+ await ch.QueueDeleteAsync(s);
+ await ch.QueueDeclareAsync(queue: s, durable: false, exclusive: true, autoDelete: false, arguments: null);
+ await ch.QueueDeclareAsync(queue: s, passive: true, durable: false, exclusive: true, autoDelete: false, arguments: null);
+
+ Assert.True(ch.IsOpen);
+ await CloseAndWaitForRecoveryAsync(conn);
+
+ Assert.True(ch.IsOpen);
+ await ch.QueueDeclareAsync(queue: s, passive: true, durable: false, exclusive: true, autoDelete: false, arguments: null);
+
+ Assert.Fail("Expected an exception");
+ }
+ catch (OperationInterruptedException)
+ {
+ // expected
+ }
+ finally
+ {
+ await ch.CloseAsync();
+ }
+ }
+
+ await conn.CloseAsync();
}
}
}
diff --git a/projects/Test/SequentialIntegration/TestConnectionTopologyRecovery.cs b/projects/Test/SequentialIntegration/TestConnectionTopologyRecovery.cs
index 2435dbb90a..f58b1d9ecd 100644
--- a/projects/Test/SequentialIntegration/TestConnectionTopologyRecovery.cs
+++ b/projects/Test/SequentialIntegration/TestConnectionTopologyRecovery.cs
@@ -32,6 +32,7 @@
using System;
using System.Collections.Generic;
using System.Threading;
+using System.Threading.Tasks;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using RabbitMQ.Client.Exceptions;
@@ -48,211 +49,248 @@ public TestConnectionTopologyRecovery(ITestOutputHelper output) : base(output)
}
[Fact]
- public void TestRecoverTopologyOnDisposedChannel()
+ public async Task TestRecoverTopologyOnDisposedChannel()
{
string x = GenerateExchangeName();
string q = GenerateQueueName();
const string rk = "routing-key";
- using (IChannel ch = _conn.CreateChannel())
+ using (IChannel ch = await _conn.CreateChannelAsync())
{
- ch.ExchangeDeclare(exchange: x, type: "fanout");
- ch.QueueDeclare(q, false, false, false, null);
- ch.QueueBind(q, x, rk);
+ await ch.ExchangeDeclareAsync(exchange: x, type: "fanout");
+ await ch.QueueDeclareAsync(q, false, false, false);
+ await ch.QueueBindAsync(q, x, rk);
+ await ch.CloseAsync();
}
var cons = new EventingBasicConsumer(_channel);
- _channel.BasicConsume(q, true, cons);
- AssertConsumerCount(_channel, q, 1);
+ await _channel.BasicConsumeAsync(q, true, cons);
+ await AssertConsumerCountAsync(_channel, q, 1);
- CloseAndWaitForRecovery();
- AssertConsumerCount(_channel, q, 1);
+ await CloseAndWaitForRecoveryAsync();
+ await AssertConsumerCountAsync(_channel, q, 1);
- var latch = new ManualResetEventSlim(false);
- cons.Received += (s, args) => latch.Set();
+ var tcs = new TaskCompletionSource();
+ cons.Received += (s, args) => tcs.SetResult(true);
- _channel.BasicPublish("", q, _messageBody);
- Wait(latch, "received event");
+ await _channel.BasicPublishAsync("", q, _messageBody);
+ await WaitAsync(tcs, "received event");
- _channel.QueueUnbind(q, x, rk);
- _channel.ExchangeDelete(x);
- _channel.QueueDelete(q);
+ await _channel.QueueUnbindAsync(q, x, rk);
+ await _channel.ExchangeDeleteAsync(x);
+ await _channel.QueueDeleteAsync(q);
}
[Fact]
- public void TestTopologyRecoveryQueueFilter()
+ public async Task TestTopologyRecoveryQueueFilter()
{
- var latch = new ManualResetEventSlim(false);
+ var tcs = new TaskCompletionSource();
var filter = new TopologyRecoveryFilter
{
QueueFilter = queue => !queue.Name.Contains("filtered")
};
- using AutorecoveringConnection conn = CreateAutorecoveringConnectionWithTopologyRecoveryFilter(filter);
- conn.RecoverySucceeded += (source, ea) => latch.Set();
- using IChannel ch = conn.CreateChannel();
+ AutorecoveringConnection conn = await CreateAutorecoveringConnectionWithTopologyRecoveryFilterAsync(filter);
+ conn.RecoverySucceeded += (source, ea) => tcs.SetResult(true);
+ IChannel ch = await conn.CreateChannelAsync();
string queueToRecover = "recovered.queue";
string queueToIgnore = "filtered.queue";
- ch.QueueDeclare(queueToRecover, false, false, false, null);
- ch.QueueDeclare(queueToIgnore, false, false, false, null);
+ await ch.QueueDeclareAsync(queueToRecover, false, false, false);
+ await ch.QueueDeclareAsync(queueToIgnore, false, false, false);
- _channel.QueueDelete(queueToRecover);
- _channel.QueueDelete(queueToIgnore);
+ await _channel.QueueDeleteAsync(queueToRecover);
+ await _channel.QueueDeleteAsync(queueToIgnore);
- CloseAndWaitForRecovery(conn);
- Wait(latch, "recovery succeeded");
+ await CloseAndWaitForRecoveryAsync(conn);
+ await WaitAsync(tcs, "recovery succeeded");
Assert.True(ch.IsOpen);
- AssertQueueRecovery(ch, queueToRecover, false);
+ await AssertQueueRecoveryAsync(ch, queueToRecover, false);
try
{
- AssertQueueRecovery(ch, queueToIgnore, false);
+ await AssertQueueRecoveryAsync(ch, queueToIgnore, false);
Assert.Fail("Expected an exception");
}
catch (OperationInterruptedException e)
{
- AssertShutdownError(e.ShutdownReason, 404);
+ IntegrationFixtureBase.AssertShutdownError(e.ShutdownReason, 404);
+ }
+ finally
+ {
+ await ch.CloseAsync();
+ await conn.CloseAsync();
+ ch.Dispose();
+ conn.Dispose();
}
}
[Fact]
- public void TestTopologyRecoveryExchangeFilter()
+ public async Task TestTopologyRecoveryExchangeFilter()
{
- var latch = new ManualResetEventSlim(false);
+ var tcs = new TaskCompletionSource();
var filter = new TopologyRecoveryFilter
{
ExchangeFilter = exchange => exchange.Type == "topic" && !exchange.Name.Contains("filtered")
};
- using AutorecoveringConnection conn = CreateAutorecoveringConnectionWithTopologyRecoveryFilter(filter);
- conn.RecoverySucceeded += (source, ea) => latch.Set();
- using IChannel ch = conn.CreateChannel();
-
- string exchangeToRecover = "recovered.exchange";
- string exchangeToIgnore = "filtered.exchange";
- ch.ExchangeDeclare(exchangeToRecover, "topic", false, true);
- ch.ExchangeDeclare(exchangeToIgnore, "direct", false, true);
-
- _channel.ExchangeDelete(exchangeToRecover);
- _channel.ExchangeDelete(exchangeToIgnore);
+ AutorecoveringConnection conn = await CreateAutorecoveringConnectionWithTopologyRecoveryFilterAsync(filter);
+ conn.RecoverySucceeded += (source, ea) => tcs.SetResult(true);
+ IChannel ch = await conn.CreateChannelAsync();
+ try
+ {
+ string exchangeToRecover = "recovered.exchange";
+ string exchangeToIgnore = "filtered.exchange";
+ await ch.ExchangeDeclareAsync(exchangeToRecover, "topic", false, true);
+ await ch.ExchangeDeclareAsync(exchangeToIgnore, "direct", false, true);
- CloseAndWaitForRecovery(conn);
- Wait(latch, "recovery succeeded");
+ await _channel.ExchangeDeleteAsync(exchangeToRecover);
+ await _channel.ExchangeDeleteAsync(exchangeToIgnore);
- Assert.True(ch.IsOpen);
- AssertExchangeRecovery(ch, exchangeToRecover);
+ await CloseAndWaitForRecoveryAsync(conn);
+ await WaitAsync(tcs, "recovery succeeded");
- try
- {
- AssertExchangeRecovery(ch, exchangeToIgnore);
+ Assert.True(ch.IsOpen);
+ await AssertExchangeRecoveryAsync(ch, exchangeToRecover);
+ await AssertExchangeRecoveryAsync(ch, exchangeToIgnore);
Assert.Fail("Expected an exception");
}
catch (OperationInterruptedException e)
{
AssertShutdownError(e.ShutdownReason, 404);
}
+ finally
+ {
+ await ch.CloseAsync();
+ await conn.CloseAsync();
+ ch.Dispose();
+ conn.Dispose();
+ }
}
[Fact]
- public void TestTopologyRecoveryBindingFilter()
+ public async Task TestTopologyRecoveryBindingFilter()
{
- var latch = new ManualResetEventSlim(false);
+ var tcs = new TaskCompletionSource();
var filter = new TopologyRecoveryFilter
{
BindingFilter = binding => !binding.RoutingKey.Contains("filtered")
};
- using AutorecoveringConnection conn = CreateAutorecoveringConnectionWithTopologyRecoveryFilter(filter);
- conn.RecoverySucceeded += (source, ea) => latch.Set();
- using IChannel ch = conn.CreateChannel();
-
- string exchange = "topology.recovery.exchange";
- string queueWithRecoveredBinding = "topology.recovery.queue.1";
- string queueWithIgnoredBinding = "topology.recovery.queue.2";
- string bindingToRecover = "recovered.binding";
- string bindingToIgnore = "filtered.binding";
-
- ch.ExchangeDeclare(exchange, "direct");
- ch.QueueDeclare(queueWithRecoveredBinding, false, false, false, null);
- ch.QueueDeclare(queueWithIgnoredBinding, false, false, false, null);
- ch.QueueBind(queueWithRecoveredBinding, exchange, bindingToRecover);
- ch.QueueBind(queueWithIgnoredBinding, exchange, bindingToIgnore);
- ch.QueuePurge(queueWithRecoveredBinding);
- ch.QueuePurge(queueWithIgnoredBinding);
-
- _channel.QueueUnbind(queueWithRecoveredBinding, exchange, bindingToRecover);
- _channel.QueueUnbind(queueWithIgnoredBinding, exchange, bindingToIgnore);
-
- CloseAndWaitForRecovery(conn);
- Wait(latch, "recovery succeeded");
+ AutorecoveringConnection conn = await CreateAutorecoveringConnectionWithTopologyRecoveryFilterAsync(filter);
+ conn.RecoverySucceeded += (source, ea) => tcs.SetResult(true);
+ IChannel ch = await conn.CreateChannelAsync();
+ try
+ {
+ string exchange = "topology.recovery.exchange";
+ string queueWithRecoveredBinding = "topology.recovery.queue.1";
+ string queueWithIgnoredBinding = "topology.recovery.queue.2";
+ string bindingToRecover = "recovered.binding";
+ string bindingToIgnore = "filtered.binding";
+
+ await ch.ExchangeDeclareAsync(exchange, "direct");
+ await ch.QueueDeclareAsync(queueWithRecoveredBinding, false, false, false);
+ await ch.QueueDeclareAsync(queueWithIgnoredBinding, false, false, false);
+ await ch.QueueBindAsync(queueWithRecoveredBinding, exchange, bindingToRecover);
+ await ch.QueueBindAsync(queueWithIgnoredBinding, exchange, bindingToIgnore);
+ await ch.QueuePurgeAsync(queueWithRecoveredBinding);
+ await ch.QueuePurgeAsync(queueWithIgnoredBinding);
+
+ await _channel.QueueUnbindAsync(queueWithRecoveredBinding, exchange, bindingToRecover);
+ await _channel.QueueUnbindAsync(queueWithIgnoredBinding, exchange, bindingToIgnore);
+
+ await CloseAndWaitForRecoveryAsync(conn);
+ await WaitAsync(tcs, "recovery succeeded");
- Assert.True(ch.IsOpen);
- Assert.True(SendAndConsumeMessage(_conn, queueWithRecoveredBinding, exchange, bindingToRecover));
- Assert.False(SendAndConsumeMessage(_conn, queueWithIgnoredBinding, exchange, bindingToIgnore));
+ Assert.True(ch.IsOpen);
+ Assert.True(await SendAndConsumeMessageAsync(_conn, queueWithRecoveredBinding, exchange, bindingToRecover));
+ Assert.False(await SendAndConsumeMessageAsync(_conn, queueWithIgnoredBinding, exchange, bindingToIgnore));
+ }
+ finally
+ {
+ await ch.CloseAsync();
+ await conn.CloseAsync();
+ ch.Dispose();
+ conn.Dispose();
+ }
}
[Fact]
- public void TestTopologyRecoveryDefaultFilterRecoversAllEntities()
+ public async Task TestTopologyRecoveryDefaultFilterRecoversAllEntities()
{
- var latch = new ManualResetEventSlim(false);
+ var connectionRecoveryTcs = new TaskCompletionSource();
var filter = new TopologyRecoveryFilter();
- using AutorecoveringConnection conn = CreateAutorecoveringConnectionWithTopologyRecoveryFilter(filter);
- conn.RecoverySucceeded += (source, ea) => latch.Set();
- using IChannel ch = conn.CreateChannel();
- ch.ConfirmSelect();
-
- string exchange = "topology.recovery.exchange";
- string queue1 = "topology.recovery.queue.1";
- string queue2 = "topology.recovery.queue.2";
- string binding1 = "recovered.binding";
- string binding2 = "filtered.binding";
-
- ch.ExchangeDeclare(exchange, "direct");
- ch.QueueDeclare(queue1, false, false, false, null);
- ch.QueueDeclare(queue2, false, false, false, null);
- ch.QueueBind(queue1, exchange, binding1);
- ch.QueueBind(queue2, exchange, binding2);
- ch.QueuePurge(queue1);
- ch.QueuePurge(queue2);
-
- var consumerLatch1 = new ManualResetEventSlim(false);
- var consumer1 = new EventingBasicConsumer(ch);
- consumer1.Received += (source, ea) => consumerLatch1.Set();
- ch.BasicConsume(queue1, true, "recovered.consumer", consumer1);
-
- var consumerLatch2 = new ManualResetEventSlim(false);
- var consumer2 = new EventingBasicConsumer(ch);
- consumer2.Received += (source, ea) => consumerLatch2.Set();
- ch.BasicConsume(queue2, true, "filtered.consumer", consumer2);
-
- _channel.ExchangeDelete(exchange);
- _channel.QueueDelete(queue1);
- _channel.QueueDelete(queue2);
-
- CloseAndWaitForRecovery(conn);
- Wait(latch, "recovery succeeded");
+ AutorecoveringConnection conn = await CreateAutorecoveringConnectionWithTopologyRecoveryFilterAsync(filter);
+ conn.RecoverySucceeded += (source, ea) => connectionRecoveryTcs.SetResult(true);
+ IChannel ch = await conn.CreateChannelAsync();
+ try
+ {
+ await ch.ConfirmSelectAsync();
+
+ string exchange = "topology.recovery.exchange";
+ string queue1 = "topology.recovery.queue.1";
+ string queue2 = "topology.recovery.queue.2";
+ string binding1 = "recovered.binding";
+ string binding2 = "filtered.binding";
+
+ await ch.ExchangeDeclareAsync(exchange, "direct");
+ await ch.QueueDeclareAsync(queue1, false, false, false);
+ await ch.QueueDeclareAsync(queue2, false, false, false);
+ await ch.QueueBindAsync(queue1, exchange, binding1);
+ await ch.QueueBindAsync(queue2, exchange, binding2);
+ await ch.QueuePurgeAsync(queue1);
+ await ch.QueuePurgeAsync(queue2);
+
+ var consumerReceivedTcs1 = new TaskCompletionSource();
+ var consumer1 = new EventingBasicConsumer(ch);
+ consumer1.Received += (source, ea) => consumerReceivedTcs1.SetResult(true);
+ await ch.BasicConsumeAsync(queue1, true, "recovered.consumer", consumer1);
+
+ var consumerReceivedTcs2 = new TaskCompletionSource();
+ var consumer2 = new EventingBasicConsumer(ch);
+ consumer2.Received += (source, ea) => consumerReceivedTcs2.SetResult(true);
+ await ch.BasicConsumeAsync(queue2, true, "filtered.consumer", consumer2);
+
+ await _channel.ExchangeDeleteAsync(exchange);
+ await _channel.QueueDeleteAsync(queue1);
+ await _channel.QueueDeleteAsync(queue2);
+
+ await CloseAndWaitForRecoveryAsync(conn);
+ await WaitAsync(connectionRecoveryTcs, "recovery succeeded");
- Assert.True(ch.IsOpen);
- AssertExchangeRecovery(ch, exchange);
- ch.QueueDeclarePassive(queue1);
- ch.QueueDeclarePassive(queue2);
+ Assert.True(ch.IsOpen);
+ await AssertExchangeRecoveryAsync(ch, exchange);
+ await ch.QueueDeclarePassiveAsync(queue1);
+ await ch.QueueDeclarePassiveAsync(queue2);
+
+ await ch.BasicPublishAsync(exchange, binding1, _encoding.GetBytes("test message"), mandatory: true);
+ // await ch.WaitForConfirmsOrDieAsync();
- ch.BasicPublish(exchange, binding1, _encoding.GetBytes("test message"));
- ch.BasicPublish(exchange, binding2, _encoding.GetBytes("test message"));
+ await ch.BasicPublishAsync(exchange, binding2, _encoding.GetBytes("test message"), mandatory: true);
+ // await ch.WaitForConfirmsOrDieAsync();
- Assert.True(consumerLatch1.Wait(TimeSpan.FromSeconds(5)));
- Assert.True(consumerLatch2.Wait(TimeSpan.FromSeconds(5)));
+ await consumerReceivedTcs1.Task.WaitAsync(TimeSpan.FromSeconds(5));
+ await consumerReceivedTcs2.Task.WaitAsync(TimeSpan.FromSeconds(5));
+ Assert.True(consumerReceivedTcs1.Task.IsCompletedSuccessfully());
+ Assert.True(consumerReceivedTcs2.Task.IsCompletedSuccessfully());
+ }
+ finally
+ {
+ await ch.CloseAsync();
+ await conn.CloseAsync();
+ ch.Dispose();
+ conn.Dispose();
+ }
}
[Fact]
- public void TestTopologyRecoveryQueueExceptionHandler()
+ public async Task TestTopologyRecoveryQueueExceptionHandler()
{
- var latch = new ManualResetEventSlim(false);
+ var tcs = new TaskCompletionSource();
var changedQueueArguments = new Dictionary
{
@@ -267,47 +305,54 @@ public void TestTopologyRecoveryQueueExceptionHandler()
&& ex is OperationInterruptedException operationInterruptedException
&& operationInterruptedException.ShutdownReason.ReplyCode == Constants.PreconditionFailed;
},
- QueueRecoveryExceptionHandler = (rq, ex, connection) =>
+ QueueRecoveryExceptionHandlerAsync = async (rq, ex, connection) =>
{
- using (IChannel channel = connection.CreateChannel())
+ using (IChannel channel = await connection.CreateChannelAsync())
{
- channel.QueueDeclare(rq.Name, false, false, false, changedQueueArguments);
+ await channel.QueueDeclareAsync(rq.Name, false, false, false,
+ noWait: false, arguments: changedQueueArguments);
+ await channel.CloseAsync();
}
}
};
- using AutorecoveringConnection conn = CreateAutorecoveringConnectionWithTopologyRecoveryExceptionHandler(exceptionHandler);
- conn.RecoverySucceeded += (source, ea) => latch.Set();
- using IChannel ch = conn.CreateChannel();
+ AutorecoveringConnection conn = await CreateAutorecoveringConnectionWithTopologyRecoveryExceptionHandlerAsync(exceptionHandler);
+ conn.RecoverySucceeded += (source, ea) => tcs.SetResult(true);
+ IChannel ch = await conn.CreateChannelAsync();
string queueToRecoverWithException = "recovery.exception.queue";
string queueToRecoverSuccessfully = "successfully.recovered.queue";
- ch.QueueDeclare(queueToRecoverWithException, false, false, false, null);
- ch.QueueDeclare(queueToRecoverSuccessfully, false, false, false, null);
+ await ch.QueueDeclareAsync(queueToRecoverWithException, false, false, false);
+ await ch.QueueDeclareAsync(queueToRecoverSuccessfully, false, false, false);
- _channel.QueueDelete(queueToRecoverSuccessfully);
- _channel.QueueDelete(queueToRecoverWithException);
- _channel.QueueDeclare(queueToRecoverWithException, false, false, false, changedQueueArguments);
+ await _channel.QueueDeleteAsync(queueToRecoverSuccessfully);
+ await _channel.QueueDeleteAsync(queueToRecoverWithException);
+ await _channel.QueueDeclareAsync(queueToRecoverWithException, false, false, false,
+ noWait: false, arguments: changedQueueArguments);
try
{
- CloseAndWaitForRecovery(conn);
- Wait(latch, "recovery succeded");
+ await CloseAndWaitForRecoveryAsync(conn);
+ await WaitAsync(tcs, "recovery succeded");
Assert.True(ch.IsOpen);
- AssertQueueRecovery(ch, queueToRecoverSuccessfully, false);
- AssertQueueRecovery(ch, queueToRecoverWithException, false, changedQueueArguments);
+ await AssertQueueRecoveryAsync(ch, queueToRecoverSuccessfully, false);
+ await AssertQueueRecoveryAsync(ch, queueToRecoverWithException, false, changedQueueArguments);
}
finally
{
- _channel.QueueDelete(queueToRecoverWithException);
+ await _channel.QueueDeleteAsync(queueToRecoverWithException);
+ await ch.CloseAsync();
+ await conn.CloseAsync();
+ ch.Dispose();
+ conn.Dispose();
}
}
[Fact]
- public void TestTopologyRecoveryExchangeExceptionHandler()
+ public async Task TestTopologyRecoveryExchangeExceptionHandler()
{
- var latch = new ManualResetEventSlim(false);
+ var tcs = new TaskCompletionSource();
var exceptionHandler = new TopologyRecoveryExceptionHandler
{
@@ -317,51 +362,57 @@ public void TestTopologyRecoveryExchangeExceptionHandler()
&& ex is OperationInterruptedException operationInterruptedException
&& operationInterruptedException.ShutdownReason.ReplyCode == Constants.PreconditionFailed;
},
- ExchangeRecoveryExceptionHandler = (re, ex, connection) =>
+ ExchangeRecoveryExceptionHandlerAsync = async (re, ex, connection) =>
{
- using (IChannel channel = connection.CreateChannel())
+ using (IChannel channel = await connection.CreateChannelAsync())
{
- channel.ExchangeDeclare(re.Name, "topic", false, false);
+ await channel.ExchangeDeclareAsync(re.Name, "topic", false, false);
+ await channel.CloseAsync();
}
}
};
- using AutorecoveringConnection conn = CreateAutorecoveringConnectionWithTopologyRecoveryExceptionHandler(exceptionHandler);
- conn.RecoverySucceeded += (source, ea) => latch.Set();
+ AutorecoveringConnection conn = await CreateAutorecoveringConnectionWithTopologyRecoveryExceptionHandlerAsync(exceptionHandler);
+ conn.RecoverySucceeded += (source, ea) => tcs.SetResult(true);
string exchangeToRecoverWithException = "recovery.exception.exchange";
string exchangeToRecoverSuccessfully = "successfully.recovered.exchange";
- using IChannel ch = conn.CreateChannel();
- ch.ExchangeDeclare(exchangeToRecoverWithException, "direct", false, false);
- ch.ExchangeDeclare(exchangeToRecoverSuccessfully, "direct", false, false);
+ IChannel ch = await conn.CreateChannelAsync();
+ await ch.ExchangeDeclareAsync(exchangeToRecoverWithException, "direct", false, false);
+ await ch.ExchangeDeclareAsync(exchangeToRecoverSuccessfully, "direct", false, false);
- _channel.ExchangeDelete(exchangeToRecoverSuccessfully);
- _channel.ExchangeDelete(exchangeToRecoverWithException);
- _channel.ExchangeDeclare(exchangeToRecoverWithException, "topic", false, false);
+ await _channel.ExchangeDeleteAsync(exchangeToRecoverSuccessfully);
+ await _channel.ExchangeDeleteAsync(exchangeToRecoverWithException);
+ await _channel.ExchangeDeclareAsync(exchangeToRecoverWithException, "topic", false, false);
try
{
- CloseAndWaitForRecovery(conn);
- Wait(latch, "recovery succeeded");
+ await CloseAndWaitForRecoveryAsync(conn);
+ await WaitAsync(tcs, "recovery succeeded");
Assert.True(_channel.IsOpen);
- AssertExchangeRecovery(_channel, exchangeToRecoverSuccessfully);
- AssertExchangeRecovery(_channel, exchangeToRecoverWithException);
+ await AssertExchangeRecoveryAsync(_channel, exchangeToRecoverSuccessfully);
+ await AssertExchangeRecoveryAsync(_channel, exchangeToRecoverWithException);
}
finally
{
- _channel.ExchangeDelete(exchangeToRecoverWithException);
+ await _channel.ExchangeDeleteAsync(exchangeToRecoverWithException);
+
+ await ch.CloseAsync();
+ await conn.CloseAsync();
+ ch.Dispose();
+ conn.Dispose();
}
}
[Fact]
- public void TestTopologyRecoveryBindingExceptionHandler()
+ public async Task TestTopologyRecoveryBindingExceptionHandler()
{
- var latch = new ManualResetEventSlim(false);
+ var connectionRecoveryTcs = new TaskCompletionSource();
- string exchange = "topology.recovery.exchange";
- string queueWithExceptionBinding = "recovery.exception.queue";
- string bindingToRecoverWithException = "recovery.exception.binding";
+ const string exchange = "topology.recovery.exchange";
+ const string queueWithExceptionBinding = "recovery.exception.queue";
+ const string bindingToRecoverWithException = "recovery.exception.binding";
var exceptionHandler = new TopologyRecoveryExceptionHandler
{
@@ -371,48 +422,54 @@ public void TestTopologyRecoveryBindingExceptionHandler()
&& ex is OperationInterruptedException operationInterruptedException
&& operationInterruptedException.ShutdownReason.ReplyCode == Constants.NotFound;
},
- BindingRecoveryExceptionHandler = (b, ex, connection) =>
+ BindingRecoveryExceptionHandlerAsync = async (b, ex, connection) =>
{
- using (IChannel channel = connection.CreateChannel())
+ using (IChannel channel = await connection.CreateChannelAsync())
{
- channel.QueueDeclare(queueWithExceptionBinding, false, false, false, null);
- channel.QueueBind(queueWithExceptionBinding, exchange, bindingToRecoverWithException);
+ await channel.QueueDeclareAsync(queueWithExceptionBinding, false, false, false);
+ await channel.QueueBindAsync(queueWithExceptionBinding, exchange, bindingToRecoverWithException);
+ await channel.CloseAsync();
}
}
};
- using AutorecoveringConnection conn = CreateAutorecoveringConnectionWithTopologyRecoveryExceptionHandler(exceptionHandler);
- conn.RecoverySucceeded += (source, ea) => latch.Set();
- using IChannel ch = conn.CreateChannel();
+ AutorecoveringConnection conn = await CreateAutorecoveringConnectionWithTopologyRecoveryExceptionHandlerAsync(exceptionHandler);
+ conn.RecoverySucceeded += (source, ea) => connectionRecoveryTcs.SetResult(true);
+ IChannel ch = await conn.CreateChannelAsync();
- string queueWithRecoveredBinding = "successfully.recovered.queue";
- string bindingToRecoverSuccessfully = "successfully.recovered.binding";
+ const string queueWithRecoveredBinding = "successfully.recovered.queue";
+ const string bindingToRecoverSuccessfully = "successfully.recovered.binding";
- _channel.QueueDeclare(queueWithExceptionBinding, false, false, false, null);
+ await _channel.QueueDeclareAsync(queueWithExceptionBinding, false, false, false);
- ch.ExchangeDeclare(exchange, "direct");
- ch.QueueDeclare(queueWithRecoveredBinding, false, false, false, null);
- ch.QueueBind(queueWithRecoveredBinding, exchange, bindingToRecoverSuccessfully);
- ch.QueueBind(queueWithExceptionBinding, exchange, bindingToRecoverWithException);
- ch.QueuePurge(queueWithRecoveredBinding);
- ch.QueuePurge(queueWithExceptionBinding);
+ await ch.ExchangeDeclareAsync(exchange, "direct");
+ await ch.QueueDeclareAsync(queueWithRecoveredBinding, false, false, false);
+ await ch.QueueBindAsync(queueWithRecoveredBinding, exchange, bindingToRecoverSuccessfully);
+ await ch.QueueBindAsync(queueWithExceptionBinding, exchange, bindingToRecoverWithException);
+ await ch.QueuePurgeAsync(queueWithRecoveredBinding);
+ await ch.QueuePurgeAsync(queueWithExceptionBinding);
- _channel.QueueUnbind(queueWithRecoveredBinding, exchange, bindingToRecoverSuccessfully);
- _channel.QueueUnbind(queueWithExceptionBinding, exchange, bindingToRecoverWithException);
- _channel.QueueDelete(queueWithExceptionBinding);
+ await _channel.QueueUnbindAsync(queueWithRecoveredBinding, exchange, bindingToRecoverSuccessfully);
+ await _channel.QueueUnbindAsync(queueWithExceptionBinding, exchange, bindingToRecoverWithException);
+ await _channel.QueueDeleteAsync(queueWithExceptionBinding);
- CloseAndWaitForRecovery(conn);
- Wait(latch, "recovery succeeded");
+ await CloseAndWaitForRecoveryAsync(conn);
+ await WaitAsync(connectionRecoveryTcs, "recovery succeeded");
Assert.True(ch.IsOpen);
- Assert.True(SendAndConsumeMessage(conn, queueWithRecoveredBinding, exchange, bindingToRecoverSuccessfully));
- Assert.True(SendAndConsumeMessage(conn, queueWithExceptionBinding, exchange, bindingToRecoverWithException));
+ Assert.True(await SendAndConsumeMessageAsync(conn, queueWithRecoveredBinding, exchange, bindingToRecoverSuccessfully));
+ Assert.True(await SendAndConsumeMessageAsync(conn, queueWithExceptionBinding, exchange, bindingToRecoverWithException));
+
+ await ch.CloseAsync();
+ await conn.CloseAsync();
+ ch.Dispose();
+ conn.Dispose();
}
[Fact]
- public void TestTopologyRecoveryConsumerExceptionHandler()
+ public async Task TestTopologyRecoveryConsumerExceptionHandler()
{
- var latch = new ManualResetEventSlim(false);
+ var connectionRecoveryTcs = new TaskCompletionSource();
string queueWithExceptionConsumer = "recovery.exception.queue";
@@ -424,11 +481,12 @@ public void TestTopologyRecoveryConsumerExceptionHandler()
&& ex is OperationInterruptedException operationInterruptedException
&& operationInterruptedException.ShutdownReason.ReplyCode == Constants.NotFound;
},
- ConsumerRecoveryExceptionHandler = (c, ex, connection) =>
+ ConsumerRecoveryExceptionHandlerAsync = async (c, ex, connection) =>
{
- using (IChannel channel = connection.CreateChannel())
+ using (IChannel channel = await connection.CreateChannelAsync())
{
- channel.QueueDeclare(queueWithExceptionConsumer, false, false, false, null);
+ await channel.QueueDeclareAsync(queueWithExceptionConsumer, false, false, false);
+ await channel.CloseAsync();
}
// So topology recovery runs again. This time he missing queue should exist, making
@@ -437,39 +495,46 @@ public void TestTopologyRecoveryConsumerExceptionHandler()
}
};
- using AutorecoveringConnection conn = CreateAutorecoveringConnectionWithTopologyRecoveryExceptionHandler(exceptionHandler);
- conn.RecoverySucceeded += (source, ea) => latch.Set();
- using IChannel ch = conn.CreateChannel();
- ch.ConfirmSelect();
+ AutorecoveringConnection conn = await CreateAutorecoveringConnectionWithTopologyRecoveryExceptionHandlerAsync(exceptionHandler);
+ conn.RecoverySucceeded += (source, ea) => connectionRecoveryTcs.SetResult(true);
+ IChannel ch = await conn.CreateChannelAsync();
+ try
+ {
+ await ch.ConfirmSelectAsync();
- _channel.QueueDeclare(queueWithExceptionConsumer, false, false, false, null);
- _channel.QueuePurge(queueWithExceptionConsumer);
+ await _channel.QueueDeclareAsync(queueWithExceptionConsumer, false, false, false);
+ await _channel.QueuePurgeAsync(queueWithExceptionConsumer);
- var recoverLatch = new ManualResetEventSlim(false);
- var consumerToRecover = new EventingBasicConsumer(ch);
- consumerToRecover.Received += (source, ea) => recoverLatch.Set();
- ch.BasicConsume(queueWithExceptionConsumer, true, "exception.consumer", consumerToRecover);
+ var recoveredConsumerReceivedTcs = new ManualResetEventSlim(false);
+ var consumerToRecover = new EventingBasicConsumer(ch);
+ consumerToRecover.Received += (source, ea) => recoveredConsumerReceivedTcs.Set();
+ await ch.BasicConsumeAsync(queueWithExceptionConsumer, true, "exception.consumer", consumerToRecover);
- _channel.QueueDelete(queueWithExceptionConsumer);
+ await _channel.QueueDeleteAsync(queueWithExceptionConsumer);
- CloseAndWaitForShutdown(conn);
- Wait(latch, TimeSpan.FromSeconds(20), "recovery succeeded");
+ await CloseAndWaitForShutdownAsync(conn);
+ await WaitAsync(connectionRecoveryTcs, TimeSpan.FromSeconds(20), "recovery succeeded");
- Assert.True(ch.IsOpen);
+ Assert.True(ch.IsOpen);
- ch.BasicPublish("", queueWithExceptionConsumer, _encoding.GetBytes("test message"));
+ await ch.BasicPublishAsync("", queueWithExceptionConsumer, _encoding.GetBytes("test message"));
- Assert.True(recoverLatch.Wait(TimeSpan.FromSeconds(5)));
+ Assert.True(recoveredConsumerReceivedTcs.Wait(TimeSpan.FromSeconds(5)));
- try
- {
- ch.BasicConsume(queueWithExceptionConsumer, true, "exception.consumer", consumerToRecover);
+ await ch.BasicConsumeAsync(queueWithExceptionConsumer, true, "exception.consumer", consumerToRecover);
Assert.Fail("Expected an exception");
}
catch (OperationInterruptedException e)
{
AssertShutdownError(e.ShutdownReason, 530); // NOT_ALLOWED - not allowed to reuse consumer tag
}
+ finally
+ {
+ await ch.CloseAsync();
+ await conn.CloseAsync();
+ ch.Dispose();
+ conn.Dispose();
+ }
}
}
}
diff --git a/projects/Test/Unit/TestIEndpointResolverExtensions.cs b/projects/Test/Unit/TestIEndpointResolverExtensions.cs
index 02bcad74cd..953776b668 100644
--- a/projects/Test/Unit/TestIEndpointResolverExtensions.cs
+++ b/projects/Test/Unit/TestIEndpointResolverExtensions.cs
@@ -66,7 +66,7 @@ public async Task SelectOneShouldReturnDefaultWhenThereAreNoEndpoints()
{
var ep = new TestEndpointResolver(new List());
- static Task selector(AmqpTcpEndpoint ep, CancellationToken ct)
+ Task