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

160 lines
5.8 KiB
C#
Raw Normal View History

2020-12-15 15:20:36 +00:00
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Composing;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Hosting;
using Umbraco.Cms.Core.Logging;
using Umbraco.Cms.Core.Runtime;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Infrastructure.Persistence;
using Constants = Umbraco.Cms.Core.Constants;
2016-08-25 15:09:51 +02:00
namespace Umbraco.Cms.Infrastructure.Runtime
2016-08-25 15:09:51 +02:00
{
public class CoreRuntime : IRuntime
{
private readonly ILogger<CoreRuntime> _logger;
2020-12-15 15:20:36 +00:00
private readonly ILoggerFactory _loggerFactory;
private readonly ComponentCollection _components;
private readonly IApplicationShutdownRegistry _applicationShutdownRegistry;
private readonly IProfilingLogger _profilingLogger;
private readonly IMainDom _mainDom;
private readonly IUmbracoDatabaseFactory _databaseFactory;
2020-12-15 15:20:36 +00:00
private readonly IEventAggregator _eventAggregator;
private readonly IHostingEnvironment _hostingEnvironment;
/// <summary>
/// Initializes a new instance of the <see cref="CoreRuntime"/> class.
/// </summary>
public CoreRuntime(
2020-12-15 15:20:36 +00:00
ILoggerFactory loggerFactory,
IRuntimeState state,
ComponentCollection components,
IApplicationShutdownRegistry applicationShutdownRegistry,
IProfilingLogger profilingLogger,
IMainDom mainDom,
2020-12-15 15:20:36 +00:00
IUmbracoDatabaseFactory databaseFactory,
IEventAggregator eventAggregator,
IHostingEnvironment hostingEnvironment)
{
State = state;
2020-12-15 15:20:36 +00:00
_loggerFactory = loggerFactory;
_components = components;
_applicationShutdownRegistry = applicationShutdownRegistry;
_profilingLogger = profilingLogger;
_mainDom = mainDom;
_databaseFactory = databaseFactory;
2020-12-15 15:20:36 +00:00
_eventAggregator = eventAggregator;
_hostingEnvironment = hostingEnvironment;
_logger = _loggerFactory.CreateLogger<CoreRuntime>();
}
2020-12-15 15:20:36 +00:00
/// <summary>
/// Gets the state of the Umbraco runtime.
/// </summary>
public IRuntimeState State { get; }
/// <inheritdoc/>
public async Task StartAsync(CancellationToken cancellationToken)
2016-08-25 15:09:51 +02:00
{
2020-12-15 15:20:36 +00:00
StaticApplicationLogging.Initialize(_loggerFactory);
AppDomain.CurrentDomain.UnhandledException += (_, args) =>
{
var exception = (Exception)args.ExceptionObject;
var isTerminating = args.IsTerminating; // always true?
var msg = "Unhandled exception in AppDomain";
2020-12-15 15:20:36 +00:00
if (isTerminating)
{
msg += " (terminating)";
}
msg += ".";
2020-12-15 15:20:36 +00:00
_logger.LogError(exception, msg);
};
AppDomain.CurrentDomain.SetData("DataDirectory", _hostingEnvironment?.MapPathContentRoot(Constants.SystemDirectories.Data));
2020-12-15 15:20:36 +00:00
Merge remote-tracking branch 'origin/v8/dev' into netcore/feature/merge-v8-18-01-2021 # Conflicts: # .gitignore # build/NuSpecs/UmbracoCms.Core.nuspec # src/SolutionInfo.cs # src/Umbraco.Core/Configuration/UmbracoSettings/BackOfficeElement.cs # src/Umbraco.Core/Configuration/UmbracoSettings/ContentElement.cs # src/Umbraco.Core/Configuration/UmbracoSettings/IBackOfficeSection.cs # src/Umbraco.Core/Configuration/UmbracoSettings/IContentSection.cs # src/Umbraco.Core/IO/SystemFiles.cs # src/Umbraco.Core/Models/ContentBase.cs # src/Umbraco.Core/Models/Identity/BackOfficeIdentityUser.cs # src/Umbraco.Core/Persistence/UmbracoDatabaseExtensions.cs # src/Umbraco.Core/Runtime/CoreRuntime.cs # src/Umbraco.Core/RuntimeOptions.cs # src/Umbraco.Core/RuntimeState.cs # src/Umbraco.Core/Telemetry/TelemetryMarkerComponent.cs # src/Umbraco.Core/Telemetry/TelemetryMarkerComposer.cs # src/Umbraco.Examine/Umbraco.Examine.csproj # src/Umbraco.Infrastructure/HostedServices/ReportSiteTask.cs # src/Umbraco.Infrastructure/Install/InstallStepCollection.cs # src/Umbraco.Infrastructure/Install/InstallSteps/NewInstallStep.cs # src/Umbraco.Infrastructure/Migrations/Install/DatabaseBuilder.cs # src/Umbraco.Infrastructure/Migrations/Install/DatabaseSchemaCreator.cs # src/Umbraco.Infrastructure/Runtime/SqlMainDomLock.cs # src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/ContentTypeRepositoryTest.cs # src/Umbraco.Tests/Runtimes/CoreRuntimeTests.cs # src/Umbraco.Tests/Runtimes/StandaloneTests.cs # src/Umbraco.Tests/Testing/TestDatabase.cs # src/Umbraco.Web.BackOffice/Controllers/BackOfficeServerVariables.cs # src/Umbraco.Web.UI.Client/src/installer/steps/database.controller.js # src/Umbraco.Web.UI.NetCore/Views/Partials/Grid/Editors/TextString.cshtml # src/Umbraco.Web.UI.NetCore/umbraco/config/lang/da.xml # src/Umbraco.Web.UI.NetCore/umbraco/config/lang/en.xml # src/Umbraco.Web.UI.NetCore/umbraco/config/lang/en_us.xml # src/Umbraco.Web.UI/Umbraco/config/lang/cs.xml # src/Umbraco.Web.UI/config/umbracoSettings.Release.config # src/Umbraco.Web/Composing/CompositionExtensions/Installer.cs # src/Umbraco.Web/Editors/PreviewController.cs # src/Umbraco.Web/Editors/UsersController.cs # src/Umbraco.Web/JavaScript/PreviewInitialize.js # src/Umbraco.Web/Telemetry/TelemetryComponent.cs # src/Umbraco.Web/UmbracoApplication.cs
2021-01-18 15:40:22 +01:00
DoUnattendedInstall();
DetermineRuntimeLevel();
if (State.Level <= RuntimeLevel.BootFailed)
2020-12-15 15:20:36 +00:00
{
throw new InvalidOperationException($"Cannot start the runtime if the runtime level is less than or equal to {RuntimeLevel.BootFailed}");
2020-12-15 15:20:36 +00:00
}
2020-12-15 15:20:36 +00:00
IApplicationShutdownRegistry hostingEnvironmentLifetime = _applicationShutdownRegistry;
if (hostingEnvironmentLifetime == null)
2020-12-15 15:20:36 +00:00
{
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(StartAsync)}");
}
// acquire the main domain - if this fails then anything that should be registered with MainDom will not operate
2020-11-24 09:22:38 +00:00
AcquireMainDom();
2020-12-15 15:20:36 +00:00
await _eventAggregator.PublishAsync(new UmbracoApplicationStarting(State.Level), cancellationToken);
// create & initialize the components
_components.Initialize();
}
Merge remote-tracking branch 'origin/v8/dev' into netcore/feature/merge-v8-18-01-2021 # Conflicts: # .gitignore # build/NuSpecs/UmbracoCms.Core.nuspec # src/SolutionInfo.cs # src/Umbraco.Core/Configuration/UmbracoSettings/BackOfficeElement.cs # src/Umbraco.Core/Configuration/UmbracoSettings/ContentElement.cs # src/Umbraco.Core/Configuration/UmbracoSettings/IBackOfficeSection.cs # src/Umbraco.Core/Configuration/UmbracoSettings/IContentSection.cs # src/Umbraco.Core/IO/SystemFiles.cs # src/Umbraco.Core/Models/ContentBase.cs # src/Umbraco.Core/Models/Identity/BackOfficeIdentityUser.cs # src/Umbraco.Core/Persistence/UmbracoDatabaseExtensions.cs # src/Umbraco.Core/Runtime/CoreRuntime.cs # src/Umbraco.Core/RuntimeOptions.cs # src/Umbraco.Core/RuntimeState.cs # src/Umbraco.Core/Telemetry/TelemetryMarkerComponent.cs # src/Umbraco.Core/Telemetry/TelemetryMarkerComposer.cs # src/Umbraco.Examine/Umbraco.Examine.csproj # src/Umbraco.Infrastructure/HostedServices/ReportSiteTask.cs # src/Umbraco.Infrastructure/Install/InstallStepCollection.cs # src/Umbraco.Infrastructure/Install/InstallSteps/NewInstallStep.cs # src/Umbraco.Infrastructure/Migrations/Install/DatabaseBuilder.cs # src/Umbraco.Infrastructure/Migrations/Install/DatabaseSchemaCreator.cs # src/Umbraco.Infrastructure/Runtime/SqlMainDomLock.cs # src/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/ContentTypeRepositoryTest.cs # src/Umbraco.Tests/Runtimes/CoreRuntimeTests.cs # src/Umbraco.Tests/Runtimes/StandaloneTests.cs # src/Umbraco.Tests/Testing/TestDatabase.cs # src/Umbraco.Web.BackOffice/Controllers/BackOfficeServerVariables.cs # src/Umbraco.Web.UI.Client/src/installer/steps/database.controller.js # src/Umbraco.Web.UI.NetCore/Views/Partials/Grid/Editors/TextString.cshtml # src/Umbraco.Web.UI.NetCore/umbraco/config/lang/da.xml # src/Umbraco.Web.UI.NetCore/umbraco/config/lang/en.xml # src/Umbraco.Web.UI.NetCore/umbraco/config/lang/en_us.xml # src/Umbraco.Web.UI/Umbraco/config/lang/cs.xml # src/Umbraco.Web.UI/config/umbracoSettings.Release.config # src/Umbraco.Web/Composing/CompositionExtensions/Installer.cs # src/Umbraco.Web/Editors/PreviewController.cs # src/Umbraco.Web/Editors/UsersController.cs # src/Umbraco.Web/JavaScript/PreviewInitialize.js # src/Umbraco.Web/Telemetry/TelemetryComponent.cs # src/Umbraco.Web/UmbracoApplication.cs
2021-01-18 15:40:22 +01:00
private void DoUnattendedInstall()
{
State.DoUnattendedInstall();
}
2020-12-15 15:20:36 +00:00
public async Task StopAsync(CancellationToken cancellationToken)
{
2020-11-24 09:22:38 +00:00
_components.Terminate();
2020-12-15 15:20:36 +00:00
await _eventAggregator.PublishAsync(new UmbracoApplicationStopping(), cancellationToken);
StaticApplicationLogging.Initialize(null);
}
2020-11-24 09:22:38 +00:00
private void AcquireMainDom()
{
2020-12-15 15:20:36 +00:00
using (DisposableTimer timer = _profilingLogger.DebugDuration<CoreRuntime>("Acquiring MainDom.", "Acquired."))
{
try
{
2020-11-24 09:22:38 +00:00
_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()
{
2020-12-15 15:20:36 +00:00
using DisposableTimer 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
{
2020-11-24 09:22:38 +00:00
State.Configure(RuntimeLevel.BootFailed, RuntimeLevelReason.BootFailedOnException);
timer?.Fail();
throw;
}
}
2016-08-25 15:09:51 +02:00
}
}