TaskExecution<T>
Represents a single hedging attempt execution alongside all the necessary resources. These are:
Distinct ResilienceContext instance for this execution.
One exception are primary task where the main context is reused.
The cancellation token associated with the execution.
using Polly.Hedging.Utils;
using Polly.Telemetry;
using Polly.Utils;
using System;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
namespace Polly.Hedging.Controller
{
[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(0)]
internal sealed class TaskExecution<[System.Runtime.CompilerServices.Nullable(2)] T>
{
private readonly ResilienceContext _cachedContext = ResilienceContextPool.Shared.Get(default(CancellationToken));
private readonly CancellationTokenSourcePool _cancellationTokenSourcePool;
private readonly TimeProvider _timeProvider;
private readonly ResilienceStrategyTelemetry _telemetry;
private readonly HedgingHandler<T> _handler;
[System.Runtime.CompilerServices.Nullable(2)]
private CancellationTokenSource _cancellationSource;
private CancellationTokenRegistration? _cancellationRegistration;
[System.Runtime.CompilerServices.Nullable(2)]
private ResilienceContext _activeContext;
private long _startExecutionTimestamp;
private long _stopExecutionTimestamp;
[System.Runtime.CompilerServices.Nullable(2)]
[field: System.Runtime.CompilerServices.Nullable(2)]
public Task ExecutionTaskSafe {
[System.Runtime.CompilerServices.NullableContext(2)]
get;
[System.Runtime.CompilerServices.NullableContext(2)]
private set;
}
[System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
[field: System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
public Outcome<T> Outcome {
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
get;
[param: System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
private set;
}
public bool IsHandled { get; set; }
public bool IsAccepted { get; set; }
public ResilienceContext Context {
get {
ResilienceContext activeContext = _activeContext;
if (activeContext == null)
throw new InvalidOperationException("TaskExecution is not initialized.");
return activeContext;
}
}
public HedgedTaskType Type { get; set; }
[System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1,
1
})]
[field: System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1,
1
})]
public Action<TaskExecution<T>> OnReset {
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1,
1
})]
get;
[param: System.Runtime.CompilerServices.Nullable(new byte[] {
2,
1,
1
})]
set;
}
public TimeSpan ExecutionTime => _timeProvider.GetElapsedTime(_startExecutionTimestamp, _stopExecutionTimestamp);
public int AttemptNumber { get; set; }
public TaskExecution(HedgingHandler<T> handler, CancellationTokenSourcePool cancellationTokenSourcePool, TimeProvider timeProvider, ResilienceStrategyTelemetry telemetry)
{
_handler = handler;
_cancellationTokenSourcePool = cancellationTokenSourcePool;
_timeProvider = timeProvider;
_telemetry = telemetry;
}
public void AcceptOutcome()
{
if (ExecutionTaskSafe?.IsCompleted ?? false) {
IsAccepted = true;
return;
}
throw new InvalidOperationException("Unable to accept outcome for a task that is not completed.");
}
public void Cancel()
{
if (!IsAccepted)
_cancellationSource.Cancel();
}
[AsyncStateMachine(typeof(<InitializeAsync>d__45<>))]
[return: System.Runtime.CompilerServices.Nullable(0)]
public ValueTask<bool> InitializeAsync<[System.Runtime.CompilerServices.Nullable(2)] TState>(HedgedTaskType type, ResilienceContext primaryContext, [System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
1,
0,
0,
1
})] Func<ResilienceContext, TState, ValueTask<Outcome<T>>> primaryCallback, TState state, int attemptNumber)
{
<InitializeAsync>d__45<TState> stateMachine = default(<InitializeAsync>d__45<TState>);
stateMachine.<>t__builder = AsyncValueTaskMethodBuilder<bool>.Create();
stateMachine.<>4__this = this;
stateMachine.type = type;
stateMachine.primaryContext = primaryContext;
stateMachine.primaryCallback = primaryCallback;
stateMachine.state = state;
stateMachine.attemptNumber = attemptNumber;
stateMachine.<>1__state = -1;
stateMachine.<>t__builder.Start(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
[AsyncStateMachine(typeof(TaskExecution<>.<HandleOnHedgingAsync>d__46))]
private Task HandleOnHedgingAsync(ResilienceContext primaryContext, int attemptNumber)
{
<HandleOnHedgingAsync>d__46 stateMachine = default(<HandleOnHedgingAsync>d__46);
stateMachine.<>t__builder = AsyncTaskMethodBuilder.Create();
stateMachine.<>4__this = this;
stateMachine.primaryContext = primaryContext;
stateMachine.attemptNumber = attemptNumber;
stateMachine.<>1__state = -1;
stateMachine.<>t__builder.Start<<HandleOnHedgingAsync>d__46>(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
private HedgingActionGeneratorArguments<TResult> CreateArguments<[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>>> primaryCallback, ResilienceContext primaryContext, TState state, int attempt)
{
return new HedgingActionGeneratorArguments<TResult>(primaryContext, this.Context, attempt, (Func<ResilienceContext, ValueTask<Outcome<TResult>>>)((ResilienceContext context) => primaryCallback(context, state)));
}
[AsyncStateMachine(typeof(TaskExecution<>.<ResetAsync>d__48))]
public ValueTask ResetAsync()
{
<ResetAsync>d__48 stateMachine = default(<ResetAsync>d__48);
stateMachine.<>t__builder = AsyncValueTaskMethodBuilder.Create();
stateMachine.<>4__this = this;
stateMachine.<>1__state = -1;
stateMachine.<>t__builder.Start<<ResetAsync>d__48>(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
[AsyncStateMachine(typeof(TaskExecution<>.<ExecuteSecondaryActionAsync>d__49))]
private Task ExecuteSecondaryActionAsync([System.Runtime.CompilerServices.Nullable(new byte[] {
1,
0,
0,
1
})] Func<ValueTask<Outcome<T>>> action)
{
<ExecuteSecondaryActionAsync>d__49 stateMachine = default(<ExecuteSecondaryActionAsync>d__49);
stateMachine.<>t__builder = AsyncTaskMethodBuilder.Create();
stateMachine.<>4__this = this;
stateMachine.action = action;
stateMachine.<>1__state = -1;
stateMachine.<>t__builder.Start<<ExecuteSecondaryActionAsync>d__49>(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
[AsyncStateMachine(typeof(TaskExecution<>.<ExecuteCreateActionException>d__50))]
private Task ExecuteCreateActionException(Exception e)
{
<ExecuteCreateActionException>d__50 stateMachine = default(<ExecuteCreateActionException>d__50);
stateMachine.<>t__builder = AsyncTaskMethodBuilder.Create();
stateMachine.<>4__this = this;
stateMachine.e = e;
stateMachine.<>1__state = -1;
stateMachine.<>t__builder.Start<<ExecuteCreateActionException>d__50>(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
[AsyncStateMachine(typeof(<ExecutePrimaryActionAsync>d__51<>))]
private Task ExecutePrimaryActionAsync<[System.Runtime.CompilerServices.Nullable(2)] TState>([System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
1,
0,
0,
1
})] Func<ResilienceContext, TState, ValueTask<Outcome<T>>> primaryCallback, TState state)
{
<ExecutePrimaryActionAsync>d__51<TState> stateMachine = default(<ExecutePrimaryActionAsync>d__51<TState>);
stateMachine.<>t__builder = AsyncTaskMethodBuilder.Create();
stateMachine.<>4__this = this;
stateMachine.primaryCallback = primaryCallback;
stateMachine.state = state;
stateMachine.<>1__state = -1;
stateMachine.<>t__builder.Start<<ExecutePrimaryActionAsync>d__51<TState>>(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
[AsyncStateMachine(typeof(TaskExecution<>.<UpdateOutcomeAsync>d__52))]
private Task UpdateOutcomeAsync([System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})] Outcome<T> outcome)
{
<UpdateOutcomeAsync>d__52 stateMachine = default(<UpdateOutcomeAsync>d__52);
stateMachine.<>t__builder = AsyncTaskMethodBuilder.Create();
stateMachine.<>4__this = this;
stateMachine.outcome = outcome;
stateMachine.<>1__state = -1;
stateMachine.<>t__builder.Start<<UpdateOutcomeAsync>d__52>(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
}
}