Skip to content

MostafaChronic/SmartRetryENG

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

17 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

SmartRetry: Robust Retry Logic for .NET Applications

Table of Contents

Introduction

SmartRetry is a lightweight and powerful .NET library that simplifies the implementation of robust retry logic in your applications. It is designed to handle transient faults, which are temporary issues that might occur in network requests, database operations, or interactions with other external resources. By automatically retrying failed operations, SmartRetry helps improve the resilience and reliability of your .NET applications.

Key Features

  • Automatic Retries: Automatically retries operations that fail due to transient faults.
  • Exponential Backoff: Gradually increases the delay between retry attempts. This is useful to prevent overwhelming a service that is temporarily overloaded.
  • Jitter: Adds randomness to the delay between retries, which helps distribute retries evenly and avoid thundering herd problems.
  • Customizable Retry Logic: Allows you to customize the retry behavior using RetryOptions, such as the maximum number of retries, the base delay, and the conditions under which retries should be performed.
  • Dependency Injection (DI) Friendly: Designed to integrate seamlessly with the .NET dependency injection system.
  • Non Retryable Exceptions: This feature allows you to define exceptions that should not be retried.
  • RetryFailedException: Provides detailed information about why an operation failed after multiple retry attempts.

Installation

Install the SmartRetry package via NuGet:


πŸ“¦ Installation

Install via NuGet:

dotnet add package Engine.SmartRetry --version 1.0.1

⚑ Getting Started

1. Register in Program.cs

builder.Services.AddSmartRetry(); // Registers SmartRetry services

πŸ’‰ Inject & Use the Retry Executor

You can use IBackoffStrategy into your app: For Exmaple Console application

 class Program
{
    static async Task Main(string[] args)
    {
        // 1. Set up Dependency Injection
        var services = new ServiceCollection();
        ConfigureServices(services);

        var serviceProvider = services.BuildServiceProvider();

        // 2. Resolve Dependencies
        var backoffStrategy = serviceProvider.GetRequiredService<IBackoffStrategy>();

        var retryOptions = serviceProvider.GetRequiredService<RetryOptions>();

        // 3.  Use RetryExecutor
        async Task OperationToRetry()
        {
            Console.WriteLine("Attempting operation...");
            // Simulate a potentially failing operation (e.g., HTTP request)
            try
            {
                var client = new HttpClient();
                var response = await client.GetAsync("https://www.google.com/nonexistent"); // Simulate failure
                response.EnsureSuccessStatusCode();
                Console.WriteLine("Operation succeeded!");
            }
            catch (HttpRequestException ex)
            {
                Console.WriteLine($"  Operation failed: {ex.Message}");
                throw; // Re-throw to trigger retry
            }
        }

        try
        {
            await RetryExecutor.ExecuteAsync(OperationToRetry, backoffStrategy, retryOptions);
            Console.WriteLine("Operation completed successfully after retries (if needed).");
        }
        catch (RetryFailedException ex)
        {
            Console.WriteLine($"Operation failed after all retries: {ex.Message}");
            Console.WriteLine($"  Inner Exception: {ex.InnerException.Message}");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"An unexpected error occurred: {ex.Message}");
        }
    }

    static void ConfigureServices(IServiceCollection services)
    { 
        services.AddSmartRetryWithDefaults(); 
    }
}

βš™οΈ Custom Retry Options

You can customize retry behavior using RetryOptions:

var options = new RetryOptions
{
    MaxRetries = 1,
    BaseDelayMs = 100,
    MaxDelayMs = 2000,
    Jitter = JitterStrategy.Decorrelated,
    ShouldRetryOnException = ex => ex is TimeoutException 
    || (ex is HttpRequestException httpEx && httpEx.StatusCode >= HttpStatusCode.InternalServerError) 
};

await _executor.ExecuteAsync(
    async () => await httpClient.GetAsync("https://api.example.com"),
    options: options
);

πŸ” Backoff & Jitter Strategy

Built-in backoff strategies include:

  • Exponential backoff
  • Full jitter / equal jitter

You can implement your own by extending IBackoffStrategy.


πŸ§ͺ Running Tests

Run Unit & Integration Tests with Coverage

dotnet test --collect:"XPlat Code Coverage"

The test results will be stored in a subfolder of /TestResults/.


πŸ“Š Generate Code Coverage Report

Use tools like ReportGenerator:

reportgenerator -reports:**/coverage.cobertura.xml -targetdir:coverage-report

Then open coverage-report/index.html in your browser to view results.

πŸ“ Project Structure

SmartRetry/
β”‚
β”œβ”€β”€ Abstractions/         # Interfaces like IRetryStrategy, IBackoffStrategy
β”œβ”€β”€ Models/               # RetryOptions, RetryFailedException
β”œβ”€β”€ Strategies/           # Built-in retry/backoff strategies
β”œβ”€β”€ SmartRetry.csproj     # Main library
β”‚
β”œβ”€β”€ SmartRetry.Test/              # Unit tests
β”œβ”€β”€ SmartRetry.IntegrationTests/  # Integration tests

🀝 Contributing

Feel free to submit issues or pull requests. All contributions are welcome and appreciated!


πŸ“„ License

This project is licensed under the MIT License.

About

SmartRetry is a lightweight and extensible retry mechanism for .NET applications. It provides customizable retry policies, exponential backoff with jitter, and clean integration with DI. Ideal for handling transient errors in HTTP calls, databases, or any unreliable operations.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages