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?
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 KeepAliveTimeout 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With