Browse Source

Background processes migrated.

pull/249/head
Sebastian Stehle 8 years ago
parent
commit
f3799c23d1
  1. 30
      src/Squidex.Domain.Apps.Entities/Contents/ContentSchedulerGrain.cs
  2. 1
      src/Squidex.Domain.Apps.Entities/Contents/Guards/GuardContent.cs
  3. 15
      src/Squidex.Domain.Apps.Entities/Contents/IContentSchedulerGrain.cs
  4. 15
      src/Squidex.Domain.Apps.Entities/Rules/IRuleDequeuerGrain.cs
  5. 42
      src/Squidex.Domain.Apps.Entities/Rules/RuleDequeuerGrain.cs
  6. 1
      src/Squidex.Domain.Apps.Entities/Squidex.Domain.Apps.Entities.csproj
  7. 16
      src/Squidex.Domain.Apps.Entities/SquidexEntities.cs
  8. 1
      src/Squidex.Infrastructure.MongoDb/MongoDb/BsonJsonConvention.cs
  9. 5
      src/Squidex.Infrastructure.MongoDb/MongoDb/MongoRepositoryBase.cs
  10. 4
      src/Squidex.Infrastructure/EventSourcing/Grains/EventConsumerGrain.cs
  11. 23
      src/Squidex.Infrastructure/EventSourcing/Grains/EventConsumerManagerGrain.cs
  12. 6
      src/Squidex.Infrastructure/EventSourcing/Grains/IEventConsumerGrain.cs
  13. 6
      src/Squidex.Infrastructure/EventSourcing/Grains/IEventConsumerManagerGrain.cs
  14. 11
      src/Squidex.Infrastructure/Orleans/Bootstrap.cs
  15. 17
      src/Squidex.Infrastructure/Orleans/IBackgroundGrain.cs
  16. 4
      src/Squidex/Areas/Api/Controllers/EventConsumers/EventConsumersController.cs
  17. 13
      src/Squidex/Config/Domain/InfrastructureServices.cs
  18. 31
      src/Squidex/Config/Domain/ReadServices.cs
  19. 2
      src/Squidex/Config/Orleans/ClientWrapper.cs
  20. 3
      src/Squidex/Config/Orleans/SiloServices.cs
  21. 19
      src/Squidex/Config/Orleans/SiloWrapper.cs
  22. 1
      src/Squidex/WebStartup.cs
  23. 4
      tests/Squidex.Domain.Apps.Entities.Tests/Rules/RuleDequeuerTests.cs
  24. 2
      tools/Migrate_01/Migrations/RebuildAssets.cs

30
src/Squidex.Domain.Apps.Entities/Contents/ContentScheduler.cs → src/Squidex.Domain.Apps.Entities/Contents/ContentSchedulerGrain.cs

@ -5,24 +5,26 @@
// All rights reserved. Licensed under the MIT license. // All rights reserved. Licensed under the MIT license.
// ========================================================================== // ==========================================================================
using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using NodaTime; using NodaTime;
using Orleans;
using Orleans.Runtime;
using Squidex.Domain.Apps.Entities.Contents.Commands; using Squidex.Domain.Apps.Entities.Contents.Commands;
using Squidex.Domain.Apps.Entities.Contents.Repositories; using Squidex.Domain.Apps.Entities.Contents.Repositories;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.Commands; using Squidex.Infrastructure.Commands;
using Squidex.Infrastructure.Timers; using Squidex.Infrastructure.Tasks;
namespace Squidex.Domain.Apps.Entities.Contents namespace Squidex.Domain.Apps.Entities.Contents
{ {
public sealed class ContentScheduler : IRunnable public sealed class ContentSchedulerGrain : Grain, IContentSchedulerGrain, IRemindable
{ {
private readonly CompletionTimer timer;
private readonly IContentRepository contentRepository; private readonly IContentRepository contentRepository;
private readonly ICommandBus commandBus; private readonly ICommandBus commandBus;
private readonly IClock clock; private readonly IClock clock;
public ContentScheduler( public ContentSchedulerGrain(
IContentRepository contentRepository, IContentRepository contentRepository,
ICommandBus commandBus, ICommandBus commandBus,
IClock clock) IClock clock)
@ -34,15 +36,24 @@ namespace Squidex.Domain.Apps.Entities.Contents
this.contentRepository = contentRepository; this.contentRepository = contentRepository;
this.commandBus = commandBus; this.commandBus = commandBus;
this.clock = clock; this.clock = clock;
}
public override Task OnActivateAsync()
{
DelayDeactivation(TimeSpan.FromDays(1));
RegisterOrUpdateReminder("Default", TimeSpan.Zero, TimeSpan.FromMinutes(10));
RegisterTimer(x => PublishAsync(), null, TimeSpan.Zero, TimeSpan.FromSeconds(10));
timer = new CompletionTimer(5000, x => PublishAsync()); return Task.FromResult(true);
} }
public void Run() public Task ActivateAsync()
{ {
return TaskHelper.Done;
} }
private Task PublishAsync() public Task PublishAsync()
{ {
var now = clock.GetCurrentInstant(); var now = clock.GetCurrentInstant();
@ -53,5 +64,10 @@ namespace Squidex.Domain.Apps.Entities.Contents
return commandBus.PublishAsync(command); return commandBus.PublishAsync(command);
}); });
} }
public Task ReceiveReminder(string reminderName, TickStatus status)
{
return TaskHelper.Done;
}
} }
} }

1
src/Squidex.Domain.Apps.Entities/Contents/Guards/GuardContent.cs

@ -5,7 +5,6 @@
// All rights reserved. Licensed under the MIT license. // All rights reserved. Licensed under the MIT license.
// ========================================================================== // ==========================================================================
using System;
using NodaTime; using NodaTime;
using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Entities.Contents.Commands; using Squidex.Domain.Apps.Entities.Contents.Commands;

15
src/Squidex.Domain.Apps.Entities/Contents/IContentSchedulerGrain.cs

@ -0,0 +1,15 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using Squidex.Infrastructure.Orleans;
namespace Squidex.Domain.Apps.Entities.Contents
{
public interface IContentSchedulerGrain : IBackgroundGrain
{
}
}

15
src/Squidex.Domain.Apps.Entities/Rules/IRuleDequeuerGrain.cs

@ -0,0 +1,15 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using Squidex.Infrastructure.Orleans;
namespace Squidex.Domain.Apps.Entities.Rules
{
public interface IRuleDequeuerGrain : IBackgroundGrain
{
}
}

42
src/Squidex.Domain.Apps.Entities/Rules/RuleDequeuer.cs → src/Squidex.Domain.Apps.Entities/Rules/RuleDequeuerGrain.cs

@ -7,31 +7,30 @@
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow; using System.Threading.Tasks.Dataflow;
using NodaTime; using NodaTime;
using Orleans;
using Orleans.Runtime;
using Squidex.Domain.Apps.Core.HandleRules; using Squidex.Domain.Apps.Core.HandleRules;
using Squidex.Domain.Apps.Core.Rules; using Squidex.Domain.Apps.Core.Rules;
using Squidex.Domain.Apps.Entities.Rules.Repositories; using Squidex.Domain.Apps.Entities.Rules.Repositories;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.Log; using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.Tasks; using Squidex.Infrastructure.Tasks;
using Squidex.Infrastructure.Timers;
namespace Squidex.Domain.Apps.Entities.Rules namespace Squidex.Domain.Apps.Entities.Rules
{ {
public class RuleDequeuer : DisposableObjectBase, IRunnable public class RuleDequeuerGrain : Grain, IRuleDequeuerGrain, IRemindable
{ {
private readonly ITargetBlock<IRuleEventEntity> requestBlock; private readonly ITargetBlock<IRuleEventEntity> requestBlock;
private readonly IRuleEventRepository ruleEventRepository; private readonly IRuleEventRepository ruleEventRepository;
private readonly RuleService ruleService; private readonly RuleService ruleService;
private readonly CompletionTimer timer;
private readonly ConcurrentDictionary<Guid, bool> executing = new ConcurrentDictionary<Guid, bool>(); private readonly ConcurrentDictionary<Guid, bool> executing = new ConcurrentDictionary<Guid, bool>();
private readonly IClock clock; private readonly IClock clock;
private readonly ISemanticLog log; private readonly ISemanticLog log;
public RuleDequeuer(RuleService ruleService, IRuleEventRepository ruleEventRepository, ISemanticLog log, IClock clock) public RuleDequeuerGrain(RuleService ruleService, IRuleEventRepository ruleEventRepository, ISemanticLog log, IClock clock)
{ {
Guard.NotNull(ruleEventRepository, nameof(ruleEventRepository)); Guard.NotNull(ruleEventRepository, nameof(ruleEventRepository));
Guard.NotNull(ruleService, nameof(ruleService)); Guard.NotNull(ruleService, nameof(ruleService));
@ -48,37 +47,37 @@ namespace Squidex.Domain.Apps.Entities.Rules
requestBlock = requestBlock =
new PartitionedActionBlock<IRuleEventEntity>(HandleAsync, x => x.Job.AggregateId.GetHashCode(), new PartitionedActionBlock<IRuleEventEntity>(HandleAsync, x => x.Job.AggregateId.GetHashCode(),
new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 32, BoundedCapacity = 32 }); new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 32, BoundedCapacity = 32 });
timer = new CompletionTimer(5000, QueryAsync);
} }
protected override void DisposeObject(bool disposing) public override Task OnActivateAsync()
{
if (disposing)
{ {
timer.StopAsync().Wait(); DelayDeactivation(TimeSpan.FromDays(1));
requestBlock.Complete(); RegisterOrUpdateReminder("Default", TimeSpan.Zero, TimeSpan.FromMinutes(10));
requestBlock.Completion.Wait(); RegisterTimer(x => QueryAsync(), null, TimeSpan.Zero, TimeSpan.FromSeconds(10));
}
return Task.FromResult(true);
} }
public void Run() public override Task OnDeactivateAsync()
{ {
requestBlock.Complete();
return requestBlock.Completion;
} }
public void Next() public Task ActivateAsync()
{ {
timer.SkipCurrentDelay(); return TaskHelper.Done;
} }
private async Task QueryAsync(CancellationToken ct) public async Task QueryAsync()
{ {
try try
{ {
var now = clock.GetCurrentInstant(); var now = clock.GetCurrentInstant();
await ruleEventRepository.QueryPendingAsync(now, requestBlock.SendAsync, ct); await ruleEventRepository.QueryPendingAsync(now, requestBlock.SendAsync);
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -153,5 +152,10 @@ namespace Squidex.Domain.Apps.Entities.Rules
return null; return null;
} }
public Task ReceiveReminder(string reminderName, TickStatus status)
{
return TaskHelper.Done;
}
} }
} }

1
src/Squidex.Domain.Apps.Entities/Squidex.Domain.Apps.Entities.csproj

@ -14,6 +14,7 @@
<ProjectReference Include="..\Squidex.Shared\Squidex.Shared.csproj" /> <ProjectReference Include="..\Squidex.Shared\Squidex.Shared.csproj" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.Orleans.OrleansCodeGenerator.Build" Version="2.0.0-beta3" />
<PackageReference Include="NodaTime" Version="2.2.3" /> <PackageReference Include="NodaTime" Version="2.2.3" />
<PackageReference Include="RefactoringEssentials" Version="5.6.0" /> <PackageReference Include="RefactoringEssentials" Version="5.6.0" />
<PackageReference Include="StyleCop.Analyzers" Version="1.0.2" /> <PackageReference Include="StyleCop.Analyzers" Version="1.0.2" />

16
src/Squidex.Domain.Apps.Entities/SquidexEntities.cs

@ -0,0 +1,16 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System.Reflection;
namespace Squidex.Domain.Apps.Entities
{
public sealed class SquidexEntities
{
public static readonly Assembly Assembly = typeof(SquidexEntities).Assembly;
}
}

1
src/Squidex.Infrastructure.MongoDb/MongoDb/BsonJsonConvention.cs

@ -11,7 +11,6 @@ using System.Reflection;
using MongoDB.Bson.Serialization; using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.Conventions; using MongoDB.Bson.Serialization.Conventions;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace Squidex.Infrastructure.MongoDb namespace Squidex.Infrastructure.MongoDb
{ {

5
src/Squidex.Infrastructure.MongoDb/MongoDb/MongoRepositoryBase.cs

@ -67,14 +67,17 @@ namespace Squidex.Infrastructure.MongoDb
private Lazy<IMongoCollection<TEntity>> CreateCollection() private Lazy<IMongoCollection<TEntity>> CreateCollection()
{ {
return new Lazy<IMongoCollection<TEntity>>(() => return new Lazy<IMongoCollection<TEntity>>(() =>
{
return Task.Run(async () =>
{ {
var databaseCollection = mongoDatabase.GetCollection<TEntity>( var databaseCollection = mongoDatabase.GetCollection<TEntity>(
CollectionName(), CollectionName(),
CollectionSettings() ?? new MongoCollectionSettings()); CollectionSettings() ?? new MongoCollectionSettings());
SetupCollectionAsync(databaseCollection).Wait(); await SetupCollectionAsync(databaseCollection).ConfigureAwait(false);
return databaseCollection; return databaseCollection;
}).Result;
}); });
} }

4
src/Squidex.Infrastructure/EventSourcing/Grains/EventConsumerGrain.cs

@ -71,7 +71,7 @@ namespace Squidex.Infrastructure.EventSourcing.Grains
eventConsumer = eventConsumerFactory(this.GetPrimaryKeyString()); eventConsumer = eventConsumerFactory(this.GetPrimaryKeyString());
persistence = store.WithSnapshots<EventConsumerGrain, EventConsumerState, string>(this.GetPrimaryKeyString(), s => state = s); persistence = store.WithSnapshots<EventConsumerState, string>(GetType(), this.GetPrimaryKeyString(), s => state = s);
return persistence.ReadAsync(); return persistence.ReadAsync();
} }
@ -81,7 +81,7 @@ namespace Squidex.Infrastructure.EventSourcing.Grains
return new RetrySubscription(eventStore, new WrapperSubscription(this.AsReference<IEventConsumerGrain>(), scheduler), streamFilter, position); return new RetrySubscription(eventStore, new WrapperSubscription(this.AsReference<IEventConsumerGrain>(), scheduler), streamFilter, position);
} }
public virtual Task<Immutable<EventConsumerInfo>> GetStateAsync() public Task<Immutable<EventConsumerInfo>> GetStateAsync()
{ {
return Task.FromResult(state.ToInfo(this.eventConsumer.Name).AsImmutable()); return Task.FromResult(state.ToInfo(this.eventConsumer.Name).AsImmutable());
} }

23
src/Squidex.Infrastructure/EventSourcing/Grains/EventConsumerManagerGrain.cs

@ -14,10 +14,11 @@ using Orleans;
using Orleans.Concurrency; using Orleans.Concurrency;
using Orleans.Core; using Orleans.Core;
using Orleans.Runtime; using Orleans.Runtime;
using Squidex.Infrastructure.Tasks;
namespace Squidex.Infrastructure.EventSourcing.Grains namespace Squidex.Infrastructure.EventSourcing.Grains
{ {
public class EventConsumerManagerGrain : Grain, IEventConsumerManagerGrain public class EventConsumerManagerGrain : Grain, IEventConsumerManagerGrain, IRemindable
{ {
private readonly IEnumerable<IEventConsumer> eventConsumers; private readonly IEnumerable<IEventConsumer> eventConsumers;
@ -37,17 +38,12 @@ namespace Squidex.Infrastructure.EventSourcing.Grains
this.eventConsumers = eventConsumers; this.eventConsumers = eventConsumers;
} }
public Task ReceiveReminder(string reminderName, TickStatus status)
{
return ActivateAsync();
}
public override Task OnActivateAsync() public override Task OnActivateAsync()
{ {
DelayDeactivation(TimeSpan.FromDays(1)); DelayDeactivation(TimeSpan.FromDays(1));
// RegisterOrUpdateReminder("Default", TimeSpan.Zero, TimeSpan.FromMinutes(10)); RegisterOrUpdateReminder("Default", TimeSpan.Zero, TimeSpan.FromMinutes(10));
// RegisterTimer(x => ActivateAsync(), null, TimeSpan.Zero, TimeSpan.FromSeconds(10)); RegisterTimer(x => WakeUpAsync(null), null, TimeSpan.Zero, TimeSpan.FromSeconds(10));
return Task.FromResult(true); return Task.FromResult(true);
} }
@ -73,14 +69,16 @@ namespace Squidex.Infrastructure.EventSourcing.Grains
return Task.WhenAll(tasks); return Task.WhenAll(tasks);
} }
public Task<Immutable<List<EventConsumerInfo>>> GetConsumersAsync() public async Task<Immutable<List<EventConsumerInfo>>> GetConsumersAsync()
{ {
var tasks = var tasks =
eventConsumers eventConsumers
.Select(c => GrainFactory.GetGrain<IEventConsumerGrain>(c.Name)) .Select(c => GrainFactory.GetGrain<IEventConsumerGrain>(c.Name))
.Select(c => c.GetStateAsync()); .Select(c => c.GetStateAsync());
return Task.WhenAll(tasks).ContinueWith(x => new Immutable<List<EventConsumerInfo>>(x.Result.Select(r => r.Value).ToList())); var consumerInfos = await Task.WhenAll(tasks);
return new Immutable<List<EventConsumerInfo>>(consumerInfos.Select(r => r.Value).ToList());
} }
public Task ResetAsync(string consumerName) public Task ResetAsync(string consumerName)
@ -103,5 +101,10 @@ namespace Squidex.Infrastructure.EventSourcing.Grains
return eventConsumer.StopAsync(); return eventConsumer.StopAsync();
} }
public Task ReceiveReminder(string reminderName, TickStatus status)
{
return TaskHelper.Done;
}
} }
} }

6
src/Squidex.Infrastructure/EventSourcing/Grains/IEventConsumerGrain.cs

@ -7,17 +7,15 @@
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Orleans;
using Orleans.Concurrency; using Orleans.Concurrency;
using Squidex.Infrastructure.Orleans;
namespace Squidex.Infrastructure.EventSourcing.Grains namespace Squidex.Infrastructure.EventSourcing.Grains
{ {
public interface IEventConsumerGrain : IGrainWithStringKey public interface IEventConsumerGrain : IBackgroundGrain
{ {
Task<Immutable<EventConsumerInfo>> GetStateAsync(); Task<Immutable<EventConsumerInfo>> GetStateAsync();
Task ActivateAsync();
Task StopAsync(); Task StopAsync();
Task StartAsync(); Task StartAsync();

6
src/Squidex.Infrastructure/EventSourcing/Grains/IEventConsumerManagerGrain.cs

@ -7,15 +7,13 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Orleans;
using Orleans.Concurrency; using Orleans.Concurrency;
using Squidex.Infrastructure.Orleans;
namespace Squidex.Infrastructure.EventSourcing.Grains namespace Squidex.Infrastructure.EventSourcing.Grains
{ {
public interface IEventConsumerManagerGrain : IGrainWithStringKey public interface IEventConsumerManagerGrain : IBackgroundGrain
{ {
Task ActivateAsync();
Task WakeUpAsync(string streamName); Task WakeUpAsync(string streamName);
Task StopAsync(string consumerName); Task StopAsync(string consumerName);

11
src/Squidex.Infrastructure/EventSourcing/Grains/EventConsumerBootstrap.cs → src/Squidex.Infrastructure/Orleans/Bootstrap.cs

@ -1,21 +1,20 @@
// ========================================================================== // ==========================================================================
// Squidex Headless CMS // Squidex Headless CMS
// ========================================================================== // ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschränkt) // Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license. // All rights reserved. Licensed under the MIT license.
// ========================================================================== // ==========================================================================
using Orleans; using Orleans;
using Orleans.Runtime;
using Squidex.Infrastructure.Tasks; using Squidex.Infrastructure.Tasks;
namespace Squidex.Infrastructure.EventSourcing.Grains namespace Squidex.Infrastructure.Orleans
{ {
public sealed class EventConsumerBootstrap : IRunnable public sealed class Bootstrap<T> : IRunnable where T : IBackgroundGrain
{ {
private readonly IGrainFactory grainFactory; private readonly IGrainFactory grainFactory;
public EventConsumerBootstrap(IGrainFactory grainFactory) public Bootstrap(IGrainFactory grainFactory)
{ {
Guard.NotNull(grainFactory, nameof(grainFactory)); Guard.NotNull(grainFactory, nameof(grainFactory));
@ -24,7 +23,7 @@ namespace Squidex.Infrastructure.EventSourcing.Grains
public void Run() public void Run()
{ {
var grain = grainFactory.GetGrain<IEventConsumerManagerGrain>("Default"); var grain = grainFactory.GetGrain<T>("Default");
grain.ActivateAsync().Forget(); grain.ActivateAsync().Forget();
} }

17
src/Squidex.Infrastructure/Orleans/IBackgroundGrain.cs

@ -0,0 +1,17 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System.Threading.Tasks;
using Orleans;
namespace Squidex.Infrastructure.Orleans
{
public interface IBackgroundGrain : IGrainWithStringKey
{
Task ActivateAsync();
}
}

4
src/Squidex/Areas/Api/Controllers/EventConsumers/EventConsumersController.cs

@ -26,10 +26,10 @@ namespace Squidex.Areas.Api.Controllers.EventConsumers
{ {
private readonly IEventConsumerManagerGrain eventConsumerManagerGrain; private readonly IEventConsumerManagerGrain eventConsumerManagerGrain;
public EventConsumersController(ICommandBus commandBus, IClusterClient orleans) public EventConsumersController(ICommandBus commandBus, IGrainFactory grainFactory)
: base(commandBus) : base(commandBus)
{ {
eventConsumerManagerGrain = orleans.GetGrain<IEventConsumerManagerGrain>("Default"); eventConsumerManagerGrain = grainFactory.GetGrain<IEventConsumerManagerGrain>("Default");
} }
[HttpGet] [HttpGet]

13
src/Squidex/Config/Domain/InfrastructureServices.cs

@ -23,10 +23,15 @@ using Squidex.Infrastructure.States;
using Squidex.Infrastructure.UsageTracking; using Squidex.Infrastructure.UsageTracking;
using Squidex.Pipeline; using Squidex.Pipeline;
#pragma warning disable RECS0092 // Convert field to readonly
namespace Squidex.Config.Domain namespace Squidex.Config.Domain
{ {
public static class InfrastructureServices public static class InfrastructureServices
{ {
private static ILogChannel console = new ConsoleLogChannel();
private static ILogChannel file;
public static void AddMyInfrastructureServices(this IServiceCollection services, IConfiguration config) public static void AddMyInfrastructureServices(this IServiceCollection services, IConfiguration config)
{ {
if (config.GetValue<bool>("logging:human")) if (config.GetValue<bool>("logging:human"))
@ -42,11 +47,14 @@ namespace Squidex.Config.Domain
if (!string.IsNullOrWhiteSpace(loggingFile)) if (!string.IsNullOrWhiteSpace(loggingFile))
{ {
services.AddSingletonAs(new FileChannel(loggingFile)) services.AddSingletonAs(file ?? (file = new FileChannel(loggingFile)))
.As<ILogChannel>() .As<ILogChannel>()
.As<IInitializable>(); .As<IInitializable>();
} }
services.AddSingletonAs(console)
.As<ILogChannel>();
services.AddSingletonAs(c => new ApplicationInfoLogAppender(typeof(Program).Assembly, Guid.NewGuid())) services.AddSingletonAs(c => new ApplicationInfoLogAppender(typeof(Program).Assembly, Guid.NewGuid()))
.As<ILogAppender>(); .As<ILogAppender>();
@ -59,9 +67,6 @@ namespace Squidex.Config.Domain
services.AddSingletonAs<DebugLogChannel>() services.AddSingletonAs<DebugLogChannel>()
.As<ILogChannel>(); .As<ILogChannel>();
services.AddSingletonAs<ConsoleLogChannel>()
.As<ILogChannel>();
services.AddSingletonAs<SemanticLog>() services.AddSingletonAs<SemanticLog>()
.As<ISemanticLog>(); .As<ISemanticLog>();

31
src/Squidex/Config/Domain/ReadServices.cs

@ -27,6 +27,7 @@ using Squidex.Infrastructure;
using Squidex.Infrastructure.Assets; using Squidex.Infrastructure.Assets;
using Squidex.Infrastructure.EventSourcing; using Squidex.Infrastructure.EventSourcing;
using Squidex.Infrastructure.EventSourcing.Grains; using Squidex.Infrastructure.EventSourcing.Grains;
using Squidex.Infrastructure.Orleans;
using Squidex.Infrastructure.States; using Squidex.Infrastructure.States;
using Squidex.Pipeline; using Squidex.Pipeline;
@ -36,18 +37,13 @@ namespace Squidex.Config.Domain
{ {
public static void AddMyReadServices(this IServiceCollection services, IConfiguration config) public static void AddMyReadServices(this IServiceCollection services, IConfiguration config)
{ {
var consumeEvents = config.GetOptionalValue("eventStore:consume", false); services.AddSingletonAs<StateFactory>()
.As<IStateFactory>()
if (consumeEvents) .As<IInitializable>();
{
services.AddSingletonAs<RuleDequeuer>()
.As<IRunnable>();
services.AddSingletonAs<ContentScheduler>()
.As<IRunnable>();
services.AddSingletonAs<EventConsumerBootstrap>() services.AddSingletonAs<OrleansEventNotifier>()
.As<IRunnable>(); .As<IEventNotifier>()
} .As<IInitializable>();
var exposeSourceUrl = config.GetOptionalValue("assetStore:exposeSourceUrl", true); var exposeSourceUrl = config.GetOptionalValue("assetStore:exposeSourceUrl", true);
@ -57,9 +53,6 @@ namespace Squidex.Config.Domain
exposeSourceUrl)) exposeSourceUrl))
.As<IGraphQLUrlGenerator>(); .As<IGraphQLUrlGenerator>();
services.AddSingletonAs<StateFactory>()
.As<IStateFactory>().As<IInitializable>();
services.AddSingletonAs(c => c.GetService<IOptions<MyUsageOptions>>()?.Value?.Plans.OrEmpty()); services.AddSingletonAs(c => c.GetService<IOptions<MyUsageOptions>>()?.Value?.Plans.OrEmpty());
services.AddSingletonAs<CachingGraphQLService>() services.AddSingletonAs<CachingGraphQLService>()
@ -113,8 +106,14 @@ namespace Squidex.Config.Domain
services.AddSingletonAs<WebhookActionHandler>() services.AddSingletonAs<WebhookActionHandler>()
.As<IRuleActionHandler>(); .As<IRuleActionHandler>();
services.AddSingletonAs<OrleansEventNotifier>() services.AddSingletonAs<Bootstrap<IRuleDequeuerGrain>>()
.As<IEventNotifier>().As<IInitializable>(); .As<IRunnable>();
services.AddSingletonAs<Bootstrap<IContentSchedulerGrain>>()
.As<IRunnable>();
services.AddSingletonAs<Bootstrap<IEventConsumerManagerGrain>>()
.As<IRunnable>();
services.AddSingletonAs<RuleEnqueuer>() services.AddSingletonAs<RuleEnqueuer>()
.As<IEventConsumer>(); .As<IEventConsumer>();

2
src/Squidex/Config/Orleans/ClientWrapper.cs

@ -8,6 +8,7 @@
using System; using System;
using Orleans; using Orleans;
using Orleans.Runtime.Configuration; using Orleans.Runtime.Configuration;
using Squidex.Domain.Apps.Entities;
using Squidex.Infrastructure; using Squidex.Infrastructure;
namespace Squidex.Config.Orleans namespace Squidex.Config.Orleans
@ -28,6 +29,7 @@ namespace Squidex.Config.Orleans
.UseDashboard() .UseDashboard()
.ConfigureApplicationParts(builder => .ConfigureApplicationParts(builder =>
{ {
builder.AddApplicationPart(SquidexEntities.Assembly);
builder.AddApplicationPart(SquidexInfrastructure.Assembly); builder.AddApplicationPart(SquidexInfrastructure.Assembly);
}) })
.UseStaticGatewayListProvider(options => .UseStaticGatewayListProvider(options =>

3
src/Squidex/Config/Orleans/SiloServices.cs

@ -11,10 +11,7 @@ using System.Net;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Orleans; using Orleans;
using Orleans.Runtime;
using Orleans.Runtime.Configuration; using Orleans.Runtime.Configuration;
using Squidex.Infrastructure;
using Squidex.Infrastructure.EventSourcing.Grains;
namespace Squidex.Config.Orleans namespace Squidex.Config.Orleans
{ {

19
src/Squidex/Config/Orleans/SiloWrapper.cs

@ -11,6 +11,7 @@ using Microsoft.Extensions.Configuration;
using Orleans; using Orleans;
using Orleans.Hosting; using Orleans.Hosting;
using Orleans.Runtime.Configuration; using Orleans.Runtime.Configuration;
using Squidex.Domain.Apps.Entities;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.Log.Adapter; using Squidex.Infrastructure.Log.Adapter;
@ -38,20 +39,21 @@ namespace Squidex.Config.Orleans
public SiloWrapper(IConfiguration configuration) public SiloWrapper(IConfiguration configuration)
{ {
silo = SiloHostBuilder.CreateDefault() silo = SiloHostBuilder.CreateDefault()
.UseConfiguration(ClusterConfiguration.LocalhostPrimarySilo(33333)) .UseConfiguration(ClusterConfiguration.LocalhostPrimarySilo(33333).WithDashboard())
.UseContentRoot(Directory.GetCurrentDirectory()) .UseContentRoot(Directory.GetCurrentDirectory())
.UseDashboard(options => .UseDashboard(options =>
{ {
options.HostSelf = false; options.HostSelf = false;
}) })
.ConfigureApplicationParts(builder =>
{
builder.AddApplicationPart(SquidexInfrastructure.Assembly);
})
.ConfigureLogging(builder => .ConfigureLogging(builder =>
{ {
builder.AddSemanticLog(); builder.AddSemanticLog();
}) })
.ConfigureApplicationParts(builder =>
{
builder.AddApplicationPart(SquidexEntities.Assembly);
builder.AddApplicationPart(SquidexInfrastructure.Assembly);
})
.ConfigureServices((context, services) => .ConfigureServices((context, services) =>
{ {
services.AddAppSiloServices(context.Configuration); services.AddAppSiloServices(context.Configuration);
@ -79,12 +81,5 @@ namespace Squidex.Config.Orleans
{ {
silo.StopAsync().Wait(); silo.StopAsync().Wait();
} }
private static string GetEnvironment()
{
var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
return environment ?? "Development";
}
} }
} }

1
src/Squidex/WebStartup.cs

@ -54,7 +54,6 @@ namespace Squidex
app.ConfigurePortal(); app.ConfigurePortal();
app.ConfigureOrleansDashboard(); app.ConfigureOrleansDashboard();
app.ConfigureIdentityServer(); app.ConfigureIdentityServer();
app.ConfigureFrontend(); app.ConfigureFrontend();
} }
} }

4
tests/Squidex.Domain.Apps.Entities.Tests/Rules/RuleDequeuerTests.cs

@ -27,13 +27,13 @@ namespace Squidex.Domain.Apps.Entities.Rules
private readonly IRuleEventRepository ruleEventRepository = A.Fake<IRuleEventRepository>(); private readonly IRuleEventRepository ruleEventRepository = A.Fake<IRuleEventRepository>();
private readonly Instant now = SystemClock.Instance.GetCurrentInstant(); private readonly Instant now = SystemClock.Instance.GetCurrentInstant();
private readonly RuleService ruleService = A.Fake<RuleService>(); private readonly RuleService ruleService = A.Fake<RuleService>();
private readonly RuleDequeuer sut; private readonly RuleDequeuerGrain sut;
public RuleDequeuerTests() public RuleDequeuerTests()
{ {
A.CallTo(() => clock.GetCurrentInstant()).Returns(now); A.CallTo(() => clock.GetCurrentInstant()).Returns(now);
sut = new RuleDequeuer( sut = new RuleDequeuerGrain(
ruleService, ruleService,
ruleEventRepository, ruleEventRepository,
log, log,

2
tools/Migrate_01/Migrations/RebuildAssets.cs

@ -5,8 +5,6 @@
// All rights reserved. Licensed under the MIT license. // All rights reserved. Licensed under the MIT license.
// ========================================================================== // ==========================================================================
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Squidex.Infrastructure.Migrations; using Squidex.Infrastructure.Migrations;

Loading…
Cancel
Save