Esempio n. 1
0
        /// <summary>
        /// Updates or Adds the object to the cluster.
        /// </summary>
        /// <param name="key">key of the entry.</param>
        /// <returns>cache entry.</returns>
        /// <remarks>
        /// This method invokes <see cref="handleInsert"/> on the specified node.
        /// </remarks>
        protected CacheInsResultWithEntry Clustered_Insert(Address dest, object key, CacheEntry cacheEntry, string taskId, object lockId, ulong version, LockAccessType accessType, OperationContext operationContext)
        {
            if (ServerMonitor.MonitorActivity)
            {
                ServerMonitor.LogClientActivity("PartCacheBase.Insert", "");
            }
            CacheInsResultWithEntry retVal = null;
            CacheEntry cloneValue          = null;

            try
            {
                operationContext?.MarkInUse(NCModulesConstants.Topology);

                Array userPayLoad; long payLoadSize;
                _context.CachingSubSystemDataService.GetEntryClone(cacheEntry, out cloneValue, out userPayLoad, out payLoadSize);

                Function func = new Function((int)OpCodes.Insert, new object[] { key, cloneValue, taskId, lockId, accessType, version, operationContext });
                func.UserPayload      = userPayLoad;
                func.ResponseExpected = true;
                object result = Cluster.SendMessage(dest, func, GroupRequest.GET_FIRST, false);
                if (result == null)
                {
                    return(retVal);
                }

                retVal = (CacheInsResultWithEntry)((OperationResponse)result).SerializablePayload;
                if (retVal.Entry != null && ((OperationResponse)result).UserPayload != null)
                {
                    retVal.Entry.Value = ((OperationResponse)result).UserPayload;
                }
            }
            catch (Runtime.Exceptions.SuspectedException se)
            {
                throw;
            }
            catch (Runtime.Exceptions.TimeoutException te)
            {
                throw;
            }
            catch (CacheException e)
            {
                throw;
            }
            catch (Exception e)
            {
                throw new GeneralFailureException(e.Message, e);
            }
            finally
            {
                operationContext?.MarkFree(NCModulesConstants.Topology);
                if (retVal == null)
                {
                    retVal = CacheInsResultWithEntry.CreateCacheInsResultWithEntry(_context.TransactionalPoolManager);
                }

                MiscUtil.ReturnEntryToPool(cloneValue, Context.TransactionalPoolManager);
            }
            return(retVal);
        }
Esempio n. 2
0
        /// <summary>
        /// Returns the set of nodes where the insertion was performed as an atomic operation.
        /// </summary>
        /// <param name="results">responses collected from all members of cluster.</param>
        /// <returns>list of nodes where the operation succeeded</returns>
        public static CacheInsResultWithEntry FindAtomicInsertStatusReplicated(RspList results, PoolManager poolManager)
        {
            int needEvictCount = 0;
            int timeoutCount   = 0;
            int suspectedCount = 0;
            int successCount   = 0;

            CacheInsResultWithEntry res = new CacheInsResultWithEntry();

            if (results == null)
            {
                return(res);
            }

            for (int i = 0; i < results.size(); i++)
            {
                Rsp rsp = (Rsp)results.elementAt(i);

                if (!rsp.wasReceived() && !rsp.wasSuspected())
                {
                    timeoutCount++;
                    continue;
                }

                if (rsp.wasSuspected())
                {
                    suspectedCount++;
                    continue;
                }

                res = (CacheInsResultWithEntry)((OperationResponse)rsp.Value).SerializablePayload;
                if (res == null)
                {
                    res = CacheInsResultWithEntry.CreateCacheInsResultWithEntry(poolManager);
                }
                if (res.Result == CacheInsResult.Success || res.Result == CacheInsResult.SuccessOverwrite)
                {
                    successCount++;
                }

                /* If all the nodes in the Cluster return NeedsEviction response then we do not need to remove */
                if (res.Result == CacheInsResult.NeedsEviction)
                {
                    needEvictCount++;
                }
            }

            if (needEvictCount == results.size())
            {
                //every node returned the NeedEviction; so we need not remove the item
                //as data is not corrupted.
                res.Result = CacheInsResult.NeedsEvictionNotRemove;
            }

            if (timeoutCount > 0 && (timeoutCount + successCount == results.size()))
            {
                if (successCount > 0)
                {
                    //operation is not succeeded on some of the nodes; therefore we throw timeout exception.
                    res.Result = CacheInsResult.PartialTimeout;
                }
                else
                {
                    //operation timed out on all of the node; no need to rollback.
                    res.Result = CacheInsResult.FullTimeout;
                }
            }
            if (timeoutCount > 0 && suspectedCount > 0)
            {
                if (successCount > 0)
                {
                    //operation is not succeeded on some of the nodes; therefore we throw timeout exception.
                    res.Result = CacheInsResult.PartialTimeout;
                }
                else
                {
                    //operation timed out on all of the node; no need to rollback.
                    res.Result = CacheInsResult.FullTimeout;
                }
            }

            return(res);
        }