Merge remote-tracking branch 'origin/temp8' into feature/IContentType-removale-from-IContent
# Conflicts: # src/Umbraco.Web/Macros/PublishedContentHashtableConverter.cs
This commit is contained in:
@@ -21,20 +21,20 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
internal class ContentCache : PublishedCacheBase, IPublishedContentCache, INavigableData, IDisposable
|
||||
{
|
||||
private readonly ContentStore.Snapshot _snapshot;
|
||||
private readonly ICacheProvider _snapshotCache;
|
||||
private readonly ICacheProvider _elementsCache;
|
||||
private readonly IAppCache _snapshotCache;
|
||||
private readonly IAppCache _elementsCache;
|
||||
private readonly DomainHelper _domainHelper;
|
||||
private readonly IGlobalSettings _globalSettings;
|
||||
private readonly ILocalizationService _localizationService;
|
||||
|
||||
#region Constructor
|
||||
|
||||
// fixme ISSUE
|
||||
// TODO: figure this out
|
||||
// after the current snapshot has been resync-ed
|
||||
// it's too late for UmbracoContext which has captured previewDefault and stuff into these ctor vars
|
||||
// but, no, UmbracoContext returns snapshot.Content which comes from elements SO a resync should create a new cache
|
||||
|
||||
public ContentCache(bool previewDefault, ContentStore.Snapshot snapshot, ICacheProvider snapshotCache, ICacheProvider elementsCache, DomainHelper domainHelper, IGlobalSettings globalSettings, ILocalizationService localizationService)
|
||||
public ContentCache(bool previewDefault, ContentStore.Snapshot snapshot, IAppCache snapshotCache, IAppCache elementsCache, DomainHelper domainHelper, IGlobalSettings globalSettings, ILocalizationService localizationService)
|
||||
: base(previewDefault)
|
||||
{
|
||||
_snapshot = snapshot;
|
||||
@@ -93,7 +93,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
// if in a domain then start with the root node of the domain
|
||||
// and follow the path
|
||||
// note: if domain has a path (eg example.com/en) which is not recommended anymore
|
||||
// then then /en part of the domain is basically ignored here...
|
||||
// then /en part of the domain is basically ignored here...
|
||||
content = GetById(preview, startNodeId);
|
||||
content = FollowRoute(content, parts, 0, culture);
|
||||
}
|
||||
@@ -243,7 +243,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
var n = _snapshot.Get(contentId);
|
||||
if (n == null) return false;
|
||||
|
||||
return preview || n.Published != null;
|
||||
return preview || n.PublishedModel != null;
|
||||
}
|
||||
|
||||
public override IEnumerable<IPublishedContent> GetAtRoot(bool preview)
|
||||
@@ -259,7 +259,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
return GetAtRootNoCache(preview);
|
||||
|
||||
// note: ToArray is important here, we want to cache the result, not the function!
|
||||
return (IEnumerable<IPublishedContent>)cache.GetCacheItem(
|
||||
return (IEnumerable<IPublishedContent>)cache.Get(
|
||||
CacheKeys.ContentCacheRoots(preview),
|
||||
() => GetAtRootNoCache(preview).ToArray());
|
||||
}
|
||||
@@ -280,8 +280,8 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
// both .Draft and .Published cannot be null at the same time
|
||||
|
||||
return preview
|
||||
? node.Draft ?? GetPublishedContentAsDraft(node.Published)
|
||||
: node.Published;
|
||||
? node.DraftModel ?? GetPublishedContentAsDraft(node.PublishedModel)
|
||||
: node.PublishedModel;
|
||||
}
|
||||
|
||||
// gets a published content as a previewing draft, if preview is true
|
||||
@@ -302,7 +302,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
{
|
||||
return preview
|
||||
? _snapshot.IsEmpty == false
|
||||
: _snapshot.GetAtRoot().Any(x => x.Published != null);
|
||||
: _snapshot.GetAtRoot().Any(x => x.PublishedModel != null);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -34,10 +34,11 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
DateTime createDate, int creatorId,
|
||||
ContentData draftData, ContentData publishedData,
|
||||
IPublishedSnapshotAccessor publishedSnapshotAccessor,
|
||||
IVariationContextAccessor variationContextAccessor)
|
||||
IVariationContextAccessor variationContextAccessor,
|
||||
IUmbracoContextAccessor umbracoContextAccessor)
|
||||
: this(id, uid, level, path, sortOrder, parentContentId, createDate, creatorId)
|
||||
{
|
||||
SetContentTypeAndData(contentType, draftData, publishedData, publishedSnapshotAccessor, variationContextAccessor);
|
||||
SetContentTypeAndData(contentType, draftData, publishedData, publishedSnapshotAccessor, variationContextAccessor, umbracoContextAccessor);
|
||||
}
|
||||
|
||||
// 2-phases ctor, phase 1
|
||||
@@ -59,7 +60,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
}
|
||||
|
||||
// two-phase ctor, phase 2
|
||||
public void SetContentTypeAndData(PublishedContentType contentType, ContentData draftData, ContentData publishedData, IPublishedSnapshotAccessor publishedSnapshotAccessor, IVariationContextAccessor variationContextAccessor)
|
||||
public void SetContentTypeAndData(PublishedContentType contentType, ContentData draftData, ContentData publishedData, IPublishedSnapshotAccessor publishedSnapshotAccessor, IVariationContextAccessor variationContextAccessor, IUmbracoContextAccessor umbracoContextAccessor)
|
||||
{
|
||||
ContentType = contentType;
|
||||
|
||||
@@ -67,13 +68,20 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
throw new ArgumentException("Both draftData and publishedData cannot be null at the same time.");
|
||||
|
||||
if (draftData != null)
|
||||
Draft = new PublishedContent(this, draftData, publishedSnapshotAccessor, variationContextAccessor).CreateModel();
|
||||
{
|
||||
DraftContent = new PublishedContent(this, draftData, publishedSnapshotAccessor, variationContextAccessor, umbracoContextAccessor);
|
||||
DraftModel = DraftContent.CreateModel();
|
||||
}
|
||||
|
||||
if (publishedData != null)
|
||||
Published = new PublishedContent(this, publishedData, publishedSnapshotAccessor, variationContextAccessor).CreateModel();
|
||||
{
|
||||
PublishedContent = new PublishedContent(this, publishedData, publishedSnapshotAccessor, variationContextAccessor, umbracoContextAccessor);
|
||||
PublishedModel = PublishedContent.CreateModel();
|
||||
}
|
||||
}
|
||||
|
||||
// clone parent
|
||||
private ContentNode(ContentNode origin)
|
||||
private ContentNode(ContentNode origin, IUmbracoContextAccessor umbracoContextAccessor)
|
||||
{
|
||||
// everything is the same, except for the child items
|
||||
// list which is a clone of the original list
|
||||
@@ -88,17 +96,20 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
CreateDate = origin.CreateDate;
|
||||
CreatorId = origin.CreatorId;
|
||||
|
||||
var originDraft = origin.Draft == null ? null : PublishedContent.UnwrapIPublishedContent(origin.Draft);
|
||||
var originPublished = origin.Published == null ? null : PublishedContent.UnwrapIPublishedContent(origin.Published);
|
||||
var originDraft = origin.DraftContent;
|
||||
var originPublished = origin.PublishedContent;
|
||||
|
||||
Draft = originDraft == null ? null : new PublishedContent(this, originDraft).CreateModel();
|
||||
Published = originPublished == null ? null : new PublishedContent(this, originPublished).CreateModel();
|
||||
|
||||
DraftContent = originDraft == null ? null : new PublishedContent(this, originDraft, umbracoContextAccessor);
|
||||
PublishedContent = originPublished == null ? null : new PublishedContent(this, originPublished, umbracoContextAccessor);
|
||||
DraftModel = DraftContent?.CreateModel();
|
||||
PublishedModel = PublishedContent?.CreateModel();
|
||||
|
||||
ChildContentIds = new List<int>(origin.ChildContentIds); // needs to be *another* list
|
||||
}
|
||||
|
||||
// clone with new content type
|
||||
public ContentNode(ContentNode origin, PublishedContentType contentType, IPublishedSnapshotAccessor publishedSnapshotAccessor, IVariationContextAccessor variationContextAccessor)
|
||||
public ContentNode(ContentNode origin, PublishedContentType contentType, IPublishedSnapshotAccessor publishedSnapshotAccessor, IVariationContextAccessor variationContextAccessor, IUmbracoContextAccessor umbracoContextAccessor)
|
||||
{
|
||||
Id = origin.Id;
|
||||
Uid = origin.Uid;
|
||||
@@ -110,13 +121,15 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
CreateDate = origin.CreateDate;
|
||||
CreatorId = origin.CreatorId;
|
||||
|
||||
var originDraft = origin.Draft == null ? null : PublishedContent.UnwrapIPublishedContent(origin.Draft);
|
||||
var originPublished = origin.Published == null ? null : PublishedContent.UnwrapIPublishedContent(origin.Published);
|
||||
var originDraft = origin.DraftContent;
|
||||
var originPublished = origin.PublishedContent;
|
||||
|
||||
Draft = originDraft == null ? null : new PublishedContent(this, originDraft._contentData, publishedSnapshotAccessor, variationContextAccessor).CreateModel();
|
||||
Published = originPublished == null ? null : new PublishedContent(this, originPublished._contentData, publishedSnapshotAccessor, variationContextAccessor).CreateModel();
|
||||
DraftContent = originDraft == null ? null : new PublishedContent(this, originDraft.ContentData, publishedSnapshotAccessor, variationContextAccessor, umbracoContextAccessor);
|
||||
DraftModel = DraftContent?.CreateModel();
|
||||
PublishedContent = originPublished == null ? null : new PublishedContent(this, originPublished.ContentData, publishedSnapshotAccessor, variationContextAccessor, umbracoContextAccessor);
|
||||
PublishedModel = PublishedContent?.CreateModel();
|
||||
|
||||
ChildContentIds = origin.ChildContentIds; // can be the *same* list FIXME oh really?
|
||||
ChildContentIds = origin.ChildContentIds; // can be the *same* list
|
||||
}
|
||||
|
||||
// everything that is common to both draft and published versions
|
||||
@@ -133,32 +146,31 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
public readonly int CreatorId;
|
||||
|
||||
// draft and published version (either can be null, but not both)
|
||||
// are models not direct PublishedContent instances
|
||||
public IPublishedContent Draft;
|
||||
public IPublishedContent Published;
|
||||
// are the direct PublishedContent instances
|
||||
public PublishedContent DraftContent;
|
||||
public PublishedContent PublishedContent;
|
||||
|
||||
public ContentNode CloneParent(IPublishedSnapshotAccessor publishedSnapshotAccessor)
|
||||
// draft and published version (either can be null, but not both)
|
||||
// are models not direct PublishedContent instances
|
||||
public IPublishedContent DraftModel;
|
||||
public IPublishedContent PublishedModel;
|
||||
|
||||
public ContentNode CloneParent(
|
||||
IPublishedSnapshotAccessor publishedSnapshotAccessor,
|
||||
IUmbracoContextAccessor umbracoContextAccessor)
|
||||
{
|
||||
return new ContentNode(this);
|
||||
return new ContentNode(this, umbracoContextAccessor);
|
||||
}
|
||||
|
||||
public ContentNodeKit ToKit()
|
||||
{
|
||||
var draft = Draft is PublishedContentModel draftModel
|
||||
? (PublishedContent) draftModel.Unwrap()
|
||||
: (PublishedContent) Draft;
|
||||
|
||||
var published = Published is PublishedContentModel publishedModel
|
||||
? (PublishedContent) publishedModel.Unwrap()
|
||||
: (PublishedContent) Published;
|
||||
|
||||
return new ContentNodeKit
|
||||
{
|
||||
Node = this,
|
||||
ContentTypeId = ContentType.Id,
|
||||
|
||||
DraftData = draft?._contentData,
|
||||
PublishedData = published?._contentData
|
||||
DraftData = DraftContent?.ContentData,
|
||||
PublishedData = PublishedContent?.ContentData
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,9 +17,14 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
|
||||
public static ContentNodeKit Null { get; } = new ContentNodeKit { ContentTypeId = -1 };
|
||||
|
||||
public void Build(PublishedContentType contentType, IPublishedSnapshotAccessor publishedSnapshotAccessor, IVariationContextAccessor variationContextAccessor, bool canBePublished)
|
||||
public void Build(
|
||||
PublishedContentType contentType,
|
||||
IPublishedSnapshotAccessor publishedSnapshotAccessor,
|
||||
IVariationContextAccessor variationContextAccessor,
|
||||
bool canBePublished,
|
||||
IUmbracoContextAccessor umbracoContextAccessor)
|
||||
{
|
||||
Node.SetContentTypeAndData(contentType, DraftData, canBePublished ? PublishedData : null, publishedSnapshotAccessor, variationContextAccessor);
|
||||
Node.SetContentTypeAndData(contentType, DraftData, canBePublished ? PublishedData : null, publishedSnapshotAccessor, variationContextAccessor,umbracoContextAccessor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
|
||||
private readonly IPublishedSnapshotAccessor _publishedSnapshotAccessor;
|
||||
private readonly IVariationContextAccessor _variationContextAccessor;
|
||||
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
|
||||
private readonly ConcurrentDictionary<int, LinkedNode<ContentNode>> _contentNodes;
|
||||
private readonly ConcurrentDictionary<int, LinkedNode<object>> _contentRootNodes;
|
||||
private readonly ConcurrentDictionary<int, LinkedNode<PublishedContentType>> _contentTypesById;
|
||||
@@ -38,16 +39,22 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
private volatile int _wlocked;
|
||||
private List<KeyValuePair<int, ContentNodeKit>> _wchanges;
|
||||
|
||||
// fixme - collection trigger (ok for now)
|
||||
// TODO: collection trigger (ok for now)
|
||||
// see SnapDictionary notes
|
||||
private const long CollectMinGenDelta = 8;
|
||||
|
||||
#region Ctor
|
||||
|
||||
public ContentStore(IPublishedSnapshotAccessor publishedSnapshotAccessor, IVariationContextAccessor variationContextAccessor, ILogger logger, BPlusTree<int, ContentNodeKit> localDb = null)
|
||||
public ContentStore(
|
||||
IPublishedSnapshotAccessor publishedSnapshotAccessor,
|
||||
IVariationContextAccessor variationContextAccessor,
|
||||
IUmbracoContextAccessor umbracoContextAccessor,
|
||||
ILogger logger,
|
||||
BPlusTree<int, ContentNodeKit> localDb = null)
|
||||
{
|
||||
_publishedSnapshotAccessor = publishedSnapshotAccessor;
|
||||
_variationContextAccessor = variationContextAccessor;
|
||||
_umbracoContextAccessor = umbracoContextAccessor;
|
||||
_logger = logger;
|
||||
_localDb = localDb;
|
||||
|
||||
@@ -104,7 +111,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
}
|
||||
|
||||
// gets a scope contextual representing a locked writer to the dictionary
|
||||
// fixme GetScopedWriter? should the dict have a ref onto the scope provider?
|
||||
// TODO: GetScopedWriter? should the dict have a ref onto the scope provider?
|
||||
public IDisposable GetWriter(IScopeProvider scopeProvider)
|
||||
{
|
||||
return ScopeContextualBase.Get(scopeProvider, _instanceId, scoped => new ContentStoreWriter(this, scoped));
|
||||
@@ -279,7 +286,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
if (node == null) continue;
|
||||
var contentTypeId = node.ContentType.Id;
|
||||
if (index.TryGetValue(contentTypeId, out PublishedContentType contentType) == false) continue;
|
||||
SetValueLocked(_contentNodes, node.Id, new ContentNode(node, contentType, _publishedSnapshotAccessor, _variationContextAccessor));
|
||||
SetValueLocked(_contentNodes, node.Id, new ContentNode(node, contentType, _publishedSnapshotAccessor, _variationContextAccessor, _umbracoContextAccessor));
|
||||
}
|
||||
}
|
||||
finally
|
||||
@@ -393,7 +400,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
_contentNodes.TryGetValue(id, out LinkedNode<ContentNode> link);
|
||||
if (link?.Value == null)
|
||||
continue;
|
||||
var node = new ContentNode(link.Value, contentType, _publishedSnapshotAccessor, _variationContextAccessor);
|
||||
var node = new ContentNode(link.Value, contentType, _publishedSnapshotAccessor, _variationContextAccessor, _umbracoContextAccessor);
|
||||
SetValueLocked(_contentNodes, id, node);
|
||||
if (_localDb != null) RegisterChange(id, node.ToKit());
|
||||
}
|
||||
@@ -419,7 +426,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
var canBePublished = ParentPublishedLocked(kit);
|
||||
|
||||
// and use
|
||||
kit.Build(link.Value, _publishedSnapshotAccessor, _variationContextAccessor, canBePublished);
|
||||
kit.Build(link.Value, _publishedSnapshotAccessor, _variationContextAccessor, canBePublished, _umbracoContextAccessor);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -631,7 +638,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
var link = GetParentLink(content);
|
||||
var parent = link.Value;
|
||||
if (link.Gen < _liveGen)
|
||||
parent = parent.CloneParent(_publishedSnapshotAccessor);
|
||||
parent = parent.CloneParent(_publishedSnapshotAccessor, _umbracoContextAccessor);
|
||||
parent.ChildContentIds.Remove(content.Id);
|
||||
if (link.Gen < _liveGen)
|
||||
SetValueLocked(_contentNodes, parent.Id, parent);
|
||||
@@ -652,7 +659,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
return true;
|
||||
var link = GetParentLink(kit.Node);
|
||||
var node = link?.Value;
|
||||
return node?.Published != null;
|
||||
return node?.PublishedModel != null;
|
||||
}
|
||||
|
||||
private void AddToParentLocked(ContentNode content)
|
||||
@@ -670,7 +677,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
var link = GetParentLink(content);
|
||||
var parent = link.Value;
|
||||
if (link.Gen < _liveGen)
|
||||
parent = parent.CloneParent(_publishedSnapshotAccessor);
|
||||
parent = parent.CloneParent(_publishedSnapshotAccessor, _umbracoContextAccessor);
|
||||
parent.ChildContentIds.Add(content.Id);
|
||||
if (link.Gen < _liveGen)
|
||||
SetValueLocked(_contentNodes, parent.Id, parent);
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
|
||||
// write each variation
|
||||
foreach (var (culture, variation) in variations)
|
||||
{
|
||||
// fixme - it's weird we're dealing with cultures here, and languageId in properties
|
||||
// TODO: it's weird we're dealing with cultures here, and languageId in properties
|
||||
|
||||
PrimitiveSerializer.String.WriteTo(culture, stream); // should never be null
|
||||
WriteObject(variation.Name, stream); // write an object in case it's null (though... should not happen)
|
||||
|
||||
@@ -15,7 +15,7 @@ using static Umbraco.Core.Persistence.NPocoSqlExtensions.Statics;
|
||||
|
||||
namespace Umbraco.Web.PublishedCache.NuCache.DataSource
|
||||
{
|
||||
// fixme - use SqlTemplate for these queries else it's going to be horribly slow!
|
||||
// TODO: use SqlTemplate for these queries else it's going to be horribly slow!
|
||||
|
||||
// provides efficient database access for NuCache
|
||||
internal class DatabaseDataSource : IDataSource
|
||||
|
||||
@@ -12,14 +12,14 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
|
||||
public string Culture
|
||||
{
|
||||
get => _culture;
|
||||
set => _culture = value ?? throw new ArgumentNullException(nameof(value)); // fixme or fallback to string.Empty? CANNOT be null
|
||||
set => _culture = value ?? throw new ArgumentNullException(nameof(value)); // TODO: or fallback to string.Empty? CANNOT be null
|
||||
}
|
||||
|
||||
[JsonProperty("seg")]
|
||||
public string Segment
|
||||
{
|
||||
get => _segment;
|
||||
set => _segment = value ?? throw new ArgumentNullException(nameof(value)); // fixme or fallback to string.Empty? CANNOT be null
|
||||
set => _segment = value ?? throw new ArgumentNullException(nameof(value)); // TODO: or fallback to string.Empty? CANNOT be null
|
||||
}
|
||||
|
||||
[JsonProperty("val")]
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace Umbraco.Web.PublishedCache.NuCache.DataSource
|
||||
case 'D':
|
||||
return PrimitiveSerializer.DateTime.ReadFrom(stream);
|
||||
default:
|
||||
throw new NotSupportedException($"Cannot deserialize unknow type '{type}'.");
|
||||
throw new NotSupportedException($"Cannot deserialize unknown type '{type}'.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,12 +13,12 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
internal class MediaCache : PublishedCacheBase, IPublishedMediaCache, INavigableData, IDisposable
|
||||
{
|
||||
private readonly ContentStore.Snapshot _snapshot;
|
||||
private readonly ICacheProvider _snapshotCache;
|
||||
private readonly ICacheProvider _elementsCache;
|
||||
private readonly IAppCache _snapshotCache;
|
||||
private readonly IAppCache _elementsCache;
|
||||
|
||||
#region Constructors
|
||||
|
||||
public MediaCache(bool previewDefault, ContentStore.Snapshot snapshot, ICacheProvider snapshotCache, ICacheProvider elementsCache)
|
||||
public MediaCache(bool previewDefault, ContentStore.Snapshot snapshot, IAppCache snapshotCache, IAppCache elementsCache)
|
||||
: base(previewDefault)
|
||||
{
|
||||
_snapshot = snapshot;
|
||||
@@ -34,14 +34,14 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
{
|
||||
// ignore preview, there's only draft for media
|
||||
var n = _snapshot.Get(contentId);
|
||||
return n?.Published;
|
||||
return n?.PublishedModel;
|
||||
}
|
||||
|
||||
public override IPublishedContent GetById(bool preview, Guid contentId)
|
||||
{
|
||||
// ignore preview, there's only draft for media
|
||||
var n = _snapshot.Get(contentId);
|
||||
return n?.Published;
|
||||
return n?.PublishedModel;
|
||||
}
|
||||
|
||||
public override bool HasById(bool preview, int contentId)
|
||||
@@ -63,7 +63,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
return GetAtRootNoCache();
|
||||
|
||||
// note: ToArray is important here, we want to cache the result, not the function!
|
||||
return (IEnumerable<IPublishedContent>)cache.GetCacheItem(
|
||||
return (IEnumerable<IPublishedContent>)cache.Get(
|
||||
CacheKeys.MediaCacheRoots(false), // ignore preview, only 1 key!
|
||||
() => GetAtRootNoCache().ToArray());
|
||||
}
|
||||
@@ -73,7 +73,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
var c = _snapshot.GetAtRoot();
|
||||
|
||||
// ignore preview, there's only draft for media
|
||||
return c.Select(n => n.Published);
|
||||
return c.Select(n => n.PublishedModel);
|
||||
}
|
||||
|
||||
public override bool HasContent(bool preview)
|
||||
|
||||
@@ -17,18 +17,22 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
internal class MemberCache : IPublishedMemberCache, INavigableData
|
||||
{
|
||||
private readonly IPublishedSnapshotAccessor _publishedSnapshotAccessor;
|
||||
|
||||
public readonly IVariationContextAccessor VariationContextAccessor;
|
||||
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
|
||||
private readonly IEntityXmlSerializer _entitySerializer;
|
||||
private readonly ICacheProvider _snapshotCache;
|
||||
private readonly IAppCache _snapshotCache;
|
||||
private readonly IMemberService _memberService;
|
||||
private readonly PublishedContentTypeCache _contentTypeCache;
|
||||
private readonly bool _previewDefault;
|
||||
|
||||
public MemberCache(bool previewDefault, ICacheProvider snapshotCache, IMemberService memberService, PublishedContentTypeCache contentTypeCache, IPublishedSnapshotAccessor publishedSnapshotAccessor, IVariationContextAccessor variationContextAccessor, IEntityXmlSerializer entitySerializer)
|
||||
public MemberCache(bool previewDefault, IAppCache snapshotCache, IMemberService memberService, PublishedContentTypeCache contentTypeCache,
|
||||
IPublishedSnapshotAccessor publishedSnapshotAccessor, IVariationContextAccessor variationContextAccessor, IUmbracoContextAccessor umbracoContextAccessor, IEntityXmlSerializer entitySerializer)
|
||||
{
|
||||
_snapshotCache = snapshotCache;
|
||||
_publishedSnapshotAccessor = publishedSnapshotAccessor;
|
||||
VariationContextAccessor = variationContextAccessor;
|
||||
_umbracoContextAccessor = umbracoContextAccessor;
|
||||
_entitySerializer = entitySerializer;
|
||||
_memberService = memberService;
|
||||
_previewDefault = previewDefault;
|
||||
@@ -64,14 +68,14 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
var member = _memberService.GetById(memberId);
|
||||
return member == null
|
||||
? null
|
||||
: PublishedMember.Create(member, GetContentType(member.ContentTypeId), _previewDefault, _publishedSnapshotAccessor, VariationContextAccessor);
|
||||
: PublishedMember.Create(member, GetContentType(member.ContentTypeId), _previewDefault, _publishedSnapshotAccessor, VariationContextAccessor, _umbracoContextAccessor);
|
||||
});
|
||||
}
|
||||
|
||||
private IPublishedContent /*IPublishedMember*/ GetById(IMember member, bool previewing)
|
||||
{
|
||||
return GetCacheItem(CacheKeys.MemberCacheMember("ById", _previewDefault, member.Id), () =>
|
||||
PublishedMember.Create(member, GetContentType(member.ContentTypeId), previewing, _publishedSnapshotAccessor, VariationContextAccessor));
|
||||
PublishedMember.Create(member, GetContentType(member.ContentTypeId), previewing, _publishedSnapshotAccessor, VariationContextAccessor, _umbracoContextAccessor));
|
||||
}
|
||||
|
||||
public IPublishedContent /*IPublishedMember*/ GetByProviderKey(object key)
|
||||
@@ -106,7 +110,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
|
||||
public IPublishedContent /*IPublishedMember*/ GetByMember(IMember member)
|
||||
{
|
||||
return PublishedMember.Create(member, GetContentType(member.ContentTypeId), _previewDefault, _publishedSnapshotAccessor, VariationContextAccessor);
|
||||
return PublishedMember.Create(member, GetContentType(member.ContentTypeId), _previewDefault, _publishedSnapshotAccessor, VariationContextAccessor, _umbracoContextAccessor);
|
||||
}
|
||||
|
||||
public IEnumerable<IPublishedContent> GetAtRoot(bool preview)
|
||||
@@ -114,7 +118,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
// because members are flat (not a tree) everything is at root
|
||||
// because we're loading everything... let's just not cache?
|
||||
var members = _memberService.GetAllMembers();
|
||||
return members.Select(m => PublishedMember.Create(m, GetContentType(m.ContentTypeId), preview, _publishedSnapshotAccessor, VariationContextAccessor));
|
||||
return members.Select(m => PublishedMember.Create(m, GetContentType(m.ContentTypeId), preview, _publishedSnapshotAccessor, VariationContextAccessor, _umbracoContextAccessor));
|
||||
}
|
||||
|
||||
public XPathNavigator CreateNavigator()
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace Umbraco.Web.PublishedCache.NuCache.Navigable
|
||||
|
||||
// note - PublishedContentType are immutable ie they do not _change_ when the actual IContentTypeComposition
|
||||
// changes, but they are replaced by a new instance, so our map here will clean itself automatically and
|
||||
// we don't have to manage cache - ConditionalWeakTable does not prevent keys from beeing GCed
|
||||
// we don't have to manage cache - ConditionalWeakTable does not prevent keys from being GCed
|
||||
|
||||
private static readonly ConditionalWeakTable<PublishedContentType, NavigableContentType> TypesMap
|
||||
= new ConditionalWeakTable<PublishedContentType,NavigableContentType>();
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
composition.SetPublishedSnapshotService<PublishedSnapshotService>();
|
||||
|
||||
// add the NuCache health check (hidden from type finder)
|
||||
// todo - no NuCache health check yet
|
||||
// TODO: no NuCache health check yet
|
||||
//composition.HealthChecks().Add<NuCacheIntegrityHealthCheck>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
{
|
||||
CacheValues cacheValues;
|
||||
PublishedSnapshot publishedSnapshot;
|
||||
ICacheProvider cache;
|
||||
IAppCache cache;
|
||||
switch (cacheLevel)
|
||||
{
|
||||
case PropertyCacheLevel.None:
|
||||
@@ -161,11 +161,11 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
return cacheValues;
|
||||
}
|
||||
|
||||
private CacheValues GetCacheValues(ICacheProvider cache)
|
||||
private CacheValues GetCacheValues(IAppCache cache)
|
||||
{
|
||||
if (cache == null) // no cache, don't cache
|
||||
return new CacheValues();
|
||||
return (CacheValues) cache.GetCacheItem(ValuesCacheKey, () => new CacheValues());
|
||||
return (CacheValues) cache.Get(ValuesCacheKey, () => new CacheValues());
|
||||
}
|
||||
|
||||
// this is always invoked from within a lock, so does not require its own lock
|
||||
|
||||
@@ -3,7 +3,6 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.PublishedContent;
|
||||
using Umbraco.Web.Composing;
|
||||
using Umbraco.Web.Models;
|
||||
@@ -14,23 +13,27 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
internal class PublishedContent : PublishedContentBase
|
||||
{
|
||||
private readonly IPublishedSnapshotAccessor _publishedSnapshotAccessor;
|
||||
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
|
||||
private readonly ContentNode _contentNode;
|
||||
// ReSharper disable once InconsistentNaming
|
||||
internal readonly ContentData _contentData; // internal for ContentNode cloning
|
||||
|
||||
private readonly string _urlSegment;
|
||||
|
||||
#region Constructors
|
||||
|
||||
public PublishedContent(ContentNode contentNode, ContentData contentData, IPublishedSnapshotAccessor publishedSnapshotAccessor, IVariationContextAccessor variationContextAccessor)
|
||||
public PublishedContent(
|
||||
ContentNode contentNode,
|
||||
ContentData contentData,
|
||||
IPublishedSnapshotAccessor publishedSnapshotAccessor,
|
||||
IVariationContextAccessor variationContextAccessor,
|
||||
IUmbracoContextAccessor umbracoContextAccessor) :base(umbracoContextAccessor)
|
||||
{
|
||||
_contentNode = contentNode;
|
||||
_contentData = contentData;
|
||||
ContentData = contentData;
|
||||
_publishedSnapshotAccessor = publishedSnapshotAccessor;
|
||||
_umbracoContextAccessor = umbracoContextAccessor;
|
||||
VariationContextAccessor = variationContextAccessor;
|
||||
|
||||
_urlSegment = _contentData.Name.ToUrlSegment();
|
||||
IsPreviewing = _contentData.Published == false;
|
||||
_urlSegment = ContentData.Name.ToUrlSegment();
|
||||
IsPreviewing = ContentData.Published == false;
|
||||
|
||||
var properties = new List<IPublishedProperty>();
|
||||
foreach (var propertyType in _contentNode.ContentType.PropertyTypes)
|
||||
@@ -48,7 +51,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
var cache = GetCurrentSnapshotCache();
|
||||
return cache == null
|
||||
? GetProfileNameByIdNoCache(id)
|
||||
: (string)cache.GetCacheItem(CacheKeys.ProfileName(id), () => GetProfileNameByIdNoCache(id));
|
||||
: (string)cache.Get(CacheKeys.ProfileName(id), () => GetProfileNameByIdNoCache(id));
|
||||
}
|
||||
|
||||
private static string GetProfileNameByIdNoCache(int id)
|
||||
@@ -66,12 +69,15 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
}
|
||||
|
||||
// (see ContentNode.CloneParent)
|
||||
public PublishedContent(ContentNode contentNode, PublishedContent origin)
|
||||
public PublishedContent(
|
||||
ContentNode contentNode,
|
||||
PublishedContent origin,
|
||||
IUmbracoContextAccessor umbracoContextAccessor) :base(umbracoContextAccessor)
|
||||
{
|
||||
_contentNode = contentNode;
|
||||
_publishedSnapshotAccessor = origin._publishedSnapshotAccessor;
|
||||
VariationContextAccessor = origin.VariationContextAccessor;
|
||||
_contentData = origin._contentData;
|
||||
ContentData = origin.ContentData;
|
||||
|
||||
_urlSegment = origin._urlSegment;
|
||||
IsPreviewing = origin.IsPreviewing;
|
||||
@@ -83,12 +89,14 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
}
|
||||
|
||||
// clone for previewing as draft a published content that is published and has no draft
|
||||
private PublishedContent(PublishedContent origin)
|
||||
private PublishedContent(
|
||||
PublishedContent origin,
|
||||
IUmbracoContextAccessor umbracoContextAccessor) :base(umbracoContextAccessor)
|
||||
{
|
||||
_publishedSnapshotAccessor = origin._publishedSnapshotAccessor;
|
||||
VariationContextAccessor = origin.VariationContextAccessor;
|
||||
_contentNode = origin._contentNode;
|
||||
_contentData = origin._contentData;
|
||||
ContentData = origin.ContentData;
|
||||
|
||||
_urlSegment = origin._urlSegment;
|
||||
IsPreviewing = true;
|
||||
@@ -170,6 +178,8 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
|
||||
#region PublishedContent
|
||||
|
||||
internal ContentData ContentData { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int Id => _contentNode.Id;
|
||||
|
||||
@@ -179,11 +189,11 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
get
|
||||
{
|
||||
if (!ContentType.VariesByCulture())
|
||||
return _contentData.Name;
|
||||
return ContentData.Name;
|
||||
|
||||
var culture = VariationContextAccessor?.VariationContext?.Culture ?? "";
|
||||
if (culture == "")
|
||||
return _contentData.Name;
|
||||
return ContentData.Name;
|
||||
|
||||
return Cultures.TryGetValue(culture, out var cultureInfos) ? cultureInfos.Name : null;
|
||||
}
|
||||
@@ -215,7 +225,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
public override string Path => _contentNode.Path;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int? TemplateId => _contentData.TemplateId;
|
||||
public override int? TemplateId => ContentData.TemplateId;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int CreatorId => _contentNode.CreatorId;
|
||||
@@ -227,13 +237,13 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
public override DateTime CreateDate => _contentNode.CreateDate;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override int WriterId => _contentData.WriterId;
|
||||
public override int WriterId => ContentData.WriterId;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string WriterName => GetProfileNameById(_contentData.WriterId);
|
||||
public override string WriterName => GetProfileNameById(ContentData.WriterId);
|
||||
|
||||
/// <inheritdoc />
|
||||
public override DateTime UpdateDate => _contentData.VersionDate;
|
||||
public override DateTime UpdateDate => ContentData.VersionDate;
|
||||
|
||||
private IReadOnlyDictionary<string, PublishedCultureInfo> _cultureInfos;
|
||||
|
||||
@@ -263,9 +273,9 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
|
||||
if (_cultureInfos != null) return _cultureInfos;
|
||||
|
||||
if (_contentData.CultureInfos == null)
|
||||
if (ContentData.CultureInfos == null)
|
||||
throw new Exception("oops: _contentDate.CultureInfos is null.");
|
||||
return _cultureInfos = _contentData.CultureInfos
|
||||
return _cultureInfos = ContentData.CultureInfos
|
||||
.ToDictionary(x => x.Key, x => new PublishedCultureInfo(x.Key, x.Value.Name, x.Value.Date), StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
@@ -273,13 +283,11 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
/// <inheritdoc />
|
||||
public override PublishedItemType ItemType => _contentNode.ContentType.ItemType;
|
||||
|
||||
// fixme
|
||||
// was => _contentData.Published == false;
|
||||
/// <inheritdoc />
|
||||
public override bool IsDraft(string culture = null)
|
||||
{
|
||||
// if this is the 'published' published content, nothing can be draft
|
||||
if (_contentData.Published)
|
||||
if (ContentData.Published)
|
||||
return false;
|
||||
|
||||
// not the 'published' published content, and does not vary = must be draft
|
||||
@@ -292,7 +300,32 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
|
||||
// not the 'published' published content, and varies
|
||||
// = depends on the culture
|
||||
return _contentData.CultureInfos.TryGetValue(culture, out var cvar) && cvar.IsDraft;
|
||||
return ContentData.CultureInfos.TryGetValue(culture, out var cvar) && cvar.IsDraft;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool IsPublished(string culture = null)
|
||||
{
|
||||
// whether we are the 'draft' or 'published' content, need to determine whether
|
||||
// there is a 'published' version for the specified culture (or at all, for
|
||||
// invariant content items)
|
||||
|
||||
// if there is no 'published' published content, no culture can be published
|
||||
var hasPublished = _contentNode.PublishedContent != null;
|
||||
if (!hasPublished)
|
||||
return false;
|
||||
|
||||
// if there is a 'published' published content, and does not vary = published
|
||||
if (!ContentType.VariesByCulture())
|
||||
return true;
|
||||
|
||||
// handle context culture
|
||||
if (culture == null)
|
||||
culture = VariationContextAccessor?.VariationContext?.Culture ?? "";
|
||||
|
||||
// there is a 'published' published content, and varies
|
||||
// = depends on the culture
|
||||
return _contentNode.PublishedContent.ContentData.CultureInfos.ContainsKey(culture);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -328,7 +361,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
return GetChildren();
|
||||
|
||||
// note: ToArray is important here, we want to cache the result, not the function!
|
||||
return (IEnumerable<IPublishedContent>)cache.GetCacheItem(ChildrenCacheKey, () => GetChildren().ToArray());
|
||||
return (IEnumerable<IPublishedContent>)cache.Get(ChildrenCacheKey, () => GetChildren().ToArray());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -355,7 +388,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
|
||||
// notes:
|
||||
// _contentNode.ChildContentIds is an unordered int[]
|
||||
// need needs to fetch & sort - do it only once, lazyily, though
|
||||
// needs to fetch & sort - do it only once, lazily, though
|
||||
// Q: perfs-wise, is it better than having the store managed an ordered list
|
||||
}
|
||||
|
||||
@@ -383,7 +416,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
#region Caching
|
||||
|
||||
// beware what you use that one for - you don't want to cache its result
|
||||
private ICacheProvider GetAppropriateCache()
|
||||
private IAppCache GetAppropriateCache()
|
||||
{
|
||||
var publishedSnapshot = (PublishedSnapshot)_publishedSnapshotAccessor.PublishedSnapshot;
|
||||
var cache = publishedSnapshot == null
|
||||
@@ -394,7 +427,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
return cache;
|
||||
}
|
||||
|
||||
private ICacheProvider GetCurrentSnapshotCache()
|
||||
private IAppCache GetCurrentSnapshotCache()
|
||||
{
|
||||
var publishedSnapshot = (PublishedSnapshot)_publishedSnapshotAccessor.PublishedSnapshot;
|
||||
return publishedSnapshot?.SnapshotCache;
|
||||
@@ -435,8 +468,8 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
return this;
|
||||
|
||||
var cache = GetAppropriateCache();
|
||||
if (cache == null) return new PublishedContent(this).CreateModel();
|
||||
return (IPublishedContent)cache.GetCacheItem(AsPreviewingCacheKey, () => new PublishedContent(this).CreateModel());
|
||||
if (cache == null) return new PublishedContent(this, _umbracoContextAccessor).CreateModel();
|
||||
return (IPublishedContent)cache.Get(AsPreviewingCacheKey, () => new PublishedContent(this, _umbracoContextAccessor).CreateModel());
|
||||
}
|
||||
|
||||
// used by Navigable.Source,...
|
||||
|
||||
@@ -15,13 +15,26 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
{
|
||||
private readonly IMember _member;
|
||||
|
||||
private PublishedMember(IMember member, ContentNode contentNode, ContentData contentData, IPublishedSnapshotAccessor publishedSnapshotAccessor, IVariationContextAccessor variationContextAccessor)
|
||||
: base(contentNode, contentData, publishedSnapshotAccessor, variationContextAccessor)
|
||||
private PublishedMember(
|
||||
IMember member,
|
||||
ContentNode contentNode,
|
||||
ContentData contentData,
|
||||
IPublishedSnapshotAccessor publishedSnapshotAccessor,
|
||||
IVariationContextAccessor variationContextAccessor,
|
||||
IUmbracoContextAccessor umbracoContextAccessor
|
||||
)
|
||||
: base(contentNode, contentData, publishedSnapshotAccessor, variationContextAccessor, umbracoContextAccessor)
|
||||
{
|
||||
_member = member;
|
||||
}
|
||||
|
||||
public static IPublishedContent Create(IMember member, PublishedContentType contentType, bool previewing, IPublishedSnapshotAccessor publishedSnapshotAccessor, IVariationContextAccessor variationContextAccessor)
|
||||
public static IPublishedContent Create(
|
||||
IMember member,
|
||||
PublishedContentType contentType,
|
||||
bool previewing,
|
||||
IPublishedSnapshotAccessor publishedSnapshotAccessor,
|
||||
IVariationContextAccessor variationContextAccessor,
|
||||
IUmbracoContextAccessor umbracoContextAccessor)
|
||||
{
|
||||
var d = new ContentData
|
||||
{
|
||||
@@ -37,7 +50,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
member.Level, member.Path, member.SortOrder,
|
||||
member.ParentId,
|
||||
member.CreateDate, member.CreatorId);
|
||||
return new PublishedMember(member, n, d, publishedSnapshotAccessor, variationContextAccessor).CreateModel();
|
||||
return new PublishedMember(member, n, d, publishedSnapshotAccessor, variationContextAccessor, umbracoContextAccessor).CreateModel();
|
||||
}
|
||||
|
||||
private static Dictionary<string, PropertyData[]> GetPropertyValues(PublishedContentType contentType, IMember member)
|
||||
|
||||
@@ -25,8 +25,8 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
public MediaCache MediaCache;
|
||||
public MemberCache MemberCache;
|
||||
public DomainCache DomainCache;
|
||||
public ICacheProvider SnapshotCache;
|
||||
public ICacheProvider ElementsCache;
|
||||
public IAppCache SnapshotCache;
|
||||
public IAppCache ElementsCache;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
@@ -48,9 +48,9 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
|
||||
#region Caches
|
||||
|
||||
public ICacheProvider SnapshotCache => Elements.SnapshotCache;
|
||||
public IAppCache SnapshotCache => Elements.SnapshotCache;
|
||||
|
||||
public ICacheProvider ElementsCache => Elements.ElementsCache;
|
||||
public IAppCache ElementsCache => Elements.ElementsCache;
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
{
|
||||
private readonly ServiceContext _serviceContext;
|
||||
private readonly IPublishedContentTypeFactory _publishedContentTypeFactory;
|
||||
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
|
||||
private readonly IScopeProvider _scopeProvider;
|
||||
private readonly IDataSource _dataSource;
|
||||
private readonly ILogger _logger;
|
||||
@@ -59,18 +60,18 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
// define constant - determines whether to use cache when previewing
|
||||
// to store eg routes, property converted values, anything - caching
|
||||
// means faster execution, but uses memory - not sure if we want it
|
||||
// so making it configureable.
|
||||
// so making it configurable.
|
||||
public static readonly bool FullCacheWhenPreviewing = true;
|
||||
|
||||
// define constant - determines whether to cache the published content
|
||||
// objects (in the elements cache, or snapshot cache, depending on preview)
|
||||
// or to refetch them all the time. caching is faster but uses more
|
||||
// or to re-fetch them all the time. caching is faster but uses more
|
||||
// memory. not sure what we want.
|
||||
public static readonly bool CachePublishedContentChildren = true;
|
||||
|
||||
// define constant - determines whether to cache the content cache root
|
||||
// objects (in the elements cache, or snapshot cache, depending on preview)
|
||||
// or to refecth them all the time. caching is faster but uses more
|
||||
// or to re-fetch them all the time. caching is faster but uses more
|
||||
// memory - not sure what we want.
|
||||
public static readonly bool CacheContentCacheRoots = true;
|
||||
|
||||
@@ -81,7 +82,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
public PublishedSnapshotService(Options options, IMainDom mainDom, IRuntimeState runtime,
|
||||
ServiceContext serviceContext, IPublishedContentTypeFactory publishedContentTypeFactory, IdkMap idkMap,
|
||||
IPublishedSnapshotAccessor publishedSnapshotAccessor, IVariationContextAccessor variationContextAccessor,
|
||||
ILogger logger, IScopeProvider scopeProvider,
|
||||
IUmbracoContextAccessor umbracoContextAccessor, ILogger logger, IScopeProvider scopeProvider,
|
||||
IDocumentRepository documentRepository, IMediaRepository mediaRepository, IMemberRepository memberRepository,
|
||||
IDefaultCultureAccessor defaultCultureAccessor,
|
||||
IDataSource dataSource, IGlobalSettings globalSettings, ISiteDomainHelper siteDomainHelper, IContentTypeService contentTypeService,
|
||||
@@ -89,10 +90,11 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
: base(publishedSnapshotAccessor, variationContextAccessor)
|
||||
{
|
||||
//if (Interlocked.Increment(ref _singletonCheck) > 1)
|
||||
// throw new Exception("Singleton must be instancianted only once!");
|
||||
// throw new Exception("Singleton must be instantiated only once!");
|
||||
|
||||
_serviceContext = serviceContext;
|
||||
_publishedContentTypeFactory = publishedContentTypeFactory;
|
||||
_umbracoContextAccessor = umbracoContextAccessor;
|
||||
_dataSource = dataSource;
|
||||
_logger = logger;
|
||||
_scopeProvider = scopeProvider;
|
||||
@@ -142,21 +144,21 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
var localMediaDbPath = IOHelper.MapPath("~/App_Data/NuCache.Media.db");
|
||||
_localDbExists = System.IO.File.Exists(localContentDbPath) && System.IO.File.Exists(localMediaDbPath);
|
||||
|
||||
// if both local dbs exist then GetTree will open them, else new dbs will be created
|
||||
// if both local databases exist then GetTree will open them, else new databases will be created
|
||||
_localContentDb = BTree.GetTree(localContentDbPath, _localDbExists);
|
||||
_localMediaDb = BTree.GetTree(localMediaDbPath, _localDbExists);
|
||||
}
|
||||
|
||||
// stores are created with a db so they can write to it, but they do not read from it,
|
||||
// stores need to be populated, happens in OnResolutionFrozen which uses _localDbExists to
|
||||
// figure out whether it can read the dbs or it should populate them from sql
|
||||
_contentStore = new ContentStore(publishedSnapshotAccessor, variationContextAccessor, logger, _localContentDb);
|
||||
_mediaStore = new ContentStore(publishedSnapshotAccessor, variationContextAccessor, logger, _localMediaDb);
|
||||
// figure out whether it can read the databases or it should populate them from sql
|
||||
_contentStore = new ContentStore(publishedSnapshotAccessor, variationContextAccessor, _umbracoContextAccessor, logger, _localContentDb);
|
||||
_mediaStore = new ContentStore(publishedSnapshotAccessor, variationContextAccessor, _umbracoContextAccessor, logger, _localMediaDb);
|
||||
}
|
||||
else
|
||||
{
|
||||
_contentStore = new ContentStore(publishedSnapshotAccessor, variationContextAccessor, logger);
|
||||
_mediaStore = new ContentStore(publishedSnapshotAccessor, variationContextAccessor, logger);
|
||||
_contentStore = new ContentStore(publishedSnapshotAccessor, variationContextAccessor, _umbracoContextAccessor, logger);
|
||||
_mediaStore = new ContentStore(publishedSnapshotAccessor, variationContextAccessor, _umbracoContextAccessor, logger);
|
||||
}
|
||||
|
||||
_domainStore = new SnapDictionary<int, Domain>();
|
||||
@@ -196,14 +198,14 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
_logger.Fatal<PublishedSnapshotService>(ex, "Panic, exception while loading cache data.");
|
||||
}
|
||||
|
||||
// finaly, cache is ready!
|
||||
// finally, cache is ready!
|
||||
_isReady = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void InitializeRepositoryEvents()
|
||||
{
|
||||
//fixme: The reason these events are in the repository is for legacy, the events should exist at the service
|
||||
// TODO: The reason these events are in the repository is for legacy, the events should exist at the service
|
||||
// level now since we can fire these events within the transaction... so move the events to service level
|
||||
|
||||
// plug repository event handlers
|
||||
@@ -255,7 +257,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
//
|
||||
//// indicates that the snapshot cache should reuse the application request cache
|
||||
//// otherwise a new cache object would be created for the snapshot specifically,
|
||||
//// which is the default - web boot manager uses this to optimze facades
|
||||
//// which is the default - web boot manager uses this to optimize facades
|
||||
//public bool PublishedSnapshotCacheIsApplicationRequestCache;
|
||||
|
||||
public bool IgnoreLocalDb;
|
||||
@@ -586,7 +588,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
continue;
|
||||
}
|
||||
|
||||
// fixme - should we do some RV check here? (later)
|
||||
// TODO: should we do some RV check here? (later)
|
||||
|
||||
var capture = payload;
|
||||
using (var scope = _scopeProvider.CreateScope())
|
||||
@@ -676,7 +678,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
continue;
|
||||
}
|
||||
|
||||
// fixme - should we do some RV checks here? (later)
|
||||
// TODO: should we do some RV checks here? (later)
|
||||
|
||||
var capture = payload;
|
||||
using (var scope = _scopeProvider.CreateScope())
|
||||
@@ -775,7 +777,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
using (_contentStore.GetWriter(_scopeProvider))
|
||||
using (_mediaStore.GetWriter(_scopeProvider))
|
||||
{
|
||||
// fixme - need to add a datatype lock
|
||||
// TODO: need to add a datatype lock
|
||||
// this is triggering datatypes reload in the factory, and right after we create some
|
||||
// content types by loading them ... there's a race condition here, which would require
|
||||
// some locking on datatypes
|
||||
@@ -934,7 +936,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
#region Create, Get Published Snapshot
|
||||
|
||||
private long _contentGen, _mediaGen, _domainGen;
|
||||
private ICacheProvider _elementsCache;
|
||||
private IAppCache _elementsCache;
|
||||
|
||||
public override IPublishedSnapshot CreatePublishedSnapshot(string previewToken)
|
||||
{
|
||||
@@ -951,18 +953,19 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
// even though the underlying elements may not change (store snapshots)
|
||||
public PublishedSnapshot.PublishedSnapshotElements GetElements(bool previewDefault)
|
||||
{
|
||||
// note: using ObjectCacheRuntimeCacheProvider for elements and snapshot caches
|
||||
// note: using ObjectCacheAppCache for elements and snapshot caches
|
||||
// is not recommended because it creates an inner MemoryCache which is a heavy
|
||||
// thing - better use a StaticCacheProvider which "just" creates a concurrent
|
||||
// thing - better use a dictionary-based cache which "just" creates a concurrent
|
||||
// dictionary
|
||||
|
||||
// for snapshot cache, StaticCacheProvider MAY be OK but it is not thread-safe,
|
||||
// for snapshot cache, DictionaryAppCache MAY be OK but it is not thread-safe,
|
||||
// nothing like that...
|
||||
// for elements cache, StaticCacheProvider is a No-No, use something better.
|
||||
// for elements cache, DictionaryAppCache is a No-No, use something better.
|
||||
// ie FastDictionaryAppCache (thread safe and all)
|
||||
|
||||
ContentStore.Snapshot contentSnap, mediaSnap;
|
||||
SnapDictionary<int, Domain>.Snapshot domainSnap;
|
||||
ICacheProvider elementsCache;
|
||||
IAppCache elementsCache;
|
||||
lock (_storesLock)
|
||||
{
|
||||
var scopeContext = _scopeProvider.Context;
|
||||
@@ -1000,11 +1003,11 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
_contentGen = contentSnap.Gen;
|
||||
_mediaGen = mediaSnap.Gen;
|
||||
_domainGen = domainSnap.Gen;
|
||||
elementsCache = _elementsCache = new DictionaryCacheProvider();
|
||||
elementsCache = _elementsCache = new FastDictionaryAppCache();
|
||||
}
|
||||
}
|
||||
|
||||
var snapshotCache = new StaticCacheProvider();
|
||||
var snapshotCache = new DictionaryAppCache();
|
||||
|
||||
var memberTypeCache = new PublishedContentTypeCache(null, null, _serviceContext.MemberTypeService, _publishedContentTypeFactory, _logger);
|
||||
|
||||
@@ -1016,7 +1019,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
{
|
||||
ContentCache = new ContentCache(previewDefault, contentSnap, snapshotCache, elementsCache, domainHelper, _globalSettings, _serviceContext.LocalizationService),
|
||||
MediaCache = new MediaCache(previewDefault, mediaSnap, snapshotCache, elementsCache),
|
||||
MemberCache = new MemberCache(previewDefault, snapshotCache, _serviceContext.MemberService, memberTypeCache, PublishedSnapshotAccessor, VariationContextAccessor, _entitySerializer),
|
||||
MemberCache = new MemberCache(previewDefault, snapshotCache, _serviceContext.MemberService, memberTypeCache, PublishedSnapshotAccessor, VariationContextAccessor, _umbracoContextAccessor, _entitySerializer),
|
||||
DomainCache = domainCache,
|
||||
SnapshotCache = snapshotCache,
|
||||
ElementsCache = elementsCache
|
||||
|
||||
@@ -30,7 +30,6 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
private Task _collectTask;
|
||||
private volatile int _wlocked;
|
||||
|
||||
// fixme - collection trigger (ok for now)
|
||||
// minGenDelta to be adjusted
|
||||
// we may want to throttle collects even if delta is reached
|
||||
// we may want to force collect if delta is not reached but very old
|
||||
@@ -59,7 +58,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
//
|
||||
// so when getting a read-lock,
|
||||
// either we are write-locked or not, but if not, we won't be write-locked
|
||||
// otoh the write-lock may be released in the meantime
|
||||
// on the other hand the write-lock may be released in the meantime
|
||||
|
||||
// Lock has a 'forceGen' parameter:
|
||||
// used to start a set of changes that may not commit, to isolate the set from any pending
|
||||
@@ -107,7 +106,7 @@ namespace Umbraco.Web.PublishedCache.NuCache
|
||||
}
|
||||
|
||||
// gets a scope contextual representing a locked writer to the dictionary
|
||||
// fixme GetScopedWriter? should the dict have a ref onto the scope provider?
|
||||
// GetScopedWriter? should the dict have a ref onto the scope provider?
|
||||
public IDisposable GetWriter(IScopeProvider scopeProvider)
|
||||
{
|
||||
return ScopeContextualBase.Get(scopeProvider, _instanceId, scoped => new SnapDictionaryWriter(this, scoped));
|
||||
|
||||
Reference in New Issue
Block a user