ResilienceContext
A context assigned to a single execution of ResilienceStrategy. It is created manually or automatically
when the user calls the various extensions on top of ResilienceStrategy. After every execution the context should be discarded and returned to the pool.
using Polly.Telemetry;
using Polly.Utils;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
using System.Threading;
namespace Polly
{
[System.Runtime.CompilerServices.NullableContext(1)]
[System.Runtime.CompilerServices.Nullable(0)]
public sealed class ResilienceContext
{
[System.Runtime.CompilerServices.NullableContext(0)]
private static class UnknownResult
{
}
private const bool ContinueOnCapturedContextDefault = false;
private static readonly ObjectPool<ResilienceContext> Pool = new ObjectPool<ResilienceContext>(() => new ResilienceContext(), (ResilienceContext c) => c.Reset());
private readonly List<ResilienceEvent> _resilienceEvents = new List<ResilienceEvent>();
[System.Runtime.CompilerServices.Nullable(2)]
[field: System.Runtime.CompilerServices.Nullable(2)]
public string OperationKey {
[System.Runtime.CompilerServices.NullableContext(2)]
get;
[System.Runtime.CompilerServices.NullableContext(2)]
private set;
}
public CancellationToken CancellationToken { get; set; }
public bool IsSynchronous { get; set; }
public Type ResultType { get; set; } = typeof(UnknownResult);
public bool IsVoid => ResultType == typeof(VoidResult);
public bool ContinueOnCapturedContext { get; set; }
internal bool IsInitialized => ResultType != typeof(UnknownResult);
public ResilienceProperties Properties { get; set; } = new ResilienceProperties();
public IReadOnlyList<ResilienceEvent> ResilienceEvents => _resilienceEvents;
private ResilienceContext()
{
}
public static ResilienceContext Get(CancellationToken cancellationToken = default(CancellationToken))
{
ResilienceContext resilienceContext = Pool.Get();
resilienceContext.CancellationToken = cancellationToken;
return resilienceContext;
}
public static ResilienceContext Get(string operationKey, CancellationToken cancellationToken = default(CancellationToken))
{
ResilienceContext resilienceContext = Pool.Get();
resilienceContext.OperationKey = operationKey;
resilienceContext.CancellationToken = cancellationToken;
return resilienceContext;
}
internal void InitializeFrom(ResilienceContext context)
{
OperationKey = context.OperationKey;
ResultType = context.ResultType;
IsSynchronous = context.IsSynchronous;
CancellationToken = context.CancellationToken;
ContinueOnCapturedContext = context.ContinueOnCapturedContext;
_resilienceEvents.Clear();
_resilienceEvents.AddRange(context.ResilienceEvents);
}
public static void Return(ResilienceContext context)
{
Guard.NotNull(context, "context");
Pool.Return(context);
}
[ExcludeFromCodeCoverage]
[Conditional("DEBUG")]
internal void AssertInitialized()
{
}
internal ResilienceContext Initialize<[System.Runtime.CompilerServices.Nullable(2)] TResult>(bool isSynchronous)
{
IsSynchronous = isSynchronous;
ResultType = typeof(TResult);
ContinueOnCapturedContext = false;
return this;
}
internal void AddResilienceEvent(ResilienceEvent event)
{
_resilienceEvents.Add(event);
}
internal bool Reset()
{
OperationKey = null;
IsSynchronous = false;
ResultType = typeof(UnknownResult);
ContinueOnCapturedContext = false;
CancellationToken = default(CancellationToken);
((ICollection<KeyValuePair<string, object>>)Properties).Clear();
_resilienceEvents.Clear();
return true;
}
}
}