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.Diagnostics;
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;
}
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})]
private HedgingActionGeneratorArguments<T> CreateArguments<[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, ResilienceContext primaryContext, TState state, int attempt)
{
return new HedgingActionGeneratorArguments<T>(primaryContext, this.Context, attempt, (Func<ResilienceContext, ValueTask<Outcome<T>>>)((ResilienceContext context) => primaryCallback(context, state)));
}
[AsyncStateMachine(typeof(TaskExecution<>.<ResetAsync>d__47))]
public ValueTask ResetAsync()
{
<ResetAsync>d__47 stateMachine = default(<ResetAsync>d__47);
stateMachine.<>t__builder = AsyncValueTaskMethodBuilder.Create();
stateMachine.<>4__this = this;
stateMachine.<>1__state = -1;
stateMachine.<>t__builder.Start<<ResetAsync>d__47>(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
[AsyncStateMachine(typeof(<ExecuteSecondaryActionAsync>d__48<>))]
[System.Diagnostics.DebuggerDisableUserUnhandledExceptions]
private Task ExecuteSecondaryActionAsync<[System.Runtime.CompilerServices.Nullable(2)] TState>([System.Runtime.CompilerServices.Nullable(new byte[] {
2,
0,
0,
1
})] Func<ValueTask<Outcome<T>>> action, [System.Runtime.CompilerServices.Nullable(new byte[] {
1,
1,
1,
0,
0,
1
})] Func<ResilienceContext, TState, ValueTask<Outcome<T>>> primaryCallback, TState state, bool isSynchronous)
{
<ExecuteSecondaryActionAsync>d__48<TState> stateMachine = default(<ExecuteSecondaryActionAsync>d__48<TState>);
stateMachine.<>t__builder = AsyncTaskMethodBuilder.Create();
stateMachine.<>4__this = this;
stateMachine.action = action;
stateMachine.primaryCallback = primaryCallback;
stateMachine.state = state;
stateMachine.isSynchronous = isSynchronous;
stateMachine.<>1__state = -1;
stateMachine.<>t__builder.Start<<ExecuteSecondaryActionAsync>d__48<TState>>(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
[return: System.Runtime.CompilerServices.Nullable(new byte[] {
0,
0,
1
})]
private ValueTask<Outcome<T>> ExecuteSecondaryActionSync<[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)
{
return new ValueTask<Outcome<T>>(Task.Run<Outcome<T>>((Func<Task<Outcome<T>>>)(() => primaryCallback(this.Context, state).AsTask())));
}
[AsyncStateMachine(typeof(<ExecutePrimaryActionAsync>d__50<>))]
[System.Diagnostics.DebuggerDisableUserUnhandledExceptions]
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__50<TState> stateMachine = default(<ExecutePrimaryActionAsync>d__50<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__50<TState>>(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
[AsyncStateMachine(typeof(TaskExecution<>.<UpdateOutcomeAsync>d__51))]
private Task UpdateOutcomeAsync([System.Runtime.CompilerServices.Nullable(new byte[] {
0,
1
})] Outcome<T> outcome)
{
<UpdateOutcomeAsync>d__51 stateMachine = default(<UpdateOutcomeAsync>d__51);
stateMachine.<>t__builder = AsyncTaskMethodBuilder.Create();
stateMachine.<>4__this = this;
stateMachine.outcome = outcome;
stateMachine.<>1__state = -1;
stateMachine.<>t__builder.Start<<UpdateOutcomeAsync>d__51>(ref stateMachine);
return stateMachine.<>t__builder.Task;
}
}
}