Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HttpClient Timeout does not appear to be working

I have a Web API Controller that looks like this:

[Route("api/[controller]")]
public class SlowController : Controller
{
    [HttpPost]
    public ActionResult Post([FromBody]SlowRequest request)
    {
        var response = new SlowResponse();
        response.Id = request.Id;
        response.StartDate = DateTime.Now;
        Thread.Sleep(new TimeSpan(0, 3, 0));
        response.EndDate = DateTime.Now;

        return Ok(response);
    }
}

Notice how there is a 3 minute sleep. This is to simulate that the post action takes a long time to return.

And I have a client Console Application that calls this web API:

static void Main(string[] args)
{
    try
    {
        var request = new SlowRequest();
        request.Id = Guid.NewGuid();

        var json = JsonConvert.SerializeObject(request);

        var httpClient = new HttpClient();
        httpClient.Timeout = new TimeSpan(0, 5, 0);
        httpClient.BaseAddress = new Uri("http://localhost:54316/");
        var result = httpClient.PostAsync("api/slow", new StringContent(json, Encoding.UTF8, "application/json")).Result.EnsureSuccessStatusCode();
        var apiResponse = result.Content.ReadAsStringAsync().Result;
        var response = JsonConvert.DeserializeObject<SlowResponse>(apiResponse);

        Console.WriteLine("Start Time = " + response.StartDate);
        Console.WriteLine("End Time = " + response.EndDate);

    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

Unfortunately the client throws an exception after 2 minutes saying:

Response status code does not indicate success: 502 (Bad Gateway).

It seems that if the API takes more than 2 minutes to return this, exception happens. Below 2 minutes, it works just fine. This is despite the fact I have put a 5 minute timeout on the client. How do I prevent web API calls that take a long time from erroring like this?

like image 987
isxpjm Avatar asked Jan 23 '18 20:01

isxpjm


1 Answers

The problem is not from the client, the problem is from the server. You're sleeping it for 3 minutes, which is exceeding the default request timeout. You can change it in the web.config:

<aspNetCore requestTimeout="00:05:00" ... />

Note that the value must be specified in whole minutes only, otherwise it defaults to 2 minutes. See the Core configuration reference.

Kersel also has a 2 minutes timeout that you need to change in Program.cs:

.UseKestrel(o => o.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(5));

See the Keep​Alive​Timeout Property.

Note: I assumed that your project is Core. If that's not the case, you have to change the executionTimeout property in the web.config. It defaults to 110 seconds:

<system.web>
    <httpRuntime executionTimeout="300" />
</system.web>

See the ExecutionTimeout Property.

like image 181
Racil Hilan Avatar answered Oct 13 '22 00:10

Racil Hilan