PollyRabbitMQ 1.0.3
dotnet add package PollyRabbitMQ --version 1.0.3
NuGet\Install-Package PollyRabbitMQ -Version 1.0.3
<PackageReference Include="PollyRabbitMQ" Version="1.0.3" />
<PackageVersion Include="PollyRabbitMQ" Version="1.0.3" />
<PackageReference Include="PollyRabbitMQ" />
paket add PollyRabbitMQ --version 1.0.3
#r "nuget: PollyRabbitMQ, 1.0.3"
#:package PollyRabbitMQ@1.0.3
#addin nuget:?package=PollyRabbitMQ&version=1.0.3
#tool nuget:?package=PollyRabbitMQ&version=1.0.3
PollyRabbitMQ
Polly v8 resilience for RabbitMQ.Client v7+ — retry, circuit-breaker, and timeout for IChannel operations, with a built-in RabbitMqTransientErrors predicate covering the most common RabbitMQ transient exceptions. Includes automatic channel recreation between retries so AlreadyClosedException never kills your publisher.
// Before — crashes on broker restart
await channel.BasicPublishAsync("orders", "order.placed", body: payload);
// After — retry + channel recreation + circuit breaker
var resilient = await connection.CreateResilientChannelAsync(options =>
{
options.MaxRetries = 3;
options.RecreateChannelOnFailure = true; // rebuild channel between retries ✔
});
await resilient.BasicPublishAsync("orders", "order.placed", body: payload);
Installation
dotnet add package PollyRabbitMQ
Targets net6.0, net8.0, and net9.0.
Dependencies: Polly.Core 8.*, RabbitMQ.Client 7.*, Microsoft.Extensions.DependencyInjection.Abstractions 8.*
RabbitMqTransientErrors — the key feature
PollyRabbitMQ ships RabbitMqTransientErrors.IsTransient — a pre-built PredicateBuilder covering the four most common transient RabbitMQ exceptions:
new RetryStrategyOptions
{
MaxRetryAttempts = 3,
ShouldHandle = RabbitMqTransientErrors.IsTransient, // built-in ✔
}
Covered exceptions
| Exception | When it occurs |
|---|---|
AlreadyClosedException |
Channel or connection closed by the broker (most common) |
OperationInterruptedException |
Operation interrupted mid-flight (e.g. during broker restart) |
BrokerUnreachableException |
Cannot reach the broker — all endpoints tried |
ConnectFailureException |
TCP connect to a broker endpoint failed |
The critical one:
AlreadyClosedExceptionis thrown when the broker closes a channel while your app is publishing. Without retry, this crashes your publisher. WithPollyRabbitMQandRecreateChannelOnFailure = true, the channel is rebuilt transparently before each retry.
Quick start
Option 1 — Options-based (recommended)
using PollyRabbitMQ;
var factory = new ConnectionFactory { HostName = "localhost" };
await using var connection = await factory.CreateConnectionAsync();
await using var resilient = await connection.CreateResilientChannelAsync(options =>
{
options.MaxRetries = 3;
options.BaseDelay = TimeSpan.FromMilliseconds(500);
options.MaxDelay = TimeSpan.FromSeconds(30);
options.OperationTimeout = TimeSpan.FromSeconds(15);
options.RecreateChannelOnFailure = true;
options.CircuitBreakerFailureRatio = 0.5;
options.CircuitBreakerMinimumThroughput = 10;
options.CircuitBreakerBreakDuration = TimeSpan.FromSeconds(5);
});
// Publish
await resilient.BasicPublishAsync("orders", "order.placed", body: payload);
// Consume single message
var message = await resilient.BasicGetAsync("order-queue", autoAck: false);
if (message is not null)
{
// Process...
await resilient.BasicAckAsync(message.DeliveryTag);
}
// Topology
await resilient.QueueDeclareAsync("order-queue", durable: true);
await resilient.ExchangeDeclareAsync("orders", ExchangeType.Direct, durable: true);
Option 2 — Dependency injection
// Program.cs
builder.Services.AddResilientRabbitMqChannel(
configureFactory: factory =>
{
factory.HostName = "localhost";
factory.UserName = "guest";
factory.Password = "guest";
},
configureOptions: options =>
{
options.MaxRetries = 3;
options.RecreateChannelOnFailure = true;
});
// Publisher
public class OrderPublisher(ResilientChannel channel)
{
public Task PublishAsync(ReadOnlyMemory<byte> payload, CancellationToken ct = default) =>
channel.BasicPublishAsync("orders", "order.placed", payload, cancellationToken: ct);
}
Supported operations
| Method | Description |
|---|---|
BasicPublishAsync |
Publish a message to an exchange |
BasicGetAsync |
Poll a queue for one message |
BasicAckAsync |
Acknowledge a delivered message |
BasicNackAsync |
Negatively acknowledge (optionally requeue) |
QueueDeclareAsync |
Declare a queue |
ExchangeDeclareAsync |
Declare an exchange |
How channel recreation works
When RecreateChannelOnFailure = true (default) and a transient error occurs, ResilientChannel will:
- Detect the failure (catch
AlreadyClosedExceptionetc.) - Check if the current channel is closed
- Create a new
IChannelfrom the same connection before the next retry attempt - Transparently continue — your code doesn't change
This is critical for long-running publishers that survive broker restarts.
Pipeline order
[Timeout] → [Retry + channel recreation] → [Circuit Breaker] → [RabbitMQ broker]
Related Packages
| Package | Downloads | Description |
|---|---|---|
| PollyHealthChecks | ASP.NET Core health checks for Polly v8 circuit breakers — expose circuit-breaker state (Closed, HalfOpen, Open, Isolated) as /health endpoint responses | |
| PollyBackoff | Backoff delay strategies for Polly v8 resilience pipelines | |
| PollyGrpc | Polly v8 resilience interceptor for gRPC | |
| PollyEFCore | Polly v8 resilience pipelines for Entity Framework Core — wrap every EF Core query and SaveChanges with retry, timeout and circuit-breaker via a single AddPollyResilience() call | |
| PollyMailKit | Polly v8 resilience pipelines for MailKit — retry, timeout, and circuit-breaker for SmtpClient.SendAsync and any MailKit SMTP operation | |
| PollyMassTransit | Polly v8 resilience pipelines for MassTransit — retry, timeout, and circuit-breaker for IBus.Publish and ISendEndpointProvider.Send | |
| PollyNpgsql | Polly v8 resilience pipelines for Npgsql (PostgreSQL) — retry, timeout, and circuit-breaker for NpgsqlConnection queries and commands, plus a built-in PostgresTransientErrors predicate covering all common PostgreSQL transient SQLSTATE codes | |
| PollyOpenAI | Polly v8 resilience for OpenAI and Azure OpenAI API calls | |
| PollyAzureEventHub | Polly v8 resilience pipelines for Azure Event Hubs — retry, timeout, and circuit-breaker for EventHubProducerClient and EventHubConsumerClient | |
| PollyElasticsearch | Polly v8 resilience pipelines for Elastic.Clients.Elasticsearch 8+ — retry, timeout, and circuit-breaker for any Elasticsearch operation, plus a built-in ElasticTransientErrors predicate covering rate limiting (429), service unavailability (503), gateway timeouts (504), and connection failures | |
| PollyHangfire | Polly v8 resilience pipelines for Hangfire — retry, timeout, and circuit-breaker for IBackgroundJobClient.Enqueue and Schedule | |
| PollyCosmosDb | Polly v8 resilience pipelines for Azure Cosmos DB — retry, timeout, and circuit-breaker for Container operations, plus a built-in CosmosTransientErrors predicate covering rate limiting (429), timeouts (408), partition failovers (410), and service unavailability (503) | |
| PollySendGrid | Polly v8 resilience pipelines for SendGrid — retry, timeout, and circuit-breaker for ISendGridClient.SendEmailAsync | |
| PollyMongo | Polly v8 resilience pipelines for MongoDB.Driver — wrap Find, InsertOne, UpdateOne, DeleteOne and other IMongoCollection calls with retry, timeout, circuit-breaker, and more using a single ResilientMongoCollection decorator | |
| PollyDapper | Polly v8 resilience pipelines for Dapper — wrap QueryAsync, ExecuteAsync, and other Dapper calls with retry, timeout, circuit-breaker, and more using a single ResilientDbConnection decorator | |
| PollyMediatR | Polly v8 resilience pipelines for MediatR — add retry, timeout, circuit-breaker, rate-limiting, hedging, and chaos engineering to any MediatR request handler with a single line of DI registration | |
| PollySqlClient | Polly v8 resilience pipelines for Microsoft.Data.SqlClient (SQL Server and Azure SQL) — retry, timeout, and circuit-breaker for SqlConnection queries and commands, plus a built-in SqlServerTransientErrors predicate covering all common SQL Server and Azure SQL transient error numbers | |
| PollyAzureKeyVault | Polly v8 resilience pipelines for Azure Key Vault — retry, timeout, and circuit-breaker for SecretClient, KeyClient, and CertificateClient | |
| PollyAzureQueueStorage | Polly v8 resilience pipelines for Azure Queue Storage — retry, timeout, and circuit-breaker for Azure.Storage.Queues QueueClient | |
| PollyRedis | Polly v8 resilience for StackExchange.Redis | |
| PollyAzureServiceBus | Polly v8 resilience for Azure Service Bus — retry, circuit breaker, and timeout for sending and receiving messages | |
| PollyAzureTableStorage | Polly v8 resilience pipelines for Azure Table Storage — retry, timeout, and circuit-breaker for Azure.Data.Tables TableClient |
💼 Need .NET consulting?
The author of this package is available for consulting on Polly v8 resilience, Azure cloud architecture, and clean .NET design.
→ solidqualitysolutions.com · LinkedIn
License
MIT
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.2)
- Polly.Core (>= 8.7.0)
- RabbitMQ.Client (>= 7.2.2)
-
net6.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.2)
- Polly.Core (>= 8.7.0)
- RabbitMQ.Client (>= 7.2.2)
-
net8.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.2)
- Polly.Core (>= 8.7.0)
- RabbitMQ.Client (>= 7.2.2)
-
net9.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.2)
- Polly.Core (>= 8.7.0)
- RabbitMQ.Client (>= 7.2.2)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
1.0.3: Add net10.0 target framework support. 1.0.2: Fix package icon (was showing an incorrect/placeholder image). 1.0.0: Initial release. ResilientChannel wraps IChannel with Polly v8 retry, circuit-breaker, and timeout. RabbitMqTransientErrors exposes a pre-built ShouldHandle predicate. Automatic channel recreation between retries. Supports net6.0, net8.0, net9.0, and net10.0.