From a1c5dd646e0ec3f464ae847846b49b23a721e148 Mon Sep 17 00:00:00 2001 From: Louis DeJardin Date: Tue, 16 Nov 2010 15:51:30 -0800 Subject: [PATCH] Perf: making content type definitions cached ContentTypeDefinition needed to fully resolve parts to avoid orphan record access ContentDefinitionManager caches results incrementally All cached definitions expire when any information is touched --HG-- branch : perf extra : rebase_source : b9779a86684aa652ed63360ab6558070e04600ee --- .../Metadata/ContentDefinitionManager.cs | 43 ++++++++++++++++--- .../MetaData/Models/ContentTypeDefinition.cs | 3 +- 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/src/Orchard.Web/Core/Settings/Metadata/ContentDefinitionManager.cs b/src/Orchard.Web/Core/Settings/Metadata/ContentDefinitionManager.cs index 4cd0b8297..e944aabaf 100644 --- a/src/Orchard.Web/Core/Settings/Metadata/ContentDefinitionManager.cs +++ b/src/Orchard.Web/Core/Settings/Metadata/ContentDefinitionManager.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Xml.Linq; +using Orchard.Caching; using Orchard.ContentManagement.MetaData; using Orchard.ContentManagement.MetaData.Models; using Orchard.Core.Settings.Metadata.Records; @@ -11,6 +12,9 @@ using Orchard.Utility.Extensions; namespace Orchard.Core.Settings.Metadata { public class ContentDefinitionManager : Component, IContentDefinitionManager { + private const string ContentDefinitionSignal = "ContentDefinitionManager"; + private readonly ICacheManager _cacheManager; + private readonly ISignals _signals; private readonly IRepository _typeDefinitionRepository; private readonly IRepository _partDefinitionRepository; private readonly IRepository _fieldDefinitionRepository; @@ -18,11 +22,15 @@ namespace Orchard.Core.Settings.Metadata { private readonly IMapper _settingsWriter; public ContentDefinitionManager( + ICacheManager cacheManager, + ISignals signals, IRepository typeDefinitionRepository, IRepository partDefinitionRepository, IRepository fieldDefinitionRepository, IMapper settingsReader, IMapper settingsWriter) { + _cacheManager = cacheManager; + _signals = signals; _typeDefinitionRepository = typeDefinitionRepository; _partDefinitionRepository = partDefinitionRepository; _fieldDefinitionRepository = fieldDefinitionRepository; @@ -31,33 +39,58 @@ namespace Orchard.Core.Settings.Metadata { } public ContentTypeDefinition GetTypeDefinition(string name) { - return _typeDefinitionRepository.Fetch(x => x.Name == name).Select(Build).SingleOrDefault(); + return _cacheManager.Get(name, ctx => { + MonitorContentDefinitionSignal(ctx); + return _typeDefinitionRepository.Fetch(x => x.Name == name).Select(Build).SingleOrDefault(); + }); } public ContentPartDefinition GetPartDefinition(string name) { - return _partDefinitionRepository.Fetch(x => x.Name == name).Select(Build).SingleOrDefault(); + return _cacheManager.Get(name, ctx => { + MonitorContentDefinitionSignal(ctx); + return _partDefinitionRepository.Fetch(x => x.Name == name).Select(Build).SingleOrDefault(); + }); } public IEnumerable ListTypeDefinitions() { - return _typeDefinitionRepository.Fetch(x => !x.Hidden).Select(Build).ToReadOnlyCollection(); + return _cacheManager.Get(string.Empty, ctx => { + MonitorContentDefinitionSignal(ctx); + return _typeDefinitionRepository.Fetch(x => !x.Hidden).Select(Build).ToReadOnlyCollection(); + }); } public IEnumerable ListPartDefinitions() { - return _partDefinitionRepository.Fetch(x => !x.Hidden).Select(Build).ToReadOnlyCollection(); + return _cacheManager.Get(string.Empty, ctx => { + MonitorContentDefinitionSignal(ctx); + return _partDefinitionRepository.Fetch(x => !x.Hidden).Select(Build).ToReadOnlyCollection(); + }); } public IEnumerable ListFieldDefinitions() { - return _fieldDefinitionRepository.Fetch(x => true, cfdr => cfdr.Asc(fdr => fdr.Name)).Select(Build).ToReadOnlyCollection(); + return _cacheManager.Get(string.Empty, ctx => { + MonitorContentDefinitionSignal(ctx); + return _fieldDefinitionRepository.Fetch(x => true, cfdr => cfdr.Asc(fdr => fdr.Name)).Select(Build).ToReadOnlyCollection(); + }); } public void StoreTypeDefinition(ContentTypeDefinition contentTypeDefinition) { + TriggerContentDefinitionSignal(); Apply(contentTypeDefinition, Acquire(contentTypeDefinition)); } public void StorePartDefinition(ContentPartDefinition contentPartDefinition) { + _signals.Trigger(ContentDefinitionSignal); Apply(contentPartDefinition, Acquire(contentPartDefinition)); } + private void MonitorContentDefinitionSignal(AcquireContext ctx) { + ctx.Monitor(_signals.When(ContentDefinitionSignal)); + } + + private void TriggerContentDefinitionSignal() { + _signals.Trigger(ContentDefinitionSignal); + } + private ContentTypeDefinitionRecord Acquire(ContentTypeDefinition contentTypeDefinition) { var result = _typeDefinitionRepository.Fetch(x => x.Name == contentTypeDefinition.Name).SingleOrDefault(); if (result == null) { diff --git a/src/Orchard/ContentManagement/MetaData/Models/ContentTypeDefinition.cs b/src/Orchard/ContentManagement/MetaData/Models/ContentTypeDefinition.cs index f85212385..a91117eb7 100644 --- a/src/Orchard/ContentManagement/MetaData/Models/ContentTypeDefinition.cs +++ b/src/Orchard/ContentManagement/MetaData/Models/ContentTypeDefinition.cs @@ -1,13 +1,14 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; +using Orchard.Utility.Extensions; namespace Orchard.ContentManagement.MetaData.Models { public class ContentTypeDefinition { public ContentTypeDefinition(string name, string displayName, IEnumerable parts, SettingsDictionary settings) { Name = name; DisplayName = displayName; - Parts = parts; + Parts = parts.ToReadOnlyCollection(); Settings = settings; }