mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-15 19:54:57 +08:00
PERF: Build shape table in parallel
We have lots of file I/O to scan directories for templates, so it was a good candidate to run in parallel. --HG-- branch : 1.x
This commit is contained in:
@@ -59,10 +59,9 @@ namespace Orchard.Tests.DisplayManagement.Descriptors {
|
||||
}
|
||||
|
||||
static IEnumerable<ShapeAlteration> GetAlterationBuilders(IShapeTableProvider strategy) {
|
||||
IList<ShapeAlterationBuilder> alterationBuilders = new List<ShapeAlterationBuilder>();
|
||||
var builder = new ShapeTableBuilder(alterationBuilders, null);
|
||||
var builder = new ShapeTableBuilder(null);
|
||||
strategy.Discover(builder);
|
||||
return alterationBuilders.Select(alterationBuilder => alterationBuilder.Build());
|
||||
return builder.BuildAlterations();
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
@@ -147,13 +147,11 @@ namespace Orchard.Tests.DisplayManagement.Descriptors {
|
||||
_testViewEngine.Add("~/Modules/Alpha/Views/AlphaShape.blah", null);
|
||||
var strategy = _container.Resolve<IShapeTableProvider>();
|
||||
|
||||
IList<ShapeAlterationBuilder> alterationBuilders = new List<ShapeAlterationBuilder>();
|
||||
var builder = new ShapeTableBuilder(alterationBuilders,null);
|
||||
var builder = new ShapeTableBuilder(null);
|
||||
strategy.Discover(builder);
|
||||
var alterations = alterationBuilders.Select(alterationBuilder=>alterationBuilder.Build());
|
||||
var alterations = builder.BuildAlterations();
|
||||
|
||||
Assert.That(alterations.Any(alteration => alteration.ShapeType.Equals("AlphaShape", StringComparison.OrdinalIgnoreCase)));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -146,10 +146,9 @@ namespace Orchard.Tests.DisplayManagement.Descriptors {
|
||||
_testViewEngine.Add("~/Modules/Alpha/Styles/alpha-shape.css", null);
|
||||
var strategy = _container.Resolve<IShapeTableProvider>();
|
||||
|
||||
IList<ShapeAlterationBuilder> alterationBuilders = new List<ShapeAlterationBuilder>();
|
||||
var builder = new ShapeTableBuilder(alterationBuilders,null);
|
||||
var builder = new ShapeTableBuilder(null);
|
||||
strategy.Discover(builder);
|
||||
var alterations = alterationBuilders.Select(alterationBuilder=>alterationBuilder.Build());
|
||||
var alterations = builder.BuildAlterations();
|
||||
|
||||
Assert.That(alterations.Any(alteration => alteration.ShapeType == "Style"));
|
||||
|
||||
|
@@ -14,13 +14,16 @@ namespace Orchard.DisplayManagement.Descriptors {
|
||||
private readonly IEnumerable<Meta<IShapeTableProvider>> _bindingStrategies;
|
||||
private readonly IExtensionManager _extensionManager;
|
||||
private readonly ICacheManager _cacheManager;
|
||||
private readonly IParallelCacheContext _parallelCacheContext;
|
||||
|
||||
public DefaultShapeTableManager(
|
||||
IEnumerable<Meta<IShapeTableProvider>> bindingStrategies,
|
||||
IExtensionManager extensionManager,
|
||||
ICacheManager cacheManager) {
|
||||
ICacheManager cacheManager,
|
||||
IParallelCacheContext parallelCacheContext) {
|
||||
_extensionManager = extensionManager;
|
||||
_cacheManager = cacheManager;
|
||||
_parallelCacheContext = parallelCacheContext;
|
||||
_bindingStrategies = bindingStrategies;
|
||||
Logger = NullLogger.Instance;
|
||||
}
|
||||
@@ -31,19 +34,20 @@ namespace Orchard.DisplayManagement.Descriptors {
|
||||
return _cacheManager.Get(themeName ?? "", x => {
|
||||
Logger.Information("Start building shape table");
|
||||
|
||||
var builderFactory = new ShapeTableBuilderFactory();
|
||||
foreach (var bindingStrategy in _bindingStrategies) {
|
||||
var alterationSets = _parallelCacheContext.RunInParallel(_bindingStrategies, bindingStrategy => {
|
||||
Feature strategyDefaultFeature = bindingStrategy.Metadata.ContainsKey("Feature") ?
|
||||
(Feature) bindingStrategy.Metadata["Feature"] :
|
||||
null;
|
||||
(Feature)bindingStrategy.Metadata["Feature"] :
|
||||
null;
|
||||
|
||||
var builder = builderFactory.CreateTableBuilder(strategyDefaultFeature);
|
||||
var builder = new ShapeTableBuilder(strategyDefaultFeature);
|
||||
bindingStrategy.Value.Discover(builder);
|
||||
}
|
||||
return builder.BuildAlterations().ToList();
|
||||
});
|
||||
|
||||
var alterations = builderFactory.BuildAlterations()
|
||||
.Where(alteration => IsModuleOrRequestedTheme(alteration, themeName))
|
||||
.OrderByDependenciesAndPriorities(AlterationHasDependency, GetPriority);
|
||||
var alterations = alterationSets
|
||||
.SelectMany(shapeAlterations => shapeAlterations)
|
||||
.Where(alteration => IsModuleOrRequestedTheme(alteration, themeName))
|
||||
.OrderByDependenciesAndPriorities(AlterationHasDependency, GetPriority);
|
||||
|
||||
var descriptors = alterations.GroupBy(alteration => alteration.ShapeType, StringComparer.OrdinalIgnoreCase)
|
||||
.Select(group => group.Aggregate(
|
||||
@@ -98,7 +102,7 @@ namespace Orchard.DisplayManagement.Descriptors {
|
||||
var availableFeatures = _extensionManager.AvailableFeatures();
|
||||
|
||||
var themeFeature = availableFeatures.SingleOrDefault(fd => fd.Id == themeName);
|
||||
while(themeFeature != null) {
|
||||
while (themeFeature != null) {
|
||||
var baseTheme = themeFeature.Extension.BaseTheme;
|
||||
if (String.IsNullOrEmpty(baseTheme)) {
|
||||
return false;
|
||||
@@ -110,21 +114,5 @@ namespace Orchard.DisplayManagement.Descriptors {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
class ShapeTableBuilderFactory {
|
||||
readonly IList<ShapeAlterationBuilder> _alterationBuilders = new List<ShapeAlterationBuilder>();
|
||||
|
||||
public ShapeTableBuilder CreateTableBuilder(Feature feature) {
|
||||
return new ShapeTableBuilder(_alterationBuilders, feature);
|
||||
}
|
||||
|
||||
public IEnumerable<ShapeAlteration> BuildAlterations() {
|
||||
return _alterationBuilders.Select(b => b.Build());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -1,13 +1,13 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Orchard.Environment.Extensions.Models;
|
||||
|
||||
namespace Orchard.DisplayManagement.Descriptors {
|
||||
public class ShapeTableBuilder {
|
||||
readonly IList<ShapeAlterationBuilder> _alterationBuilders;
|
||||
readonly Feature _feature;
|
||||
private readonly IList<ShapeAlterationBuilder> _alterationBuilders = new List<ShapeAlterationBuilder>();
|
||||
private readonly Feature _feature;
|
||||
|
||||
public ShapeTableBuilder(IList<ShapeAlterationBuilder> alterationBuilders, Feature feature) {
|
||||
_alterationBuilders = alterationBuilders;
|
||||
public ShapeTableBuilder(Feature feature) {
|
||||
_feature = feature;
|
||||
}
|
||||
|
||||
@@ -17,5 +17,8 @@ namespace Orchard.DisplayManagement.Descriptors {
|
||||
return alterationBuilder;
|
||||
}
|
||||
|
||||
public IEnumerable<ShapeAlteration> BuildAlterations() {
|
||||
return _alterationBuilders.Select(b => b.Build());
|
||||
}
|
||||
}
|
||||
}
|
@@ -23,6 +23,7 @@ namespace Orchard.DisplayManagement.Descriptors.ShapeTemplateStrategy {
|
||||
private readonly IVirtualPathProvider _virtualPathProvider;
|
||||
private readonly IEnumerable<IShapeTemplateHarvester> _harvesters;
|
||||
private readonly IEnumerable<IShapeTemplateViewEngine> _shapeTemplateViewEngines;
|
||||
private readonly IParallelCacheContext _parallelCacheContext;
|
||||
|
||||
|
||||
public ShapeTemplateBindingStrategy(
|
||||
@@ -32,7 +33,9 @@ namespace Orchard.DisplayManagement.Descriptors.ShapeTemplateStrategy {
|
||||
ICacheManager cacheManager,
|
||||
IVirtualPathMonitor virtualPathMonitor,
|
||||
IVirtualPathProvider virtualPathProvider,
|
||||
IEnumerable<IShapeTemplateViewEngine> shapeTemplateViewEngines) {
|
||||
IEnumerable<IShapeTemplateViewEngine> shapeTemplateViewEngines,
|
||||
IParallelCacheContext parallelCacheContext) {
|
||||
|
||||
_harvesters = harvesters;
|
||||
_shellDescriptor = shellDescriptor;
|
||||
_extensionManager = extensionManager;
|
||||
@@ -40,6 +43,7 @@ namespace Orchard.DisplayManagement.Descriptors.ShapeTemplateStrategy {
|
||||
_virtualPathMonitor = virtualPathMonitor;
|
||||
_virtualPathProvider = virtualPathProvider;
|
||||
_shapeTemplateViewEngines = shapeTemplateViewEngines;
|
||||
_parallelCacheContext = parallelCacheContext;
|
||||
Logger = NullLogger.Instance;
|
||||
}
|
||||
|
||||
@@ -59,7 +63,7 @@ namespace Orchard.DisplayManagement.Descriptors.ShapeTemplateStrategy {
|
||||
var activeFeatures = availableFeatures.Where(FeatureIsEnabled);
|
||||
var activeExtensions = Once(activeFeatures);
|
||||
|
||||
var hits = activeExtensions.SelectMany(extensionDescriptor => {
|
||||
var hits = _parallelCacheContext.RunInParallel(activeExtensions, extensionDescriptor => {
|
||||
Logger.Information("Start discovering candidate views filenames");
|
||||
var pathContexts = harvesterInfos.SelectMany(harvesterInfo => harvesterInfo.subPaths.Select(subPath => {
|
||||
var basePath = Path.Combine(extensionDescriptor.Location, extensionDescriptor.Id).Replace(Path.DirectorySeparatorChar, '/');
|
||||
@@ -92,8 +96,8 @@ namespace Orchard.DisplayManagement.Descriptors.ShapeTemplateStrategy {
|
||||
return harvestShapeHits.Select(harvestShapeHit => new { harvestShapeInfo, harvestShapeHit, fileContext });
|
||||
});
|
||||
|
||||
return shapeContexts.Select(shapeContext => new { extensionDescriptor, shapeContext });
|
||||
});
|
||||
return shapeContexts.Select(shapeContext => new { extensionDescriptor, shapeContext }).ToList();
|
||||
}).SelectMany(hits2 => hits2);
|
||||
|
||||
|
||||
foreach (var iter in hits) {
|
||||
|
Reference in New Issue
Block a user