Beispiel #1
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();
            }
        }
        /// <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);
        }
Beispiel #3
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);
        }
        /// <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;
        }