From f7fbf14a9fd07cbc23a2e448d5126559fcc94ef8 Mon Sep 17 00:00:00 2001 From: Brennan Date: Tue, 4 Feb 2025 14:30:26 -0800 Subject: [PATCH] fixup --- .../AspNetCore/applicationmanager.cpp | 11 ++++++-- .../AspNetCore/globalmodule.cpp | 25 +++++++++++-------- .../IntegrationTesting.IIS/src/IISDeployer.cs | 3 +-- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/applicationmanager.cpp b/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/applicationmanager.cpp index 5f9224e39c76..ae56d4178f34 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/applicationmanager.cpp +++ b/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/applicationmanager.cpp @@ -23,9 +23,16 @@ APPLICATION_MANAGER::GetOrCreateApplicationInfo( ) { // GetOrCreateApplicationInfo is called from proxymodule when a request is received. - // Set this value to indicate that a request has been received so we can disable shutdown logic in OnGlobalApplicationStop - m_hasStarted = true; + PCWSTR pszVariableValue = nullptr; + DWORD cbLength = 0; + // Check for preload or warmup request, part of the application initialization process, see comments in ASPNET_CORE_GLOBAL_MODULE::OnGlobalApplicationStop for more info + if (FAILED(pHttpContext.GetServerVariable("PRELOAD_REQUEST", &pszVariableValue, &cbLength)) && + FAILED(pHttpContext.GetServerVariable("WARMUP_REQUEST", &pszVariableValue, &cbLength))) + { + // Set this value to indicate that a request has been received so we can disable shutdown logic in OnGlobalApplicationStop + m_hasStarted = true; + } auto &pApplication = *pHttpContext.GetApplication(); // The configuration path is unique for each application and is used for the diff --git a/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/globalmodule.cpp b/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/globalmodule.cpp index eeb30d71779a..e920072f7684 100644 --- a/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/globalmodule.cpp +++ b/src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/globalmodule.cpp @@ -35,6 +35,9 @@ ASPNET_CORE_GLOBAL_MODULE::OnGlobalStopListening( return GL_NOTIFICATION_CONTINUE; } +// We prefer shutting down from OnGlobalStopListening as it is called right before the IIS request handler is disabled, which means it'll start queueing requests +// But if we stopped in OnGlobalApplicationStop then we can start shutting down while the request handler is still active resulting in us returning 503's since we're shutting down. +// We still need to shutdown in specific cases where OnGlobalStopListening isn't called, like IISExpress or if the app never receives a request (app preload). GLOBAL_NOTIFICATION_STATUS ASPNET_CORE_GLOBAL_MODULE::OnGlobalApplicationStop( IN IHttpApplicationStopProvider* pProvider @@ -51,17 +54,19 @@ ASPNET_CORE_GLOBAL_MODULE::OnGlobalApplicationStop( LOG_INFO(L"ASPNET_CORE_GLOBAL_MODULE::OnGlobalApplicationStop"); - if (!g_fInShutdown && !m_shutdown.joinable() - && (m_pApplicationManager->IsIISExpress() || !m_pApplicationManager->HasReceivedRequest())) + if (!g_fInShutdown && !m_shutdown.joinable()) { - // Apps with preload + always running that don't receive a request before recycle/shutdown will never call OnGlobalStopListening - // IISExpress can also close without calling OnGlobalStopListening which is where we usually would trigger shutdown - // so we should make sure to shutdown the server in those cases - StartShutdown(); - } - else - { - LOG_INFO(L"Ignoring OnGlobalApplicationStop, OnGlobalStopListening should be called shortly."); + if ((m_pApplicationManager->IsIISExpress() || !m_pApplicationManager->HasReceivedRequest())) + { + // Apps with preload + always running that don't receive a request before recycle/shutdown will never call OnGlobalStopListening + // IISExpress can also close without calling OnGlobalStopListening which is where we usually would trigger shutdown + // so we should make sure to shutdown the server in those cases + StartShutdown(); + } + else + { + LOG_INFO(L"Ignoring OnGlobalApplicationStop, OnGlobalStopListening has been called or should be called shortly."); + } } return GL_NOTIFICATION_CONTINUE; diff --git a/src/Servers/IIS/IntegrationTesting.IIS/src/IISDeployer.cs b/src/Servers/IIS/IntegrationTesting.IIS/src/IISDeployer.cs index 3f56b6a7d151..400dc74287e9 100644 --- a/src/Servers/IIS/IntegrationTesting.IIS/src/IISDeployer.cs +++ b/src/Servers/IIS/IntegrationTesting.IIS/src/IISDeployer.cs @@ -307,7 +307,7 @@ private static Site FindSite(ServerManager serverManager, string contentRoot) private void AddTemporaryAppHostConfig(string contentRoot, int port) { - var multiSite = true; + var multiSite = _applicationHostConfig is not null; XDocument config; if (_applicationHostConfig is not null) { @@ -315,7 +315,6 @@ private void AddTemporaryAppHostConfig(string contentRoot, int port) } else { - multiSite = false; _configPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("D")); _applicationHostConfig = Path.Combine(_configPath, "applicationHost.config"); Directory.CreateDirectory(_configPath);