Ensures the xml cache is distributed properly including variants as well as Examine updating correctly.
This commit is contained in:
@@ -19,7 +19,10 @@ namespace Umbraco.Core.Models.ContentVariations
|
||||
|
||||
public VariantInfo(params int[] variantIds)
|
||||
{
|
||||
VariantIds = variantIds;
|
||||
VariantIds = variantIds.Any()
|
||||
? variantIds
|
||||
: new int[] {};
|
||||
|
||||
IsVariant = false;
|
||||
}
|
||||
|
||||
@@ -28,6 +31,7 @@ namespace Umbraco.Core.Models.ContentVariations
|
||||
IsVariant = true;
|
||||
MasterDocId = masterDocId;
|
||||
Key = key;
|
||||
VariantIds = new int[] { };
|
||||
}
|
||||
|
||||
public int[] VariantIds { get; set; }
|
||||
|
||||
@@ -266,6 +266,7 @@ namespace Umbraco.Web.Cache
|
||||
// newly published ones will be synced with the published page cache refresher
|
||||
var unpublished = e.SavedEntities.Where(x => x.JustPublished() == false).ToArray();
|
||||
var ids = unpublished.Select(x => x.Id).ToList();
|
||||
//ensure the variants are refreshed too
|
||||
ids.AddRange(unpublished.SelectMany(x => x.VariantInfo.VariantIds));
|
||||
ids.AddRange(unpublished.Select(x => x.VariantInfo.MasterDocId));
|
||||
|
||||
|
||||
@@ -206,46 +206,28 @@ namespace Umbraco.Web.Cache
|
||||
dc.RefreshAll(new Guid(DistributedCache.PageCacheRefresherId));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Refreshes the cache amongst servers for a page
|
||||
/// </summary>
|
||||
/// <param name="dc"></param>
|
||||
/// <param name="documentId"></param>
|
||||
public static void RefreshPageCache(this DistributedCache dc, int documentId)
|
||||
{
|
||||
dc.Refresh(new Guid(DistributedCache.PageCacheRefresherId), documentId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Refreshes page cache for all instances passed in
|
||||
/// </summary>
|
||||
/// <param name="dc"></param>
|
||||
/// <param name="content"></param>
|
||||
public static void RefreshPageCache(this DistributedCache dc, params IContent[] content)
|
||||
/// <param name="contentIds"></param>
|
||||
public static void RefreshPageCache(this DistributedCache dc, params int[] contentIds)
|
||||
{
|
||||
dc.Refresh(new Guid(DistributedCache.PageCacheRefresherId), x => x.Id, content);
|
||||
dc.RefreshByJson(new Guid(DistributedCache.PageCacheRefresherId),
|
||||
PageCacheRefresher.SerializeToJsonPayload(PageCacheRefresher.OperationType.Saved, contentIds));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the cache amongst servers for a page
|
||||
/// </summary>
|
||||
/// <param name="dc"></param>
|
||||
/// <param name="content"></param>
|
||||
public static void RemovePageCache(this DistributedCache dc, params IContent[] content)
|
||||
/// <param name="contentIds"></param>
|
||||
public static void RemovePageCache(this DistributedCache dc, params int[] contentIds)
|
||||
{
|
||||
dc.Remove(new Guid(DistributedCache.PageCacheRefresherId), x => x.Id, content);
|
||||
dc.RefreshByJson(new Guid(DistributedCache.PageCacheRefresherId),
|
||||
PageCacheRefresher.SerializeToJsonPayload(PageCacheRefresher.OperationType.Deleted, contentIds));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the cache amongst servers for a page
|
||||
/// </summary>
|
||||
/// <param name="dc"></param>
|
||||
/// <param name="documentId"></param>
|
||||
public static void RemovePageCache(this DistributedCache dc, int documentId)
|
||||
{
|
||||
dc.Remove(new Guid(DistributedCache.PageCacheRefresherId), documentId);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// invokes the unpublished page cache refresher
|
||||
/// </summary>
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
using System;
|
||||
using System.Web.Script.Serialization;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Sync;
|
||||
using umbraco;
|
||||
using umbraco.cms.businesslogic.web;
|
||||
using System.Linq;
|
||||
|
||||
namespace Umbraco.Web.Cache
|
||||
{
|
||||
@@ -15,7 +17,7 @@ namespace Umbraco.Web.Cache
|
||||
/// If Load balancing is enabled (by default disabled, is set in umbracoSettings.config) PageCacheRefresher will be called
|
||||
/// everytime content is added/updated/removed to ensure that the content cache is identical on all load balanced servers
|
||||
/// </remarks>
|
||||
public class PageCacheRefresher : TypedCacheRefresherBase<PageCacheRefresher, IContent>
|
||||
public class PageCacheRefresher : JsonCacheRefresherBase<PageCacheRefresher>
|
||||
{
|
||||
|
||||
protected override PageCacheRefresher Instance
|
||||
@@ -44,6 +46,51 @@ namespace Umbraco.Web.Cache
|
||||
get { return "Page Refresher"; }
|
||||
}
|
||||
|
||||
#region Static helpers
|
||||
|
||||
/// <summary>
|
||||
/// Converts the json to a JsonPayload object
|
||||
/// </summary>
|
||||
/// <param name="json"></param>
|
||||
/// <returns></returns>
|
||||
internal static JsonPayload[] DeserializeFromJsonPayload(string json)
|
||||
{
|
||||
var serializer = new JavaScriptSerializer();
|
||||
var jsonObject = serializer.Deserialize<JsonPayload[]>(json);
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
|
||||
internal static string SerializeToJsonPayload(OperationType op, params int[] contentIds)
|
||||
{
|
||||
var serializer = new JavaScriptSerializer();
|
||||
var items = contentIds.Select(x => new JsonPayload
|
||||
{
|
||||
Id = x,
|
||||
Operation = op
|
||||
}).ToArray();
|
||||
var json = serializer.Serialize(items);
|
||||
return json;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Sub classes
|
||||
|
||||
internal enum OperationType
|
||||
{
|
||||
Deleted,
|
||||
Saved
|
||||
}
|
||||
|
||||
internal class JsonPayload
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public OperationType Operation { get; set; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Refreshes all nodes in umbraco.
|
||||
/// </summary>
|
||||
@@ -79,22 +126,34 @@ namespace Umbraco.Web.Cache
|
||||
base.Remove(id);
|
||||
}
|
||||
|
||||
public override void Refresh(IContent instance)
|
||||
/// <summary>
|
||||
/// Implement the IJsonCacheRefresher so that we can bulk delete/refresh the cache based on multiple IDs
|
||||
/// </summary>
|
||||
/// <param name="jsonPayload"></param>
|
||||
public override void Refresh(string jsonPayload)
|
||||
{
|
||||
ApplicationContext.Current.ApplicationCache.ClearPartialViewCache();
|
||||
content.Instance.UpdateDocumentCache(new Document(instance));
|
||||
DistributedCache.Instance.ClearAllMacroCacheOnCurrentServer();
|
||||
DistributedCache.Instance.ClearXsltCacheOnCurrentServer();
|
||||
base.Refresh(instance);
|
||||
}
|
||||
var payloads = DeserializeFromJsonPayload(jsonPayload);
|
||||
|
||||
if (payloads.Any() == false) return;
|
||||
|
||||
public override void Remove(IContent instance)
|
||||
{
|
||||
ApplicationContext.Current.ApplicationCache.ClearPartialViewCache();
|
||||
content.Instance.ClearDocumentCache(new Document(instance));
|
||||
DistributedCache.Instance.ClearAllMacroCacheOnCurrentServer();
|
||||
DistributedCache.Instance.ClearXsltCacheOnCurrentServer();
|
||||
base.Remove(instance);
|
||||
|
||||
foreach (var payload in payloads)
|
||||
{
|
||||
switch (payload.Operation)
|
||||
{
|
||||
case OperationType.Deleted:
|
||||
content.Instance.ClearDocumentCache(payload.Id);
|
||||
break;
|
||||
case OperationType.Saved:
|
||||
content.Instance.UpdateDocumentCache(payload.Id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
base.Refresh(jsonPayload);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Umbraco.Web.Cache
|
||||
/// <summary>
|
||||
/// A cache refresher used for non-published content, this is primarily to notify Examine indexes to update and to refresh the RuntimeCacheRefresher
|
||||
/// </summary>
|
||||
public sealed class UnpublishedPageCacheRefresher : CacheRefresherBase<UnpublishedPageCacheRefresher>, IJsonCacheRefresher
|
||||
public sealed class UnpublishedPageCacheRefresher : JsonCacheRefresherBase<UnpublishedPageCacheRefresher>
|
||||
{
|
||||
protected override UnpublishedPageCacheRefresher Instance
|
||||
{
|
||||
@@ -95,14 +95,14 @@ namespace Umbraco.Web.Cache
|
||||
/// Implement the IJsonCacheRefresher so that we can bulk delete/refresh the cache based on multiple IDs
|
||||
/// </summary>
|
||||
/// <param name="jsonPayload"></param>
|
||||
public void Refresh(string jsonPayload)
|
||||
public override void Refresh(string jsonPayload)
|
||||
{
|
||||
foreach (var payload in DeserializeFromJsonPayload(jsonPayload))
|
||||
{
|
||||
RuntimeCacheProvider.Current.Delete(typeof(IContent), payload.Id);
|
||||
}
|
||||
|
||||
OnCacheUpdated(Instance, new CacheRefresherEventArgs(jsonPayload, MessageType.RefreshByJson));
|
||||
base.Refresh(jsonPayload);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -475,25 +475,21 @@ namespace Umbraco.Web.PublishedCache.XmlPublishedCache
|
||||
//determine which child to add based on the current VariantInfo
|
||||
if (_variantInfo.IsVariant)
|
||||
{
|
||||
//get the master, then children
|
||||
if (xmlChild.ParentNode != null)
|
||||
{
|
||||
//TODO: There's probably a faster way with the old xml api to do this
|
||||
|
||||
//find a variant of the current child for the current variant key
|
||||
var variant = xmlChild.ParentNode.ChildNodes.OfType<XmlElement>()
|
||||
.FirstOrDefault(x =>
|
||||
//find all
|
||||
x.AttributeValue<int>("masterDocId") == xmlChild.AttributeValue<int>("id")
|
||||
&& xmlChild.AttributeValue<string>("variantKey") == _variantInfo.Key);
|
||||
//TODO: There's probably a faster way with the old xml api to do this
|
||||
|
||||
if (variant != null)
|
||||
{
|
||||
//we found a variant!
|
||||
_children.Add(
|
||||
(new XmlPublishedContent(variant, _isPreviewing, true, _variantInfo)).CreateModel());
|
||||
useVariant = true;
|
||||
}
|
||||
//find a variant of the current child for the current variant key
|
||||
var variant = workingNode.ChildNodes.OfType<XmlElement>()
|
||||
.FirstOrDefault(x =>
|
||||
//find all
|
||||
x.AttributeValue<int>("masterDocId") == xmlChild.AttributeValue<int>("id")
|
||||
&& x.AttributeValue<string>("variantKey") == _variantInfo.Key);
|
||||
|
||||
if (variant != null)
|
||||
{
|
||||
//we found a variant!
|
||||
_children.Add(
|
||||
(new XmlPublishedContent(variant, _isPreviewing, true, _variantInfo)).CreateModel());
|
||||
useVariant = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -342,10 +342,14 @@ namespace Umbraco.Web.Search
|
||||
DeleteIndexForEntity(payload.Id, false);
|
||||
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
}
|
||||
case UnpublishedPageCacheRefresher.OperationType.Saved:
|
||||
|
||||
var c5 = ApplicationContext.Current.Services.ContentService.GetById(payload.Id);
|
||||
ReIndexForContent(c5, false);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
@@ -62,7 +62,13 @@ namespace Umbraco.Web.Strategies.Publishing
|
||||
/// </summary>
|
||||
private void UpdateMultipleContentCache(IEnumerable<IContent> content)
|
||||
{
|
||||
DistributedCache.Instance.RefreshPageCache(content.ToArray());
|
||||
var asArray = content.ToArray();
|
||||
var ids = asArray.Select(x => x.Id).ToList();
|
||||
//ensure the variants are refreshed too
|
||||
ids.AddRange(asArray.SelectMany(x => x.VariantInfo.VariantIds));
|
||||
ids.AddRange(asArray.Select(x => x.VariantInfo.MasterDocId));
|
||||
|
||||
DistributedCache.Instance.RefreshPageCache(ids.ToArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -70,7 +76,11 @@ namespace Umbraco.Web.Strategies.Publishing
|
||||
/// </summary>
|
||||
private void UpdateSingleContentCache(IContent content)
|
||||
{
|
||||
DistributedCache.Instance.RefreshPageCache(content);
|
||||
var ids = new List<int> {content.Id};
|
||||
//ensure the variants are refreshed too
|
||||
ids.AddRange(content.VariantInfo.VariantIds);
|
||||
ids.Add(content.VariantInfo.MasterDocId);
|
||||
DistributedCache.Instance.RefreshPageCache(ids.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Configuration;
|
||||
@@ -53,7 +54,12 @@ namespace Umbraco.Web.Strategies.Publishing
|
||||
/// </summary>
|
||||
private void UnPublishSingle(IContent content)
|
||||
{
|
||||
DistributedCache.Instance.RemovePageCache(content);
|
||||
var ids = new List<int> { content.Id };
|
||||
//ensure the variants are refreshed too
|
||||
ids.AddRange(content.VariantInfo.VariantIds);
|
||||
ids.Add(content.VariantInfo.MasterDocId);
|
||||
|
||||
DistributedCache.Instance.RemovePageCache(ids.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user