Make startup timeout recycle worker process (#25321)
This commit is contained in:
parent
f0a5233b2c
commit
ee712265d5
|
|
@ -30,6 +30,7 @@
|
||||||
#define CS_ENABLED L"enabled"
|
#define CS_ENABLED L"enabled"
|
||||||
#define CS_ASPNETCORE_HANDLER_CALL_STARTUP_HOOK L"callStartupHook"
|
#define CS_ASPNETCORE_HANDLER_CALL_STARTUP_HOOK L"callStartupHook"
|
||||||
#define CS_ASPNETCORE_HANDLER_STACK_SIZE L"stackSize"
|
#define CS_ASPNETCORE_HANDLER_STACK_SIZE L"stackSize"
|
||||||
|
#define CS_ASPNETCORE_SUPPRESS_RECYCLE_ON_STARTUP_TIMEOUT L"suppressRecycleOnStartupTimeout"
|
||||||
#define CS_ASPNETCORE_DETAILEDERRORS L"ASPNETCORE_DETAILEDERRORS"
|
#define CS_ASPNETCORE_DETAILEDERRORS L"ASPNETCORE_DETAILEDERRORS"
|
||||||
#define CS_ASPNETCORE_ENVIRONMENT L"ASPNETCORE_ENVIRONMENT"
|
#define CS_ASPNETCORE_ENVIRONMENT L"ASPNETCORE_ENVIRONMENT"
|
||||||
#define CS_DOTNET_ENVIRONMENT L"DOTNET_ENVIRONMENT"
|
#define CS_DOTNET_ENVIRONMENT L"DOTNET_ENVIRONMENT"
|
||||||
|
|
|
||||||
|
|
@ -66,6 +66,7 @@ InProcessOptions::InProcessOptions(const ConfigurationSource &configurationSourc
|
||||||
m_fSetCurrentDirectory = equals_ignore_case(find_element(handlerSettings, CS_ASPNETCORE_HANDLER_SET_CURRENT_DIRECTORY).value_or(L"true"), L"true");
|
m_fSetCurrentDirectory = equals_ignore_case(find_element(handlerSettings, CS_ASPNETCORE_HANDLER_SET_CURRENT_DIRECTORY).value_or(L"true"), L"true");
|
||||||
m_fCallStartupHook = equals_ignore_case(find_element(handlerSettings, CS_ASPNETCORE_HANDLER_CALL_STARTUP_HOOK).value_or(L"true"), L"true");
|
m_fCallStartupHook = equals_ignore_case(find_element(handlerSettings, CS_ASPNETCORE_HANDLER_CALL_STARTUP_HOOK).value_or(L"true"), L"true");
|
||||||
m_strStackSize = find_element(handlerSettings, CS_ASPNETCORE_HANDLER_STACK_SIZE).value_or(L"1048576");
|
m_strStackSize = find_element(handlerSettings, CS_ASPNETCORE_HANDLER_STACK_SIZE).value_or(L"1048576");
|
||||||
|
m_fSuppressRecycleOnStartupTimeout = equals_ignore_case(find_element(handlerSettings, CS_ASPNETCORE_SUPPRESS_RECYCLE_ON_STARTUP_TIMEOUT).value_or(L"false"), L"true");
|
||||||
|
|
||||||
m_dwStartupTimeLimitInMS = aspNetCoreSection->GetRequiredLong(CS_ASPNETCORE_PROCESS_STARTUP_TIME_LIMIT) * 1000;
|
m_dwStartupTimeLimitInMS = aspNetCoreSection->GetRequiredLong(CS_ASPNETCORE_PROCESS_STARTUP_TIME_LIMIT) * 1000;
|
||||||
m_dwShutdownTimeLimitInMS = aspNetCoreSection->GetRequiredLong(CS_ASPNETCORE_PROCESS_SHUTDOWN_TIME_LIMIT) * 1000;
|
m_dwShutdownTimeLimitInMS = aspNetCoreSection->GetRequiredLong(CS_ASPNETCORE_PROCESS_SHUTDOWN_TIME_LIMIT) * 1000;
|
||||||
|
|
|
||||||
|
|
@ -118,6 +118,12 @@ public:
|
||||||
return m_strStackSize;
|
return m_strStackSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
QuerySuppressRecycleOnStartupTimeout() const
|
||||||
|
{
|
||||||
|
return m_fSuppressRecycleOnStartupTimeout;
|
||||||
|
}
|
||||||
|
|
||||||
InProcessOptions(const ConfigurationSource &configurationSource, IHttpSite* pSite);
|
InProcessOptions(const ConfigurationSource &configurationSource, IHttpSite* pSite);
|
||||||
|
|
||||||
static
|
static
|
||||||
|
|
@ -139,6 +145,7 @@ private:
|
||||||
bool m_fWindowsAuthEnabled;
|
bool m_fWindowsAuthEnabled;
|
||||||
bool m_fBasicAuthEnabled;
|
bool m_fBasicAuthEnabled;
|
||||||
bool m_fAnonymousAuthEnabled;
|
bool m_fAnonymousAuthEnabled;
|
||||||
|
bool m_fSuppressRecycleOnStartupTimeout;
|
||||||
DWORD m_dwStartupTimeLimitInMS;
|
DWORD m_dwStartupTimeLimitInMS;
|
||||||
DWORD m_dwShutdownTimeLimitInMS;
|
DWORD m_dwShutdownTimeLimitInMS;
|
||||||
DWORD m_dwMaxRequestBodySize;
|
DWORD m_dwMaxRequestBodySize;
|
||||||
|
|
|
||||||
|
|
@ -169,7 +169,14 @@ IN_PROCESS_APPLICATION::LoadManagedApplication(ErrorContext& errorContext)
|
||||||
errorContext.errorReason = format("ASP.NET Core app failed to start after %d milliseconds", m_pConfig->QueryStartupTimeLimitInMS());
|
errorContext.errorReason = format("ASP.NET Core app failed to start after %d milliseconds", m_pConfig->QueryStartupTimeLimitInMS());
|
||||||
|
|
||||||
m_waitForShutdown = false;
|
m_waitForShutdown = false;
|
||||||
StopClr();
|
if (m_pConfig->QuerySuppressRecycleOnStartupTimeout())
|
||||||
|
{
|
||||||
|
StopClr();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Stop(/* fServerInitiated */false);
|
||||||
|
}
|
||||||
throw InvalidOperationException(format(L"Managed server didn't initialize after %u ms.", m_pConfig->QueryStartupTimeLimitInMS()));
|
throw InvalidOperationException(format(L"Managed server didn't initialize after %u ms.", m_pConfig->QueryStartupTimeLimitInMS()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -453,9 +453,10 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess
|
||||||
}
|
}
|
||||||
|
|
||||||
[ConditionalFact]
|
[ConditionalFact]
|
||||||
|
[RequiresNewHandler]
|
||||||
public async Task StartupTimeoutIsApplied()
|
public async Task StartupTimeoutIsApplied()
|
||||||
{
|
{
|
||||||
// From what I can tell, this failure is due to ungraceful shutdown.
|
// From what we can tell, this failure is due to ungraceful shutdown.
|
||||||
// The error could be the same as https://github.com/dotnet/core-setup/issues/4646
|
// The error could be the same as https://github.com/dotnet/core-setup/issues/4646
|
||||||
// But can't be certain without another repro.
|
// But can't be certain without another repro.
|
||||||
using (AppVerifier.Disable(DeployerSelector.ServerType, 0x300))
|
using (AppVerifier.Disable(DeployerSelector.ServerType, 0x300))
|
||||||
|
|
@ -470,11 +471,45 @@ namespace Microsoft.AspNetCore.Server.IIS.FunctionalTests.InProcess
|
||||||
var response = await deploymentResult.HttpClient.GetAsync("/");
|
var response = await deploymentResult.HttpClient.GetAsync("/");
|
||||||
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
|
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
|
||||||
|
|
||||||
|
// Startup timeout now recycles process.
|
||||||
|
deploymentResult.AssertWorkerProcessStop();
|
||||||
|
|
||||||
|
EventLogHelpers.VerifyEventLogEvent(deploymentResult,
|
||||||
|
EventLogHelpers.InProcessFailedToStart(deploymentResult, "Managed server didn't initialize after 1000 ms."),
|
||||||
|
Logger);
|
||||||
|
|
||||||
|
if (DeployerSelector.HasNewHandler)
|
||||||
|
{
|
||||||
|
var responseContent = await response.Content.ReadAsStringAsync();
|
||||||
|
Assert.Contains("500.37", responseContent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[ConditionalFact]
|
||||||
|
[MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")]
|
||||||
|
public async Task StartupTimeoutIsApplied_DisableRecycleOnStartupTimeout()
|
||||||
|
{
|
||||||
|
// From what we can tell, this failure is due to ungraceful shutdown.
|
||||||
|
// The error could be the same as https://github.com/dotnet/core-setup/issues/4646
|
||||||
|
// But can't be certain without another repro.
|
||||||
|
using (AppVerifier.Disable(DeployerSelector.ServerType, 0x300))
|
||||||
|
{
|
||||||
|
var deploymentParameters = Fixture.GetBaseDeploymentParameters(Fixture.InProcessTestSite);
|
||||||
|
deploymentParameters.TransformArguments((a, _) => $"{a} Hang");
|
||||||
|
deploymentParameters.WebConfigActionList.Add(
|
||||||
|
WebConfigHelpers.AddOrModifyAspNetCoreSection("startupTimeLimit", "1"));
|
||||||
|
deploymentParameters.HandlerSettings["suppressRecycleOnStartupTimeout"] = "true";
|
||||||
|
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||||
|
|
||||||
|
var response = await deploymentResult.HttpClient.GetAsync("/");
|
||||||
|
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
|
||||||
|
|
||||||
StopServer(gracefulShutdown: false);
|
StopServer(gracefulShutdown: false);
|
||||||
|
|
||||||
EventLogHelpers.VerifyEventLogEvents(deploymentResult,
|
EventLogHelpers.VerifyEventLogEvent(deploymentResult,
|
||||||
EventLogHelpers.InProcessFailedToStart(deploymentResult, "Managed server didn't initialize after 1000 ms.")
|
EventLogHelpers.InProcessFailedToStart(deploymentResult, "Managed server didn't initialize after 1000 ms."),
|
||||||
);
|
Logger);
|
||||||
|
|
||||||
if (DeployerSelector.HasNewHandler)
|
if (DeployerSelector.HasNewHandler)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue