Browse Source

Improve startup time.

pull/262/head
Sebastian Stehle 8 years ago
parent
commit
40d99cac8b
  1. 12
      src/Squidex.Domain.Apps.Entities/Contents/ContentSchedulerGrain.cs
  2. 20
      src/Squidex.Infrastructure/Lazier.cs
  3. 4
      src/Squidex/Config/Domain/InfrastructureServices.cs
  4. 16
      src/Squidex/Config/Orleans/SiloServices.cs
  5. 81
      src/Squidex/Config/Orleans/SiloWrapper.cs
  6. 8
      src/Squidex/Squidex.csproj
  7. 9
      src/Squidex/appsettings.json

12
src/Squidex.Domain.Apps.Entities/Contents/ContentSchedulerGrain.cs

@ -20,13 +20,13 @@ namespace Squidex.Domain.Apps.Entities.Contents
{ {
public sealed class ContentSchedulerGrain : Grain, IContentSchedulerGrain, IRemindable public sealed class ContentSchedulerGrain : Grain, IContentSchedulerGrain, IRemindable
{ {
private readonly IContentRepository contentRepository; private readonly Lazy<IContentRepository> contentRepository;
private readonly ICommandBus commandBus; private readonly Lazy<ICommandBus> commandBus;
private readonly IClock clock; private readonly IClock clock;
public ContentSchedulerGrain( public ContentSchedulerGrain(
IContentRepository contentRepository, Lazy<IContentRepository> contentRepository,
ICommandBus commandBus, Lazy<ICommandBus> commandBus,
IClock clock) IClock clock)
{ {
Guard.NotNull(contentRepository, nameof(contentRepository)); Guard.NotNull(contentRepository, nameof(contentRepository));
@ -57,11 +57,11 @@ namespace Squidex.Domain.Apps.Entities.Contents
{ {
var now = clock.GetCurrentInstant(); var now = clock.GetCurrentInstant();
return contentRepository.QueryScheduledWithoutDataAsync(now, content => return contentRepository.Value.QueryScheduledWithoutDataAsync(now, content =>
{ {
var command = new ChangeContentStatus { ContentId = content.Id, Status = content.ScheduledTo.Value, Actor = content.ScheduledBy }; var command = new ChangeContentStatus { ContentId = content.Id, Status = content.ScheduledTo.Value, Actor = content.ScheduledBy };
return commandBus.PublishAsync(command); return commandBus.Value.PublishAsync(command);
}); });
} }

20
src/Squidex.Infrastructure/Lazier.cs

@ -0,0 +1,20 @@
// ==========================================================================
// Squidex Headless CMS
// ==========================================================================
// Copyright (c) Squidex UG (haftungsbeschraenkt)
// All rights reserved. Licensed under the MIT license.
// ==========================================================================
using System;
using Microsoft.Extensions.DependencyInjection;
namespace Squidex.Infrastructure
{
public sealed class Lazier<T> : Lazy<T> where T : class
{
public Lazier(IServiceProvider provider)
: base(provider.GetRequiredService<T>)
{
}
}
}

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

@ -5,10 +5,12 @@
// All rights reserved. Licensed under the MIT license. // All rights reserved. Licensed under the MIT license.
// ========================================================================== // ==========================================================================
using System;
using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Infrastructure; using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using NodaTime; using NodaTime;
using Squidex.Infrastructure;
using Squidex.Infrastructure.UsageTracking; using Squidex.Infrastructure.UsageTracking;
#pragma warning disable RECS0092 // Convert field to readonly #pragma warning disable RECS0092 // Convert field to readonly
@ -30,6 +32,8 @@ namespace Squidex.Config.Domain
services.AddSingletonAs<ActionContextAccessor>() services.AddSingletonAs<ActionContextAccessor>()
.As<IActionContextAccessor>(); .As<IActionContextAccessor>();
services.AddTransient(typeof(Lazy<>), typeof(Lazier<>));
} }
} }
} }

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

@ -22,18 +22,18 @@ namespace Squidex.Config.Orleans
var mongoConfiguration = config.GetRequiredValue("store:mongoDb:configuration"); var mongoConfiguration = config.GetRequiredValue("store:mongoDb:configuration");
var mongoDatabaseName = config.GetRequiredValue("store:mongoDb:database"); var mongoDatabaseName = config.GetRequiredValue("store:mongoDb:database");
services.AddMongoDBMembershipTable(c => services.AddMongoDBMembershipTable(options =>
{ {
c.ConnectionString = mongoConfiguration; options.ConnectionString = mongoConfiguration;
c.CollectionPrefix = "Orleans_"; options.CollectionPrefix = "Orleans_";
c.DatabaseName = mongoDatabaseName; options.DatabaseName = mongoDatabaseName;
}); });
services.AddMongoDBReminders(c => services.AddMongoDBReminders(options =>
{ {
c.ConnectionString = mongoConfiguration; options.ConnectionString = mongoConfiguration;
c.CollectionPrefix = "Orleans_"; options.CollectionPrefix = "Orleans_";
c.DatabaseName = mongoDatabaseName; options.DatabaseName = mongoDatabaseName;
}); });
} }
}); });

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

@ -6,6 +6,7 @@
// ========================================================================== // ==========================================================================
using System; using System;
using System.Diagnostics;
using System.Net; using System.Net;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
@ -20,6 +21,7 @@ using Squidex.Domain.Apps.Entities.Contents;
using Squidex.Domain.Apps.Entities.Rules; using Squidex.Domain.Apps.Entities.Rules;
using Squidex.Infrastructure; using Squidex.Infrastructure;
using Squidex.Infrastructure.EventSourcing.Grains; using Squidex.Infrastructure.EventSourcing.Grains;
using Squidex.Infrastructure.Log;
using Squidex.Infrastructure.Log.Adapter; using Squidex.Infrastructure.Log.Adapter;
using Squidex.Infrastructure.Orleans; using Squidex.Infrastructure.Orleans;
@ -27,7 +29,8 @@ namespace Squidex.Config.Orleans
{ {
public class SiloWrapper : DisposableObjectBase, IInitializable, IDisposable public class SiloWrapper : DisposableObjectBase, IInitializable, IDisposable
{ {
private readonly ISiloHost silo; private readonly Lazy<ISiloHost> silo;
private readonly ISemanticLog log;
internal sealed class Source : IConfigurationSource internal sealed class Source : IConfigurationSource
{ {
@ -44,16 +47,19 @@ namespace Squidex.Config.Orleans
} }
} }
public SiloWrapper(IConfiguration configuration) public SiloWrapper(IConfiguration config, ISemanticLog log)
{
this.log = log;
silo = new Lazy<ISiloHost>(() =>
{ {
J.Serializer = SerializationServices.DefaultJsonSerializer; J.Serializer = SerializationServices.DefaultJsonSerializer;
silo = new SiloHostBuilder() var hostBuilder = new SiloHostBuilder()
.UseDashboard(options => options.HostSelf = true) .UseDashboard(options => options.HostSelf = true)
.AddStartupTask<Bootstrap<IContentSchedulerGrain>>() .AddStartupTask<Bootstrap<IContentSchedulerGrain>>()
.AddStartupTask<Bootstrap<IEventConsumerManagerGrain>>() .AddStartupTask<Bootstrap<IEventConsumerManagerGrain>>()
.AddStartupTask<Bootstrap<IRuleDequeuerGrain>>() .AddStartupTask<Bootstrap<IRuleDequeuerGrain>>()
.ConfigureEndpoints(Dns.GetHostName(), 11111, 40000, listenOnAnyHostAddress: true)
.Configure<ClusterOptions>(options => .Configure<ClusterOptions>(options =>
{ {
options.ClusterId = "squidex"; options.ClusterId = "squidex";
@ -78,27 +84,84 @@ namespace Squidex.Config.Orleans
}) })
.ConfigureAppConfiguration((hostContext, builder) => .ConfigureAppConfiguration((hostContext, builder) =>
{ {
if (configuration is IConfigurationRoot root) if (config is IConfigurationRoot root)
{ {
foreach (var provider in root.Providers) foreach (var provider in root.Providers)
{ {
builder.Add(new Source(provider)); builder.Add(new Source(provider));
} }
} }
}) });
.Build();
config.ConfigureByOption("orleans:clustering", new Options
{
["MongoDB"] = () =>
{
hostBuilder.ConfigureEndpoints(Dns.GetHostName(), 11111, 40000, listenOnAnyHostAddress: true);
var mongoConfiguration = config.GetRequiredValue("store:mongoDb:configuration");
var mongoDatabaseName = config.GetRequiredValue("store:mongoDb:database");
hostBuilder.UseMongoDBClustering(options =>
{
options.ConnectionString = mongoConfiguration;
options.CollectionPrefix = "Orleans_";
options.DatabaseName = mongoDatabaseName;
});
},
["Development"] = () =>
{
hostBuilder.UseLocalhostClustering(gatewayPort: 40000, clusterId: "squidex");
hostBuilder.Configure<ClusterMembershipOptions>(options => options.ExpectedClusterSize = 1);
}
});
config.ConfigureByOption("store:type", new Options
{
["MongoDB"] = () =>
{
var mongoConfiguration = config.GetRequiredValue("store:mongoDb:configuration");
var mongoDatabaseName = config.GetRequiredValue("store:mongoDb:database");
hostBuilder.UseMongoDBReminders(options =>
{
options.ConnectionString = mongoConfiguration;
options.CollectionPrefix = "Orleans_";
options.DatabaseName = mongoDatabaseName;
});
}
});
return hostBuilder.Build();
});
} }
public void Initialize() public void Initialize()
{ {
silo.StartAsync().Wait(); var watch = Stopwatch.StartNew();
try
{
silo.Value.StartAsync().Wait();
}
finally
{
watch.Stop();
log.LogInformation(w => w
.WriteProperty("message", "Silo started")
.WriteProperty("elapsed", watch.Elapsed)
.WriteProperty("elapsedMs", watch.ElapsedMilliseconds));
}
} }
protected override void DisposeObject(bool disposing) protected override void DisposeObject(bool disposing)
{ {
if (disposing) if (disposing)
{ {
Task.Run(() => silo.StopAsync()).Wait(); if (silo.IsValueCreated)
{
Task.Run(() => silo.Value.StopAsync()).Wait();
}
} }
} }
} }

8
src/Squidex/Squidex.csproj

@ -70,8 +70,8 @@
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.0.1" /> <PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="2.0.1" />
<PackageReference Include="Microsoft.Data.Edm" Version="5.8.3" /> <PackageReference Include="Microsoft.Data.Edm" Version="5.8.3" />
<PackageReference Include="Microsoft.OData.Core" Version="7.4.1" /> <PackageReference Include="Microsoft.OData.Core" Version="7.4.1" />
<PackageReference Include="Microsoft.Orleans.Client" Version="2.0.0-rc1" /> <PackageReference Include="Microsoft.Orleans.Client" Version="2.0.0-rc2" />
<PackageReference Include="Microsoft.Orleans.Server " Version="2.0.0-beta3" /> <PackageReference Include="Microsoft.Orleans.Server " Version="2.0.0-rc2" />
<PackageReference Include="Microsoft.VisualStudio.Web.BrowserLink" Version="2.0.2" /> <PackageReference Include="Microsoft.VisualStudio.Web.BrowserLink" Version="2.0.2" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.0.3" /> <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.0.3" />
<PackageReference Include="MongoDB.Driver" Version="2.5.0" /> <PackageReference Include="MongoDB.Driver" Version="2.5.0" />
@ -104,8 +104,4 @@
<AdditionalFiles Include="..\..\stylecop.json" Link="stylecop.json" /> <AdditionalFiles Include="..\..\stylecop.json" Link="stylecop.json" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<PackageReference Update="Microsoft.Orleans.Server" Version="2.0.0-rc2" />
</ItemGroup>
</Project> </Project>

9
src/Squidex/appsettings.json

@ -84,6 +84,15 @@
"exposeSourceUrl": false "exposeSourceUrl": false
}, },
"orleans": {
/*
* Define the clustering type.
*
* Supported: MongoDB, Development
*/
"clustering": "MongoDb"
},
"eventStore": { "eventStore": {
/* /*
* Define the type of the event store. * Define the type of the event store.

Loading…
Cancel
Save