-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
Closed as not planned
Labels
Description
Is your feature request related to a specific problem? Or an existing feature?
Polly already supports 2 main core concepts:
- Resilience Policy
- Resilience Pipeline
What I want to is:
- Add Resilience Execution Concept & Abstraction for reducing effort when we write Lamba or callback with [Resilience Pipeline] (https://www.pollydocs.org/pipelines/index.html).
I used it somewhere but wanted to contribute it back to Polly as I think it should be general and after it is added in polly, user can create resilience business logic easily & quickly. It can also be used for non-http related resilience.
Sample usage:
// 1. Config Hedging & Timeout
ResiliencePipelineBuilder<HttpResponseMessage> builder =
new ResiliencePipelineBuilder<HttpResponseMessage>();
builder = builder.AddHedging(
new Polly.Hedging.HedgingStrategyOptions<HttpResponseMessage>
{
Delay = TimeSpan.FromSeconds(2),
MaxHedgedAttempts = 1,
ShouldHandle = async args =>
{
return await Task.FromResult(args.Outcome.Result?.IsSuccessStatusCode ?? true);
},
});
builder.AddTimeout(TimeSpan.FromSeconds(25));
// 2. Build pipeline
ResiliencePipeline<HttpResponseMessage> pipeline = builder.Build();
// 3. Config ResilienceInvoker with multiple HttpClients
FakeHttpClient fakeHttpClientA = new FakeHttpClient("A", 20);
FakeHttpClient fakeHttpClientB = new FakeHttpClient("B", 5);
// 4. runtime
using HttpRequestMessage httpRequestMessage = new HttpRequestMessage();
CancellationToken cancellationToken = new CancellationToken(false);
// Invokers per request or we may have thread safety issue
ResilienceInvoker<HttpResponseMessage, HttpRequestMessage> resilienceInvoker = new ResilienceInvoker<HttpResponseMessage, HttpRequestMessage>(
pipeline,
// Create one composite invoker internally
new List<IInvoker<HttpResponseMessage, HttpRequestMessage>>
{
// Add multiple HttpClient here
fakeHttpClientA,
fakeHttpClientB
});
HttpResponseMessage httpResponseMessage = await resilienceInvoker.ExecuteAsync(httpRequestMessage, cancellationToken);
Assert.Equal(HttpStatusCode.OK, httpResponseMessage.StatusCode);
Assert.True(fakeHttpClientA.CalledNumber == 1 || fakeHttpClientB.CalledNumber == 1);
Describe the solution you'd like
/// <summary>
/// IInvoker interface: work together with Polly ResiliencePipeline as callback
/// See: https://www.pollydocs.org/pipelines/index.html .
/// </summary>
/// <typeparam name="TResult">The type of the result.</typeparam>
/// <typeparam name="TInput">The type of the input.</typeparam>
public interface IInvoker
<TResult, TInput>
{
/// <summary>
/// Execute the request.
/// </summary>
/// <param name="request">The request.</param>
/// <param name="cancellationToken">The cancellationToken.</param>
/// <returns>The result.</returns>
Task<TResult> ExecuteAsync(TInput request, CancellationToken cancellationToken);
}
classDiagram
IInvoker <|-- CompositeInvoker
IInvoker <|-- ResilienceInvoker
class IInvoker{
-//Execution abstraction
-ExecuteAsync()
}
class CompositeInvoker{
-IList _invokers
+ExecuteAsync()
}
class ResilienceInvoker{
+ResiliencePipeline _resiliencePipeline
+CompositeInvoker _compositeInvoker
+ExecuteAsync()
}
Additional context
IInvoker could be public.
CompositeInvoker could reuse current Composite infra in Polly Core.
No response