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

Optimize modules loading. #2972

Merged
merged 2 commits into from
Jan 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
Expand All @@ -8,7 +7,7 @@ namespace OrchardCore.Modules
{
public class Application
{
private readonly Dictionary<string, List<Module>> _modulesByName;
private readonly Dictionary<string, Module> _modulesByName;
private readonly List<Module> _modules;

public static readonly string ModulesPath = "Areas";
Expand All @@ -26,7 +25,7 @@ public Application(IHostingEnvironment environment, IEnumerable<Module> modules)
Assembly = Assembly.Load(new AssemblyName(Name));

_modules = new List<Module>(modules);
_modulesByName = _modules.GroupBy(x => x.Name).ToDictionary(x => x.Key, x => x.ToList());
_modulesByName = _modules.ToDictionary(m => m.Name, m => m);
}

public string Name { get; }
Expand All @@ -39,12 +38,12 @@ public Application(IHostingEnvironment environment, IEnumerable<Module> modules)

public Module GetModule(string name)
{
if (!_modulesByName.TryGetValue(name, out var modules) || modules.Count == 0)
if (!_modulesByName.TryGetValue(name, out var module))
{
return new Module(string.Empty);
}

return modules[modules.Count - 1];
return module;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;

namespace OrchardCore.Modules
Expand Down Expand Up @@ -48,13 +49,18 @@ private void EnsureInitialized()

private IEnumerable<Module> GetModules()
{
var modules = new List<Module>();
var modules = new ConcurrentBag<Module>();
modules.Add(new Module(_environment.ApplicationName, true));

foreach (var provider in _moduleNamesProviders)
var names = _moduleNamesProviders
.SelectMany(p => p.GetModuleNames())
.Where(n => n != _environment.ApplicationName)
.Distinct();

Parallel.ForEach(names, new ParallelOptions { MaxDegreeOfParallelism = 8 }, (name) =>
{
modules.AddRange(provider.GetModuleNames().Select(name => new Module(name, name == _environment.ApplicationName)));
}
modules.Add(new Module(name, false));
});

return modules;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ namespace OrchardCore.Environment.Shell.Builders
{
public class ShellContainerFactory : IShellContainerFactory
{
private readonly IFeatureInfo _applicationFeature;
private IFeatureInfo _applicationFeature;

private readonly IHostingEnvironment _hostingEnvironment;
private readonly IExtensionManager _extensionManager;
private readonly IServiceProvider _serviceProvider;
private readonly ILogger _logger;
private readonly ILoggerFactory _loggerFactory;
Expand All @@ -27,9 +30,8 @@ public ShellContainerFactory(
ILogger<ShellContainerFactory> logger,
IServiceCollection applicationServices)
{
_applicationFeature = extensionManager.GetFeatures().FirstOrDefault(
f => f.Id == hostingEnvironment.ApplicationName);

_hostingEnvironment = hostingEnvironment;
_extensionManager = extensionManager;
_applicationServices = applicationServices;
_serviceProvider = serviceProvider;
_loggerFactory = loggerFactory;
Expand Down Expand Up @@ -84,6 +86,10 @@ public IServiceProvider CreateContainer(ShellSettings settings, ShellBlueprint b
// OrderBy performs a stable sort so order is preserved among equal Order values.
startups = startups.OrderBy(s => s.Order);

// To not trigger features loading before it is normally done by 'ShellHost',
// init here the application feature in place of doing it in the constructor.
EnsureApplicationFeature();

// Let any module add custom service descriptors to the tenant
foreach (var startup in startups)
{
Expand All @@ -97,7 +103,7 @@ public IServiceProvider CreateContainer(ShellSettings settings, ShellBlueprint b
}

(moduleServiceProvider as IDisposable).Dispose();

var shellServiceProvider = tenantServiceCollection.BuildServiceProvider(true);

// Register all DIed types in ITypeFeatureProvider
Expand All @@ -124,5 +130,20 @@ public IServiceProvider CreateContainer(ShellSettings settings, ShellBlueprint b

return shellServiceProvider;
}

private void EnsureApplicationFeature()
{
if (_applicationFeature == null)
{
lock (this)
{
if (_applicationFeature == null)
{
_applicationFeature = _extensionManager.GetFeatures()
.FirstOrDefault(f => f.Id == _hostingEnvironment.ApplicationName);
}
}
}
}
}
}