Add support for suspending ANCM startup (#7252)
Uses the `ASPNETCORE_STARTUP_SUSPEND_EVENT` environment variable to get an event name. Fixes: https://github.com/aspnet/AspNetCore/issues/6972
This commit is contained in:
parent
ad0377e88f
commit
6a46f48eb0
|
|
@ -133,6 +133,30 @@ APPLICATION_INFO::CreateApplication(IHttpContext& pHttpContext)
|
||||||
HRESULT
|
HRESULT
|
||||||
APPLICATION_INFO::TryCreateApplication(IHttpContext& pHttpContext, const ShimOptions& options)
|
APPLICATION_INFO::TryCreateApplication(IHttpContext& pHttpContext, const ShimOptions& options)
|
||||||
{
|
{
|
||||||
|
const auto startupEvent = Environment::GetEnvironmentVariableValue(L"ASPNETCORE_STARTUP_SUSPEND_EVENT");
|
||||||
|
if (startupEvent.has_value())
|
||||||
|
{
|
||||||
|
LOG_INFOF(L"Startup suspend event %ls", startupEvent.value().c_str());
|
||||||
|
|
||||||
|
HandleWrapper<NullHandleTraits> eventHandle = OpenEvent(SYNCHRONIZE, false, startupEvent.value().c_str());
|
||||||
|
|
||||||
|
if (eventHandle == nullptr)
|
||||||
|
{
|
||||||
|
LOG_INFOF(L"Unable to open startup suspend event");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto const suspendedEventName = startupEvent.value() + L"_suspended";
|
||||||
|
|
||||||
|
HandleWrapper<NullHandleTraits> suspendedEventHandle = OpenEvent(EVENT_MODIFY_STATE, false, suspendedEventName.c_str());
|
||||||
|
if (suspendedEventHandle != nullptr)
|
||||||
|
{
|
||||||
|
LOG_LAST_ERROR_IF(!SetEvent(suspendedEventHandle));
|
||||||
|
}
|
||||||
|
LOG_LAST_ERROR_IF(WaitForSingleObject(eventHandle, INFINITE) != WAIT_OBJECT_0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
RETURN_IF_FAILED(m_handlerResolver.GetApplicationFactory(*pHttpContext.GetApplication(), m_pApplicationFactory, options));
|
RETURN_IF_FAILED(m_handlerResolver.GetApplicationFactory(*pHttpContext.GetApplication(), m_pApplicationFactory, options));
|
||||||
LOG_INFO(L"Creating handler application");
|
LOG_INFO(L"Creating handler application");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
|
using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
|
||||||
|
|
@ -520,6 +521,41 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||||
Assert.Equal(deploymentResult.ContentRoot + "\\", await deploymentResult.HttpClient.GetStringAsync("/ASPNETCORE_IIS_PHYSICAL_PATH"));
|
Assert.Equal(deploymentResult.ContentRoot + "\\", await deploymentResult.HttpClient.GetStringAsync("/ASPNETCORE_IIS_PHYSICAL_PATH"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[ConditionalFact]
|
||||||
|
[RequiresNewShim]
|
||||||
|
[RequiresIIS(IISCapability.PoolEnvironmentVariables)]
|
||||||
|
public async Task StartupIsSuspendedWhenEventIsUsed()
|
||||||
|
{
|
||||||
|
var deploymentParameters = _fixture.GetBaseDeploymentParameters();
|
||||||
|
deploymentParameters.ApplicationType = ApplicationType.Standalone;
|
||||||
|
deploymentParameters.EnvironmentVariables["ASPNETCORE_STARTUP_SUSPEND_EVENT"] = "ANCM_TestEvent";
|
||||||
|
|
||||||
|
var eventPrefix = deploymentParameters.ServerType == ServerType.IISExpress ? "" : "Global\\";
|
||||||
|
|
||||||
|
var startWaitHandle = new EventWaitHandle(false, EventResetMode.ManualReset, eventPrefix + "ANCM_TestEvent");
|
||||||
|
var suspendedWaitHandle = new EventWaitHandle(false, EventResetMode.ManualReset, eventPrefix + "ANCM_TestEvent_suspended");
|
||||||
|
|
||||||
|
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||||
|
|
||||||
|
var request = deploymentResult.AssertStarts();
|
||||||
|
|
||||||
|
Assert.True(suspendedWaitHandle.WaitOne(TimeoutExtensions.DefaultTimeoutValue));
|
||||||
|
|
||||||
|
// didn't figure out a better way to check that ANCM is waiting to start
|
||||||
|
var applicationDll = Path.Combine(deploymentResult.ContentRoot, "InProcessWebSite.dll");
|
||||||
|
var handlerDll = Path.Combine(deploymentResult.ContentRoot, "aspnetcorev2_inprocess.dll");
|
||||||
|
// Make sure application dll is not locked
|
||||||
|
File.WriteAllBytes(applicationDll, File.ReadAllBytes(applicationDll));
|
||||||
|
// Make sure handler dll is not locked
|
||||||
|
File.WriteAllBytes(handlerDll, File.ReadAllBytes(handlerDll));
|
||||||
|
// Make sure request is not completed
|
||||||
|
Assert.False(request.IsCompleted);
|
||||||
|
|
||||||
|
startWaitHandle.Set();
|
||||||
|
|
||||||
|
await request;
|
||||||
|
}
|
||||||
|
|
||||||
private static void MoveApplication(
|
private static void MoveApplication(
|
||||||
IISDeploymentParameters parameters,
|
IISDeploymentParameters parameters,
|
||||||
string subdirectory)
|
string subdirectory)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue