/// <summary> /// Asynchronously checks the replications status of a key. /// </summary> /// <param name="op">The <see cref="ObserveParams"/> object.</param> /// <param name="replicaIndex">The index of the replica within the <see cref="IVBucket"/></param> /// <returns>True if the durability requirements specified by <see cref="PersistTo"/> and <see cref="ReplicateTo"/> have been satisfied.</returns> static async Task <bool> CheckReplica(ObserveParams op, int replicaIndex) { Log.Debug(m => m("checking replica {0}", replicaIndex)); if (op.IsDurabilityMet()) { return(true); } var replica = op.VBucket.LocateReplica(replicaIndex); var result = await Task.Run(() => replica.Send(new Observe(op.Key, op.VBucket, new AutoByteConverter()))) .ConfigureAwait(false); Log.Debug(m => m("Replica {0} - {1} [0]", replica.EndPoint, result.Value, replicaIndex)); var state = result.Value; if (state.KeyState == op.Criteria.PersistState) { Interlocked.Increment(ref op.ReplicatedToCount); Interlocked.Increment(ref op.PersistedToCount); } else if (state.KeyState == op.Criteria.ReplicateState) { Interlocked.Increment(ref op.ReplicatedToCount); } return(op.IsDurabilityMet() && !op.HasMutated(state.Cas)); }
/// <summary> /// Asynchronously checks the replications status of a key. /// </summary> /// <param name="observeParams">The <see cref="ObserveParams"/> object.</param> /// <param name="replicaIndex">The replicaIndex of the replica within the <see cref="IVBucket"/></param> /// <returns>True if the durability requirements specified by <see cref="PersistTo"/> and <see cref="ReplicateTo"/> have been satisfied.</returns> private async Task <bool> CheckReplicaAsync(ObserveParams observeParams, int replicaIndex) { if (observeParams.IsDurabilityMet()) { return(true); } var operation = new Observe(observeParams.Key, observeParams.VBucket, _clusterController.Transcoder, (uint)_timeout); var tcs = new TaskCompletionSource <IOperationResult <ObserveState> >(); operation.Completed = CallbackFactory.CompletedFuncForRetry(_pending, _clusterController, tcs); _pending.TryAdd(operation.Opaque, operation); var replica = observeParams.VBucket.LocateReplica(replicaIndex); await replica.SendAsync(operation).ContinueOnAnyContext(); var result = await tcs.Task.ContinueOnAnyContext(); Log.Debug("Replica {0} - {1} {2} - opaque: {3} key:{4}", replica.EndPoint, result.Value.KeyState, replicaIndex, operation.Opaque, observeParams.Key); var state = result.Value; if (state.KeyState == observeParams.Criteria.PersistState) { Interlocked.Increment(ref observeParams.ReplicatedToCount); Interlocked.Increment(ref observeParams.PersistedToCount); } else if (state.KeyState == observeParams.Criteria.ReplicateState) { Interlocked.Increment(ref observeParams.ReplicatedToCount); } return(!observeParams.HasMutated(state.Cas)); }
private async Task <bool> CheckPersistToAsync(ObserveParams observeParams) { if (observeParams.PersistTo == PersistTo.Zero) { return(true); } var op = new ObserveSeqno(observeParams.Token, _clusterController.Transcoder, _timeout); observeParams.Operation = op; var tcs = new TaskCompletionSource <IOperationResult <ObserveSeqnoResponse> >(); op.Completed = CallbackFactory.CompletedFuncForRetry(_pending, _clusterController, tcs); _pending.TryAdd(op.Opaque, op); var server = await GetServerAsync(observeParams); await server.SendAsync(op).ContinueOnAnyContext(); var response = await tcs.Task.ContinueOnAnyContext(); observeParams.CheckMutationLost(response); observeParams.CheckPersisted(response); return(observeParams.IsDurabilityMet()); }
/// <summary> /// Asynchronously checks the replications status of a key. /// </summary> /// <param name="observeParams">The <see cref="ObserveParams"/> object.</param> /// <param name="operation">The Observe operation.</param> /// <param name="replicaIndex">The replicaIndex of the replica within the <see cref="IVBucket"/></param> /// <returns>True if the durability requirements specified by <see cref="PersistTo"/> and <see cref="ReplicateTo"/> have been satisfied.</returns> static async Task <bool> CheckReplicaAsync(ObserveParams observeParams, Observe operation, int replicaIndex) { Log.Debug(m => m("checking replica {0}", replicaIndex)); if (observeParams.IsDurabilityMet()) { return(true); } //clone the operation since we already checked the primary and we want to maintain internal state (opaque, timer, etc) operation = (Observe)operation.Clone(); var replica = observeParams.VBucket.LocateReplica(replicaIndex); var result = await Task.Run(() => replica.Send(operation)).ContinueOnAnyContext(); Log.Debug(m => m("Replica {0} - {1} [0]", replica.EndPoint, result.Value, replicaIndex)); var state = result.Value; if (state.KeyState == observeParams.Criteria.PersistState) { Interlocked.Increment(ref observeParams.ReplicatedToCount); Interlocked.Increment(ref observeParams.PersistedToCount); } else if (state.KeyState == observeParams.Criteria.ReplicateState) { Interlocked.Increment(ref observeParams.ReplicatedToCount); } return(!observeParams.HasMutated(state.Cas)); }
/// <summary> /// Checks the replicas to see if the key has met the durability constraints defined by the caller. /// </summary> /// <param name="observeParams">The observe parameters.</param> /// <param name="operation">The operation observe operation reference; will be cloned if reused.</param> /// <returns></returns> private bool CheckReplicas(ObserveParams observeParams, Observe operation) { //Get the candidate replicas, if none are defined that match the specified durability return false. var replicas = observeParams.GetReplicas(); //Check each replica to see if has met the durability constraints specified. A mutation means we failed. var notMutated = replicas.All(index => CheckReplica(observeParams, operation, index)); return(observeParams.IsDurabilityMet() && notMutated); }
/// <summary> /// Checks a replica for durability constraints. /// </summary> /// <param name="observeParams">The observe parameters.</param> /// <param name="op">The op.</param> /// <param name="replicaId">The replica identifier.</param> /// <returns></returns> private bool CheckReplica(ObserveParams observeParams, ObserveSeqno op, int replicaId) { var cloned = (ObserveSeqno)op.Clone(); var replica = observeParams.VBucket.LocateReplica(replicaId); var result = replica.Send(cloned); observeParams.CheckMutationLost(result); observeParams.CheckPersisted(result); observeParams.CheckReplicated(result); return(observeParams.IsDurabilityMet()); }
private async Task <bool> CheckReplicasAsync(ObserveParams observeParams) { if (observeParams.ReplicateTo == ReplicateTo.Zero) { return(true); } var replicas = observeParams.GetReplicas().Select(x => CheckReplicaAsync(observeParams, x)); await Task.WhenAll(replicas); return(observeParams.IsDurabilityMet()); }
async Task <bool> CheckReplicasAsync(ObserveParams observeParams, ObserveSeqno op) { var replicas = observeParams.GetReplicas(); var tasks = new List <Task <bool> >(); replicas.ForEach(x => tasks.Add(CheckReplicaAsync(observeParams, op, x))); await Task.WhenAll(tasks); return(observeParams.IsDurabilityMet()); }
static Task <bool> CheckReplicaAsync(ObserveParams observeParams, ObserveSeqno op, int replicaId) { var cloned = (ObserveSeqno)op.Clone(); var replica = observeParams.VBucket.LocateReplica(replicaId); var result = replica.Send(cloned); observeParams.CheckMutationLost(result.Value); observeParams.CheckPersisted(result.Value); observeParams.CheckReplicated(result.Value); return(Task.FromResult(observeParams.IsDurabilityMet())); }
/// <summary> /// Performs an observe event on the durability requirements specified on a key. /// </summary> /// <param name="key">The key to observe.</param> /// <param name="cas">The 'Check and Set' value of the key.</param> /// <param name="deletion">True if this is a delete operation.</param> /// <param name="replicateTo">The number of replicas that the key must be replicated to to satisfy the durability constraint.</param> /// <param name="persistTo">The number of replicas that the key must be persisted to to satisfy the durability constraint.</param> /// <returns>True if the durability constraints have been met.</returns> /// <exception cref="ReplicaNotConfiguredException">Thrown if the number of replicas requested /// in the ReplicateTo parameter does not match the # of replicas configured on the server.</exception> public bool Observe(string key, ulong cas, bool deletion, ReplicateTo replicateTo, PersistTo persistTo) { var criteria = GetDurabilityCriteria(deletion); var keyMapper = _configInfo.GetKeyMapper(); var vBucket = (IVBucket)keyMapper.MapKey(key); var p = new ObserveParams { Cas = cas, Criteria = criteria, Key = key, PersistTo = persistTo, ReplicateTo = replicateTo, VBucket = vBucket }; p.CheckConfiguredReplicas(); var operation = new Observe(key, vBucket, _clusterController.Transcoder, (uint)_timeout); do { var master = p.VBucket.LocatePrimary(); var result = master.Send(operation); var state = result.Value; if (state.KeyState == p.Criteria.PersistState) { Interlocked.Increment(ref p.PersistedToCount); } if (!deletion && p.HasMutated(state.Cas)) { return(false); } //First check if durability has already been met if (p.IsDurabilityMet()) { return(true); } //If not check each replica if (CheckReplicas(p, operation)) { return(true); } //prepare for another attempt operation = (Observe)operation.Clone(); p.Reset(); } while (!operation.TimedOut()); return(false); }
/// <summary> /// Checks the replicas to see if the key has met the durability constraints defined by the caller. /// </summary> /// <param name="observeParams">The observe parameters.</param> /// <param name="operation">The operation observe operation reference; will be cloned if reused.</param> /// <param name="replicateTo">The replication durability that must be met.</param> /// <param name="persistTo">The persistence durbaility that must be met.</param> /// <returns></returns> bool CheckReplicas(ObserveParams observeParams, Observe operation, ReplicateTo replicateTo, PersistTo persistTo) { //Get the candidate replicas, if none are defined that match the specified durability return false. var replicas = GetReplicas(observeParams.VBucket, replicateTo, persistTo); if (replicas.Count < (int)replicateTo) { return(false); } //Check each replica to see if has met the durability constraints specified. A mutation means we failed. var mutated = replicas.All(index => CheckReplica(observeParams, operation, index)); return(observeParams.IsDurabilityMet() && !mutated); }
private async Task <bool> CheckReplicasAsync(ObserveParams observeParams) { if (observeParams.ReplicateTo == ReplicateTo.Zero) { return(true); } var replicas = observeParams.GetReplicas().Select(x => CheckReplicaAsync(observeParams, x)).ToList(); //Wait for all tasks to finish await Task.WhenAll(replicas).ContinueOnAnyContext(); var notMutated = replicas.All(subtask => subtask.Result); var durabilityMet = observeParams.IsDurabilityMet(); return(durabilityMet && notMutated); }
/// <summary> /// Observes the specified key using the Seqno. /// </summary> /// <param name="key">The key.</param> /// <param name="token">The token.</param> /// <param name="replicateTo">The replicate to.</param> /// <param name="persistTo">The persist to.</param> /// <returns>True if durability constraints were matched.</returns> /// <exception cref="DocumentMutationLostException">Thrown if the observed document was lost during /// a hard failover because the document did not reach the replica in time.</exception> /// <exception cref="ReplicaNotConfiguredException">Thrown if the number of replicas requested /// in the ReplicateTo parameter does not match the # of replicas configured on the server.</exception> public bool Observe(MutationToken token, ReplicateTo replicateTo, PersistTo persistTo) { var keyMapper = (VBucketKeyMapper)_configInfo.GetKeyMapper(); var p = new ObserveParams { ReplicateTo = replicateTo, PersistTo = persistTo, Token = token, VBucket = keyMapper[token.VBucketId] }; p.CheckConfiguredReplicas(); var op = new ObserveSeqno(p.Token, _transcoder, _timeout); do { var master = p.VBucket.LocatePrimary(); var result = master.Send(op); var osr = result.Value; p.CheckMutationLost(osr); p.CheckPersisted(osr); if (p.IsDurabilityMet()) { return(true); } if (CheckReplicas(p, op)) { return(true); } //prepare for another attempt op = (ObserveSeqno)op.Clone(); p.Reset(); } while (!op.TimedOut()); return(false); }
private async Task <bool> CheckPersistToAsync(ObserveParams observeParams) { if (observeParams.PersistTo == PersistTo.Zero) { return(true); } var tcs = new TaskCompletionSource <IOperationResult <ObserveState> >(); var operation = new Observe(observeParams.Key, observeParams.VBucket, _clusterController.Transcoder, (uint)_timeout); operation.Completed = CallbackFactory.CompletedFuncForRetry(_pending, _clusterController, tcs); _pending.TryAdd(operation.Opaque, operation); var server = await GetServerAsync(observeParams); await server.SendAsync(operation).ContinueOnAnyContext(); var result = await tcs.Task.ContinueOnAnyContext(); Log.Debug("Master {0} - {1} key:{2}", server.EndPoint, result.Value, observeParams.Key); var state = result.Value; if (state.KeyState == observeParams.Criteria.PersistState) { Interlocked.Increment(ref observeParams.PersistedToCount); } //Key mutation detected so fail if (observeParams.HasMutated(state.Cas)) { Log.Debug("Mutation detected {0} - {1} - opaque: {2} key:{3}", server.EndPoint, result.Value, operation.Opaque, observeParams.Key); throw new DocumentMutationException(string.Format("Document mutation detected during observe for key '{0}'", observeParams.Key)); } //Check if durability requirements have been met if (observeParams.IsDurabilityMet()) { Log.Debug("Durability met {0} - {1} - opaque: {2} key:{3}", server.EndPoint, result.Value, operation.Opaque, observeParams.Key); return(true); } return(false); }
private async Task <bool> CheckReplicaAsync(ObserveParams observeParams, int replicaId) { var op = new ObserveSeqno(observeParams.Token, _clusterController.Transcoder, _timeout); observeParams.Operation = op; var tcs = new TaskCompletionSource <IOperationResult <ObserveSeqnoResponse> >(); op.Completed = CallbackFactory.CompletedFuncForRetry(_pending, _clusterController, tcs); _pending.TryAdd(op.Opaque, op); Log.Debug("checking replica {0} - opaque: {1}", replicaId, op.Opaque); var replica = observeParams.VBucket.LocateReplica(replicaId); await replica.SendAsync(op).ContinueOnAnyContext(); var response = await tcs.Task.ContinueOnAnyContext(); observeParams.CheckMutationLost(response); observeParams.CheckPersisted(response); observeParams.CheckReplicated(response); return(observeParams.IsDurabilityMet()); }
/// <summary> /// Asynchronously checks the replications status of a key. /// </summary> /// <param name="op">The <see cref="ObserveParams"/> object.</param> /// <param name="replicaIndex">The index of the replica within the <see cref="IVBucket"/></param> /// <returns>True if the durability requirements specified by <see cref="PersistTo"/> and <see cref="ReplicateTo"/> have been satisfied.</returns> static async Task<bool> CheckReplica(ObserveParams op, int replicaIndex) { Log.Debug(m=>m("checking replica {0}", replicaIndex)); if (op.IsDurabilityMet()) return true; var replica = op.VBucket.LocateReplica(replicaIndex); var result = await Task.Run(()=>replica.Send(new Observe(op.Key, op.VBucket, new AutoByteConverter()))); Log.Debug(m=>m("Replica {0} - {1} [0]", replica.EndPoint, result.Value, replicaIndex)); var state = result.Value; if (state.KeyState == op.Criteria.PersistState) { Interlocked.Increment(ref op.ReplicatedToCount); Interlocked.Increment(ref op.PersistedToCount); } else if (state.KeyState == op.Criteria.ReplicateState) { Interlocked.Increment(ref op.ReplicatedToCount); } return op.IsDurabilityMet() && !op.HasMutated(state.Cas); }
/// <summary> /// Checks the replicas to see if the key has met the durability constraints defined by the caller. /// </summary> /// <param name="observeParams">The observe parameters.</param> /// <param name="operation">The operation observe operation reference; will be cloned if reused.</param> /// <param name="replicateTo">The replication durability that must be met.</param> /// <param name="persistTo">The persistence durbaility that must be met.</param> /// <returns></returns> bool CheckReplicas(ObserveParams observeParams, Observe operation, ReplicateTo replicateTo, PersistTo persistTo) { //Get the candidate replicas, if none are defined that match the specified durability return false. var replicas = GetReplicas(observeParams.VBucket, replicateTo, persistTo); if (replicas.Count < (int)replicateTo) { return false; } //Check each replica to see if has met the durability constraints specified. A mutation means we failed. var mutated = replicas.All(index => CheckReplica(observeParams, operation, index)); return observeParams.IsDurabilityMet() && !mutated; }
private async Task<bool> CheckReplicasAsync(ObserveParams observeParams) { if (observeParams.ReplicateTo == ReplicateTo.Zero) return true; var replicas = observeParams.GetReplicas().Select(x=>CheckReplicaAsync(observeParams, x)); await Task.WhenAll(replicas); return observeParams.IsDurabilityMet(); }
async Task<bool> CheckReplicasAsync(ObserveParams observeParams, ObserveSeqno op) { var replicas = observeParams.GetReplicas(); var tasks = new List<Task<bool>>(); replicas.ForEach(x => tasks.Add(CheckReplicaAsync(observeParams, op, x))); await Task.WhenAll(tasks); return observeParams.IsDurabilityMet(); }
private async Task<bool> CheckReplicaAsync(ObserveParams observeParams, int replicaId) { var op = new ObserveSeqno(observeParams.Token, _clusterController.Transcoder, _timeout); observeParams.Operation = op; var tcs = new TaskCompletionSource<IOperationResult<ObserveSeqnoResponse>>(); op.Completed = CallbackFactory.CompletedFuncForRetry(_pending, _clusterController, tcs); _pending.TryAdd(op.Opaque, op); Log.Debug(m => m("checking replica {0} - opaque: {1}", replicaId, op.Opaque)); var replica = observeParams.VBucket.LocateReplica(replicaId); await replica.SendAsync(op).ContinueOnAnyContext(); var response = await tcs.Task.ContinueOnAnyContext(); observeParams.CheckMutationLost(response); observeParams.CheckPersisted(response); observeParams.CheckReplicated(response); return observeParams.IsDurabilityMet(); }
/// <summary> /// Performs an observe event on the durability requirements specified on a key. /// </summary> /// <param name="key">The key to observe.</param> /// <param name="cas">The 'Check and Set' value of the key.</param> /// <param name="deletion">True if this is a delete operation.</param> /// <param name="replicateTo">The number of replicas that the key must be replicated to to satisfy the durability constraint.</param> /// <param name="persistTo">The number of replicas that the key must be persisted to to satisfy the durability constraint.</param> /// <returns>True if the durability constraints have been met.</returns> /// <exception cref="ReplicaNotConfiguredException">Thrown if the number of replicas requested /// in the ReplicateTo parameter does not match the # of replicas configured on the server.</exception> public bool Observe(string key, ulong cas, bool deletion, ReplicateTo replicateTo, PersistTo persistTo) { var criteria = GetDurabilityCriteria(deletion); var keyMapper = _configInfo.GetKeyMapper(); var vBucket = (IVBucket)keyMapper.MapKey(key); var p = new ObserveParams { Cas = cas, Criteria = criteria, Key = key, PersistTo = persistTo, ReplicateTo = replicateTo, VBucket = vBucket }; p.CheckConfiguredReplicas(); var operation = new Observe(key, vBucket, _transcoder, (uint)_timeout); do { var master = p.VBucket.LocatePrimary(); var result = master.Send(operation); var state = result.Value; if (state.KeyState == p.Criteria.PersistState) { Interlocked.Increment(ref p.PersistedToCount); } if (!deletion && p.HasMutated(state.Cas)) { return false; } //First check if durability has already been met if (p.IsDurabilityMet()) { return true; } //If not check each replica if (CheckReplicas(p, operation)) { return true; } //prepare for another attempt operation = (Observe)operation.Clone(); p.Reset(); } while (!operation.TimedOut()); return false; }
/// <summary> /// Asynchronously checks the replications status of a key. /// </summary> /// <param name="observeParams">The <see cref="ObserveParams"/> object.</param> /// <param name="operation">The Observe operation.</param> /// <param name="replicaIndex">The replicaIndex of the replica within the <see cref="IVBucket"/></param> /// <returns>True if the durability requirements specified by <see cref="PersistTo"/> and <see cref="ReplicateTo"/> have been satisfied.</returns> static async Task<bool> CheckReplicaAsync(ObserveParams observeParams, Observe operation, int replicaIndex) { Log.Debug(m=>m("checking replica {0}", replicaIndex)); if (observeParams.IsDurabilityMet()) return true; //clone the operation since we already checked the primary and we want to maintain internal state (opaque, timer, etc) operation = (Observe)operation.Clone(); var replica = observeParams.VBucket.LocateReplica(replicaIndex); var result = await Task.Run(()=>replica.Send(operation)).ContinueOnAnyContext(); Log.Debug(m=>m("Replica {0} - {1} [0]", replica.EndPoint, result.Value, replicaIndex)); var state = result.Value; if (state.KeyState == observeParams.Criteria.PersistState) { Interlocked.Increment(ref observeParams.ReplicatedToCount); Interlocked.Increment(ref observeParams.PersistedToCount); } else if (state.KeyState == observeParams.Criteria.ReplicateState) { Interlocked.Increment(ref observeParams.ReplicatedToCount); } return !observeParams.HasMutated(state.Cas); }
private async Task<bool> CheckReplicasAsync(ObserveParams observeParams) { if (observeParams.ReplicateTo == ReplicateTo.Zero) return true; var replicas = observeParams.GetReplicas().Select(x=>CheckReplicaAsync(observeParams, x)).ToList(); //Wait for all tasks to finish await Task.WhenAll(replicas).ContinueOnAnyContext(); var notMutated = replicas.All(subtask => subtask.Result); var durabilityMet = observeParams.IsDurabilityMet(); return durabilityMet && notMutated; }
/// <summary> /// Checks a replica for durability constraints. /// </summary> /// <param name="observeParams">The observe parameters.</param> /// <param name="op">The op.</param> /// <param name="replicaId">The replica identifier.</param> /// <returns></returns> private bool CheckReplica(ObserveParams observeParams, ObserveSeqno op, int replicaId) { var cloned = (ObserveSeqno)op.Clone(); var replica = observeParams.VBucket.LocateReplica(replicaId); var result = replica.Send(cloned); observeParams.CheckMutationLost(result); observeParams.CheckPersisted(result); observeParams.CheckReplicated(result); return observeParams.IsDurabilityMet(); }
/// <summary> /// Checks the replicas to see if the key has met the durability constraints defined by the caller. /// </summary> /// <param name="observeParams">The observe parameters.</param> /// <param name="operation">The operation observe operation reference; will be cloned if reused.</param> /// <returns></returns> bool CheckReplicas(ObserveParams observeParams, Observe operation) { //Get the candidate replicas, if none are defined that match the specified durability return false. var replicas = observeParams.GetReplicas(); //Check each replica to see if has met the durability constraints specified. A mutation means we failed. var mutated = replicas.All(index => CheckReplica(observeParams, operation, index)); return observeParams.IsDurabilityMet() && !mutated; }
private async Task<bool> CheckPersistToAsync(ObserveParams observeParams) { if (observeParams.PersistTo == PersistTo.Zero) return true; var tcs = new TaskCompletionSource<IOperationResult<ObserveState>>(); var operation = new Observe(observeParams.Key, observeParams.VBucket, _clusterController.Transcoder, (uint)_timeout); operation.Completed = CallbackFactory.CompletedFuncForRetry(_pending, _clusterController, tcs); _pending.TryAdd(operation.Opaque, operation); var server = await GetServerAsync(observeParams); await server.SendAsync(operation).ContinueOnAnyContext(); var result = await tcs.Task.ContinueOnAnyContext(); Log.Debug(m => m("Master {0} - {1} key:{2}", server.EndPoint, result.Value, observeParams.Key)); var state = result.Value; if (state.KeyState == observeParams.Criteria.PersistState) { Interlocked.Increment(ref observeParams.PersistedToCount); } //Key mutation detected so fail if (observeParams.HasMutated(state.Cas)) { Log.Debug(m => m("Mutation detected {0} - {1} - opaque: {2} key:{3}",server.EndPoint, result.Value, operation.Opaque, observeParams.Key)); throw new DocumentMutationException(string.Format("Document mutation detected during observe for key '{0}'", observeParams.Key)); } //Check if durability requirements have been met if (observeParams.IsDurabilityMet()) { Log.Debug(m => m("Durability met {0} - {1} - opaque: {2} key:{3}", server.EndPoint, result.Value, operation.Opaque, observeParams.Key)); return true; } return false; }
/// <summary> /// Observes the specified key using the Seqno. /// </summary> /// <param name="key">The key.</param> /// <param name="token">The token.</param> /// <param name="replicateTo">The replicate to.</param> /// <param name="persistTo">The persist to.</param> /// <returns>True if durability constraints were matched.</returns> /// <exception cref="DocumentMutationLostException">Thrown if the observed document was lost during /// a hard failover because the document did not reach the replica in time.</exception> /// <exception cref="ReplicaNotConfiguredException">Thrown if the number of replicas requested /// in the ReplicateTo parameter does not match the # of replicas configured on the server.</exception> public bool Observe(MutationToken token, ReplicateTo replicateTo, PersistTo persistTo) { var keyMapper = (VBucketKeyMapper)_configInfo.GetKeyMapper(); var p = new ObserveParams { ReplicateTo = replicateTo, PersistTo = persistTo, Token = token, VBucket = keyMapper[token.VBucketId] }; p.CheckConfiguredReplicas(); var op = new ObserveSeqno(p.Token, _transcoder, _timeout); do { var master = p.VBucket.LocatePrimary(); var result = master.Send(op); var osr = result.Value; p.CheckMutationLost(osr); p.CheckPersisted(osr); if (p.IsDurabilityMet()) { return true; } if (CheckReplicas(p, op)) { return true; } //prepare for another attempt op = (ObserveSeqno)op.Clone(); p.Reset(); } while (!op.TimedOut()); return false; }
/// <summary> /// Asynchronously checks the replications status of a key. /// </summary> /// <param name="observeParams">The <see cref="ObserveParams"/> object.</param> /// <param name="replicaIndex">The replicaIndex of the replica within the <see cref="IVBucket"/></param> /// <returns>True if the durability requirements specified by <see cref="PersistTo"/> and <see cref="ReplicateTo"/> have been satisfied.</returns> private async Task<bool> CheckReplicaAsync(ObserveParams observeParams, int replicaIndex) { if (observeParams.IsDurabilityMet()) return true; var operation = new Observe(observeParams.Key, observeParams.VBucket, _clusterController.Transcoder, (uint)_timeout); var tcs = new TaskCompletionSource<IOperationResult<ObserveState>>(); operation.Completed = CallbackFactory.CompletedFuncForRetry(_pending, _clusterController, tcs); _pending.TryAdd(operation.Opaque, operation); var replica = observeParams.VBucket.LocateReplica(replicaIndex); await replica.SendAsync(operation).ContinueOnAnyContext(); var result = await tcs.Task.ContinueOnAnyContext(); Log.Debug(m=>m("Replica {0} - {1} {2} - opaque: {3} key:{4}", replica.EndPoint, result.Value.KeyState, replicaIndex, operation.Opaque, observeParams.Key)); var state = result.Value; if (state.KeyState == observeParams.Criteria.PersistState) { Interlocked.Increment(ref observeParams.ReplicatedToCount); Interlocked.Increment(ref observeParams.PersistedToCount); } else if (state.KeyState == observeParams.Criteria.ReplicateState) { Interlocked.Increment(ref observeParams.ReplicatedToCount); } return !observeParams.HasMutated(state.Cas); }
static Task<bool> CheckReplicaAsync(ObserveParams observeParams, ObserveSeqno op, int replicaId) { var cloned = (ObserveSeqno)op.Clone(); var replica = observeParams.VBucket.LocateReplica(replicaId); var result = replica.Send(cloned); observeParams.CheckMutationLost(result.Value); observeParams.CheckPersisted(result.Value); observeParams.CheckReplicated(result.Value); return Task.FromResult(observeParams.IsDurabilityMet()); }
private async Task<bool> CheckPersistToAsync(ObserveParams observeParams) { if (observeParams.PersistTo == PersistTo.Zero) return true; var op = new ObserveSeqno(observeParams.Token, _clusterController.Transcoder, _timeout); observeParams.Operation = op; var tcs = new TaskCompletionSource<IOperationResult<ObserveSeqnoResponse>>(); op.Completed = CallbackFactory.CompletedFuncForRetry(_pending, _clusterController, tcs); _pending.TryAdd(op.Opaque, op); var server = await GetServerAsync(observeParams); await server.SendAsync(op).ContinueOnAnyContext(); var response = await tcs.Task.ContinueOnAnyContext(); observeParams.CheckMutationLost(response); observeParams.CheckPersisted(response); return observeParams.IsDurabilityMet(); }