in src/WebJobs.Script.WebHost/WebJobsScriptHostService.cs [849:917]
private async Task Orphan(IHost instance, CancellationToken cancellationToken = default)
{
if (instance == null)
{
_logger.LogDebug("Cannot stop or dispose a null host instance.");
return;
}
var isStandbyHost = false;
string hostInstanceId = "unknown";
try
{
var scriptHost = instance.Services.GetService<ScriptHost>();
if (scriptHost != null)
{
scriptHost.HostInitializing -= OnHostInitializing;
scriptHost.HostInitialized -= OnHostInitialized;
isStandbyHost = scriptHost.IsStandbyHost;
hostInstanceId = scriptHost.ScriptOptions.InstanceId;
}
}
catch (ObjectDisposedException)
{
// If the instance is already disposed, we cannot access its services.
}
try
{
await instance.StopAsync(cancellationToken);
}
catch (Exception ex) when (!ex.IsFatal())
{
// some errors are expected here - e.g. in error/shutdown situations
// we might attempt to stop the host before it has fully started
_logger.LogError(ex, "Failed to stop host instance '{hostInstanceId}'.", hostInstanceId);
}
finally
{
GetHostLogger(instance).LogDebug("Disposing ScriptHost.");
if (isStandbyHost && !_scriptWebHostEnvironment.InStandbyMode)
{
// For cold start reasons delay disposing script host if specializing out of placeholder mode
Utility.ExecuteAfterColdStartDelay(_environment, () =>
{
try
{
GetHostLogger(instance).LogDebug("Starting Standby ScriptHost dispose");
instance.Dispose();
_logger.LogDebug("Standby ScriptHost disposed");
}
catch (Exception e)
{
_logger.LogError(e, "Failed to dispose Standby ScriptHost instance");
throw;
}
}, cancellationToken);
_logger.LogDebug("Standby ScriptHost marked for disposal");
}
else
{
DisposeDependencyTrackingModule(instance);
FlushOpenTelemetry(instance);
instance.Dispose();
_logger.LogDebug("ScriptHost disposed");
}
}
}