Thoughts on when to use GetFromReplica


#1

Hi there,

This is more of a subjective question so I would appreciate anyone’s thoughts on the subject. I’ve gone through all the documentation I can find on error handling and failure scenarios, but don’t see much official guidance on when I should consider trying GetFromReplica if my result is failed. The one code example I see shows using it with a KeyNotFound operation result, but I can’t tell if that’s just a random example or what is recommended. My anecdotal experience tells me that the vast majority of when GetFromReplica would help is on a timeout.

I have two thoughts on how I should be utilizing it, curious what you think:

The most protective method I thought of uses ShouldRetry as well as GetFromReplica. I’m not sure if ShouldRetry() is even needed, I know the client handles some retries on it’s own. This has the worst potential performance, but seems like the “safest” way to handle failure if I can’t tolerate it:

private T InternalGet(bool retry = false)
{
var result = _couchbaseBucket.Get<T>(“key”);

        if (!result.Success)
        {
            if (result.ShouldRetry() && !retry) //only retry once
            {
                return InternalGet(true);
            }
            else 
            {
                var replicaResult = _couchbaseBucket.GetFromReplica<T>("key");

                if (!replicaResult.Success)
                {
                    //some custom exception
  	    throw new CouchbaseGetException();
                }

                return replicaResult.Value;
            }
        }

        return result.Value;
    }

The second way just ignores ShouldRetry() and goes straight to the replica. This seems a little broad to me as there are probably some operation results that retrying on replica will not have any effect.

private T InternalGet()
{
var result = _couchbaseBucket.Get<T>(GetKey());

if (!result.Success)
{
var replicaResult = _couchbaseBucket.GetFromReplica<T>(“key”);

  if (!replicaResult.Success)
  {
                //some custom exception
  	throw new CouchbaseGetException();
  }

  return replicaResult.Value;

}

return result.Value;
}

sorry the formatting is a little funky on these snippets.


#2

@brian.hulse -

In general, you would read from replicas when you care more about availability and less about consistency; a replica read may return a version of the document that is not up to date (i.e. master is the most consistent - its the master). In certain situations, if the GET from the master fails and you really need to return a result, a replica read may help by returning a document that is older than the master.

Your second example is probably the best way to do this: try to fetch from from the master, if it does not succeed try another node via GetFromReplica. Yes, the client does retry and ShouldRetry is actually something used internally by the SDK and probably shouldn’t be used directly. WRT to operations that do not retry, most do if CAS is provided and there is no side effects if the operation succeeded on the server and the failure occured while recieving the response, for example. GET can always retry because its not a mutation/write operation - no side effects.

-Jeff


#3

Thanks Jeff! This helps a lot.