Skip to main content
Version: 2.0.2

C#

For reasons explained in the Introduction to conflict resolution, we strongly recommend adopting a conflict resolution strategy that requires applications to resolve siblings according to use-case-specific criteria. Here, we'll provide a brief guide to conflict resolution using the official Riak .NET client.

How the .NET Client Handles Conflict Resolution​

In the Riak .NET client, every Riak object has a siblings property that provides access to a list of that object's sibling values. If there are no siblings, that property will return an empty list.

Here's an example of an object with siblings:

var id = new RiakObjectId("siblings_allowed", "nickolodeon", "best_character");

var renObj = new RiakObject(id, "Ren", RiakConstants.ContentTypes.TextPlain);
var stimpyObj = new RiakObject(id, "Stimpy", RiakConstants.ContentTypes.TextPlain);

var renResult = client.Put(renObj);
var stimpyResult = client.Put(stimpyObj);

var getResult = client.Get(id);
RiakObject obj = getResult.Value;
Debug.WriteLine(format: "Sibling count: {0}", args: obj.Siblings.Count);
foreach (var sibling in obj.Siblings)
{
Debug.WriteLine(
format: " VTag: {0}",
args: sibling.VTag);
}

So what happens if the count of obj.Siblings is greater than 0, as in the case above?

In order to resolve siblings, you need to either fetch, update and store a canonical value, or choose a sibling from the Siblings list and store that as the canonical value.

Basic Conflict Resolution Example​

In this example, you will ignore the contents of the Siblings list and will fetch, update and store the definitive value.

var id = new RiakObjectId("siblings_allowed", "nickolodeon", "best_character");

var renObj = new RiakObject(id, "Ren", RiakConstants.ContentTypes.TextPlain);
var stimpyObj = new RiakObject(id, "Stimpy", RiakConstants.ContentTypes.TextPlain);

var renResult = client.Put(renObj);
var stimpyResult = client.Put(stimpyObj);

var getResult = client.Get(id);
RiakObject obj = getResult.Value;
Debug.Assert(obj.Siblings.Count == 2);

// Now, modify the object's value
obj.SetObject<string>("Stimpy", RiakConstants.ContentTypes.TextPlain);

// Then, store the object which has vector clock attached
var putRslt = client.Put(obj);
CheckResult(putRslt);

obj = putRslt.Value;
// Voila, no more siblings!
Debug.Assert(obj.Siblings.Count == 0);

Choosing a value from Siblings​

This example shows a basic sibling resolution strategy in which the first sibling is chosen as the canonical value.

var id = new RiakObjectId("siblings_allowed", "nickolodeon", "best_character");

var renObj = new RiakObject(id, "Ren", RiakConstants.ContentTypes.TextPlain);
var stimpyObj = new RiakObject(id, "Stimpy", RiakConstants.ContentTypes.TextPlain);

var renResult = client.Put(renObj);
var stimpyResult = client.Put(stimpyObj);

var getResult = client.Get(id);
RiakObject obj = getResult.Value;
Debug.Assert(obj.Siblings.Count == 2);

// Pick the first sibling
RiakObject chosenSibling = getResult.Value.Siblings.First();

// Then, store the chosen object
var putRslt = client.Put(chosenSibling);
CheckResult(putRslt);

RiakObject updatedObject = putRslt.Value;
// Voila, no more siblings!
Debug.Assert(updatedObject.Siblings.Count == 0);