extensions icon indicating copy to clipboard operation
extensions copied to clipboard

[Http.Resilience] Timeout can't filter based on request?

Open marcinjahn opened this issue 1 year ago • 3 comments

It seems that Microsoft.Extensions.Http.Resilience replaces the older Microsoft.Extensions.Http.Polly extensions.

One thing I noticed is that the newer package lost the functionality to filter whether to apply timeouts or not based on the HttpRequestMessage object.

In the Microsoft.Extensions.Http.Polly package, I could do:

 services
     .AddHttpClient<MyClient>()
     .AddPolicyHandler((serviceProvider, request) =>
           request.RequestUri?.AbsolutePath.Contains("something", StringComparison.OrdinalIgnoreCase) is true
                ? Policy.TimeoutAsync(timeSpan)
                : Policy.NoOpAsync());

I don't see such option with the new APIs (which seem to directly use the Polly API). Some strategies, like Retry, do allow to access the HttpRequestMessage object, in the RetryStrategyOptions's ShouldHandle. The TimeoutStrategyOptions doesn't seem to have any configuration like that.

Am I missing something and there is some way to filter timeout strategy based on the request message, or is this functionality just not there? Will it be added?

marcinjahn avatar Mar 16 '24 07:03 marcinjahn

@martintmk Any feedback on this?

geeknoid avatar Mar 16 '24 15:03 geeknoid

Hey @marcinjahn

You can use TimeoutGenerator to dynamically enable/disable timeout. What you need to do is to store a flag into ResilienceContext that determines whether the timeout is disabled or not. If disabled, return Timeout.InfiniteTimespan.

See https://www.pollydocs.org/strategies/timeout.html#defaults for more details.

martintmk avatar Mar 19 '24 09:03 martintmk

Hey @marcinjahn

You can use TimeoutGenerator to dynamically enable/disable timeout. What you need to do is to store a flag into ResilienceContext that determines whether the timeout is disabled or not. If disabled, return Timeout.InfiniteTimespan.

See https://www.pollydocs.org/strategies/timeout.html#defaults for more details.

Could you add some pseudo-code? i'm still a bit puzzeld. I'm using .net aspire which by default uses;

builder.Services.ConfigureHttpClientDefaults(http =>
{
    // Turn on resilience by default
    http.AddStandardResilienceHandler();

    // Turn on service discovery by default
    http.UseServiceDiscovery();
});

This is great, but i have some third-party services for which i definitely don't want to retry. I need some way to be able to disable the retry for a single client.

sommmen avatar Apr 07 '24 10:04 sommmen