Skip to content

Return timedOut, but don't cancel task, let exception come and log exception #722

@aalia

Description

@aalia

I am using Retry and timeout policy for my http client.
It normally takes more time for an exception to come and then if we retry it for say 3 times, it will take even more time. We want to reduce this time. So, what we want is, to set a timeout, even if exception haven't occurred, it should timeout. But, because we need the information for exception, we want to continue the call in a background thread may be, so that we can log the exception details.

Following is the code that I have done till now, we are using .NET core, so adding in Startup.cs:

 services.AddHttpClient<IClient,
                            Client>("Client", c => { c.DefaultRequestHeaders.Add("Accept", "application/json"); })
 
            .SetHandlerLifetime(Timeout.InfiniteTimeSpan)
            .AddPolicyHandler(GetFallbackPolicy())
            .AddPolicyHandler(GetRetryPolicy())
            .AddPolicyHandler(GetTimeOutPolicy());
			
			private IAsyncPolicy<HttpResponseMessage> GetRetryPolicy()
        {
            return HttpPolicyExtensions
                    .HandleTransientHttpError() 
                    .OrInner<WebException>(exception => new[] {WebExceptionStatus.ConnectionClosed,
                  WebExceptionStatus.Timeout,
                  WebExceptionStatus.RequestCanceled }.
            Contains(exception.Status))                   
                    .OrResult(msg => msg.StatusCode == System.Net.HttpStatusCode.NotFound)
                    .WaitAndRetryAsync(3, retryAttempt => TimeSpan.FromSeconds(Math.Pow(500, retryAttempt)));
        }

        private IAsyncPolicy<HttpResponseMessage> GetFallbackPolicy()
        {            
            return HttpPolicyExtensions
                    .HandleTransientHttpError().Or<Exception>()
                    .FallbackAsync<HttpResponseMessage>(fallbackAction: (context) =>
                    {
                        return new Task<HttpResponseMessage>(() => new HttpResponseMessage() { StatusCode = HttpStatusCode.InternalServerError });
                    }, onFallbackAsync: (exception) =>
                    {                        
                        throw exception.Exception;
                    });
        }

        private IAsyncPolicy<HttpResponseMessage> GetTimeOutPolicy()
        {
            return Policy.TimeoutAsync(30, TimeoutStrategy.Optimistic).AsAsyncPolicy<HttpResponseMessage>();           
        }

We don't want to cancel the task, it should go on and log exception, and it should return timedout, whne timed out. Please help me how to go about it?

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions