From e482bf93fe4b9a0d7e8dfcd7470afb431a753582 Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Fri, 8 Mar 2019 13:31:23 +0100 Subject: [PATCH] Migration improved. --- .../DependencyInjectionExtensions.cs | 9 ++++- .../IBackgroundProcess.cs | 17 +++++++++ .../{Bootstrap.cs => GrainBootstrap.cs} | 6 +-- src/Squidex/Config/Domain/EntitiesServices.cs | 14 +++++-- .../Config/Domain/InfrastructureServices.cs | 9 +++++ src/Squidex/Config/Orleans/OrleansServices.cs | 8 ---- src/Squidex/Config/Startup/BackgroundHost.cs | 38 +++++++++++++++++++ src/Squidex/WebStartup.cs | 1 + .../Orleans/BootstrapTests.cs | 4 +- .../MongoDb/RestructureContentCollection.cs | 5 ++- 10 files changed, 92 insertions(+), 19 deletions(-) create mode 100644 src/Squidex.Infrastructure/IBackgroundProcess.cs rename src/Squidex.Infrastructure/Orleans/{Bootstrap.cs => GrainBootstrap.cs} (85%) create mode 100644 src/Squidex/Config/Startup/BackgroundHost.cs diff --git a/src/Squidex.Infrastructure/DependencyInjection/DependencyInjectionExtensions.cs b/src/Squidex.Infrastructure/DependencyInjection/DependencyInjectionExtensions.cs index 13f245759..9ee638ac0 100644 --- a/src/Squidex.Infrastructure/DependencyInjection/DependencyInjectionExtensions.cs +++ b/src/Squidex.Infrastructure/DependencyInjection/DependencyInjectionExtensions.cs @@ -83,10 +83,17 @@ namespace Microsoft.Extensions.DependencyInjection private static void RegisterDefaults(IServiceCollection services) where T : class { - if (typeof(T).GetInterfaces().Contains(typeof(IInitializable))) + var interfaces = typeof(T).GetInterfaces(); + + if (interfaces.Contains(typeof(IInitializable))) { services.AddSingleton(typeof(IInitializable), c => c.GetRequiredService()); } + + if (interfaces.Contains(typeof(IBackgroundProcess))) + { + services.AddSingleton(typeof(IBackgroundProcess), c => c.GetRequiredService()); + } } } } diff --git a/src/Squidex.Infrastructure/IBackgroundProcess.cs b/src/Squidex.Infrastructure/IBackgroundProcess.cs new file mode 100644 index 000000000..38003910c --- /dev/null +++ b/src/Squidex.Infrastructure/IBackgroundProcess.cs @@ -0,0 +1,17 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using System.Threading; +using System.Threading.Tasks; + +namespace Squidex.Infrastructure +{ + public interface IBackgroundProcess + { + Task StartAsync(CancellationToken ct); + } +} diff --git a/src/Squidex.Infrastructure/Orleans/Bootstrap.cs b/src/Squidex.Infrastructure/Orleans/GrainBootstrap.cs similarity index 85% rename from src/Squidex.Infrastructure/Orleans/Bootstrap.cs rename to src/Squidex.Infrastructure/Orleans/GrainBootstrap.cs index 5a3bb7a19..fd2e4d1f3 100644 --- a/src/Squidex.Infrastructure/Orleans/Bootstrap.cs +++ b/src/Squidex.Infrastructure/Orleans/GrainBootstrap.cs @@ -12,19 +12,19 @@ using Orleans.Runtime; namespace Squidex.Infrastructure.Orleans { - public sealed class Bootstrap : IStartupTask where T : IBackgroundGrain + public sealed class GrainBootstrap : IBackgroundProcess where T : IBackgroundGrain { private const int NumTries = 10; private readonly IGrainFactory grainFactory; - public Bootstrap(IGrainFactory grainFactory) + public GrainBootstrap(IGrainFactory grainFactory) { Guard.NotNull(grainFactory, nameof(grainFactory)); this.grainFactory = grainFactory; } - public async Task Execute(CancellationToken cancellationToken) + public async Task StartAsync(CancellationToken ct) { for (var i = 1; i <= NumTries; i++) { diff --git a/src/Squidex/Config/Domain/EntitiesServices.cs b/src/Squidex/Config/Domain/EntitiesServices.cs index d29a8c256..0ae7ce401 100644 --- a/src/Squidex/Config/Domain/EntitiesServices.cs +++ b/src/Squidex/Config/Domain/EntitiesServices.cs @@ -44,7 +44,9 @@ using Squidex.Domain.Apps.Entities.Tags; using Squidex.Infrastructure.Assets; using Squidex.Infrastructure.Commands; using Squidex.Infrastructure.EventSourcing; +using Squidex.Infrastructure.EventSourcing.Grains; using Squidex.Infrastructure.Migrations; +using Squidex.Infrastructure.Orleans; using Squidex.Pipeline; using Squidex.Pipeline.CommandMiddlewares; @@ -63,12 +65,10 @@ namespace Squidex.Config.Domain .As().As().As(); services.AddSingletonAs() - .As() - .As(); + .As().As(); services.AddSingletonAs() - .As() - .As(); + .As().As(); services.AddSingletonAs() .As(); @@ -118,6 +118,12 @@ namespace Squidex.Config.Domain services.AddSingletonAs() .AsOptional(); + services.AddSingletonAs>() + .AsSelf(); + + services.AddSingletonAs>() + .AsSelf(); + services.AddCommandPipeline(); services.AddBackupHandlers(); diff --git a/src/Squidex/Config/Domain/InfrastructureServices.cs b/src/Squidex/Config/Domain/InfrastructureServices.cs index 310f33d2e..915dd035a 100644 --- a/src/Squidex/Config/Domain/InfrastructureServices.cs +++ b/src/Squidex/Config/Domain/InfrastructureServices.cs @@ -14,9 +14,12 @@ using Microsoft.Extensions.DependencyInjection; using NodaTime; using Squidex.Areas.Api.Controllers.News.Service; using Squidex.Domain.Apps.Entities.Apps.Diagnostics; +using Squidex.Domain.Apps.Entities.Rules.UsageTracking; using Squidex.Domain.Users; using Squidex.Infrastructure.Caching; using Squidex.Infrastructure.Diagnostics; +using Squidex.Infrastructure.EventSourcing.Grains; +using Squidex.Infrastructure.Orleans; using Squidex.Infrastructure.Translations; using Squidex.Infrastructure.UsageTracking; using Squidex.Shared.Users; @@ -48,6 +51,12 @@ namespace Squidex.Config.Domain services.AddSingletonAs() .AsSelf(); + services.AddSingletonAs>() + .AsSelf(); + + services.AddSingletonAs>() + .AsSelf(); + services.AddSingletonAs() .As(); diff --git a/src/Squidex/Config/Orleans/OrleansServices.cs b/src/Squidex/Config/Orleans/OrleansServices.cs index 36c3cdc71..b6672f004 100644 --- a/src/Squidex/Config/Orleans/OrleansServices.cs +++ b/src/Squidex/Config/Orleans/OrleansServices.cs @@ -12,10 +12,6 @@ using Microsoft.Extensions.DependencyInjection; using Orleans; using Orleans.Configuration; using Orleans.Hosting; -using Squidex.Domain.Apps.Entities.Contents; -using Squidex.Domain.Apps.Entities.Rules; -using Squidex.Domain.Apps.Entities.Rules.UsageTracking; -using Squidex.Infrastructure.EventSourcing.Grains; using Squidex.Infrastructure.Orleans; namespace Squidex.Config.Orleans @@ -45,10 +41,6 @@ namespace Squidex.Config.Orleans .UseDashboardEx() .EnableDirectClient() .AddIncomingGrainCallFilter() - .AddStartupTask>() - .AddStartupTask>() - .AddStartupTask>() - .AddStartupTask>() .ConfigureApplicationParts(builder => { builder.AddMyParts(); diff --git a/src/Squidex/Config/Startup/BackgroundHost.cs b/src/Squidex/Config/Startup/BackgroundHost.cs new file mode 100644 index 000000000..e16e6fe9b --- /dev/null +++ b/src/Squidex/Config/Startup/BackgroundHost.cs @@ -0,0 +1,38 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Hosting; +using Squidex.Infrastructure; +using Squidex.Infrastructure.Log; + +namespace Squidex.Config.Startup +{ + public sealed class BackgroundHost : SafeHostedService + { + private readonly IEnumerable targets; + + public BackgroundHost(IEnumerable targets, IApplicationLifetime lifetime, ISemanticLog log) + : base(lifetime, log) + { + this.targets = targets; + } + + protected override async Task StartAsync(ISemanticLog log, CancellationToken ct) + { + foreach (var target in targets.Distinct()) + { + await target.StartAsync(ct); + + log.LogInformation(w => w.WriteProperty("backgroundSystem", target.GetType().Name)); + } + } + } +} diff --git a/src/Squidex/WebStartup.cs b/src/Squidex/WebStartup.cs index a23db7df9..115dbcb31 100644 --- a/src/Squidex/WebStartup.cs +++ b/src/Squidex/WebStartup.cs @@ -103,6 +103,7 @@ namespace Squidex var provider = services.AddAndBuildOrleans(configuration, afterServices => { afterServices.AddHostedService(); + afterServices.AddHostedService(); }); return provider; diff --git a/tests/Squidex.Infrastructure.Tests/Orleans/BootstrapTests.cs b/tests/Squidex.Infrastructure.Tests/Orleans/BootstrapTests.cs index b2fb54fd8..4efe764e3 100644 --- a/tests/Squidex.Infrastructure.Tests/Orleans/BootstrapTests.cs +++ b/tests/Squidex.Infrastructure.Tests/Orleans/BootstrapTests.cs @@ -19,13 +19,13 @@ namespace Squidex.Infrastructure.Orleans public class BootstrapTests { private readonly IBackgroundGrain grain = A.Fake(); - private readonly Bootstrap sut; + private readonly GrainBootstrap sut; public BootstrapTests() { var factory = A.Fake(); - sut = new Bootstrap(factory); + sut = new GrainBootstrap(factory); A.CallTo(() => factory.GetGrain("Default", null)) .Returns(grain); diff --git a/tools/Migrate_01/Migrations/MongoDb/RestructureContentCollection.cs b/tools/Migrate_01/Migrations/MongoDb/RestructureContentCollection.cs index 38987dc2b..ea5511052 100644 --- a/tools/Migrate_01/Migrations/MongoDb/RestructureContentCollection.cs +++ b/tools/Migrate_01/Migrations/MongoDb/RestructureContentCollection.cs @@ -29,8 +29,11 @@ namespace Migrate_01.Migrations.MongoDb await contentDatabase.DropCollectionAsync("State_Contents"); await contentDatabase.DropCollectionAsync("State_Content_Published"); await contentDatabase.RenameCollectionAsync("State_Content_Draft", "State_Contents"); + } - var collection = contentDatabase.GetCollection("State_Content"); + if (await contentDatabase.CollectionExistsAsync("State_Contents")) + { + var collection = contentDatabase.GetCollection("State_Contents"); await collection.UpdateManyAsync(new BsonDocument(), Builders.Update.Unset("dt")); }