Class Shield<TResult>
- Namespace
- Kevlar
- Assembly
- Kevlar.dll
An immutable, thread-safe, result-aware resilience pipeline for executions returning
TResult. Unlike Shield, its handling clauses can react to
result values (WhenResult) as well as exceptions. The first strategy in a chain is the
outermost.
public sealed class Shield<TResult>
Type Parameters
TResult
- Inheritance
-
Shield<TResult>
- Inherited Members
- Extension Methods
Properties
Empty
A shield with no strategies: executions pass straight through.
public static Shield<TResult> Empty { get; }
Property Value
- Shield<TResult>
InvokesContinuationAtMostOnce
Gets whether every strategy guarantees invoking the execution continuation at most once. Custom strategies may opt in through InvokesContinuationAtMostOnce.
public bool InvokesContinuationAtMostOnce { get; }
Property Value
Remarks
A live-forwarding shield reports false because a later publication may introduce retry, hedging, or another multi-attempt strategy.
Name
The shield's diagnostic name, if assigned via WithName(string).
public string? Name { get; }
Property Value
Methods
CircuitBreaker(Action<CircuitBreakerOptions<TResult>>)
Adds a circuit breaker strategy configured via configure.
public Shield<TResult> CircuitBreaker(Action<CircuitBreakerOptions<TResult>> configure)
Parameters
configureAction<CircuitBreakerOptions<TResult>>
Returns
- Shield<TResult>
CircuitBreaker(int, TimeSpan)
Breaks the circuit for breakDuration after consecutiveFailures consecutive handled outcomes.
public Shield<TResult> CircuitBreaker(int consecutiveFailures, TimeSpan breakDuration)
Parameters
Returns
- Shield<TResult>
Compose(params Shield<TResult>[])
Merges result-aware shields into one pipeline. The first shield is the outermost. Stateful strategies keep their identity, so a shared circuit breaker shield shares its circuit here. The result keeps the first non-null Name and TimeProvider among the inputs. Composition seals handling clauses, so reactive strategies appended afterwards use default handling unless a new clause is declared.
public static Shield<TResult> Compose(params Shield<TResult>[] shields)
Parameters
shieldsShield<TResult>[]
Returns
- Shield<TResult>
ConcurrencyLimit(Action<ConcurrencyLimitOptions>)
Adds a concurrency limit strategy configured via configure.
public Shield<TResult> ConcurrencyLimit(Action<ConcurrencyLimitOptions> configure)
Parameters
configureAction<ConcurrencyLimitOptions>
Returns
- Shield<TResult>
ConcurrencyLimit(int, int)
Caps concurrent executions at maxConcurrency with an optional wait queue.
public Shield<TResult> ConcurrencyLimit(int maxConcurrency, int queueLimit = 0)
Parameters
Returns
- Shield<TResult>
Execute(Func<CancellationToken, TResult>, CancellationToken)
Executes the delegate synchronously through the pipeline. Delays block the calling thread. Hedging is not supported synchronously.
public TResult Execute(Func<CancellationToken, TResult> action, CancellationToken cancellationToken = default)
Parameters
actionFunc<CancellationToken, TResult>cancellationTokenCancellationToken
Returns
- TResult
ExecuteAsync(Func<CancellationToken, ValueTask<TResult>>, CancellationToken)
Executes the delegate through the pipeline. The delegate must use the cancellation token it is handed.
public ValueTask<TResult> ExecuteAsync(Func<CancellationToken, ValueTask<TResult>> action, CancellationToken cancellationToken = default)
Parameters
actionFunc<CancellationToken, ValueTask<TResult>>cancellationTokenCancellationToken
Returns
- ValueTask<TResult>
ExecuteAsync<TState>(TState, Func<TState, CancellationToken, ValueTask<TResult>>, CancellationToken)
Executes the delegate through the pipeline, threading state to avoid closure allocations.
public ValueTask<TResult> ExecuteAsync<TState>(TState state, Func<TState, CancellationToken, ValueTask<TResult>> action, CancellationToken cancellationToken = default)
Parameters
stateTStateactionFunc<TState, CancellationToken, ValueTask<TResult>>cancellationTokenCancellationToken
Returns
- ValueTask<TResult>
Type Parameters
TState
ExecuteOutcome(Func<CancellationToken, TResult>, CancellationToken)
Executes the delegate synchronously and returns its outcome instead of throwing.
public Outcome<TResult> ExecuteOutcome(Func<CancellationToken, TResult> action, CancellationToken cancellationToken = default)
Parameters
actionFunc<CancellationToken, TResult>cancellationTokenCancellationToken
Returns
- Outcome<TResult>
ExecuteOutcomeAsync(Func<CancellationToken, ValueTask<TResult>>, CancellationToken)
Executes the delegate through the pipeline and returns the outcome instead of throwing.
public ValueTask<Outcome<TResult>> ExecuteOutcomeAsync(Func<CancellationToken, ValueTask<TResult>> action, CancellationToken cancellationToken = default)
Parameters
actionFunc<CancellationToken, ValueTask<TResult>>cancellationTokenCancellationToken
Returns
ExecuteOutcomeAsync<TState>(TState, Func<TState, CancellationToken, ValueTask<TResult>>, CancellationToken)
Executes the delegate through the pipeline, threading state to avoid closure allocations,
and returns the outcome instead of throwing.
public ValueTask<Outcome<TResult>> ExecuteOutcomeAsync<TState>(TState state, Func<TState, CancellationToken, ValueTask<TResult>> action, CancellationToken cancellationToken = default)
Parameters
stateTStateactionFunc<TState, CancellationToken, ValueTask<TResult>>cancellationTokenCancellationToken
Returns
Type Parameters
TState
ExecuteOutcome<TState>(TState, Func<TState, CancellationToken, TResult>, CancellationToken)
Executes the delegate synchronously, threading state to avoid closure
allocations, and returns its outcome instead of throwing.
public Outcome<TResult> ExecuteOutcome<TState>(TState state, Func<TState, CancellationToken, TResult> action, CancellationToken cancellationToken = default)
Parameters
stateTStateactionFunc<TState, CancellationToken, TResult>cancellationTokenCancellationToken
Returns
- Outcome<TResult>
Type Parameters
TState
ExecuteWithContext(KevlarContext, Func<KevlarContext, TResult>)
Executes a context-aware delegate synchronously through the pipeline using the properties,
cancellation token, and time provider from parentContext.
public TResult ExecuteWithContext(KevlarContext parentContext, Func<KevlarContext, TResult> action)
Parameters
parentContextKevlarContextactionFunc<KevlarContext, TResult>
Returns
- TResult
ExecuteWithContext(Func<KevlarContext, TResult>, CancellationToken)
Executes a context-aware delegate synchronously through the pipeline without seeding execution properties. The context is pooled and is valid only for the duration of the delegate invocation; never retain it.
public TResult ExecuteWithContext(Func<KevlarContext, TResult> action, CancellationToken cancellationToken = default)
Parameters
actionFunc<KevlarContext, TResult>cancellationTokenCancellationToken
Returns
- TResult
ExecuteWithContextAsync(KevlarContext, Func<KevlarContext, ValueTask<TResult>>)
Executes a context-aware delegate through the pipeline using the properties, cancellation
token, and time provider from parentContext.
public ValueTask<TResult> ExecuteWithContextAsync(KevlarContext parentContext, Func<KevlarContext, ValueTask<TResult>> action)
Parameters
parentContextKevlarContextactionFunc<KevlarContext, ValueTask<TResult>>
Returns
- ValueTask<TResult>
ExecuteWithContextAsync(Func<KevlarContext, ValueTask<TResult>>, CancellationToken)
Executes a context-aware delegate through the pipeline without seeding execution properties. The context is pooled and is valid only for the duration of the delegate invocation; never retain it.
public ValueTask<TResult> ExecuteWithContextAsync(Func<KevlarContext, ValueTask<TResult>> action, CancellationToken cancellationToken = default)
Parameters
actionFunc<KevlarContext, ValueTask<TResult>>cancellationTokenCancellationToken
Returns
- ValueTask<TResult>
ExecuteWithContextAsync<TState>(KevlarContext, TState, Func<TState, KevlarContext, ValueTask<TResult>>)
Executes a context-aware delegate through the pipeline using the properties, cancellation
token, and time provider from parentContext, threading
state to avoid closure allocations.
public ValueTask<TResult> ExecuteWithContextAsync<TState>(KevlarContext parentContext, TState state, Func<TState, KevlarContext, ValueTask<TResult>> action)
Parameters
parentContextKevlarContextstateTStateactionFunc<TState, KevlarContext, ValueTask<TResult>>
Returns
- ValueTask<TResult>
Type Parameters
TState
ExecuteWithContextAsync<TState>(TState, Action<TState, KevlarProperties>, Func<TState, KevlarContext, ValueTask<TResult>>, Action<TState, KevlarProperties>, CancellationToken)
Initializes execution properties, executes a context-aware delegate, then exposes the final
properties to onCompleted before the pooled context is returned.
public ValueTask<TResult> ExecuteWithContextAsync<TState>(TState state, Action<TState, KevlarProperties> initializeProperties, Func<TState, KevlarContext, ValueTask<TResult>> action, Action<TState, KevlarProperties> onCompleted, CancellationToken cancellationToken = default)
Parameters
stateTStateinitializePropertiesAction<TState, KevlarProperties>actionFunc<TState, KevlarContext, ValueTask<TResult>>onCompletedAction<TState, KevlarProperties>cancellationTokenCancellationToken
Returns
- ValueTask<TResult>
Type Parameters
TState
ExecuteWithContextAsync<TState>(TState, Action<TState, KevlarProperties>, Func<TState, KevlarContext, ValueTask<TResult>>, CancellationToken)
Initializes execution properties, then executes a context-aware delegate through the pipeline. The context is pooled and is valid only for the duration of the delegate invocation; never retain it.
public ValueTask<TResult> ExecuteWithContextAsync<TState>(TState state, Action<TState, KevlarProperties> initializeProperties, Func<TState, KevlarContext, ValueTask<TResult>> action, CancellationToken cancellationToken = default)
Parameters
stateTStateinitializePropertiesAction<TState, KevlarProperties>actionFunc<TState, KevlarContext, ValueTask<TResult>>cancellationTokenCancellationToken
Returns
- ValueTask<TResult>
Type Parameters
TState
ExecuteWithContext<TState>(KevlarContext, TState, Func<TState, KevlarContext, TResult>)
Executes a context-aware delegate synchronously through the pipeline using the properties,
cancellation token, and time provider from parentContext, threading
state to avoid closure allocations.
public TResult ExecuteWithContext<TState>(KevlarContext parentContext, TState state, Func<TState, KevlarContext, TResult> action)
Parameters
parentContextKevlarContextstateTStateactionFunc<TState, KevlarContext, TResult>
Returns
- TResult
Type Parameters
TState
ExecuteWithContext<TState>(TState, Action<TState, KevlarProperties>, Func<TState, KevlarContext, TResult>, CancellationToken)
Initializes execution properties, then executes a context-aware delegate synchronously through the pipeline. The context is pooled and is valid only for the duration of the delegate invocation; never retain it.
public TResult ExecuteWithContext<TState>(TState state, Action<TState, KevlarProperties> initializeProperties, Func<TState, KevlarContext, TResult> action, CancellationToken cancellationToken = default)
Parameters
stateTStateinitializePropertiesAction<TState, KevlarProperties>actionFunc<TState, KevlarContext, TResult>cancellationTokenCancellationToken
Returns
- TResult
Type Parameters
TState
Execute<TState>(TState, Func<TState, CancellationToken, TResult>, CancellationToken)
Executes the delegate synchronously, threading state to avoid closure allocations.
public TResult Execute<TState>(TState state, Func<TState, CancellationToken, TResult> action, CancellationToken cancellationToken = default)
Parameters
stateTStateactionFunc<TState, CancellationToken, TResult>cancellationTokenCancellationToken
Returns
- TResult
Type Parameters
TState
Fallback(Func<Outcome<TResult>, CancellationToken, ValueTask<TResult>>)
Replaces handled outcomes with the result of fallback, which receives the handled outcome.
public Shield<TResult> Fallback(Func<Outcome<TResult>, CancellationToken, ValueTask<TResult>> fallback)
Parameters
fallbackFunc<Outcome<TResult>, CancellationToken, ValueTask<TResult>>
Returns
- Shield<TResult>
Fallback(Func<Outcome<TResult>, CancellationToken, ValueTask<TResult>>, Action<FallbackOptions<TResult>>)
Replaces handled outcomes with the result of fallback, which receives
the handled outcome, and configures notifications.
public Shield<TResult> Fallback(Func<Outcome<TResult>, CancellationToken, ValueTask<TResult>> fallback, Action<FallbackOptions<TResult>> configure)
Parameters
fallbackFunc<Outcome<TResult>, CancellationToken, ValueTask<TResult>>configureAction<FallbackOptions<TResult>>
Returns
- Shield<TResult>
Remarks
Runs and awaits OnFallback before recovery. Notification failures are reported and recovery continues.
Fallback(Func<CancellationToken, ValueTask<TResult>>)
Replaces handled outcomes with the result of fallback.
public Shield<TResult> Fallback(Func<CancellationToken, ValueTask<TResult>> fallback)
Parameters
fallbackFunc<CancellationToken, ValueTask<TResult>>
Returns
- Shield<TResult>
Fallback(Func<CancellationToken, ValueTask<TResult>>, Action<FallbackOptions<TResult>>)
Replaces handled outcomes with the result of fallback and configures notifications.
public Shield<TResult> Fallback(Func<CancellationToken, ValueTask<TResult>> fallback, Action<FallbackOptions<TResult>> configure)
Parameters
fallbackFunc<CancellationToken, ValueTask<TResult>>configureAction<FallbackOptions<TResult>>
Returns
- Shield<TResult>
Remarks
Runs and awaits OnFallback before recovery. Notification failures are reported and recovery continues.
FallbackTo(TResult)
Replaces handled outcomes with fallbackValue.
public Shield<TResult> FallbackTo(TResult fallbackValue)
Parameters
fallbackValueTResult
Returns
- Shield<TResult>
FallbackTo(TResult, Action<FallbackOptions<TResult>>)
Replaces handled outcomes with fallbackValue and configures notifications.
public Shield<TResult> FallbackTo(TResult fallbackValue, Action<FallbackOptions<TResult>> configure)
Parameters
fallbackValueTResultconfigureAction<FallbackOptions<TResult>>
Returns
- Shield<TResult>
Remarks
Runs and awaits OnFallback before recovery. Notification failures are reported and recovery continues.
Hedge(Action<HedgeOptions<TResult>>)
Adds a hedging strategy configured via configure.
public Shield<TResult> Hedge(Action<HedgeOptions<TResult>> configure)
Parameters
configureAction<HedgeOptions<TResult>>
Returns
- Shield<TResult>
Hedge(int, TimeSpan)
Races the primary with up to maxHedgedAttempts additional attempts staggered by delay; first acceptable outcome wins.
public Shield<TResult> Hedge(int maxHedgedAttempts, TimeSpan delay)
Parameters
maxHedgedAttemptsintMaximum additional attempts after the primary attempt.
delayTimeSpanThe delay between attempts. Zero launches attempts in parallel; any negative value launches another attempt only after a handled failure.
Returns
- Shield<TResult>
RateLimit(Action<RateLimitOptions>)
Adds a rate limit strategy configured via configure.
public Shield<TResult> RateLimit(Action<RateLimitOptions> configure)
Parameters
configureAction<RateLimitOptions>
Returns
- Shield<TResult>
RateLimit(int, TimeSpan)
Limits throughput to permits executions per perWindow (token bucket).
public Shield<TResult> RateLimit(int permits, TimeSpan perWindow)
Parameters
Returns
- Shield<TResult>
Retry(Action<RetryOptions<TResult>>)
Adds a retry strategy configured via configure. The options expose
result-typed events: OnRetry and DelayGenerator receive a
RetryEvent<TResult> carrying the handled Outcome<T>.
public Shield<TResult> Retry(Action<RetryOptions<TResult>> configure)
Parameters
configureAction<RetryOptions<TResult>>
Returns
- Shield<TResult>
Remarks
MaxRetries counts retries, not attempts:
MaxRetries = 3 makes up to 4 total attempts — the initial call plus 3 retries.
Retry(int)
Retries handled outcomes up to maxRetries times with
Default: exponential from 250 milliseconds with factor 2, equal
jitter, and a 30-second cap.
public Shield<TResult> Retry(int maxRetries = 3)
Parameters
maxRetriesintThe number of retries, not the number of attempts:
Retry(3)makes up to 4 total attempts — the initial call plus 3 retries.
Returns
- Shield<TResult>
Retry(int, Backoff)
Retries handled outcomes up to maxRetries times with the given backoff.
public Shield<TResult> Retry(int maxRetries, Backoff backoff)
Parameters
maxRetriesintThe number of retries, not the number of attempts:
Retry(3)makes up to 4 total attempts — the initial call plus 3 retries.backoffBackoffThe delay computation applied between attempts.
Returns
- Shield<TResult>
RetryForever()
Retries handled outcomes indefinitely with Default: exponential from 250 milliseconds with factor 2, equal jitter, and a 30-second cap.
public Shield<TResult> RetryForever()
Returns
- Shield<TResult>
RetryForever(Backoff)
Retries handled outcomes indefinitely with the given backoff.
public Shield<TResult> RetryForever(Backoff backoff)
Parameters
backoffBackoffThe delay computation applied between attempts.
Returns
- Shield<TResult>
Timeout(Action<TimeoutOptions>)
Adds a timeout strategy configured via configure.
public Shield<TResult> Timeout(Action<TimeoutOptions> configure)
Parameters
configureAction<TimeoutOptions>
Returns
- Shield<TResult>
Timeout(TimeSpan)
Cancels executions that exceed timeout, surfacing TimeoutExceededException.
public Shield<TResult> Timeout(TimeSpan timeout)
Parameters
timeoutTimeSpan
Returns
- Shield<TResult>
ToString()
Describes the pipeline, outermost strategy first, like ToString().
public override string ToString()
Returns
Use(Strategy)
Appends a custom Strategy implementation to the pipeline.
public Shield<TResult> Use(Strategy strategy)
Parameters
strategyStrategy
Returns
- Shield<TResult>
Use(Func<HandlingClause, Strategy>)
Appends a custom strategy created from the active handling clause. The factory runs once; reactive custom strategies should retain and consult the supplied clause.
public Shield<TResult> Use(Func<HandlingClause, Strategy> factory)
Parameters
factoryFunc<HandlingClause, Strategy>
Returns
- Shield<TResult>
When(Func<Exception, bool>)
Starts a handling clause for exceptions matching predicate. Use WithDefaultHandling() to return to default handling.
public ShieldBuilder<TResult> When(Func<Exception, bool> predicate)
Parameters
Returns
- ShieldBuilder<TResult>
WhenContext(Func<HandlingEvent<TResult>, bool>)
Starts a handling clause using the typed outcome and active execution context.
public ShieldBuilder<TResult> WhenContext(Func<HandlingEvent<TResult>, bool> predicate)
Parameters
predicateFunc<HandlingEvent<TResult>, bool>
Returns
- ShieldBuilder<TResult>
WhenInner<TException>()
Starts a handling clause for exceptions containing an exception of type TException. Use WithDefaultHandling() to return to default handling.
public ShieldBuilder<TResult> WhenInner<TException>() where TException : Exception
Returns
- ShieldBuilder<TResult>
Type Parameters
TException
Remarks
The outer exception, ordinary inner-exception chains, and every branch of an AggregateException are searched.
WhenInner<TException>(Func<TException, bool>)
Starts a handling clause for exceptions containing an exception of type TException matching predicate. Use WithDefaultHandling() to return to default handling.
public ShieldBuilder<TResult> WhenInner<TException>(Func<TException, bool> predicate) where TException : Exception
Parameters
Returns
- ShieldBuilder<TResult>
Type Parameters
TException
Remarks
The outer exception, ordinary inner-exception chains, and every branch of an AggregateException are searched.
WhenResult(Func<TResult, bool>)
Starts a handling clause for results matching predicate. Use WithDefaultHandling() to return to default handling.
public ShieldBuilder<TResult> WhenResult(Func<TResult, bool> predicate)
Parameters
Returns
- ShieldBuilder<TResult>
WhenResultContext(Func<HandlingEvent<TResult>, bool>)
Starts a result handling clause using the typed outcome and active execution context.
public ShieldBuilder<TResult> WhenResultContext(Func<HandlingEvent<TResult>, bool> predicate)
Parameters
predicateFunc<HandlingEvent<TResult>, bool>
Returns
- ShieldBuilder<TResult>
WhenResultEquals(TResult)
Starts a handling clause for results equal to result. Use WithDefaultHandling() to return to default handling.
public ShieldBuilder<TResult> WhenResultEquals(TResult result)
Parameters
resultTResult
Returns
- ShieldBuilder<TResult>
WhenResultIsDefault()
Starts a handling clause for results equal to default(TResult) — null
for reference types. Use WithDefaultHandling() to return to default handling.
public ShieldBuilder<TResult> WhenResultIsDefault()
Returns
- ShieldBuilder<TResult>
Remarks
For a reference type prefer WhenResultIsNull<TResult>(Shield<TResult>),
which says what it matches. This method stays for value types and generic code, where
default(TResult) — 0, false — may or may not be a failure.
When<TException>()
Starts a handling clause: subsequent reactive strategies act on exceptions of type TException. Use WithDefaultHandling() to return to default handling.
public ShieldBuilder<TResult> When<TException>() where TException : Exception
Returns
- ShieldBuilder<TResult>
Type Parameters
TException
When<TException>(Func<TException, bool>)
Starts a handling clause for exceptions of type TException matching predicate. Use WithDefaultHandling() to return to default handling.
public ShieldBuilder<TResult> When<TException>(Func<TException, bool> predicate) where TException : Exception
Parameters
Returns
- ShieldBuilder<TResult>
Type Parameters
TException
WithDefaultHandling()
Resets the ambient handling clause. Subsequent reactive strategies use the default handling defined by Default.
public Shield<TResult> WithDefaultHandling()
Returns
- Shield<TResult>
WithName(string)
Returns a copy of this shield with a diagnostic name (surfaced as ShieldName).
public Shield<TResult> WithName(string name)
Parameters
namestring
Returns
- Shield<TResult>
WithTimeProvider(TimeProvider)
Returns a copy of this shield using the given TimeProvider for delays, timeouts and time windows.
public Shield<TResult> WithTimeProvider(TimeProvider timeProvider)
Parameters
timeProviderTimeProvider
Returns
- Shield<TResult>
Wrap(Shield)
Wraps inner inside this shield: this shield's strategies run outermost.
The first non-null name and time provider win. Composition seals handling clauses, so reactive
strategies appended afterwards use default handling unless a new clause is declared.
public Shield<TResult> Wrap(Shield inner)
Parameters
innerShield
Returns
- Shield<TResult>
Wrap(Shield<TResult>)
Wraps inner inside this shield: this shield's strategies run outermost.
The first non-null name and time provider win. Composition seals handling clauses, so reactive
strategies appended afterwards use default handling unless a new clause is declared.
public Shield<TResult> Wrap(Shield<TResult> inner)
Parameters
innerShield<TResult>
Returns
- Shield<TResult>