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
|
||||
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));
|
||||
LOG_INFO(L"Creating handler application");
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ using System.IO;
|
|||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Linq;
|
||||
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"));
|
||||
}
|
||||
|
||||
[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(
|
||||
IISDeploymentParameters parameters,
|
||||
string subdirectory)
|
||||
|
|
|
|||
Loading…
Reference in New Issue