Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initialize important services before unattended installs #17366

2 changes: 1 addition & 1 deletion build/azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ stages:
- job: A
displayName: Build Umbraco CMS
pool:
vmImage: 'windows-latest'
vmImage: 'ubuntu-latest'
steps:
- checkout: self
submodules: true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,45 @@ namespace Umbraco.Cms.Persistence.EFCore.Scoping;

public class AmbientEFCoreScopeStack<TDbContext> : IAmbientEFCoreScopeStack<TDbContext> where TDbContext : DbContext
{

private static Lock _lock = new();
private static AsyncLocal<ConcurrentStack<IEfCoreScope<TDbContext>>> _stack = new();

public IEfCoreScope<TDbContext>? AmbientScope
{
get
{
if (_stack.Value?.TryPeek(out IEfCoreScope<TDbContext>? ambientScope) ?? false)
lock (_lock)
{
return ambientScope;
}
if (_stack.Value?.TryPeek(out IEfCoreScope<TDbContext>? ambientScope) ?? false)
{
return ambientScope;
}

return null;
return null;
}
}
}

public IEfCoreScope<TDbContext> Pop()
{
if (_stack.Value?.TryPop(out IEfCoreScope<TDbContext>? ambientScope) ?? false)
lock (_lock)
{
return ambientScope;
}
if (_stack.Value?.TryPop(out IEfCoreScope<TDbContext>? ambientScope) ?? false)
{
return ambientScope;
}

throw new InvalidOperationException("No AmbientScope was found.");
throw new InvalidOperationException("No AmbientScope was found.");
}
}

public void Push(IEfCoreScope<TDbContext> scope)
{
_stack.Value ??= new ConcurrentStack<IEfCoreScope<TDbContext>>();
lock (_lock)
{
_stack.Value ??= new ConcurrentStack<IEfCoreScope<TDbContext>>();

_stack.Value.Push(scope);
_stack.Value.Push(scope);
}
}
}
2 changes: 1 addition & 1 deletion src/Umbraco.Core/Constants-Composing.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public static class Composing
{
public static readonly string[] UmbracoCoreAssemblyNames =
{
"Umbraco.Core", "Umbraco.Infrastructure", "Umbraco.PublishedCache.NuCache", "Umbraco.Examine.Lucene",
"Umbraco.Core", "Umbraco.Infrastructure", "Umbraco.Examine.Lucene",
"Umbraco.Web.Common", "Umbraco.Cms.Api.Common","Umbraco.Cms.Api.Delivery","Umbraco.Cms.Api.Management", "Umbraco.Web.Website",
};
}
Expand Down
3 changes: 2 additions & 1 deletion src/Umbraco.Core/DependencyInjection/UmbracoBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,8 @@ private void AddCoreServices()

// Routing
Services.AddUnique<IDocumentUrlService, DocumentUrlService>();
Services.AddHostedService<DocumentUrlServiceInitializer>();
Services.AddNotificationAsyncHandler<UmbracoApplicationStartingNotification, DocumentUrlServiceInitializerNotificationHandler>();

}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Umbraco.Cms.Core.Notifications;

public class PostRuntimePremigrationsUpgradeNotification : INotification
{

}
53 changes: 0 additions & 53 deletions src/Umbraco.Core/Services/DocumentUrlServiceInitializer.cs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Notifications;

namespace Umbraco.Cms.Core.Services;

public class DocumentUrlServiceInitializerNotificationHandler : INotificationAsyncHandler<UmbracoApplicationStartingNotification>
{
private readonly IDocumentUrlService _documentUrlService;
private readonly IRuntimeState _runtimeState;

public DocumentUrlServiceInitializerNotificationHandler(IDocumentUrlService documentUrlService, IRuntimeState runtimeState)
{
_documentUrlService = documentUrlService;
_runtimeState = runtimeState;
}

public async Task HandleAsync(UmbracoApplicationStartingNotification notification, CancellationToken cancellationToken)
{
if (_runtimeState.Level == RuntimeLevel.Upgrade)
{
//Special case on the first upgrade, as the database is not ready yet.
return;
}

await _documentUrlService.InitAsync(
_runtimeState.Level <= RuntimeLevel.Install,
cancellationToken);
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
using Microsoft.Extensions.Hosting;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Notifications;

namespace Umbraco.Cms.Core.Services.Navigation;

/// <summary>
/// Responsible for seeding the in-memory navigation structures at application's startup
/// by rebuild the navigation structures.
/// </summary>
public sealed class NavigationInitializationHostedService : IHostedLifecycleService
public sealed class NavigationInitializationNotificationHandler : INotificationAsyncHandler<PostRuntimePremigrationsUpgradeNotification>
{
private readonly IRuntimeState _runtimeState;
private readonly IDocumentNavigationManagementService _documentNavigationManagementService;
private readonly IMediaNavigationManagementService _mediaNavigationManagementService;

public NavigationInitializationHostedService(
public NavigationInitializationNotificationHandler(
IRuntimeState runtimeState,
IDocumentNavigationManagementService documentNavigationManagementService,
IMediaNavigationManagementService mediaNavigationManagementService)
Expand All @@ -22,7 +24,7 @@ public NavigationInitializationHostedService(
_mediaNavigationManagementService = mediaNavigationManagementService;
}

public async Task StartingAsync(CancellationToken cancellationToken)
public async Task HandleAsync(PostRuntimePremigrationsUpgradeNotification notification, CancellationToken cancellationToken)
{
if(_runtimeState.Level < RuntimeLevel.Upgrade)
{
Expand All @@ -34,14 +36,4 @@ public async Task StartingAsync(CancellationToken cancellationToken)
await _mediaNavigationManagementService.RebuildAsync();
await _mediaNavigationManagementService.RebuildBinAsync();
}

public Task StartAsync(CancellationToken cancellationToken) => Task.CompletedTask;

public Task StartedAsync(CancellationToken cancellationToken) => Task.CompletedTask;

public Task StoppingAsync(CancellationToken cancellationToken) => Task.CompletedTask;

public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;

public Task StoppedAsync(CancellationToken cancellationToken) => Task.CompletedTask;
}
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
using Microsoft.Extensions.Hosting;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Notifications;

namespace Umbraco.Cms.Core.Services.Navigation;

/// <summary>
/// Responsible for seeding the in-memory publish status cache at application's startup
/// by loading all data from the database.
/// </summary>
public sealed class PublishStatusInitializationHostedService : IHostedLifecycleService
public sealed class PublishStatusInitializationNotificationHandler : INotificationAsyncHandler<PostRuntimePremigrationsUpgradeNotification>
{
private readonly IRuntimeState _runtimeState;
private readonly IPublishStatusManagementService _publishStatusManagementService;

public PublishStatusInitializationHostedService(
public PublishStatusInitializationNotificationHandler(
IRuntimeState runtimeState,
IPublishStatusManagementService publishStatusManagementService
)
Expand All @@ -20,7 +22,7 @@ IPublishStatusManagementService publishStatusManagementService
_publishStatusManagementService = publishStatusManagementService;
}

public async Task StartingAsync(CancellationToken cancellationToken)
public async Task HandleAsync(PostRuntimePremigrationsUpgradeNotification notification, CancellationToken cancellationToken)
{
if(_runtimeState.Level < RuntimeLevel.Upgrade)
{
Expand All @@ -29,14 +31,4 @@ public async Task StartingAsync(CancellationToken cancellationToken)

await _publishStatusManagementService.InitializeAsync(cancellationToken);
}

public Task StartAsync(CancellationToken cancellationToken) => Task.CompletedTask;

public Task StartedAsync(CancellationToken cancellationToken) => Task.CompletedTask;

public Task StoppingAsync(CancellationToken cancellationToken) => Task.CompletedTask;

public Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask;

public Task StoppedAsync(CancellationToken cancellationToken) => Task.CompletedTask;
}
2 changes: 1 addition & 1 deletion src/Umbraco.Infrastructure/Install/PremigrationUpgrader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
namespace Umbraco.Cms.Infrastructure.Install;

/// <summary>
/// Handles <see cref="RuntimeUnattendedUpgradeNotification" /> to execute the unattended Umbraco upgrader
/// Handles <see cref="RuntimePremigrationsUpgradeNotification" /> to execute the unattended Umbraco upgrader
/// or the unattended Package migrations runner.
/// </summary>
public class PremigrationUpgrader : INotificationAsyncHandler<RuntimePremigrationsUpgradeNotification>
Expand Down
4 changes: 2 additions & 2 deletions src/Umbraco.Infrastructure/Migrations/Upgrade/UmbracoPlan.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,14 @@ protected virtual void DefinePlan()
To<V_13_5_0.ChangeRedirectUrlToNvarcharMax>("{CC47C751-A81B-489A-A2BC-0240245DB687}");

// To 14.0.0
To<V_14_0_0.AddPropertyEditorUiAliasColumn>("{419827A0-4FCE-464B-A8F3-247C6092AF55}");
To<NoopMigration>("{419827A0-4FCE-464B-A8F3-247C6092AF55}");
To<NoopMigration>("{69E12556-D9B3-493A-8E8A-65EC89FB658D}");
To<NoopMigration>("{F2B16CD4-F181-4BEE-81C9-11CF384E6025}");
To<NoopMigration>("{A8E01644-9F2E-4988-8341-587EF5B7EA69}");
To<V_14_0_0.UpdateDefaultGuidsOfCreatedPackages>("{E073DBC0-9E8E-4C92-8210-9CB18364F46E}");
To<V_14_0_0.RenameTechnologyLeakingPropertyEditorAliases>("{80D282A4-5497-47FF-991F-BC0BCE603121}");
To<V_14_0_0.MigrateSchduledPublishesToUtc>("{96525697-E9DC-4198-B136-25AD033442B8}");
To<V_14_0_0.AddListViewKeysToDocumentTypes>("{7FC5AC9B-6F56-415B-913E-4A900629B853}");
To<NoopMigration>("{7FC5AC9B-6F56-415B-913E-4A900629B853}");
To<V_14_0_0.MigrateDataTypeConfigurations>("{1539A010-2EB5-4163-8518-4AE2AA98AFC6}");
To<NoopMigration>("{C567DE81-DF92-4B99-BEA8-CD34EF99DA5D}");
To<V_14_0_0.DeleteMacroTables>("{0D82C836-96DD-480D-A924-7964E458BD34}");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,5 +65,7 @@ protected virtual void DefinePlan()
To<V_14_0_0.MigrateTours>("{A08254B6-D9E7-4207-A496-2ED0A87FB4FD}");
To<V_15_0_0.AddKindToUser>("{69AA6889-8B67-42B4-AA4F-114704487A45}");
To<V_15_0_0.AddDocumentUrl>("{B9133686-B758-404D-AF12-708AA80C7E44}");
To<V_14_0_0.AddPropertyEditorUiAliasColumn>("{EEB1F012-B44D-4AB4-8756-F7FB547345B4}");
To<V_14_0_0.AddListViewKeysToDocumentTypes>("{0F49E1A4-AFD8-4673-A91B-F64E78C48174}");
}
}
Loading