Files
Umbraco-CMS/src/Umbraco.Infrastructure/Runtime/CoreRuntime.cs

118 lines
4.2 KiB
C#
Raw Normal View History

2016-08-25 15:09:51 +02:00
using System;
using Microsoft.Extensions.Logging;
2017-05-30 15:46:25 +02:00
using Umbraco.Core.Composing;
using Umbraco.Core.Hosting;
2016-08-25 15:09:51 +02:00
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence;
2016-08-25 15:09:51 +02:00
2017-12-28 09:27:57 +01:00
namespace Umbraco.Core.Runtime
2016-08-25 15:09:51 +02:00
{
public class CoreRuntime : IRuntime
{
public IRuntimeState State { get; }
2016-08-25 15:09:51 +02:00
private readonly ILogger<CoreRuntime> _logger;
private readonly ComponentCollection _components;
private readonly IApplicationShutdownRegistry _applicationShutdownRegistry;
private readonly IProfilingLogger _profilingLogger;
private readonly IMainDom _mainDom;
private readonly IUmbracoDatabaseFactory _databaseFactory;
public CoreRuntime(
ILogger<CoreRuntime> logger,
IRuntimeState state,
ComponentCollection components,
IApplicationShutdownRegistry applicationShutdownRegistry,
IProfilingLogger profilingLogger,
IMainDom mainDom,
IUmbracoDatabaseFactory databaseFactory)
{
State = state;
_logger = logger;
_components = components;
_applicationShutdownRegistry = applicationShutdownRegistry;
_profilingLogger = profilingLogger;
_mainDom = mainDom;
_databaseFactory = databaseFactory;
}
public void Start()
2016-08-25 15:09:51 +02:00
{
AppDomain.CurrentDomain.UnhandledException += (_, args) =>
{
var exception = (Exception)args.ExceptionObject;
var isTerminating = args.IsTerminating; // always true?
var msg = "Unhandled exception in AppDomain";
if (isTerminating) msg += " (terminating)";
msg += ".";
_logger.LogError(exception, msg);
};
DetermineRuntimeLevel();
if (State.Level <= RuntimeLevel.BootFailed)
throw new InvalidOperationException($"Cannot start the runtime if the runtime level is less than or equal to {RuntimeLevel.BootFailed}");
var hostingEnvironmentLifetime = _applicationShutdownRegistry;
if (hostingEnvironmentLifetime == null)
throw new InvalidOperationException($"An instance of {typeof(IApplicationShutdownRegistry)} could not be resolved from the container, ensure that one if registered in your runtime before calling {nameof(IRuntime)}.{nameof(Start)}");
// acquire the main domain - if this fails then anything that should be registered with MainDom will not operate
AcquireMainDom(_mainDom, _applicationShutdownRegistry);
// create & initialize the components
_components.Initialize();
}
public void Terminate()
{
_components?.Terminate();
}
private void AcquireMainDom(IMainDom mainDom, IApplicationShutdownRegistry applicationShutdownRegistry)
{
using (var timer = _profilingLogger.DebugDuration<CoreRuntime>("Acquiring MainDom.", "Acquired."))
{
try
{
mainDom.Acquire(applicationShutdownRegistry);
}
catch
{
2019-02-05 20:01:20 +01:00
timer?.Fail();
throw;
}
}
2016-08-25 15:09:51 +02:00
}
private void DetermineRuntimeLevel()
{
using var timer = _profilingLogger.DebugDuration<CoreRuntime>("Determining runtime level.", "Determined.");
try
{
State.DetermineRuntimeLevel();
_logger.LogDebug("Runtime level: {RuntimeLevel} - {RuntimeLevelReason}", State.Level, State.Reason);
if (State.Level == RuntimeLevel.Upgrade)
{
_logger.LogDebug("Configure database factory for upgrades.");
_databaseFactory.ConfigureForUpgrade();
}
}
catch
{
// BOO a cast, yay no CoreRuntimeBootstrapper
((RuntimeState)State).Level = RuntimeLevel.BootFailed;
((RuntimeState)State).Reason = RuntimeLevelReason.BootFailedOnException;
timer?.Fail();
throw;
}
}
2016-08-25 15:09:51 +02:00
}
}