/// <summary> /// Performs an observe event on the durability requirements specified on a key asynchronously /// </summary> /// <param name="token">The <see cref="MutationToken"/> to compare against.</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> /// <param name="cts"></param> /// <returns> A <see cref="Task{boolean}"/> representing the aynchronous operation.</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 async Task <bool> ObserveAsync(MutationToken token, ReplicateTo replicateTo, PersistTo persistTo, CancellationTokenSource cts) { var keyMapper = (VBucketKeyMapper)_configInfo.GetKeyMapper(); var obParams = new ObserveParams { ReplicateTo = replicateTo, PersistTo = persistTo, Token = token, VBucket = keyMapper[token.VBucketId] }; obParams.CheckConfiguredReplicas(); var persisted = await CheckPersistToAsync(obParams).ContinueOnAnyContext(); var replicated = await CheckReplicasAsync(obParams).ContinueOnAnyContext(); if (persisted && replicated) { Log.Debug("Persisted and replicated on first try: {0}", _key); return(true); } return(await ObserveEveryAsync(async p => { Log.Debug("trying again: {0}", _key); persisted = await CheckPersistToAsync(obParams).ContinueOnAnyContext(); replicated = await CheckReplicasAsync(obParams).ContinueOnAnyContext(); return persisted & replicated; }, obParams, _interval, cts.Token)); }
public async Task <bool> ObserveAsync(string key, ulong cas, bool deletion, ReplicateTo replicateTo, PersistTo persistTo, CancellationTokenSource cts) { var criteria = GetDurabilityCriteria(deletion); var keyMapper = _configInfo.GetKeyMapper(); var vBucket = (IVBucket)keyMapper.MapKey(key); var observeParams = new ObserveParams { Cas = cas, Criteria = criteria, Key = key, PersistTo = persistTo, ReplicateTo = replicateTo, VBucket = vBucket }; observeParams.CheckConfiguredReplicas(); var persisted = await CheckPersistToAsync(observeParams).ContinueOnAnyContext(); var replicated = await CheckReplicasAsync(observeParams).ContinueOnAnyContext(); if (persisted && replicated) { return(true); } return(await ObserveEveryAsync(async p => { Log.Debug("trying again: {0}", key); persisted = await CheckPersistToAsync(observeParams).ContinueOnAnyContext(); replicated = await CheckReplicasAsync(observeParams).ContinueOnAnyContext(); return persisted & replicated; }, observeParams, _interval, cts.Token)); }
/// <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> /// Performs an observe event on the durability requirements specified on a key asynchronously /// </summary> /// <param name="token">The <see cref="MutationToken"/> to compare against.</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> A <see cref="Task{bool}"/> representing the aynchronous operation.</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 async Task <bool> ObserveAsync(MutationToken token, ReplicateTo replicateTo, PersistTo persistTo) { var keyMapper = (VBucketKeyMapper)_configInfo.GetKeyMapper(); var obParams = new ObserveParams { ReplicateTo = replicateTo, PersistTo = persistTo, Token = token, VBucket = keyMapper[token.VBucketId] }; obParams.CheckConfiguredReplicas(); var op = new ObserveSeqno(obParams.Token, _transcoder, _timeout); using (var cts = new CancellationTokenSource((int)_timeout)) { //perform the observe operation at the set interval and terminate if not successful by the timeout var task = await ObserveEvery(async p => { IServer master; var attempts = 0; while ((master = p.VBucket.LocatePrimary()) == null) { if (attempts++ > 10) { throw new TimeoutException("Could not acquire a server."); } await Task.Delay((int)Math.Pow(2, attempts)).ContinueOnAnyContext(); } var result = master.Send(op); var osr = result.Value; p.CheckMutationLost(osr); p.CheckPersisted(osr); if (p.IsDurabilityMet()) { return(true); } return(await CheckReplicasAsync(p, op).ContinueOnAnyContext()); }, obParams, _interval, op, cts.Token).ContinueOnAnyContext(); return(task); } }
/// <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> /// Performs an observe event on the durability requirements specified on a key asynchronously /// </summary> /// <param name="token">The <see cref="MutationToken"/> to compare against.</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> A <see cref="Task{bool}"/> representing the aynchronous operation.</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 async Task<bool> ObserveAsync(MutationToken token, ReplicateTo replicateTo, PersistTo persistTo) { var keyMapper = (VBucketKeyMapper)_configInfo.GetKeyMapper(); var obParams = new ObserveParams { ReplicateTo = replicateTo, PersistTo = persistTo, Token = token, VBucket = keyMapper[token.VBucketId] }; obParams.CheckConfiguredReplicas(); var op = new ObserveSeqno(obParams.Token, _transcoder, _timeout); using (var cts = new CancellationTokenSource((int)_timeout)) { //perform the observe operation at the set interval and terminate if not successful by the timeout var task = await ObserveEvery(async p => { IServer master; var attempts = 0; while ((master = p.VBucket.LocatePrimary()) == null) { if (attempts++ > 10) { throw new TimeoutException("Could not acquire a server."); } await Task.Delay((int)Math.Pow(2, attempts)).ContinueOnAnyContext(); } var result = master.Send(op); var osr = result.Value; p.CheckMutationLost(osr); p.CheckPersisted(osr); if (p.IsDurabilityMet()) { return true; } return await CheckReplicasAsync(p, op).ContinueOnAnyContext(); }, obParams, _interval, op, cts.Token).ContinueOnAnyContext(); return task; } }
/// <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> /// Performs an observe event on the durability requirements specified on a key asynchronously /// </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> A <see cref="Task{bool}"/> representing the aynchronous operation.</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 async Task<bool> ObserveAsync(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 observeParams = new ObserveParams { Cas = cas, Criteria = criteria, Key = key, PersistTo = persistTo, ReplicateTo = replicateTo, VBucket = vBucket }; observeParams.CheckConfiguredReplicas(); var operation = new Observe(key, vBucket, _transcoder, (uint)_timeout); //Used to terminate the loop at the specific timeout using (var cts = new CancellationTokenSource(_timeout)) { //perform the observe operation at the set interval and terminate if not successful by the timeout var task = await ObserveEvery(async p => { //check the master for persistence to disk IServer master; var attempts = 0; while ((master = p.VBucket.LocatePrimary()) == null) { if (attempts++ > 10) { throw new TimeoutException("Could not acquire a server."); } await Task.Delay((int) Math.Pow(2, attempts)); } var result = master.Send(operation); Log.Debug(m => m("Master {0} - {1}", master.EndPoint, result.Value)); var state = result.Value; if (state.KeyState == p.Criteria.PersistState) { Interlocked.Increment(ref p.PersistedToCount); } //Key mutation detected so fail if (p.HasMutated(state.Cas)) { return false; } //Check if durability requirements have been met if (p.IsDurabilityMet()) { return true; } //Run the durability requirement check on each replica var tasks = new List<Task<bool>>(); var replicas = p.GetReplicas(); replicas.ForEach(x => tasks.Add(CheckReplicaAsync(p, operation, x))); //Wait for all tasks to finish await Task.WhenAll(tasks.ToArray()).ContinueOnAnyContext(); var mutated = tasks.All(subtask => subtask.Result); return p.IsDurabilityMet() && !mutated; }, observeParams, operation, _interval, cts.Token).ContinueOnAnyContext(); return task; } }
public async Task<bool> ObserveAsync(string key, ulong cas, bool deletion, ReplicateTo replicateTo, PersistTo persistTo, CancellationTokenSource cts) { var criteria = GetDurabilityCriteria(deletion); var keyMapper = _configInfo.GetKeyMapper(); var vBucket = (IVBucket)keyMapper.MapKey(key); var observeParams = new ObserveParams { Cas = cas, Criteria = criteria, Key = key, PersistTo = persistTo, ReplicateTo = replicateTo, VBucket = vBucket }; observeParams.CheckConfiguredReplicas(); var persisted = await CheckPersistToAsync(observeParams).ContinueOnAnyContext(); var replicated = await CheckReplicasAsync(observeParams).ContinueOnAnyContext(); if (persisted && replicated) { return true; } return await ObserveEveryAsync(async p => { Log.DebugFormat("trying again: {0}", key); persisted = await CheckPersistToAsync(observeParams).ContinueOnAnyContext(); replicated = await CheckReplicasAsync(observeParams).ContinueOnAnyContext(); return persisted & replicated; }, observeParams, _interval, cts.Token); }
/// <summary> /// Performs an observe event on the durability requirements specified on a key asynchronously /// </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> A <see cref="Task{bool}"/> representing the aynchronous operation.</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 async Task <bool> ObserveAsync(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 observeParams = new ObserveParams { Cas = cas, Criteria = criteria, Key = key, PersistTo = persistTo, ReplicateTo = replicateTo, VBucket = vBucket }; observeParams.CheckConfiguredReplicas(); var operation = new Observe(key, vBucket, _transcoder, (uint)_timeout); //Used to terminate the loop at the specific timeout using (var cts = new CancellationTokenSource(_timeout)) { //perform the observe operation at the set interval and terminate if not successful by the timeout var task = await ObserveEvery(async p => { //check the master for persistence to disk IServer master; var attempts = 0; while ((master = p.VBucket.LocatePrimary()) == null) { if (attempts++ > 10) { throw new TimeoutException("Could not acquire a server."); } await Task.Delay((int)Math.Pow(2, attempts)); } var result = master.Send(operation); Log.Debug(m => m("Master {0} - {1}", master.EndPoint, result.Value)); var state = result.Value; if (state.KeyState == p.Criteria.PersistState) { Interlocked.Increment(ref p.PersistedToCount); } //Key mutation detected so fail if (p.HasMutated(state.Cas)) { return(false); } //Check if durability requirements have been met if (p.IsDurabilityMet()) { return(true); } //Run the durability requirement check on each replica var tasks = new List <Task <bool> >(); var replicas = p.GetReplicas(); replicas.ForEach(x => tasks.Add(CheckReplicaAsync(p, operation, x))); //Wait for all tasks to finish await Task.WhenAll(tasks.ToArray()).ContinueOnAnyContext(); var notMutated = tasks.All(subtask => subtask.Result); return(p.IsDurabilityMet() && notMutated); }, observeParams, operation, _interval, cts.Token).ContinueOnAnyContext(); return(task); } }
/// <summary> /// Performs an observe event on the durability requirements specified on a key asynchronously /// </summary> /// <param name="token">The <see cref="MutationToken"/> to compare against.</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> /// <param name="cts"></param> /// <returns> A <see cref="Task{boolean}"/> representing the aynchronous operation.</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 async Task<bool> ObserveAsync(MutationToken token, ReplicateTo replicateTo, PersistTo persistTo, CancellationTokenSource cts) { var keyMapper = (VBucketKeyMapper) _configInfo.GetKeyMapper(); var obParams = new ObserveParams { ReplicateTo = replicateTo, PersistTo = persistTo, Token = token, VBucket = keyMapper[token.VBucketId] }; obParams.CheckConfiguredReplicas(); var persisted = await CheckPersistToAsync(obParams).ContinueOnAnyContext(); var replicated = await CheckReplicasAsync(obParams).ContinueOnAnyContext(); if (persisted && replicated) { Log.DebugFormat("Persisted and replicated on first try: {0}", _key); return true; } return await ObserveEveryAsync(async p => { Log.DebugFormat("trying again: {0}", _key); persisted = await CheckPersistToAsync(obParams).ContinueOnAnyContext(); replicated = await CheckReplicasAsync(obParams).ContinueOnAnyContext(); return persisted & replicated; }, obParams, _interval, cts.Token); }