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()); }
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())); }
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()); }
/// <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> /// 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); }
public void Test_ObserveSeqno2() { var key = "bar"; var delete = new Delete(key, GetVBucket(), Transcoder, OperationLifespanTimeout); var deleteResult = IOService.Execute(delete); var features = new List<short>(); features.Add((short)ServerFeatures.MutationSeqno); var hello = new Hello("couchbase-net-sdk/2.1.4", features.ToArray(), Transcoder, 0, 0); var result = IOService.Execute(hello); Assert.IsTrue(result.Success); var add = new Add<string>(key, "foo", GetVBucket(), Transcoder, OperationLifespanTimeout); var result2 = IOService.Execute(add); var observeSeqno = new ObserveSeqno(result2.Token, Transcoder, 1000); var observeSeqnoResult = IOService.Execute(observeSeqno); Assert.IsTrue(observeSeqnoResult.Success); }
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()); }
public void Test_ObserveSeqno2() { var key = "bar"; var delete = new Delete(key, GetVBucket(), Transcoder, OperationLifespanTimeout); var deleteResult = IOStrategy.Execute(delete); var features = new List <short>(); features.Add((short)ServerFeatures.MutationSeqno); var hello = new Hello("couchbase-net-sdk/2.1.4", features.ToArray(), Transcoder, 0, 0); var result = IOStrategy.Execute(hello); Assert.IsTrue(result.Success); var add = new Add <string>(key, "foo", GetVBucket(), Transcoder, OperationLifespanTimeout); var result2 = IOStrategy.Execute(add); var observeSeqno = new ObserveSeqno(result2.Token, Transcoder, 1000); var observeSeqnoResult = IOStrategy.Execute(observeSeqno); Assert.IsTrue(observeSeqnoResult.Success); }
/// <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 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> /// Checks the replicas for durability constraints. /// </summary> /// <param name="observeParams">The observe parameters.</param> /// <param name="op">The op.</param> /// <returns></returns> bool CheckReplicas(ObserveParams observeParams, ObserveSeqno op) { var replicas = observeParams.GetReplicas(); return(replicas.Any(replicaId => CheckReplica(observeParams, op, replicaId))); }
/// <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(); }
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> /// 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> /// Checks the replicas for durability constraints. /// </summary> /// <param name="observeParams">The observe parameters.</param> /// <param name="op">The op.</param> /// <returns></returns> bool CheckReplicas(ObserveParams observeParams, ObserveSeqno op) { var replicas = observeParams.GetReplicas(); return replicas.Any(replicaId => CheckReplica(observeParams, op, replicaId)); }
/// <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(); } }
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(); }