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());
        }
示例#2
0
        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()));
        }
示例#3
0
        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());
        }
示例#5
0
        /// <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);
            }
        }
示例#6
0
        /// <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;
            }
        }
示例#12
0
        /// <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));
 }
示例#18
0
        /// <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();
        }