/// <summary> /// Observes a set of keys at a specified interval and timeout. /// </summary> /// <param name="observe">The func to call at the specific interval</param> /// <param name="observeParams">The parameters to pass in.</param> /// <param name="interval">The interval to check.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> to use to terminate the observation at the specified timeout.</param> /// <returns>True if the durability requirements specified by <see cref="PersistTo"/> and <see cref="ReplicateTo"/> have been satisfied.</returns> static async Task <bool> ObserveEvery(Func <ObserveParams, Task <bool> > observe, ObserveParams observeParams, int interval, ObserveSeqno op, CancellationToken cancellationToken) { while (true) { var result = await observe(observeParams).ContinueOnAnyContext(); if (result) { return(true); } var task = Task.Delay(interval, cancellationToken).ContinueOnAnyContext(); try { await task; } catch (TaskCanceledException) { return(false); } //prepare for a second attempt op = (ObserveSeqno)op.Clone(); observeParams.Reset(); } }
/// <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> /// 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> /// 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> /// Observes a set of keys at a specified interval and timeout. /// </summary> /// <param name="observe">The func to call at the specific interval</param> /// <param name="observeParams">The parameters to pass in.</param> /// <param name="interval">The interval to check.</param> /// <param name="cancellationToken">The <see cref="CancellationToken"/> to use to terminate the observation at the specified timeout.</param> /// <returns>True if the durability requirements specified by <see cref="PersistTo"/> and <see cref="ReplicateTo"/> have been satisfied.</returns> static async Task<bool> ObserveEvery(Func<ObserveParams, Task<bool>> observe, ObserveParams observeParams, int interval, ObserveSeqno op, CancellationToken cancellationToken) { while (true) { var result = await observe(observeParams).ContinueOnAnyContext(); if (result) { return true; } var task = Task.Delay(interval, cancellationToken).ContinueOnAnyContext(); try { await task; } catch (TaskCanceledException) { return false; } //prepare for a second attempt op = (ObserveSeqno)op.Clone(); observeParams.Reset(); } }
/// <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; }