Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save kijanawoodard/5307086 to your computer and use it in GitHub Desktop.
Save kijanawoodard/5307086 to your computer and use it in GitHub Desktop.
Last One Wins Raven Resolver - Updated for 2.x
using System;
using System.Linq;
using Raven.Abstractions.Data;
using Raven.Abstractions.Logging;
using Raven.Bundles.Replication.Plugins;
using Raven.Json.Linq;
namespace RavenConflictResolverPlugin
{
public class LastInWinsReplicationConflictResolver
: AbstractDocumentReplicationConflictResolver
{
private readonly ILog log = LogManager.GetCurrentClassLogger();
public const string RavenReplicationConflict = "Raven-Replication-Conflict";
public override bool TryResolve(
string id,
RavenJObject metadata,
RavenJObject document,
JsonDocument existingDoc,
Func<string, JsonDocument> getDocument)
{
if (this.ExistingDocShouldWin(metadata, existingDoc))
{
this.ReplaceValues(metadata, existingDoc.Metadata);
this.ReplaceValues(document, existingDoc.DataAsJson);
log.Debug("Replication conflict for '{0}' resolved by choosing existing document.", id);
}
else
{
log.Debug("Replication conflict for '{0}' resolved by choosing inbound document.", id);
}
return true;
}
private bool ExistingDocShouldWin(RavenJObject newMetadata, JsonDocument existingDoc)
{
if (existingDoc == null ||
this.ExistingDocHasConflict(existingDoc) ||
this.ExistingDocIsOlder(newMetadata, existingDoc))
{
return false;
}
return true;
}
private bool ExistingDocHasConflict(JsonDocument existingDoc)
{
return existingDoc.Metadata[RavenReplicationConflict] != null;
}
private bool ExistingDocIsOlder(RavenJObject newMetadata, JsonDocument existingDoc)
{
var newLastModified = this.GetLastModified(newMetadata);
if (!existingDoc.LastModified.HasValue ||
newLastModified.HasValue &&
existingDoc.LastModified <= newLastModified)
{
return true;
}
return false;
}
private DateTime? GetLastModified(RavenJObject metadata)
{
var lastModified = metadata[Constants.LastModified];
return (lastModified == null) ?
new DateTime?() :
lastModified.Value<DateTime?>();
}
private void ReplaceValues(RavenJObject target, RavenJObject source)
{
var targetKeys = target.Keys.ToArray();
foreach (var key in targetKeys)
{
target.Remove(key);
}
foreach (var key in source.Keys)
{
target.Add(key, source[key]);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment