Skip to content

Commit aabcdd6

Browse files
committed
Generally working, need to fix small shutdown issue
1 parent f3e4c2c commit aabcdd6

17 files changed

+120
-16
lines changed

src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/AppOfflineApplication.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ HRESULT AppOfflineApplication::CreateHandler(IHttpContext* pHttpContext, IREQUES
1111
{
1212
try
1313
{
14+
LOG_INFO(L"AppOfflineApp CreateHandler");
1415
auto handler = std::make_unique<AppOfflineHandler>(*pHttpContext, m_strAppOfflineContent);
1516
*pRequestHandler = handler.release();
1617
}

src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/HandlerResolver.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,13 @@ void HandlerResolver::ResetHostingModel()
182182
m_loadedApplicationId.resize(0);
183183
}
184184

185+
APP_HOSTING_MODEL HandlerResolver::GetHostingModel()
186+
{
187+
SRWExclusiveLock lock(m_requestHandlerLoadLock);
188+
189+
return m_loadedApplicationHostingModel;
190+
}
191+
185192
HRESULT
186193
HandlerResolver::FindNativeAssemblyFromGlobalLocation(
187194
const ShimOptions& pConfiguration,

src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/HandlerResolver.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class HandlerResolver
1818
HandlerResolver(HMODULE hModule, const IHttpServer &pServer);
1919
HRESULT GetApplicationFactory(const IHttpApplication &pApplication, std::filesystem::path shadowCopyPath, std::unique_ptr<ApplicationFactory>& pApplicationFactory, const ShimOptions& options, ErrorContext& errorContext);
2020
void ResetHostingModel();
21+
APP_HOSTING_MODEL GetHostingModel();
2122

2223
private:
2324
HRESULT LoadRequestHandlerAssembly(const IHttpApplication &pApplication, std::filesystem::path shadowCopyPath, const ShimOptions& pConfiguration, std::unique_ptr<ApplicationFactory>& pApplicationFactory, ErrorContext& errorContext);

src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/applicationinfo.cpp

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "file_utility.h"
2121

2222
extern HINSTANCE g_hServerModule;
23+
extern BOOL g_fInShutdown;
2324

2425
HRESULT
2526
APPLICATION_INFO::CreateHandler(
@@ -32,10 +33,11 @@ APPLICATION_INFO::CreateHandler(
3233
{
3334
SRWSharedLock lock(m_applicationLock);
3435

35-
RETURN_IF_FAILED(hr = TryCreateHandler(pHttpContext, pHandler));
36+
hr = TryCreateHandler(pHttpContext, pHandler);
3637

3738
if (hr == S_OK)
3839
{
40+
LOG_INFO(L"Created handler from application");
3941
return S_OK;
4042
}
4143
}
@@ -44,7 +46,7 @@ APPLICATION_INFO::CreateHandler(
4446
SRWExclusiveLock lock(m_applicationLock);
4547

4648
// check if other thread created application
47-
RETURN_IF_FAILED(hr = TryCreateHandler(pHttpContext, pHandler));
49+
hr = TryCreateHandler(pHttpContext, pHandler);
4850

4951
// In some cases (adding and removing app_offline quickly) application might start and stop immediately
5052
// so retry until we get valid handler or error
@@ -62,6 +64,7 @@ APPLICATION_INFO::CreateHandler(
6264
m_pApplicationFactory = nullptr;
6365
}
6466

67+
LOG_INFO(L"Calling create application");
6568
RETURN_IF_FAILED(CreateApplication(pHttpContext));
6669

6770
RETURN_IF_FAILED(hr = TryCreateHandler(pHttpContext, pHandler));
@@ -75,7 +78,7 @@ HRESULT
7578
APPLICATION_INFO::CreateApplication(IHttpContext& pHttpContext)
7679
{
7780
auto& pHttpApplication = *pHttpContext.GetApplication();
78-
if (AppOfflineApplication::ShouldBeStarted(pHttpApplication))
81+
if (AppOfflineApplication::ShouldBeStarted(pHttpApplication) || g_fInShutdown)
7982
{
8083
LOG_INFO(L"Detected app_offline file, creating polling application");
8184
m_pApplication = make_application<AppOfflineApplication>(pHttpApplication);
@@ -93,7 +96,6 @@ APPLICATION_INFO::CreateApplication(IHttpContext& pHttpContext)
9396
errorContext.statusCode = 500i16;
9497
errorContext.subStatusCode = 0i16;
9598

96-
9799
const auto hr = TryCreateApplication(pHttpContext, options, errorContext);
98100

99101
if (FAILED_LOG(hr))
@@ -135,10 +137,11 @@ APPLICATION_INFO::CreateApplication(IHttpContext& pHttpContext)
135137
}
136138
catch (...)
137139
{
140+
OBSERVE_CAUGHT_EXCEPTION();
138141
EventLog::Error(
139142
ASPNETCORE_CONFIGURATION_LOAD_ERROR,
140143
ASPNETCORE_CONFIGURATION_LOAD_ERROR_MSG,
141-
L"");
144+
L"Create Application");
142145
}
143146

144147
m_pApplication = make_application<ServerErrorApplication>(
@@ -202,15 +205,16 @@ APPLICATION_INFO::TryCreateApplication(IHttpContext& pHttpContext, const ShimOpt
202205
{
203206
// TODO maybe able to read last directory in directory iteration?
204207
std::string::size_type sz;
205-
int i_dec = std::stoi(entry.path(), &sz);
208+
int i_dec = std::stoi(entry.path().filename().string(), &sz);
206209
if (i_dec > directoryName)
207210
{
208211
directoryName = i_dec;
209212
directoryNameStr = std::string(entry.path().string());
210213
}
211214
}
212-
catch (const std::exception&)
215+
catch (...)
213216
{
217+
OBSERVE_CAUGHT_EXCEPTION();
214218
// Ignore any folders that can't be converted to an int.
215219
}
216220
}
@@ -220,7 +224,7 @@ APPLICATION_INFO::TryCreateApplication(IHttpContext& pHttpContext, const ShimOpt
220224
shadowCopyPath = shadowCopyPath / std::filesystem::path(directoryNameStr);
221225
RETURN_IF_FAILED(Environment::CopyToDirectory(shadowCopyPath, physicalPath, options.QueryCleanShadowCopyDirectory()));
222226
}
223-
227+
224228
RETURN_IF_FAILED(m_handlerResolver.GetApplicationFactory(*pHttpContext.GetApplication(), shadowCopyPath, m_pApplicationFactory, options, error));
225229
LOG_INFO(L"Creating handler application");
226230

@@ -245,6 +249,7 @@ APPLICATION_INFO::TryCreateHandler(
245249
IREQUEST_HANDLER * newHandler;
246250
const auto result = m_pApplication->TryCreateHandler(&pHttpContext, &newHandler);
247251
RETURN_IF_FAILED(result);
252+
LOG_INFO(L"Created handler");
248253

249254
if (result == S_OK)
250255
{
@@ -253,6 +258,10 @@ APPLICATION_INFO::TryCreateHandler(
253258
return S_OK;
254259
}
255260
}
261+
else
262+
{
263+
LOG_INFO(L"No Handler, no app");
264+
}
256265
return S_FALSE;
257266
}
258267

@@ -265,6 +274,7 @@ APPLICATION_INFO::ShutDownApplication(bool fServerInitiated)
265274
{
266275
LOG_INFOF(L"Stopping application '%ls'", QueryApplicationInfoKey().c_str());
267276
m_pApplication->Stop(fServerInitiated);
277+
LOG_INFO(L"Setting app to null");
268278
m_pApplication = nullptr;
269279
m_pApplicationFactory = nullptr;
270280
}

src/Servers/IIS/AspNetCoreModuleV2/AspNetCore/applicationmanager.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,11 @@ APPLICATION_MANAGER::RecycleApplicationFromManager(
116116
}
117117
}
118118

119+
if (m_handlerResolver.GetHostingModel() == APP_HOSTING_MODEL::HOSTING_IN_PROCESS)
120+
{
121+
g_fInShutdown = true;
122+
}
123+
119124
// All applications were unloaded reset handler resolver validation logic
120125
if (m_pApplicationInfoHash.empty())
121126
{

src/Servers/IIS/AspNetCoreModuleV2/CommonLib/Environment.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,29 @@ HRESULT Environment::CopyToDirectory(std::filesystem::path destination, std::wst
168168

169169
// Always does a copy on startup, as if there are not files to update
170170
// this copy should be fast.
171-
std::filesystem::copy(source, destination, std::filesystem::copy_options::recursive | std::filesystem::copy_options::update_existing);
171+
//"C:\inetpub\wwwroot\", "C:\inetpub\ShadowCopyDirectory\1"'
172+
Environment::CopyDirTo(source, destination.wstring());
172173
return S_OK;
173174
}
175+
176+
bool Environment::CopyDirTo( const std::wstring& source_folder, const std::wstring& target_folder )
177+
{
178+
std::wstring new_sf = source_folder + L"\\*";
179+
WCHAR sf[MAX_PATH+1];
180+
WCHAR tf[MAX_PATH+1];
181+
182+
wcscpy_s(sf, MAX_PATH, new_sf.c_str());
183+
wcscpy_s(tf, MAX_PATH, target_folder.c_str());
184+
185+
sf[lstrlenW(sf)+1] = 0;
186+
tf[lstrlenW(tf)+1] = 0;
187+
188+
SHFILEOPSTRUCTW s = { 0 };
189+
s.wFunc = FO_COPY;
190+
s.pTo = tf;
191+
s.pFrom = sf;
192+
s.fFlags = FOF_SILENT | FOF_NOCONFIRMMKDIR | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_NO_UI;
193+
int res = SHFileOperationW( &s );
194+
195+
return res == 0;
196+
}

src/Servers/IIS/AspNetCoreModuleV2/CommonLib/Environment.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,7 @@ class Environment
2424
bool IsRunning64BitProcess();
2525
static
2626
HRESULT CopyToDirectory(std::filesystem::path destination, std::wstring source, bool cleanDest);
27+
static
28+
bool CopyDirTo( const std::wstring& source_folder, const std::wstring& target_folder );
2729
};
2830

src/Servers/IIS/AspNetCoreModuleV2/CommonLib/PollingAppOfflineApplication.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
HRESULT PollingAppOfflineApplication::TryCreateHandler(_In_ IHttpContext* pHttpContext, _Outptr_result_maybenull_ IREQUEST_HANDLER** pRequestHandler)
1212
{
1313
CheckAppOffline();
14+
LOG_INFO(L"Trying to create handler");
15+
1416
return LOG_IF_FAILED(APPLICATION::TryCreateHandler(pHttpContext, pRequestHandler));
1517
}
1618

src/Servers/IIS/AspNetCoreModuleV2/CommonLib/ServerErrorApplication.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class ServerErrorApplication : public PollingAppOfflineApplication
2424

2525
HRESULT CreateHandler(IHttpContext *pHttpContext, IREQUEST_HANDLER ** pRequestHandler) override
2626
{
27+
LOG_INFO(L"Server error");
2728
*pRequestHandler = std::make_unique<ServerErrorHandler>(*pHttpContext, m_statusCode, m_subStatusCode, m_statusText, m_HR, m_disableStartupPage, m_responseContent).release();
2829

2930
return S_OK;

src/Servers/IIS/AspNetCoreModuleV2/InProcessRequestHandler/InProcessApplicationBase.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ InProcessApplicationBase::StopInternal(bool fServerInitiated)
3030
// We don't actually handle any shutdown logic here.
3131
// Instead, we notify IIS that the process needs to be recycled, which will call
3232
// ApplicationManager->Shutdown(). This will call shutdown on the application.
33+
LOG_INFO(L"Recycling process NOW");
3334
m_pHttpServer.RecycleProcess(L"AspNetCore InProcess Recycle Process on Demand");
3435
}
3536
else

src/Servers/IIS/AspNetCoreModuleV2/InProcessRequestHandler/ShuttingDownApplication.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class ShuttingDownApplication : public InProcessApplicationBase
4040

4141
HRESULT CreateHandler(IHttpContext * pHttpContext, IREQUEST_HANDLER ** pRequestHandler) override
4242
{
43+
LOG_INFO(L"ShuttingDown CreateHandler");
4344
*pRequestHandler = new ShuttingDownHandler(pHttpContext);
4445
return S_OK;
4546
}

src/Servers/IIS/AspNetCoreModuleV2/InProcessRequestHandler/StartupExceptionApplication.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ class StartupExceptionApplication : public InProcessApplicationBase
3333

3434
HRESULT CreateHandler(IHttpContext* pHttpContext, IREQUEST_HANDLER** pRequestHandler)
3535
{
36+
LOG_INFO(L"StartupException CreateHandler");
3637
*pRequestHandler = new ServerErrorHandler(*pHttpContext, m_statusCode, m_subStatusCode, m_statusText, m_HR, m_disableLogs, m_error);
3738

3839
return S_OK;

src/Servers/IIS/AspNetCoreModuleV2/InProcessRequestHandler/inprocessapplication.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ IN_PROCESS_APPLICATION::~IN_PROCESS_APPLICATION()
5050
VOID
5151
IN_PROCESS_APPLICATION::StopInternal(bool fServerInitiated)
5252
{
53+
AppOfflineTrackingApplication::StopInternal(fServerInitiated);
5354
StopClr();
5455
InProcessApplicationBase::StopInternal(fServerInitiated);
5556
}
@@ -582,7 +583,7 @@ IN_PROCESS_APPLICATION::CreateHandler(
582583
try
583584
{
584585
SRWSharedLock dataLock(m_dataLock);
585-
586+
LOG_INFO(L"Creating handler inprocessapplication");
586587
DBG_ASSERT(!m_fStopCalled);
587588
m_requestCount++;
588589

src/Servers/IIS/AspNetCoreModuleV2/RequestHandlerLib/AppOfflineTrackingApplication.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,15 @@ HRESULT AppOfflineTrackingApplication::StartMonitoringAppOffline()
2525

2626
void AppOfflineTrackingApplication::StopInternal(bool fServerInitiated)
2727
{
28-
APPLICATION::StopInternal(fServerInitiated);
28+
LOG_INFO(L"Stop Internal AppOfflineTracking");
2929

3030
if (m_fileWatcher)
3131
{
3232
m_fileWatcher->StopMonitor();
3333
m_fileWatcher = nullptr;
3434
}
35+
36+
APPLICATION::StopInternal(fServerInitiated);
3537
}
3638

3739
HRESULT AppOfflineTrackingApplication::StartMonitoringAppOflineImpl()

src/Servers/IIS/AspNetCoreModuleV2/RequestHandlerLib/filewatcher.cpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ void FILE_WATCHER::WaitForMonitor(DWORD dwRetryCounter)
4949
{
5050
// fail to get thread status
5151
// call terminitethread
52+
LOG_INFO(L"BAD");
5253
TerminateThread(m_hChangeNotificationThread, 1);
5354
m_fThreadExit = TRUE;
5455
}
@@ -57,6 +58,7 @@ void FILE_WATCHER::WaitForMonitor(DWORD dwRetryCounter)
5758

5859
if (!m_fThreadExit)
5960
{
61+
LOG_INFO(L"BAD");
6062
TerminateThread(m_hChangeNotificationThread, 1);
6163
}
6264
}
@@ -337,9 +339,7 @@ FILE_WATCHER::TimerCallback(
337339

338340
DWORD WINAPI FILE_WATCHER::CopyAndShutdown(LPVOID arg)
339341
{
340-
EventLog::Error(
341-
1,
342-
L"Callback");
342+
LOG_INFO(L"Start copy and shutdown");
343343
auto directoryName = 0;
344344
// wrong path.
345345
auto watcher = (FILE_WATCHER*)arg;
@@ -365,8 +365,10 @@ DWORD WINAPI FILE_WATCHER::CopyAndShutdown(LPVOID arg)
365365

366366
watcher->_pApplication->ReferenceApplication();
367367
SetEvent(watcher->m_pShutdownEvent);
368-
368+
369369
QueueUserWorkItem(RunNotificationCallback, watcher->_pApplication.get(), WT_EXECUTEDEFAULT);
370+
371+
LOG_INFO(L"End copy and shutdown");
370372
return 0;
371373
}
372374

@@ -423,6 +425,8 @@ FILE_WATCHER::StopMonitor()
423425
return;
424426
}
425427

428+
LOG_INFO(L"Stop monitor");
429+
426430
InterlockedExchange(&_lStopMonitorCalled, 1);
427431
// signal the file watch thread to exit
428432
PostQueuedCompletionStatus(m_hCompletionPort, 0, FILE_WATCHER_SHUTDOWN_KEY, NULL);
@@ -435,4 +439,6 @@ FILE_WATCHER::StopMonitor()
435439

436440
// Release application reference
437441
_pApplication.reset(nullptr);
442+
443+
LOG_INFO(L"End stop monitor");
438444
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
{
2+
"iisSettings": {
3+
"windowsAuthentication": true,
4+
"anonymousAuthentication": true,
5+
"iisExpress": {
6+
"applicationUrl": "http://localhost:5762/",
7+
"sslPort": 0
8+
}
9+
},
10+
"profiles": {
11+
"ANCM IIS Express": {
12+
"commandName": "Executable",
13+
"executablePath": "$(IISExpressPath)",
14+
"commandLineArgs": "$(IISExpressArguments)",
15+
"environmentVariables": {
16+
"IIS_SITE_PATH": "$(MSBuildThisFileDirectory)",
17+
"ANCMV2_PATH": "$(AspNetCoreModuleV2ShimDll)",
18+
"ASPNETCORE_MODULE_OUTOFPROCESS_HANDLER": "$(AspNetCoreModuleV2OutOfProcessHandlerDll)",
19+
"LAUNCHER_ARGS": "$(TargetPath)",
20+
"ASPNETCORE_ENVIRONMENT": "Development",
21+
"LAUNCHER_PATH": "$(DotNetPath)",
22+
"ASPNETCORE_MODULE_DEBUG": "console"
23+
}
24+
},
25+
"ANCM IIS": {
26+
"commandName": "Executable",
27+
"executablePath": "$(IISPath)",
28+
"commandLineArgs": "$(IISArguments)",
29+
"environmentVariables": {
30+
"IIS_SITE_PATH": "$(MSBuildThisFileDirectory)",
31+
"ANCMV2_PATH": "$(AspNetCoreModuleV2ShimDll)",
32+
"ASPNETCORE_MODULE_OUTOFPROCESS_HANDLER": "$(AspNetCoreModuleV2OutOfProcessHandlerDll)",
33+
"LAUNCHER_ARGS": "$(TargetPath)",
34+
"ASPNETCORE_ENVIRONMENT": "Development",
35+
"LAUNCHER_PATH": "$(DotNetPath)",
36+
"ASPNETCORE_MODULE_DEBUG": "console"
37+
}
38+
}
39+
}
40+
}

src/Servers/IIS/IIS/test/Common.FunctionalTests/LoggingTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ public async Task StartupMessagesAreLoggedIntoDefaultDebugLogFileWhenEnabledWith
137137
}
138138

139139
[ConditionalTheory]
140-
[MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")]
140+
//[MaximumOSVersion(OperatingSystems.Windows, WindowsVersions.Win10_20H1, SkipReason = "Shutdown hangs https://github.com/dotnet/aspnetcore/issues/25107")]
141141
[RequiresIIS(IISCapability.PoolEnvironmentVariables)]
142142
[MemberData(nameof(InprocessTestVariants))]
143143
public async Task StartupMessagesLogFileSwitchedWhenLogFilePresentInWebConfig(TestVariant variant)

0 commit comments

Comments
 (0)