Resilience and retry extension for WorkflowForge workflow engine. Provides circuit breakers, retry strategies, and timeout management for robust workflow execution.
$ dotnet add package WorkflowForge.Extensions.ResilienceBase resilience patterns extension for WorkflowForge with fundamental retry logic and resilience strategies.
This extension has ZERO external dependencies. This means:
Lightweight architecture: Built entirely on WorkflowForge core with no external libraries.
dotnet add package WorkflowForge.Extensions.Resilience
Requires: .NET Standard 2.0 or later
using WorkflowForge.Extensions.Resilience;
using WorkflowForge.Extensions.Resilience.Strategies;
// Wrap operations with retry logic
var resilientOperation = RetryWorkflowOperation.WithExponentialBackoff(
operation: myOperation,
baseDelay: TimeSpan.FromMilliseconds(100),
maxDelay: TimeSpan.FromSeconds(30),
maxAttempts: 3);
// Use in workflow
var workflow = WorkflowForge.CreateWorkflow("ProcessOrder")
.AddOperation("ProcessPayment", resilientOperation)
.Build();
await smith.ForgeAsync(workflow, foundry);
IWorkflowResilienceStrategy interfaceRetryPolicySettingsvar strategy = new ExponentialBackoffStrategy(
maxAttempts: 5,
baseDelay: TimeSpan.FromSeconds(1),
maxDelay: TimeSpan.FromSeconds(60),
logger: logger);
var resilientOp = new RetryWorkflowOperation(myOperation, strategy);
Use when: Calling external APIs, databases, or services that may be temporarily unavailable.
var retryOp = RetryWorkflowOperation.WithFixedInterval(
operation: myOperation,
interval: TimeSpan.FromSeconds(1),
maxAttempts: 5);
Use when: Database queries, file operations, or scenarios where consistent retry timing is needed.
var retryOp = RetryWorkflowOperation.WithRandomInterval(
operation: myOperation,
minDelay: TimeSpan.FromMilliseconds(100),
maxDelay: TimeSpan.FromSeconds(5),
maxAttempts: 3);
Use when: Multiple concurrent workflows might retry simultaneously.
public class CustomRetryStrategy : ResilienceStrategyBase
{
public CustomRetryStrategy(IWorkflowForgeLogger logger)
: base("CustomRetry", logger) { }
public override async Task<bool> ShouldRetryAsync(
int attemptNumber,
Exception exception,
CancellationToken cancellationToken)
{
// Custom retry logic
return attemptNumber < 5 && exception is TransientException;
}
public override TimeSpan GetRetryDelay(int attemptNumber, Exception exception)
{
// Custom delay calculation
return TimeSpan.FromSeconds(Math.Pow(2, attemptNumber));
}
public override async Task ExecuteAsync(
Func<Task> operation,
CancellationToken cancellationToken)
{
// Custom execution logic with retry
}
}
var settings = new RetryPolicySettings
{
MaxAttempts = 3,
BaseDelay = TimeSpan.FromSeconds(1),
MaxDelay = TimeSpan.FromSeconds(30),
UseExponentialBackoff = true,
UseJitter = true
};
This extension uses programmatic configuration only. There is no appsettings.json support. For file-based configuration, use WorkflowForge.Extensions.Resilience.Polly.
using WorkflowForge.Extensions.Resilience;
using WorkflowForge.Extensions.Resilience.Strategies;
// Wrap operations with retry logic
var resilientOperation = RetryWorkflowOperation.WithExponentialBackoff(
operation: myOperation,
baseDelay: TimeSpan.FromMilliseconds(100),
maxDelay: TimeSpan.FromSeconds(30),
maxAttempts: 3);
// Or use specific strategies
var strategy = new ExponentialBackoffStrategy(
maxAttempts: 5,
baseDelay: TimeSpan.FromSeconds(1),
maxDelay: TimeSpan.FromSeconds(60),
logger: logger);
var resilientOp = new RetryWorkflowOperation(myOperation, strategy);
// Add to workflow
var workflow = WorkflowForge.CreateWorkflow("ResilientProcess")
.AddOperation("ProcessWithRetry", resilientOp)
.Build();
Strategies Available:
ExponentialBackoffStrategy - Best for external servicesFixedIntervalStrategy - Best for databasesRandomIntervalStrategy - Prevents thundering herdSee Configuration Guide for complete options.
public interface IWorkflowResilienceStrategy
{
string Name { get; }
Task<bool> ShouldRetryAsync(int attemptNumber, Exception exception, CancellationToken cancellationToken);
TimeSpan GetRetryDelay(int attemptNumber, Exception exception);
Task ExecuteAsync(Func<Task> operation, CancellationToken cancellationToken);
Task<T> ExecuteAsync<T>(Func<Task<T>> operation, CancellationToken cancellationToken);
}
Use Resilience (this extension) when:
Use Resilience.Polly extension when:
Resilience.Polly internalizes Polly with ILRepack; this extension has no third-party dependencies.
See Sample 14: PollyResilienceSample for complete examples of resilience patterns.
MIT License - see LICENSE for details.