#298 Add a timeout for draining requests on shutdown

This commit is contained in:
Chris R 2017-01-24 13:28:13 -08:00
Родитель e19dea255b
Коммит 56bd85aaf2
3 изменённых файлов: 40 добавлений и 2 удалений

Просмотреть файл

@ -81,6 +81,12 @@ namespace Microsoft.AspNetCore.Server.HttpSys
}
}
/// <summary>
/// The amount of time to wait for active requests to drain while the server is shutting down.
/// New requests will receive a 503 response in this time period. The default is 5 seconds.
/// </summary>
public TimeSpan ShutdownTimeout { get; set; } = TimeSpan.FromSeconds(5);
internal void SetRequestQueueLimit(RequestQueue requestQueue)
{
_requestQueue = requestQueue;

Просмотреть файл

@ -221,7 +221,15 @@ namespace Microsoft.AspNetCore.Server.HttpSys
if (_outstandingRequests > 0)
{
LogHelper.LogInfo(_logger, "Stopping, waiting for " + _outstandingRequests + " request(s) to drain.");
_shutdownSignal.WaitOne();
var drained = _shutdownSignal.WaitOne(Listener.Options.ShutdownTimeout);
if (drained)
{
LogHelper.LogInfo(_logger, "All requests drained successfully.");
}
else
{
LogHelper.LogInfo(_logger, "Timed out, terminating " + _outstandingRequests + " request(s).");
}
}
// All requests are finished
_listener.Dispose();

Просмотреть файл

@ -68,7 +68,7 @@ namespace Microsoft.AspNetCore.Server.HttpSys
}
[ConditionalFact]
public async Task Server_ShutdownDurringRequest_Success()
public async Task Server_ShutdownDuringRequest_Success()
{
Task<string> responseTask;
ManualResetEvent received = new ManualResetEvent(false);
@ -87,6 +87,30 @@ namespace Microsoft.AspNetCore.Server.HttpSys
Assert.Equal("Hello World", response);
}
[ConditionalFact]
public async Task Server_ShutdownDuringLongRunningRequest_TimesOut()
{
Task<string> responseTask;
var received = new ManualResetEvent(false);
bool? shutdown = null;
var waitForShutdown = new ManualResetEvent(false);
string address;
using (Utilities.CreateHttpServer(out address, httpContext =>
{
received.Set();
shutdown = waitForShutdown.WaitOne(TimeSpan.FromSeconds(15));
httpContext.Response.ContentLength = 11;
return httpContext.Response.WriteAsync("Hello World");
}))
{
responseTask = SendRequestAsync(address);
Assert.True(received.WaitOne(TimeSpan.FromSeconds(10)));
}
Assert.False(shutdown.HasValue);
waitForShutdown.Set();
await Assert.ThrowsAsync<HttpRequestException>(async () => await responseTask);
}
[ConditionalFact]
public void Server_AppException_ClientReset()
{