Created strongly typed ICacheRefresher<T> so that now we can have cache refreshers execute against a
real instance object like IContent, this will dramatically increase performance for bulk publishing when not in a load balanced environment. Updated methods on DistributedCache to refresh many instances at one time, this also means we're not re-looking it back up again. Need to update media, users, templates, members and macros to use this new feature too.
This commit is contained in:
@@ -4,6 +4,7 @@ using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Threading;
|
||||
using System.Web.Script.Serialization;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Logging;
|
||||
using umbraco.interfaces;
|
||||
@@ -44,7 +45,12 @@ namespace Umbraco.Core.Sync
|
||||
if (servers == null) throw new ArgumentNullException("servers");
|
||||
if (refresher == null) throw new ArgumentNullException("refresher");
|
||||
|
||||
instances.ForEach(x => InvokeDispatchMethod(servers, refresher, MessageType.RefreshById, getNumericId(x)));
|
||||
//copy local
|
||||
var idGetter = getNumericId;
|
||||
|
||||
MessageSeversForManyObjects(servers, refresher, MessageType.RefreshById,
|
||||
x => idGetter(x),
|
||||
instances);
|
||||
}
|
||||
|
||||
public void PerformRefresh<T>(IEnumerable<IServerRegistration> servers, ICacheRefresher refresher, Func<T, Guid> getGuidId, params T[] instances)
|
||||
@@ -52,7 +58,12 @@ namespace Umbraco.Core.Sync
|
||||
if (servers == null) throw new ArgumentNullException("servers");
|
||||
if (refresher == null) throw new ArgumentNullException("refresher");
|
||||
|
||||
instances.ForEach(x => InvokeDispatchMethod(servers, refresher, MessageType.RefreshById, getGuidId(x)));
|
||||
//copy local
|
||||
var idGetter = getGuidId;
|
||||
|
||||
MessageSeversForManyObjects(servers, refresher, MessageType.RefreshById,
|
||||
x => idGetter(x),
|
||||
instances);
|
||||
}
|
||||
|
||||
public void PerformRemove<T>(IEnumerable<IServerRegistration> servers, ICacheRefresher refresher, Func<T, int> getNumericId, params T[] instances)
|
||||
@@ -60,7 +71,12 @@ namespace Umbraco.Core.Sync
|
||||
if (servers == null) throw new ArgumentNullException("servers");
|
||||
if (refresher == null) throw new ArgumentNullException("refresher");
|
||||
|
||||
instances.ForEach(x => InvokeDispatchMethod(servers, refresher, MessageType.RemoveById, getNumericId(x)));
|
||||
//copy local
|
||||
var idGetter = getNumericId;
|
||||
|
||||
MessageSeversForManyObjects(servers, refresher, MessageType.RemoveById,
|
||||
x => idGetter(x),
|
||||
instances);
|
||||
}
|
||||
|
||||
public void PerformRemove(IEnumerable<IServerRegistration> servers, ICacheRefresher refresher, params int[] numericIds)
|
||||
@@ -68,7 +84,7 @@ namespace Umbraco.Core.Sync
|
||||
if (servers == null) throw new ArgumentNullException("servers");
|
||||
if (refresher == null) throw new ArgumentNullException("refresher");
|
||||
|
||||
numericIds.ForEach(x => InvokeDispatchMethod(servers, refresher, MessageType.RemoveById, x));
|
||||
MessageSeversForManyIds(servers, refresher, MessageType.RemoveById, numericIds.Cast<object>());
|
||||
}
|
||||
|
||||
public void PerformRefresh(IEnumerable<IServerRegistration> servers, ICacheRefresher refresher, params int[] numericIds)
|
||||
@@ -76,7 +92,7 @@ namespace Umbraco.Core.Sync
|
||||
if (servers == null) throw new ArgumentNullException("servers");
|
||||
if (refresher == null) throw new ArgumentNullException("refresher");
|
||||
|
||||
numericIds.ForEach(x => InvokeDispatchMethod(servers, refresher, MessageType.RefreshById, x));
|
||||
MessageSeversForManyIds(servers, refresher, MessageType.RefreshById, numericIds.Cast<object>());
|
||||
}
|
||||
|
||||
public void PerformRefresh(IEnumerable<IServerRegistration> servers, ICacheRefresher refresher, params Guid[] guidIds)
|
||||
@@ -84,62 +100,155 @@ namespace Umbraco.Core.Sync
|
||||
if (servers == null) throw new ArgumentNullException("servers");
|
||||
if (refresher == null) throw new ArgumentNullException("refresher");
|
||||
|
||||
guidIds.ForEach(x => InvokeDispatchMethod(servers, refresher, MessageType.RefreshById, x));
|
||||
|
||||
MessageSeversForManyIds(servers, refresher, MessageType.RefreshById, guidIds.Cast<object>());
|
||||
}
|
||||
|
||||
public void PerformRefreshAll(IEnumerable<IServerRegistration> servers, ICacheRefresher refresher)
|
||||
{
|
||||
InvokeDispatchMethod(servers, refresher, MessageType.RefreshAll, null);
|
||||
MessageSeversForManyIds(servers, refresher, MessageType.RefreshAll, Enumerable.Empty<object>().ToArray());
|
||||
}
|
||||
|
||||
private void InvokeMethodOnRefresherInstance(ICacheRefresher refresher, MessageType dispatchType, object id)
|
||||
private void InvokeMethodOnRefresherInstance<T>(ICacheRefresher refresher, MessageType dispatchType, Func<T, object> getId, IEnumerable<T> instances)
|
||||
{
|
||||
if (refresher == null) throw new ArgumentNullException("refresher");
|
||||
|
||||
//if we are not, then just invoke the call on the cache refresher
|
||||
switch (dispatchType)
|
||||
var stronglyTypedRefresher = refresher as ICacheRefresher<T>;
|
||||
|
||||
foreach (var instance in instances)
|
||||
{
|
||||
case MessageType.RefreshAll:
|
||||
refresher.RefreshAll();
|
||||
break;
|
||||
case MessageType.RefreshById:
|
||||
if (id is int)
|
||||
{
|
||||
refresher.Refresh((int)id);
|
||||
}
|
||||
else if (id is Guid)
|
||||
{
|
||||
refresher.Refresh((Guid) id);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException("The id must be either an int or a Guid");
|
||||
}
|
||||
|
||||
break;
|
||||
case MessageType.RemoveById:
|
||||
refresher.Remove((int)id);
|
||||
break;
|
||||
//if we are not, then just invoke the call on the cache refresher
|
||||
switch (dispatchType)
|
||||
{
|
||||
case MessageType.RefreshAll:
|
||||
refresher.RefreshAll();
|
||||
break;
|
||||
case MessageType.RefreshById:
|
||||
if (stronglyTypedRefresher != null)
|
||||
{
|
||||
stronglyTypedRefresher.Refresh(instance);
|
||||
}
|
||||
else
|
||||
{
|
||||
var id = getId(instance);
|
||||
if (id is int)
|
||||
{
|
||||
refresher.Refresh((int)id);
|
||||
}
|
||||
else if (id is Guid)
|
||||
{
|
||||
refresher.Refresh((Guid)id);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException("The id must be either an int or a Guid");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MessageType.RemoveById:
|
||||
if (stronglyTypedRefresher != null)
|
||||
{
|
||||
stronglyTypedRefresher.Remove(instance);
|
||||
}
|
||||
else
|
||||
{
|
||||
var id = getId(instance);
|
||||
refresher.Refresh((int)id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void InvokeDispatchMethod(
|
||||
IEnumerable<IServerRegistration> servers,
|
||||
ICacheRefresher refresher,
|
||||
MessageType dispatchType,
|
||||
object id)
|
||||
private void InvokeMethodOnRefresherInstance(ICacheRefresher refresher, MessageType dispatchType, IEnumerable<object> ids)
|
||||
{
|
||||
if (refresher == null) throw new ArgumentNullException("refresher");
|
||||
|
||||
//if it is a refresh all we'll do it here since ids will be null or empty
|
||||
if (dispatchType == MessageType.RefreshAll)
|
||||
{
|
||||
refresher.RefreshAll();
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var id in ids)
|
||||
{
|
||||
//if we are not, then just invoke the call on the cache refresher
|
||||
switch (dispatchType)
|
||||
{
|
||||
case MessageType.RefreshById:
|
||||
if (id is int)
|
||||
{
|
||||
refresher.Refresh((int)id);
|
||||
}
|
||||
else if (id is Guid)
|
||||
{
|
||||
refresher.Refresh((Guid)id);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException("The id must be either an int or a Guid");
|
||||
}
|
||||
|
||||
break;
|
||||
case MessageType.RemoveById:
|
||||
refresher.Remove((int)id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void MessageSeversForManyObjects<T>(
|
||||
IEnumerable<IServerRegistration> servers,
|
||||
ICacheRefresher refresher,
|
||||
MessageType dispatchType,
|
||||
Func<T, object> getId,
|
||||
IEnumerable<T> instances)
|
||||
{
|
||||
if (servers == null) throw new ArgumentNullException("servers");
|
||||
if (refresher == null) throw new ArgumentNullException("refresher");
|
||||
if (!(id is int) && (!(id is Guid))) throw new ArgumentException("The id must be either an int or a Guid");
|
||||
|
||||
//Now, check if we are using Distrubuted calls. If there are no servers in the list then we
|
||||
// can definitely not distribute.
|
||||
if (!_useDistributedCalls || !servers.Any())
|
||||
{
|
||||
//if we are not, then just invoke the call on the cache refresher
|
||||
InvokeMethodOnRefresherInstance(refresher, dispatchType, id);
|
||||
InvokeMethodOnRefresherInstance(refresher, dispatchType, getId, instances);
|
||||
return;
|
||||
}
|
||||
|
||||
//if we are distributing calls then we'll need to do it by id
|
||||
MessageSeversForManyIds(servers, refresher, dispatchType, instances.Select(getId));
|
||||
}
|
||||
|
||||
private void MessageSeversForManyIds(
|
||||
IEnumerable<IServerRegistration> servers,
|
||||
ICacheRefresher refresher,
|
||||
MessageType dispatchType,
|
||||
IEnumerable<object> ids)
|
||||
{
|
||||
if (servers == null) throw new ArgumentNullException("servers");
|
||||
if (refresher == null) throw new ArgumentNullException("refresher");
|
||||
Type arrayType = null;
|
||||
foreach (var id in ids)
|
||||
{
|
||||
if (!(id is int) && (!(id is Guid)))
|
||||
throw new ArgumentException("The id must be either an int or a Guid");
|
||||
if (arrayType == null)
|
||||
arrayType = id.GetType();
|
||||
if (arrayType != id.GetType())
|
||||
throw new ArgumentException("The array must contain the same type of " + arrayType);
|
||||
}
|
||||
|
||||
//Now, check if we are using Distrubuted calls. If there are no servers in the list then we
|
||||
// can definitely not distribute.
|
||||
if (!_useDistributedCalls || !servers.Any())
|
||||
{
|
||||
//if we are not, then just invoke the call on the cache refresher
|
||||
InvokeMethodOnRefresherInstance(refresher, dispatchType, ids);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -152,9 +261,8 @@ namespace Umbraco.Core.Sync
|
||||
|
||||
LogStartDispatch();
|
||||
|
||||
var nodes = servers;
|
||||
// Go through each configured node submitting a request asynchronously
|
||||
foreach (var n in nodes)
|
||||
foreach (var n in servers)
|
||||
{
|
||||
//set the server address
|
||||
cacheRefresher.Url = n.ServerAddress;
|
||||
@@ -168,21 +276,29 @@ namespace Umbraco.Core.Sync
|
||||
refresher.UniqueIdentifier, _login, _password, null, null));
|
||||
break;
|
||||
case MessageType.RefreshById:
|
||||
IAsyncResult result;
|
||||
if (id is int)
|
||||
if (arrayType == typeof(int))
|
||||
{
|
||||
result = cacheRefresher.BeginRefreshById(refresher.UniqueIdentifier, (int) id, _login, _password, null, null);
|
||||
var serializer = new JavaScriptSerializer();
|
||||
var jsonIds = serializer.Serialize(ids.Cast<int>().ToArray());
|
||||
//we support bulk loading of Integers
|
||||
var result = cacheRefresher.BeginRefreshByIds(refresher.UniqueIdentifier, jsonIds, _login, _password, null, null);
|
||||
asyncResultsList.Add(result);
|
||||
}
|
||||
else
|
||||
{
|
||||
result = cacheRefresher.BeginRefreshByGuid(refresher.UniqueIdentifier, (Guid)id, _login, _password, null, null);
|
||||
//we don't currently support bulk loading of GUIDs (not even sure if we have any Guid ICacheRefreshers)
|
||||
//so we'll just iterate
|
||||
asyncResultsList.AddRange(
|
||||
ids.Select(i => cacheRefresher.BeginRefreshByGuid(
|
||||
refresher.UniqueIdentifier, (Guid) i, _login, _password, null, null)));
|
||||
}
|
||||
asyncResultsList.Add(result);
|
||||
break;
|
||||
|
||||
break;
|
||||
case MessageType.RemoveById:
|
||||
asyncResultsList.Add(
|
||||
cacheRefresher.BeginRemoveById(
|
||||
refresher.UniqueIdentifier, (int)id, _login, _password, null, null));
|
||||
//we don't currently support bulk removing so we'll iterate
|
||||
asyncResultsList.AddRange(
|
||||
ids.Select(i => cacheRefresher.BeginRemoveById(
|
||||
refresher.UniqueIdentifier, (int)i, _login, _password, null, null)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -207,7 +323,7 @@ namespace Umbraco.Core.Sync
|
||||
cacheRefresher.EndRefreshAll(t);
|
||||
break;
|
||||
case MessageType.RefreshById:
|
||||
if (id is int)
|
||||
if (arrayType == typeof(int))
|
||||
{
|
||||
cacheRefresher.EndRefreshById(t);
|
||||
}
|
||||
|
||||
18
src/Umbraco.Core/Sync/ICacheRefresher.cs
Normal file
18
src/Umbraco.Core/Sync/ICacheRefresher.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using umbraco.interfaces;
|
||||
|
||||
namespace Umbraco.Core.Sync
|
||||
{
|
||||
/// <summary>
|
||||
/// Strongly type cache refresher that is able to refresh cache of real instances of objects as well as IDs
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <remarks>
|
||||
/// This is much better for performance when we're not running in a load balanced environment so we can refresh the cache
|
||||
/// against a already resolved object instead of looking the object back up by id.
|
||||
/// </remarks>
|
||||
interface ICacheRefresher<T> : ICacheRefresher
|
||||
{
|
||||
void Refresh(T instance);
|
||||
void Remove(T instance);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Web.Services;
|
||||
using System.Collections.Generic;
|
||||
using System.Web.Services;
|
||||
using Umbraco.Core.IO;
|
||||
|
||||
namespace Umbraco.Core.Sync
|
||||
@@ -73,7 +74,11 @@ namespace Umbraco.Core.Sync
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://umbraco.org/webservices/RefreshById", RequestNamespace = "http://umbraco.org/webservices/", ResponseNamespace = "http://umbraco.org/webservices/", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
|
||||
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://umbraco.org/webservices/RefreshById",
|
||||
RequestNamespace = "http://umbraco.org/webservices/",
|
||||
ResponseNamespace = "http://umbraco.org/webservices/",
|
||||
Use = System.Web.Services.Description.SoapBindingUse.Literal,
|
||||
ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
|
||||
public void RefreshById(System.Guid uniqueIdentifier, int Id, string Login, string Password)
|
||||
{
|
||||
this.Invoke("RefreshById", new object[] {
|
||||
@@ -99,6 +104,40 @@ namespace Umbraco.Core.Sync
|
||||
this.EndInvoke(asyncResult);
|
||||
}
|
||||
|
||||
|
||||
/// <remarks/>
|
||||
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://umbraco.org/webservices/RefreshByIds",
|
||||
RequestNamespace = "http://umbraco.org/webservices/",
|
||||
ResponseNamespace = "http://umbraco.org/webservices/",
|
||||
Use = System.Web.Services.Description.SoapBindingUse.Literal,
|
||||
ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
|
||||
public void RefreshByIds(System.Guid uniqueIdentifier, string jsonIds, string Login, string Password)
|
||||
{
|
||||
this.Invoke("RefreshByIds", new object[] {
|
||||
uniqueIdentifier,
|
||||
jsonIds,
|
||||
Login,
|
||||
Password});
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
public System.IAsyncResult BeginRefreshByIds(System.Guid uniqueIdentifier, string jsonIds, string Login, string Password, System.AsyncCallback callback, object asyncState)
|
||||
{
|
||||
return this.BeginInvoke("RefreshByIds", new object[] {
|
||||
uniqueIdentifier,
|
||||
jsonIds,
|
||||
Login,
|
||||
Password}, callback, asyncState);
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
public void EndRefreshByIds(System.IAsyncResult asyncResult)
|
||||
{
|
||||
this.EndInvoke(asyncResult);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <remarks/>
|
||||
[System.Web.Services.Protocols.SoapDocumentMethodAttribute("http://umbraco.org/webservices/RemoveById", RequestNamespace = "http://umbraco.org/webservices/", ResponseNamespace = "http://umbraco.org/webservices/", Use = System.Web.Services.Description.SoapBindingUse.Literal, ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
|
||||
public void RemoveById(System.Guid uniqueIdentifier, int Id, string Login, string Password)
|
||||
|
||||
@@ -61,6 +61,7 @@
|
||||
<Reference Include="System.Runtime.Serialization" />
|
||||
<Reference Include="System.Transactions" />
|
||||
<Reference Include="System.Web" />
|
||||
<Reference Include="System.Web.Extensions" />
|
||||
<Reference Include="System.Web.Helpers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
|
||||
<Private>True</Private>
|
||||
<HintPath>..\packages\Microsoft.AspNet.WebPages.2.0.20710.0\lib\net40\System.Web.Helpers.dll</HintPath>
|
||||
@@ -669,6 +670,7 @@
|
||||
<Compile Include="Services\ServiceContext.cs" />
|
||||
<Compile Include="Services\UserService.cs" />
|
||||
<Compile Include="Sync\DefaultServerMessenger.cs" />
|
||||
<Compile Include="Sync\ICacheRefresher.cs" />
|
||||
<Compile Include="Sync\ServerSyncWebServiceClient.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
|
||||
@@ -45,6 +45,19 @@ namespace Umbraco.Tests.Sync
|
||||
Assert.AreEqual(10, ((TestServerMessenger)ServerMessengerResolver.Current.Messenger).IntIdsRefreshed.Count);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RefreshIntIdFromObject()
|
||||
{
|
||||
for (var i = 0; i < 10; i++)
|
||||
{
|
||||
DistributedCache.Instance.Refresh(
|
||||
Guid.Parse("E0F452CB-DCB2-4E84-B5A5-4F01744C5C73"),
|
||||
x => x.Id,
|
||||
new TestObjectWithId{Id = i});
|
||||
}
|
||||
Assert.AreEqual(10, ((TestServerMessenger)ServerMessengerResolver.Current.Messenger).IntIdsRefreshed.Count);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RefreshGuidId()
|
||||
{
|
||||
@@ -77,6 +90,11 @@ namespace Umbraco.Tests.Sync
|
||||
|
||||
#region internal test classes
|
||||
|
||||
internal class TestObjectWithId
|
||||
{
|
||||
public int Id { get; set; }
|
||||
}
|
||||
|
||||
internal class TestCacheRefresher : ICacheRefresher
|
||||
{
|
||||
public Guid UniqueIdentifier
|
||||
|
||||
@@ -102,28 +102,22 @@ namespace Umbraco.Web.Cache
|
||||
|
||||
static void MediaServiceTrashing(IMediaService sender, Core.Events.MoveEventArgs<Core.Models.IMedia> e)
|
||||
{
|
||||
DistributedCache.Instance.RemoveMediaCache(e.Entity.Id);
|
||||
DistributedCache.Instance.RemoveMediaCache(e.Entity);
|
||||
}
|
||||
|
||||
static void MediaServiceMoving(IMediaService sender, Core.Events.MoveEventArgs<Core.Models.IMedia> e)
|
||||
{
|
||||
DistributedCache.Instance.RefreshMediaCache(e.Entity.Id);
|
||||
DistributedCache.Instance.RefreshMediaCache(e.Entity);
|
||||
}
|
||||
|
||||
static void MediaServiceDeleting(IMediaService sender, Core.Events.DeleteEventArgs<Core.Models.IMedia> e)
|
||||
{
|
||||
foreach (var item in e.DeletedEntities)
|
||||
{
|
||||
DistributedCache.Instance.RemoveMediaCache(item.Id);
|
||||
}
|
||||
DistributedCache.Instance.RemoveMediaCache(e.DeletedEntities.ToArray());
|
||||
}
|
||||
|
||||
static void MediaServiceSaved(IMediaService sender, Core.Events.SaveEventArgs<Core.Models.IMedia> e)
|
||||
{
|
||||
foreach (var item in e.SavedEntities)
|
||||
{
|
||||
DistributedCache.Instance.RefreshMediaCache(item.Id);
|
||||
}
|
||||
DistributedCache.Instance.RefreshMediaCache(e.SavedEntities.ToArray());
|
||||
}
|
||||
|
||||
static void MemberBeforeDelete(Member sender, DeleteEventArgs e)
|
||||
|
||||
@@ -132,6 +132,23 @@ namespace Umbraco.Web.Cache
|
||||
GetRefresherById(factoryGuid),
|
||||
id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sends a request to all registered load-balanced servers to remove the node specified
|
||||
/// using the specified ICacheRefresher with the guid factoryGuid.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="factoryGuid"></param>
|
||||
/// <param name="getNumericId"></param>
|
||||
/// <param name="instances"></param>
|
||||
public void Remove<T>(Guid factoryGuid, Func<T, int> getNumericId, params T[] instances)
|
||||
{
|
||||
ServerMessengerResolver.Current.Messenger.PerformRemove<T>(
|
||||
ServerRegistrarResolver.Current.Registrar.Registrations,
|
||||
GetRefresherById(factoryGuid),
|
||||
getNumericId,
|
||||
instances);
|
||||
}
|
||||
|
||||
private static ICacheRefresher GetRefresherById(Guid uniqueIdentifier)
|
||||
{
|
||||
|
||||
@@ -53,30 +53,40 @@ namespace Umbraco.Web.Cache
|
||||
/// Refreshes the cache amongst servers for a page
|
||||
/// </summary>
|
||||
/// <param name="dc"></param>
|
||||
/// <param name="pageId"></param>
|
||||
public static void RefreshPageCache(this DistributedCache dc, int pageId)
|
||||
/// <param name="documentId"></param>
|
||||
public static void RefreshPageCache(this DistributedCache dc, int documentId)
|
||||
{
|
||||
dc.Refresh(new Guid(DistributedCache.PageCacheRefresherId), pageId);
|
||||
}
|
||||
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, IEnumerable<IContent> content)
|
||||
public static void RefreshPageCache(this DistributedCache dc, params IContent[] content)
|
||||
{
|
||||
dc.Refresh(new Guid(DistributedCache.PageCacheRefresherId), x => x.Id, content.ToArray());
|
||||
dc.Refresh(new Guid(DistributedCache.PageCacheRefresherId), x => x.Id, content);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the cache amongst servers for a page
|
||||
/// </summary>
|
||||
/// <param name="dc"></param>
|
||||
/// <param name="pageId"></param>
|
||||
public static void RemovePageCache(this DistributedCache dc, int pageId)
|
||||
/// <param name="content"></param>
|
||||
public static void RemovePageCache(this DistributedCache dc, params IContent[] content)
|
||||
{
|
||||
dc.Remove(new Guid(DistributedCache.PageCacheRefresherId), pageId);
|
||||
dc.Remove(new Guid(DistributedCache.PageCacheRefresherId), x => x.Id, content);
|
||||
}
|
||||
|
||||
/// <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>
|
||||
@@ -109,6 +119,16 @@ namespace Umbraco.Web.Cache
|
||||
dc.Refresh(new Guid(DistributedCache.MediaCacheRefresherId), mediaId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Refreshes the cache amongst servers for a media item
|
||||
/// </summary>
|
||||
/// <param name="dc"></param>
|
||||
/// <param name="media"></param>
|
||||
public static void RefreshMediaCache(this DistributedCache dc, params IMedia[] media)
|
||||
{
|
||||
dc.Refresh(new Guid(DistributedCache.MediaCacheRefresherId), x => x.Id, media);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the cache amongst servers for a media item
|
||||
/// </summary>
|
||||
@@ -119,6 +139,16 @@ namespace Umbraco.Web.Cache
|
||||
dc.Remove(new Guid(DistributedCache.MediaCacheRefresherId), mediaId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the cache amongst servers for media items
|
||||
/// </summary>
|
||||
/// <param name="dc"></param>
|
||||
/// <param name="media"></param>
|
||||
public static void RemoveMediaCache(this DistributedCache dc, params IMedia[] media)
|
||||
{
|
||||
dc.Remove(new Guid(DistributedCache.MediaCacheRefresherId), x => x.Id, media);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Refreshes the cache amongst servers for a macro item
|
||||
/// </summary>
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
using System;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Sync;
|
||||
using umbraco;
|
||||
using umbraco.cms.businesslogic.web;
|
||||
using umbraco.interfaces;
|
||||
using umbraco.presentation.cache;
|
||||
|
||||
@@ -12,7 +15,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 : ICacheRefresher
|
||||
public class PageCacheRefresher : ICacheRefresher<IContent>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the unique identifier of the CacheRefresher.
|
||||
@@ -69,5 +72,15 @@ namespace Umbraco.Web.Cache
|
||||
{
|
||||
content.Instance.ClearDocumentCache(id);
|
||||
}
|
||||
|
||||
public void Refresh(IContent instance)
|
||||
{
|
||||
content.Instance.UpdateDocumentCache(new Document(instance));
|
||||
}
|
||||
|
||||
public void Remove(IContent instance)
|
||||
{
|
||||
content.Instance.ClearDocumentCache(new Document(instance));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace Umbraco.Web.Strategies.Publishing
|
||||
/// </summary>
|
||||
private void UpdateMultipleContentCache(IEnumerable<IContent> content)
|
||||
{
|
||||
DistributedCache.Instance.RefreshPageCache(content);
|
||||
DistributedCache.Instance.RefreshPageCache(content.ToArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -74,7 +74,7 @@ namespace Umbraco.Web.Strategies.Publishing
|
||||
/// </summary>
|
||||
private void UpdateSingleContentCache(IContent content)
|
||||
{
|
||||
DistributedCache.Instance.RefreshPageCache(content.Id);
|
||||
DistributedCache.Instance.RefreshPageCache(content);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -51,7 +51,7 @@ namespace Umbraco.Web.Strategies.Publishing
|
||||
/// </summary>
|
||||
private void UnPublishSingle(IContent content)
|
||||
{
|
||||
DistributedCache.Instance.RemovePageCache(content.Id);
|
||||
DistributedCache.Instance.RemovePageCache(content);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,11 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Diagnostics;
|
||||
using System.Web;
|
||||
using System.Web.Script.Serialization;
|
||||
using System.Web.Services;
|
||||
using System.Xml;
|
||||
using Umbraco.Core;
|
||||
@@ -82,6 +84,29 @@ namespace umbraco.presentation.webservices
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Refreshes objects for all Ids matched in the json string
|
||||
/// </summary>
|
||||
/// <param name="uniqueIdentifier"></param>
|
||||
/// <param name="jsonIds">A JSON Serialized string of ids to match</param>
|
||||
/// <param name="Login"></param>
|
||||
/// <param name="Password"></param>
|
||||
[WebMethod]
|
||||
public void RefreshByIds(Guid uniqueIdentifier, string jsonIds, string Login, string Password)
|
||||
{
|
||||
var serializer = new JavaScriptSerializer();
|
||||
var ids = serializer.Deserialize<int[]>(jsonIds);
|
||||
|
||||
if (BusinessLogic.User.validateCredentials(Login, Password))
|
||||
{
|
||||
var cr = CacheRefreshersResolver.Current.GetById(uniqueIdentifier);
|
||||
foreach (var i in ids)
|
||||
{
|
||||
cr.Refresh(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[WebMethod]
|
||||
public void RemoveById(Guid uniqueIdentifier, int Id, string Login, string Password) {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user