Perf: ExtensionManager (#8677)

* WIP extension manager allowing serial loading of features

* Proper comments in HostComponents.config. Removed test/dev logs in ExtensionManager.
This commit is contained in:
Matteo Piovanelli
2023-05-05 08:56:22 +02:00
committed by GitHub
parent ff2f222695
commit bf8cc13922
2 changed files with 49 additions and 4 deletions

View File

@@ -80,6 +80,14 @@
<Property Name="Disabled" Value="false"/>
</Properties>
</Component>
<Component Type="Orchard.Environment.Extensions.ExtensionManager">
<Properties>
<!-- Set Value="true" to disable parallel loading of feature assemblies. This may boost application startup times by
decreasing the number of parallel tasks the application attempts to start. -->
<Property Name="ParallelizationDisabled" Value="false"/>
</Properties>
</Component>
<Component Type="Orchard.Data.SessionConfigurationCache">
<Properties>

View File

@@ -10,6 +10,13 @@ using Orchard.Logging;
using Orchard.Utility;
using Orchard.Utility.Extensions;
using Orchard.Exceptions;
using System.Diagnostics;
using NHibernate.Cfg;
using NHibernate.Linq.Functions;
using System.Web.Http.Results;
using System.Threading;
using System.Security.Cryptography;
using System.Text;
namespace Orchard.Environment.Extensions {
public class ExtensionManager : IExtensionManager {
@@ -22,6 +29,11 @@ namespace Orchard.Environment.Extensions {
public Localizer T { get; set; }
public ILogger Logger { get; set; }
/// <summary>
/// Allow disabling parallel behavior through HostComponents.config
/// </summary>
public bool ParallelizationDisabled { get; set; }
public ExtensionManager(
IEnumerable<IExtensionFolders> folders,
IEnumerable<IExtensionLoader> loaders,
@@ -36,8 +48,11 @@ namespace Orchard.Environment.Extensions {
_loaders = loaders.OrderBy(x => x.Order).ToArray();
T = NullLocalizer.Instance;
Logger = NullLogger.Instance;
_md5 = MD5.Create();
}
private MD5 _md5;
// This method does not load extension types, simply parses extension manifests from
// the filesystem.
public ExtensionDescriptor GetExtension(string id) {
@@ -91,10 +106,32 @@ namespace Orchard.Environment.Extensions {
public IEnumerable<Feature> LoadFeatures(IEnumerable<FeatureDescriptor> featureDescriptors) {
Logger.Information("Loading features");
var result =
_parallelCacheContext
.RunInParallel(featureDescriptors, descriptor => _cacheManager.Get(descriptor.Id, true, ctx => LoadFeature(descriptor)))
.ToArray();
// generate a cachekey by hashing the ids of all feature descriptors
var cacheKey = BitConverter.ToString(
_md5.ComputeHash(
Encoding.UTF8.GetBytes(
string.Join(";",
featureDescriptors
.Select(fd => fd.Id)
.OrderBy(x => x)))));
var result = _cacheManager.Get(cacheKey,
true,
ctk => {
if (ParallelizationDisabled) {
return featureDescriptors.Select(descriptor => _cacheManager
.Get(descriptor.Id, true, ctx => LoadFeature(descriptor)))
.ToArray();
}
else {
return _parallelCacheContext
.RunInParallel(featureDescriptors,
descriptor => _cacheManager
.Get(descriptor.Id, true, ctx => LoadFeature(descriptor)))
.ToArray();
}
});
Logger.Information("Done loading features");
return result;