diff --git a/src/Umbraco.Core/Cache/IPayloadCacheRefresher.cs b/src/Umbraco.Core/Cache/IPayloadCacheRefresher.cs
new file mode 100644
index 0000000000..416cb223d7
--- /dev/null
+++ b/src/Umbraco.Core/Cache/IPayloadCacheRefresher.cs
@@ -0,0 +1,16 @@
+using umbraco.interfaces;
+
+namespace Umbraco.Core.Cache
+{
+ ///
+ /// A cache refresher that supports refreshing cache based on a custom payload
+ ///
+ interface IPayloadCacheRefresher : IJsonCacheRefresher
+ {
+ ///
+ /// Refreshes, clears, etc... any cache based on the information provided in the payload
+ ///
+ ///
+ void Refresh(object payload);
+ }
+}
diff --git a/src/Umbraco.Core/Cache/JsonCacheRefresherBase.cs b/src/Umbraco.Core/Cache/JsonCacheRefresherBase.cs
index 708e2e1605..48dd008a3d 100644
--- a/src/Umbraco.Core/Cache/JsonCacheRefresherBase.cs
+++ b/src/Umbraco.Core/Cache/JsonCacheRefresherBase.cs
@@ -4,17 +4,16 @@ using umbraco.interfaces;
namespace Umbraco.Core.Cache
{
///
- /// A base class for json cache refreshers that ensures the correct events are raised when
- /// cache refreshing occurs.
+ /// Provides a base class for "json" cache refreshers.
///
- /// The real cache refresher type, this is used for raising strongly typed events
- public abstract class JsonCacheRefresherBase : CacheRefresherBase, IJsonCacheRefresher
- where TInstanceType : ICacheRefresher
+ /// The actual cache refresher type.
+ /// Ensures that the correct events are raised when cache refreshing occurs.
+ public abstract class JsonCacheRefresherBase : CacheRefresherBase, IJsonCacheRefresher
+ where TInstance : ICacheRefresher
{
-
- public virtual void Refresh(string jsonPayload)
+ public virtual void Refresh(string json)
{
- OnCacheUpdated(Instance, new CacheRefresherEventArgs(jsonPayload, MessageType.RefreshByJson));
+ OnCacheUpdated(Instance, new CacheRefresherEventArgs(json, MessageType.RefreshByJson));
}
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Cache/PayloadCacheRefresherBase.cs b/src/Umbraco.Core/Cache/PayloadCacheRefresherBase.cs
new file mode 100644
index 0000000000..b3ea2ff7b1
--- /dev/null
+++ b/src/Umbraco.Core/Cache/PayloadCacheRefresherBase.cs
@@ -0,0 +1,27 @@
+using Umbraco.Core.Sync;
+using umbraco.interfaces;
+
+namespace Umbraco.Core.Cache
+{
+ ///
+ /// Provides a base class for "payload" cache refreshers.
+ ///
+ /// The actual cache refresher type.
+ /// Ensures that the correct events are raised when cache refreshing occurs.
+ public abstract class PayloadCacheRefresherBase : JsonCacheRefresherBase, IPayloadCacheRefresher
+ where TInstance : ICacheRefresher
+ {
+ protected abstract object Deserialize(string json);
+
+ public override void Refresh(string json)
+ {
+ var payload = Deserialize(json);
+ Refresh(payload);
+ }
+
+ public virtual void Refresh(object payload)
+ {
+ OnCacheUpdated(Instance, new CacheRefresherEventArgs(payload, MessageType.RefreshByPayload));
+ }
+ }
+}
diff --git a/src/Umbraco.Core/Sync/DatabaseServerMessenger.cs b/src/Umbraco.Core/Sync/DatabaseServerMessenger.cs
index 956903d96d..e6ce565280 100644
--- a/src/Umbraco.Core/Sync/DatabaseServerMessenger.cs
+++ b/src/Umbraco.Core/Sync/DatabaseServerMessenger.cs
@@ -187,25 +187,42 @@ namespace Umbraco.Core.Sync
// the local server as they've already been processed. We should NOT assume that the sequence of
// instructions in the database makes any sense whatsoever, because it's all async.
var localIdentity = GetLocalIdentity();
- var remoteDtos = dtos.Where(x => x.OriginIdentity != localIdentity);
var lastId = 0;
- foreach (var dto in remoteDtos)
+ foreach (var dto in dtos)
{
+ if (dto.OriginIdentity == localIdentity)
+ {
+ // just skip that local one but update lastId nevertheless
+ lastId = dto.Id;
+ continue;
+ }
+
+ // deserialize remote instructions & skip if it fails
+ JArray jsonA;
try
{
- var jsonArray = JsonConvert.DeserializeObject(dto.Instructions);
- NotifyRefreshers(jsonArray);
- lastId = dto.Id;
+ jsonA = JsonConvert.DeserializeObject(dto.Instructions);
}
catch (JsonException ex)
{
- // FIXME
- // if we cannot deserialize then it's OK to skip the instructions
- // but what if NotifyRefreshers throws?!
-
- LogHelper.Error("Could not deserialize a distributed cache instruction (\"" + dto.Instructions + "\").", ex);
+ LogHelper.Error(string.Format("Failed to deserialize instructions ({0}: \"{1}\").", dto.Id, dto.Instructions), ex);
+ lastId = dto.Id; // skip
+ continue;
}
+
+ // execute remote instructions & update lastId
+ try
+ {
+ NotifyRefreshers(jsonA);
+ lastId = dto.Id;
+ }
+ catch (Exception ex)
+ {
+ LogHelper.Error(string.Format("Failed to execute instructions ({0}: \"{1}\").", dto.Id, dto.Instructions), ex);
+ LogHelper.Warn("BEWARE - DISTRIBUTED CACHE IS NOT UPDATED.");
+ throw;
+ }
}
if (lastId > 0)
diff --git a/src/Umbraco.Core/Sync/IServerMessenger.cs b/src/Umbraco.Core/Sync/IServerMessenger.cs
index 100638c202..1208ea3caf 100644
--- a/src/Umbraco.Core/Sync/IServerMessenger.cs
+++ b/src/Umbraco.Core/Sync/IServerMessenger.cs
@@ -10,15 +10,13 @@ namespace Umbraco.Core.Sync
/// Also ensures that the notification is processed on the local environment.
public interface IServerMessenger
{
- // TODO
- // everything we do "by JSON" means that data is serialized then deserialized on the local server
- // we should stop using this, and instead use Notify() with an actual object that can be passed
- // around locally, and serialized for remote messaging - but that would break backward compat ;-(
- //
- // and then ServerMessengerBase must be able to handle Notify(), and all messengers too
- // and then ICacheRefresher (or INotifiableCacheRefresher?) must be able to handle it too
- //
- // >> v8
+ ///
+ /// Notifies the distributed cache, for a specified .
+ ///
+ /// The servers that compose the load balanced environment.
+ /// The ICacheRefresher.
+ /// The notification content.
+ void PerformRefresh(IEnumerable servers, ICacheRefresher refresher, object payload);
///
/// Notifies the distributed cache, for a specified .
@@ -28,15 +26,6 @@ namespace Umbraco.Core.Sync
/// The notification content.
void PerformRefresh(IEnumerable servers, ICacheRefresher refresher, string jsonPayload);
- /////
- ///// Notifies the distributed cache, for a specified .
- /////
- ///// The servers that compose the load balanced environment.
- ///// The ICacheRefresher.
- ///// The notification content.
- ///// A custom Json serializer.
- //void Notify(IEnumerable servers, ICacheRefresher refresher, object payload, Func