mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2025-10-14 19:04:51 +08:00
Added two optimisations to avoid duplicate work
Avoids many retrievals of ShellStateRecord and stops enabling the same feature multiple times. This can significantly improve recipe execution time for those recipes with large numbers of features with long dependency chains.
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Orchard.Caching;
|
||||||
using Orchard.Core.Settings.State.Records;
|
using Orchard.Core.Settings.State.Records;
|
||||||
using Orchard.Data;
|
using Orchard.Data;
|
||||||
using Orchard.Environment.State;
|
using Orchard.Environment.State;
|
||||||
@@ -10,16 +11,19 @@ namespace Orchard.Core.Settings.State {
|
|||||||
public class ShellStateManager : Component, IShellStateManager {
|
public class ShellStateManager : Component, IShellStateManager {
|
||||||
private readonly IRepository<ShellStateRecord> _shellStateRepository;
|
private readonly IRepository<ShellStateRecord> _shellStateRepository;
|
||||||
private readonly IShellDescriptorManager _shellDescriptorManager;
|
private readonly IShellDescriptorManager _shellDescriptorManager;
|
||||||
|
private readonly ICacheManager _cacheManager;
|
||||||
|
|
||||||
public ShellStateManager(
|
public ShellStateManager(
|
||||||
IRepository<ShellStateRecord> shellStateRepository,
|
IRepository<ShellStateRecord> shellStateRepository,
|
||||||
IShellDescriptorManager shellDescriptorManager) {
|
IShellDescriptorManager shellDescriptorManager,
|
||||||
|
ICacheManager cacheManager) {
|
||||||
_shellStateRepository = shellStateRepository;
|
_shellStateRepository = shellStateRepository;
|
||||||
_shellDescriptorManager = shellDescriptorManager;
|
_shellDescriptorManager = shellDescriptorManager;
|
||||||
|
_cacheManager = cacheManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ShellState GetShellState() {
|
public ShellState GetShellState() {
|
||||||
var stateRecord = _shellStateRepository.Get(x => x != null) ?? new ShellStateRecord();
|
var stateRecord = GetExistingOrNewShellStateRecord();
|
||||||
var descriptor = _shellDescriptorManager.GetShellDescriptor();
|
var descriptor = _shellDescriptorManager.GetShellDescriptor();
|
||||||
var extraFeatures = descriptor == null ? Enumerable.Empty<string>() : descriptor.Features
|
var extraFeatures = descriptor == null ? Enumerable.Empty<string>() : descriptor.Features
|
||||||
.Select(r => r.Name)
|
.Select(r => r.Name)
|
||||||
@@ -38,9 +42,23 @@ namespace Orchard.Core.Settings.State {
|
|||||||
.ToArray(),
|
.ToArray(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
private ShellStateRecord GetExistingOrNewShellStateRecord() {
|
||||||
|
//Fix for https://orchard.codeplex.com/workitem/21176 / https://github.com/OrchardCMS/Orchard/issues/6075 change to get ensure ShellState record only retrieved once.
|
||||||
|
var shellStateRecordId = _cacheManager.Get("ShellStateRecordId", ctx => {
|
||||||
|
var shellState = _shellStateRepository.Table.FirstOrDefault();
|
||||||
|
|
||||||
|
if (shellState == null) {
|
||||||
|
shellState = new ShellStateRecord();
|
||||||
|
_shellStateRepository.Create(shellState);
|
||||||
|
}
|
||||||
|
return shellState.Id;
|
||||||
|
});
|
||||||
|
|
||||||
|
return _shellStateRepository.Get(shellStateRecordId);
|
||||||
|
}
|
||||||
|
|
||||||
private ShellFeatureStateRecord FeatureRecord(string name) {
|
private ShellFeatureStateRecord FeatureRecord(string name) {
|
||||||
var stateRecord = _shellStateRepository.Get(x => x != null) ?? new ShellStateRecord();
|
var stateRecord = GetExistingOrNewShellStateRecord();
|
||||||
var record = stateRecord.Features.SingleOrDefault(x => x.Name == name);
|
var record = stateRecord.Features.SingleOrDefault(x => x.Name == name);
|
||||||
if (record == null) {
|
if (record == null) {
|
||||||
record = new ShellFeatureStateRecord { Name = name };
|
record = new ShellFeatureStateRecord { Name = name };
|
||||||
|
@@ -69,9 +69,10 @@ namespace Orchard.Environment.Features {
|
|||||||
.ToDictionary(featureDescriptor => featureDescriptor,
|
.ToDictionary(featureDescriptor => featureDescriptor,
|
||||||
featureDescriptor => enabledFeatures.FirstOrDefault(shellFeature => shellFeature.Name == featureDescriptor.Id) != null);
|
featureDescriptor => enabledFeatures.FirstOrDefault(shellFeature => shellFeature.Name == featureDescriptor.Id) != null);
|
||||||
|
|
||||||
|
//Fix for https://orchard.codeplex.com/workitem/21176 / https://github.com/OrchardCMS/Orchard/issues/6075 - added distinct to the end to ensure each feature is only listed once
|
||||||
IEnumerable<string> featuresToEnable = featureIds
|
IEnumerable<string> featuresToEnable = featureIds
|
||||||
.Select(featureId => EnableFeature(featureId, availableFeatures, force)).ToList()
|
.Select(featureId => EnableFeature(featureId, availableFeatures, force)).ToList()
|
||||||
.SelectMany(ies => ies.Select(s => s));
|
.SelectMany(ies => ies.Select(s => s)).Distinct();
|
||||||
|
|
||||||
if (featuresToEnable.Count() > 0) {
|
if (featuresToEnable.Count() > 0) {
|
||||||
foreach (string featureId in featuresToEnable) {
|
foreach (string featureId in featuresToEnable) {
|
||||||
|
Reference in New Issue
Block a user