/// <summary> /// Checks the primary node for the key, if a NMV is encountered, will retry on each replica, asynchronously. /// </summary> /// <typeparam name="T">The Type of the body of the request.</typeparam> /// <param name="operation">The <see cref="IOperation" /> to execiute.</param> /// <returns> /// The <see cref="Task{IOperationResult}" /> object representing asynchcronous operation. /// </returns> public async Task <IOperationResult <T> > ReadFromReplicaAsync <T>(ReplicaRead <T> operation) { var tcs = new TaskCompletionSource <IOperationResult <T> >(); var cts = new CancellationTokenSource(OperationLifeSpan); cts.CancelAfter(OperationLifeSpan); var keyMapper = ConfigInfo.GetKeyMapper(); var vBucket = (IVBucket)keyMapper.MapKey(operation.Key); operation.VBucket = vBucket; operation.Completed = CallbackFactory.CompletedFuncForRetry(Pending, ClusterController, tcs); Pending.TryAdd(operation.Opaque, operation); IOperationResult <T> result = null; if (vBucket.HasReplicas) { foreach (var index in vBucket.Replicas) { var replica = vBucket.LocateReplica(index); if (replica == null) { continue; } await replica.SendAsync(operation).ContinueOnAnyContext(); result = await tcs.Task; if (result.Success && !result.IsNmv()) { return(result); } } } else { result = new OperationResult <T> { Id = operation.Key, Status = ResponseStatus.NoReplicasFound, Message = "No replicas found; have you configured the bucket for replica reads?", Success = false }; } return(result); }
/// <summary> /// Checks the primary node for the key, if a NMV is encountered, will retry on each replica. /// </summary> /// <typeparam name="T">The Type of the body of the request.</typeparam> /// <param name="operation">The <see cref="IOperation" /> to execiute.</param> /// <returns> /// The result of the operation. /// </returns> /// <exception cref="System.NotImplementedException"></exception> public IOperationResult <T> ReadFromReplica <T>(ReplicaRead <T> operation) { var keyMapper = ConfigInfo.GetKeyMapper(); var vBucket = (IVBucket)keyMapper.MapKey(operation.Key); operation.VBucket = vBucket; IOperationResult <T> result = null; if (vBucket.HasReplicas) { foreach (var index in vBucket.Replicas) { var replica = vBucket.LocateReplica(index); if (replica == null) { continue; } result = replica.Send(operation); if (result.Success && !result.IsNmv()) { return(result); } operation = (ReplicaRead <T>)operation.Clone(); } } else { result = new OperationResult <T> { Status = ResponseStatus.NoReplicasFound, Message = "No replicas found; have you configured the bucket for replica reads?", Success = false }; } return(result); }