Example #1
0
        public long GetAndSubtract(long delta)
        {
            var targetAddress   = GetCRDTOperationTarget(_emptyAddressList);
            var response        = InvokeAddInternal(-delta, true, _emptyAddressList, null, targetAddress);
            var decodedResponse = PNCounterAddCodec.DecodeResponse(response);

            UpdateObservedReplicaTimestamps(decodedResponse.replicaTimestamps);

            return(decodedResponse.value);
        }
Example #2
0
        public long IncrementAndGet()
        {
            var targetAddress   = GetCRDTOperationTarget(_emptyAddressList);
            var response        = InvokeAddInternal(1, false, _emptyAddressList, null, targetAddress);
            var decodedResponse = PNCounterAddCodec.DecodeResponse(response);

            UpdateObservedReplicaTimestamps(decodedResponse.replicaTimestamps);

            return(decodedResponse.value);
        }
Example #3
0
        /// <summary>
        /// Adds the delta and returns the value of the counter before the update
        /// if getBeforeUpdate" is true or the value after the update if it is false.
        /// It will invoke client messages recursively on viable replica addresses
        /// until successful or the list of viable replicas is exhausted.
        /// Replicas with addresses contained in the excludedAddresses are skipped.
        /// If there are no viable replicas, this method will throw the lastException if not null
        /// or a NoDataMemberInClusterException if the lastException is null.
        /// </summary>
        /// <param name="delta">the delta to add to the counter value, can be negative</param>
        /// <param name="getBeforeUpdate">true if the operation should return the counter value before the addition,
        /// false if it should return the value after the addition</param>
        /// <param name="excludedAddresses">the addresses to exclude when choosing a replica address, must not be null</param>
        /// <param name="lastException">the exception thrown from the last invocation of the request on a replica, may be null</param>
        /// <param name="targetAddress">the target address</param>
        /// <returns>the result of the request invocation on a replica</returns>
        /// <exception cref="NoDataMemberInClusterException">if there are no replicas and the lastException is null</exception>
        internal IClientMessage InvokeAddInternal(long delta, bool getBeforeUpdate, HashSet <Address> excludedAddresses, Exception lastException, Address targetAddress)
        {
            if (targetAddress == null)
            {
                if (lastException != null)
                {
                    throw lastException;
                }

                throw new NoDataMemberInClusterException("Cannot invoke operations on a CRDT because the cluster does not contain any data members");
            }

            try
            {
                var request = PNCounterAddCodec.EncodeRequest(GetName(), delta, getBeforeUpdate, _observedClock.EntrySet(), targetAddress);
                return(InvokeOnTarget(request, targetAddress));
            }
            catch (Exception ex)
            {
                Logger.GetLogger(GetType()).Finest("Unable to provide session guarantees when sending operations to " +
                                                   targetAddress.ToString() + ", choosing different target. Cause: " +
                                                   ex.ToString());

                // Make sure that this only affects the local variable of the method
                if (excludedAddresses == _emptyAddressList)
                {
                    excludedAddresses = new HashSet <Address>();
                }

                // Add current/failed address to exclusion list
                excludedAddresses.Add(targetAddress);

                // Look for the new target address (taking into account exclusion list)
                var newTarget = GetCRDTOperationTarget(excludedAddresses);

                // Send null target address in case it's uninitialized instance
                return(InvokeAddInternal(delta, getBeforeUpdate, excludedAddresses, ex, newTarget));
            }
        }