Polly integration for WorkflowForge providing advanced resilience patterns including circuit breakers, retries, timeouts, bulkhead isolation, and rate limiting for robust workflow execution.
$ dotnet add package WorkflowForge.Extensions.Resilience.PollyAdvanced resilience extension for WorkflowForge with Polly integration for retry, circuit breaker, timeout, and rate limiting policies.
This extension internalizes Polly with ILRepack. This means:
dotnet add package WorkflowForge.Extensions.Resilience.Polly
Requires: .NET Standard 2.0 or later
using WorkflowForge.Extensions.Resilience.Polly;
using Polly;
// Configure retry policy
var retryPolicy = Policy
.Handle<HttpRequestException>()
.WaitAndRetryAsync(
retryCount: 3,
sleepDurationProvider: attempt => TimeSpan.FromSeconds(Math.Pow(2, attempt)),
onRetry: (exception, timeSpan, retryCount, context) =>
{
logger.LogWarning("Retry {RetryCount} after {Delay}ms",
retryCount, timeSpan.TotalMilliseconds);
});
// Wrap operation with policy
var operation = new PollyWrappedOperation<HttpResponseMessage>(
new CallExternalApiOperation(),
retryPolicy);
var workflow = WorkflowForge.CreateWorkflow("ResilientWorkflow")
.AddOperation(operation)
.Build();
{
"WorkflowForge": {
"Extensions": {
"Polly": {
"Enabled": true,
"EnableComprehensivePolicies": false,
"EnableDetailedLogging": true,
"DefaultTags": {
"environment": "production",
"application": "my-app"
},
"Retry": {
"IsEnabled": true,
"MaxRetryAttempts": 3,
"BaseDelay": "00:00:01",
"BackoffType": "Exponential",
"UseJitter": true
},
"CircuitBreaker": {
"IsEnabled": true,
"FailureThreshold": 5,
"BreakDuration": "00:00:30",
"SamplingDuration": "00:00:30",
"MinimumThroughput": 10
},
"Timeout": {
"IsEnabled": true,
"DefaultTimeout": "00:00:30",
"UseOptimisticTimeout": true
},
"RateLimiter": {
"IsEnabled": false,
"PermitLimit": 100,
"Window": "00:01:00",
"QueueLimit": 0
}
}
}
}
}
using WorkflowForge.Extensions.Resilience.Polly.Options;
var options = new PollyMiddlewareOptions
{
Enabled = true,
Retry = { IsEnabled = true, MaxRetryAttempts = 3, BaseDelay = TimeSpan.FromSeconds(1) },
CircuitBreaker = { IsEnabled = true, FailureThreshold = 5 },
Timeout = { IsEnabled = true, DefaultTimeout = TimeSpan.FromSeconds(30) }
};
foundry.UsePollyFromSettings(options);
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using WorkflowForge.Extensions.Resilience.Polly;
services.AddWorkflowForgePolly(configuration, PollyMiddlewareOptions.DefaultSectionName);
var options = serviceProvider.GetRequiredService<PollyMiddlewareOptions>();
// Development settings (minimal retry)
var devOptions = PollyMiddlewareOptions.ForDevelopment();
// Production settings (retry + circuit breaker)
var prodOptions = PollyMiddlewareOptions.ForProduction();
// Enterprise settings (all policies enabled)
var enterpriseOptions = PollyMiddlewareOptions.ForEnterprise();
// Minimal settings (basic retry only)
var minimalOptions = PollyMiddlewareOptions.Minimal();
See Configuration Guide for complete options.
var retryPolicy = Policy
.Handle<HttpRequestException>()
.WaitAndRetryAsync(3,
attempt => TimeSpan.FromSeconds(Math.Pow(2, attempt)));
var circuitBreakerPolicy = Policy
.Handle<HttpRequestException>()
.CircuitBreakerAsync(5, TimeSpan.FromSeconds(30));
var timeoutPolicy = Policy
.TimeoutAsync(TimeSpan.FromSeconds(30));
var combinedPolicy = Policy.WrapAsync(
retryPolicy,
circuitBreakerPolicy,
timeoutPolicy);