Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save jtbennett/2012016 to your computer and use it in GitHub Desktop.
Save jtbennett/2012016 to your computer and use it in GitHub Desktop.
RavenDB LastInWinsReplicationConflictResolver
using System;
using System.Linq;
using NLog;
using Raven.Abstractions.Data;
using Raven.Bundles.Replication;
using Raven.Bundles.Replication.Plugins;
using Raven.Json.Linq;
namespace MyRavenReplicationBundle
{
public class LastInWinsReplicationConflictResolver
: AbstractDocumentReplicationConflictResolver
{
private readonly Logger log = LogManager.GetCurrentClassLogger();
public override bool TryResolve(
string id,
RavenJObject metadata,
RavenJObject document,
JsonDocument existingDoc)
{
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[ReplicationConstants.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]);
}
}
}
}
@afifmohammed
Copy link

This does not work with 2261. The bundles nuget package only goes upto 1.0.992.

@johnculviner
Copy link

This still works just fine, ignore the comment above which unfortunately discouraged me from even trying!

Just change "ReplicationConstants." to "Constants." and you should be good.

All you need to do is create a class library assembly "project" and import the "RavenDB.Database" nuget package and create the above class in the project. Compile and then add the resulting DLL to {RavenInstallDirectory}\Plugins and bounce the server. Quite impressed with the flexibility here!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment