ToolWheel.Extensions.JobManager.Resilience
1.0.0-preview6
dotnet add package ToolWheel.Extensions.JobManager.Resilience --version 1.0.0-preview6
NuGet\Install-Package ToolWheel.Extensions.JobManager.Resilience -Version 1.0.0-preview6
<PackageReference Include="ToolWheel.Extensions.JobManager.Resilience" Version="1.0.0-preview6" />
<PackageVersion Include="ToolWheel.Extensions.JobManager.Resilience" Version="1.0.0-preview6" />
<PackageReference Include="ToolWheel.Extensions.JobManager.Resilience" />
paket add ToolWheel.Extensions.JobManager.Resilience --version 1.0.0-preview6
#r "nuget: ToolWheel.Extensions.JobManager.Resilience, 1.0.0-preview6"
#:package ToolWheel.Extensions.JobManager.Resilience@1.0.0-preview6
#addin nuget:?package=ToolWheel.Extensions.JobManager.Resilience&version=1.0.0-preview6&prerelease
#tool nuget:?package=ToolWheel.Extensions.JobManager.Resilience&version=1.0.0-preview6&prerelease
ToolWheel.Extensions.JobManager.Resilience
Adds resilience patterns to the ToolWheel Job Manager: circuit breaker, configurable retry strategies and per-operation/total timeouts.
Package Info
| Property | Value |
|---|---|
| Target Framework | net8.0 |
| NuGet Package ID | ToolWheel.Extensions.JobManager.Resilience |
| Project Reference | ToolWheel.Extensions.JobManager.Abstractions |
| Package Dependencies | Microsoft.Extensions.Logging.Abstractions |
Auto Configuration
This package ships JobManagerResilienceConfigurator implementing IAutoFeatureConfigurator. When AddJobManager() scans loaded assemblies it automatically:
- Registers
IRetryService,ICircuitBreakerServiceandITimeoutServiceas singletons. - Adds
CircuitBreakerMiddleware,TotalTimeoutMiddleware,RetryMiddlewareandOperationTimeoutMiddlewareto the pipeline (in that order). - Adds
CircuitBreakerConditionas anIExecutionCondition.
No manual registration is required – referencing the package is sufficient.
Per-job configuration flows through each feature's Apply method called by IJobService.Add:
| Feature | Apply calls |
|---|---|
RetryFeature |
IRetryService.UpdateRetryConfiguration |
CircuitBreakerFeature |
ICircuitBreakerService.UpdateConfiguration |
TimeoutFeature |
ITimeoutService.UpdateConfiguration |
Fluent Configuration
All resilience features are reached via a single .Resilience() entry point:
jobs.Add("import-job", worker.RunImport)
.Name("Data Import")
.Enabled()
.Resilience()
.WithCircuitBreaker(failureThreshold: 3, openDuration: TimeSpan.FromMinutes(2))
.WithExponentialRetry(maxAttempts: 3, initialDelay: TimeSpan.FromSeconds(2))
.WithTimeout(t => t
.WithOperationTimeout(TimeSpan.FromSeconds(30))
.WithTotalTimeout(TimeSpan.FromMinutes(2)))
.JobBuilder;
Circuit Breaker
Prevents a job from starting when the circuit is open (too many recent failures). The circuit transitions through three states:
| State | Behaviour |
|---|---|
| Closed | Execution is allowed normally. |
| Open | Execution is blocked. CircuitBreakerCondition returns NotReady. |
| Half-Open | One probe execution is allowed to test recovery. |
Configuration
// Shorthand
.WithCircuitBreaker(failureThreshold: 5, openDuration: TimeSpan.FromMinutes(1))
// Full configuration
.WithCircuitBreaker(cb => cb
.WithFailureThreshold(3)
.WithOpenDuration(TimeSpan.FromSeconds(30))
.WithSuccessThreshold(2) // successes in half-open to close
.WithSamplingDuration(TimeSpan.FromMinutes(5)) // rolling failure window
.OnlyFor(typeof(HttpRequestException), typeof(TimeoutException)))
How It Works
CircuitBreakerConditionblocks execution when the circuit is open.CircuitBreakerMiddlewarerecords the outcome of each execution (RecordFailure/RecordSuccess).- After
FailureThresholdfailures the circuit opens. - After
OpenDurationelapses, the circuit transitions to half-open and allows one probe. - After
SuccessThresholdconsecutive successes in half-open state, the circuit closes.
Retry
Automatically retries a failed job execution with configurable delay strategies.
Configuration
// Exponential backoff
.WithExponentialRetry(maxAttempts: 3, initialDelay: TimeSpan.FromSeconds(1))
// Linear delay
.WithLinearRetry(maxAttempts: 5, delay: TimeSpan.FromSeconds(10))
// Full configuration
.WithRetry(r => r
.WithMaxAttempts(4)
.WithStrategy(RetryStrategy.Exponential)
.WithInitialDelay(TimeSpan.FromSeconds(2))
.WithMaxDelay(TimeSpan.FromMinutes(5))
.WithBackoffMultiplier(2.0)
.OnlyFor(typeof(HttpRequestException)))
Retry Strategies
| Strategy | Delay calculation |
|---|---|
Linear |
Constant delay between every attempt. |
Exponential |
initialDelay × multiplier^attempt, capped at MaxDelay. |
Retries stop when the maximum number of attempts is reached, a non-retryable exception is thrown, or the total timeout (if configured) is exceeded.
Timeout
Two independent timeouts can be configured:
| Timeout | Scope | Middleware |
|---|---|---|
OperationTimeout |
Each individual attempt (including retries). | OperationTimeoutMiddleware |
TotalTimeout |
All attempts combined. | TotalTimeoutMiddleware |
Configuration
.WithTimeout(t => t
.WithOperationTimeout(TimeSpan.FromSeconds(30))
.WithTotalTimeout(TimeSpan.FromMinutes(2))
.WithTimeoutException(true)) // throw JobTimeoutException instead of OperationCanceledException
Middleware Execution Order
The pipeline order is fixed by JobManagerResilienceConfigurator:
Request
└─ CircuitBreakerMiddleware (1 – blocks if circuit is open)
└─ TotalTimeoutMiddleware (2 – deadline for all attempts)
└─ RetryMiddleware (3 – retry loop)
└─ OperationTimeoutMiddleware (4 – timeout per attempt)
└─ Job TargetMethod
API Reference
Extension Method
IJobDescriptionResilienceBuilder Resilience(this IJobDescriptionBuilder builder)
Services
| Interface | Description |
|---|---|
ICircuitBreakerService |
Manages circuit states. Supports CanExecute, RecordSuccess, RecordFailure, Reset, UpdateConfiguration. |
IRetryService |
Stores and retrieves retry configurations per job. |
ITimeoutService |
Stores and retrieves timeout configurations per job. |
Features
| Type | Stores |
|---|---|
CircuitBreakerFeature |
FailureThreshold, OpenDuration, SuccessThreshold, SamplingDuration, FailureExceptionTypes. |
RetryFeature |
MaxRetryAttempts, InitialDelay, Strategy, MaxDelay, BackoffMultiplier, RetryOnExceptionTypes. |
TimeoutFeature |
OperationTimeout, TotalTimeout, ThrowTimeoutException. |
Conditions
| Type | Blocks when |
|---|---|
CircuitBreakerCondition |
The circuit breaker for the job is in the open state. |
Middleware
| Type | Purpose |
|---|---|
CircuitBreakerMiddleware |
Records success/failure outcomes and manages state transitions. |
RetryMiddleware |
Retries failed executions with the configured delay strategy. |
OperationTimeoutMiddleware |
Cancels an individual attempt after the configured timeout. |
TotalTimeoutMiddleware |
Cancels all further retries after the total timeout deadline. |
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | 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 was computed. 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
- Cronos (>= 0.11.1)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.5)
- ToolWheel.Extensions.JobManager.Abstractions (>= 1.0.0-preview6)
-
net8.0
- Cronos (>= 0.11.1)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.5)
- ToolWheel.Extensions.JobManager.Abstractions (>= 1.0.0-preview6)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.0-preview6 | 55 | 3/26/2026 |
| 1.0.0-preview5 | 57 | 2/21/2026 |