<PackageReference Include="Polly.Core" Version="8.0.0-alpha.7" />

ResilienceStrategyPipeline

A pipeline of strategies.
using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Runtime.CompilerServices; using System.Threading.Tasks; namespace Polly.Utils { [System.Runtime.CompilerServices.NullableContext(1)] [System.Runtime.CompilerServices.Nullable(0)] [DebuggerDisplay("ResilienceStrategyPipeline, Strategies = {Strategies.Count}")] [DebuggerTypeProxy(typeof(DebuggerProxy))] internal sealed class ResilienceStrategyPipeline : ResilienceStrategy { [System.Runtime.CompilerServices.NullableContext(2)] [System.Runtime.CompilerServices.Nullable(0)] private sealed class DelegatingResilienceStrategy : ResilienceStrategy { [System.Runtime.CompilerServices.Nullable(1)] private readonly ResilienceStrategy _strategy; public ResilienceStrategy Next { get; set; } [System.Runtime.CompilerServices.NullableContext(1)] public DelegatingResilienceStrategy(ResilienceStrategy strategy) { _strategy = strategy; } [System.Runtime.CompilerServices.NullableContext(1)] [return: System.Runtime.CompilerServices.Nullable(new byte[] { 0, 0, 1 })] protected internal override ValueTask<Outcome<TResult>> ExecuteCore<[System.Runtime.CompilerServices.Nullable(2)] TResult, [System.Runtime.CompilerServices.Nullable(2)] TState>([System.Runtime.CompilerServices.Nullable(new byte[] { 1, 1, 1, 0, 0, 1 })] Func<ResilienceContext, TState, ValueTask<Outcome<TResult>>> callback, ResilienceContext context, TState state) { return _strategy.ExecuteCore(delegate(ResilienceContext context, (ResilienceStrategy Next, Func<ResilienceContext, TState, ValueTask<Outcome<TResult>>> callback, TState state) state) { if (context.CancellationToken.IsCancellationRequested) return Outcome.FromExceptionAsTask<TResult>((Exception)ExceptionUtilities.TrySetStackTrace<OperationCanceledException>(new OperationCanceledException(context.CancellationToken))); return state.Next.ExecuteCore<TResult, TState>(state.callback, context, state.state); }, context, (Next, callback, state)); } } [System.Runtime.CompilerServices.Nullable(0)] internal sealed class DebuggerProxy { private readonly ResilienceStrategyPipeline _resilienceStrategy; [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] public IEnumerable<ResilienceStrategy> Strategies { get { return _resilienceStrategy.Strategies; } } public DebuggerProxy(ResilienceStrategyPipeline resilienceStrategy) { _resilienceStrategy = resilienceStrategy; } } private readonly ResilienceStrategy _pipeline; public IReadOnlyList<ResilienceStrategy> Strategies { get; } public static ResilienceStrategyPipeline CreatePipeline(IReadOnlyList<ResilienceStrategy> strategies) { Guard.NotNull(strategies, "strategies"); if (strategies.Count < 2) throw new InvalidOperationException("The resilience pipeline must contain at least two resilience strategies."); if (strategies.Distinct().Count() != strategies.Count) throw new InvalidOperationException("The resilience pipeline must contain unique resilience strategies."); List<DelegatingResilienceStrategy> list = (from strategy in strategies.Take(strategies.Count - 1) select new DelegatingResilienceStrategy(strategy)).ToList(); List<DelegatingResilienceStrategy> list2 = list; list2[list2.Count - 1].Next = strategies[strategies.Count - 1]; for (int i = 0; i < list.Count - 1; i++) { list[i].Next = list[i + 1]; } return new ResilienceStrategyPipeline(list[0], strategies); } private ResilienceStrategyPipeline(ResilienceStrategy pipeline, IReadOnlyList<ResilienceStrategy> strategies) { Strategies = strategies; _pipeline = pipeline; } [return: System.Runtime.CompilerServices.Nullable(new byte[] { 0, 0, 1 })] protected internal override ValueTask<Outcome<TResult>> ExecuteCore<[System.Runtime.CompilerServices.Nullable(2)] TResult, [System.Runtime.CompilerServices.Nullable(2)] TState>([System.Runtime.CompilerServices.Nullable(new byte[] { 1, 1, 1, 0, 0, 1 })] Func<ResilienceContext, TState, ValueTask<Outcome<TResult>>> callback, ResilienceContext context, TState state) { if (context.CancellationToken.IsCancellationRequested) return Outcome.FromExceptionAsTask<TResult>(new OperationCanceledException(context.CancellationToken).TrySetStackTrace()); return _pipeline.ExecuteCore(callback, context, state); } } }