admin管理员组

文章数量:1277900

I have an older policy that fallsback to a custom action.

// Several other overloads including one that's synchronous and has `void` as a return type. 
// Required as some of our older services have not been asyncified yet
public void RetryWithPolicy(Action action) { 
    var policy = Policy.Handle<BrokenCircuitException>()
                                 .Fallback(_ => action())
                                 .Wrap(someCircuitBreakerPolicy)
                                 .Wrap(someWaitAndRetryPolicy);

    policy.Execute(action);
}

I'm unable to find a way to do this using the new resilience strategy properly? Is the correct way to add a hedging strategy that allows the callback to be re-executed? Looking at the fallback strategy, I wasn't able to find a way to execute the callback?

I have an older policy that fallsback to a custom action.

// Several other overloads including one that's synchronous and has `void` as a return type. 
// Required as some of our older services have not been asyncified yet
public void RetryWithPolicy(Action action) { 
    var policy = Policy.Handle<BrokenCircuitException>()
                                 .Fallback(_ => action())
                                 .Wrap(someCircuitBreakerPolicy)
                                 .Wrap(someWaitAndRetryPolicy);

    policy.Execute(action);
}

I'm unable to find a way to do this using the new resilience strategy properly? Is the correct way to add a hedging strategy that allows the callback to be re-executed? Looking at the fallback strategy, I wasn't able to find a way to execute the callback?

Share Improve this question edited Feb 25 at 9:17 Peter Csala 22.8k16 gold badges48 silver badges92 bronze badges asked Feb 25 at 2:15 SamIAmSamIAm 2,4897 gold badges38 silver badges55 bronze badges 1
  • @SamlAm Did my proposed solution help you to solve your issue? Do you have further questions? – Peter Csala Commented Feb 27 at 8:02
Add a comment  | 

1 Answer 1

Reset to default 0

In case of V8 the top-level data structure is the ResiliencePipeline. In order to create a pipeline, you should use the ResiliencePipelineBuilder to register multiple changed strategies. (In V8 the resilience patterns are called strategies, whereas in V7 they are called policies.) So, there is no Wrap{Async} concept in V8.

Here is an example how to chain together a fallback and retry: (I've omitted the circuit breaker from the setup for the sake of simplicity.)

public static void Main()
{
    var shouldHandle= new PredicateBuilder<HttpResponseMessage>()
        .HandleResult(r => r.StatusCode == HttpStatusCode.InternalServerError);

    var pipeline = new ResiliencePipelineBuilder<HttpResponseMessage>()
        .AddFallback(new()
        {
            ShouldHandle = shouldHandle,
            FallbackAction = static args => Outcome.FromResultAsValueTask(ResolveFallbackResponse(args.Outcome))
        })
        .AddRetry(new()
        {
           ShouldHandle = shouldHandle,
           MaxRetryAttempts = 3,
           Delay = TimeSpan.FromSeconds(0.5),
        })
        .Build();

    var result = pipeline.Execute(() => new HttpResponseMessage(HttpStatusCode.InternalServerError));
    result.StatusCode.Dump();
}

static HttpResponseMessage ResolveFallbackResponse(Outcome<HttpResponseMessage> outcome)
    => new HttpResponseMessage(HttpStatusCode.RequestTimeout);
  • I've extracted the predicate when to trigger retry and fallback
  • The fallback action is also extracted into a dedicated method ResolveFallbackResponse
  • A retry and a fallback are chained together

I suggest checking the following documentation pages where we have tried to easy to use examples:

  • https://www.pollydocs./pipelines/index.html
  • https://www.pollydocs./strategies/index.html
  • https://www.pollydocs./migration-v8.html#migrating-policy-wrap
  • https://www.pollydocs./strategies/retry.html
  • https://www.pollydocs./strategies/fallback.html

本文标签: