Exemple #1
0
        public static bool FindAtomicLockStatusReplicated(RspList results, ref object lockId, ref DateTime lockDate)
        {
            bool        res      = true;
            LockOptions lockInfo = null;

            if (results == null)
            {
                return(res);
            }
            int lockAcquired = 0;
            int itemNotFound = 0;
            int rspReceived  = results.size();

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

                if (rsp.wasSuspected())
                {
                    rspReceived--;
                    continue;
                }
                if (!rsp.wasReceived())
                {
                    rspReceived--;
                    continue;
                }

                lockInfo = (LockOptions)rsp.Value;
                if (Object.Equals(lockInfo.LockId, lockId))
                {
                    lockDate = lockInfo.LockDate;
                    lockAcquired++;
                }
                else
                {
                    if (lockInfo.LockId == null)
                    {
                        //item was not present on the node.
                        lockId   = null;
                        lockDate = new DateTime();
                        itemNotFound++;
                    }
                    else
                    {
                        res      = false;
                        lockId   = lockInfo.LockId;
                        lockDate = lockInfo.LockDate;
                        break;
                    }
                }
            }
            if (lockAcquired > 0 && (lockAcquired + itemNotFound == rspReceived))
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
Exemple #2
0
        /// <summary>
        /// Returns the set of nodes where the addition 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 CacheAddResult FindAtomicAddStatusReplicated(RspList results)
        {
            CacheAddResult res = CacheAddResult.Failure;

            if (results == null)
            {
                return(res);
            }
            int timeoutCount   = 0;
            int suspectedCount = 0;
            int successCount   = 0;

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

                if (rsp.wasSuspected())
                {
                    //throw new Alachisoft.NGroups.SuspectedException(rsp.Sender);
                    suspectedCount++;
                    continue;
                }
                if (!rsp.wasReceived() && !rsp.wasSuspected())
                {
                    //throw new Alachisoft.NGroups.TimeoutException();
                    timeoutCount++;
                    continue;
                }
                res = (CacheAddResult)rsp.Value;
                if (res == CacheAddResult.Success)
                {
                    successCount++;
                }
                if (res != CacheAddResult.Success && res != CacheAddResult.KeyExists)
                {
                    return(res);
                }
            }
            if (suspectedCount > 0 && successCount > 0 && (suspectedCount + successCount == results.size()))
            {
                //as operation is successfull on all other nodes other than suspected node(s).
                return(CacheAddResult.Success);
            }
            if (timeoutCount > 0 && (timeoutCount + successCount == results.size()))
            {
                if (successCount > 0)
                {
                    //operation is not succeeded on some of the nodes; therefore we throw timeout exception.
                    return(CacheAddResult.PartialTimeout);
                }
                else
                {
                    //operation timed out on all of the node; no need to rollback.
                    return(CacheAddResult.FullTimeout);
                }
            }
            if (timeoutCount > 0 && suspectedCount > 0)
            {
                if (successCount > 0)
                {
                    return(CacheAddResult.PartialTimeout);
                }
                else
                {
                    return(CacheAddResult.FullTimeout);
                }
            }

            return(res);
        }
Exemple #3
0
 public static Rsp FindAtomicRemoveStatusReplicated(RspList results)
 {
     return(FindAtomicRemoveStatusReplicated(results, null));
 }
Exemple #4
0
        public static void ValidateResponses(RspList results, Type type, string serializationContext, Boolean throwSuspected = false)
        {
            if (results == null)
            {
                return;
            }
            ArrayList parserExceptions = new ArrayList();
            ArrayList exceptions       = new ArrayList(11);

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

                if (rsp.wasSuspected())
                {
                    if (throwSuspected)
                    {
                        throw new NGroups.SuspectedException(rsp.Sender);
                    }
                    continue;
                }

                if (!rsp.wasReceived())
                {
                    continue;
                }

                if (rsp.Value != null)
                {
                    object rspValue = rsp.Value;
                    if ((rspValue as Exception) is Alachisoft.NCache.Runtime.Exceptions.InvalidReaderException)
                    {
                        Exception invlidReader = rspValue as Exception;
                        throw invlidReader;
                    }
                    if (rspValue is ParserException)
                    {
                        parserExceptions.Add((ParserException)rspValue);
                        continue;
                    }



                    var licenseException = rspValue as LicensingException;

                    if (licenseException != null)
                    {
                        throw licenseException;
                    }

                    if (rspValue is Exception)
                    {
                        exceptions.Add((Exception)rspValue);
                        continue;
                    }

                    if (type != null && !rspValue.GetType().Equals(type))
                    {
                        exceptions.Add(new Alachisoft.NCache.Runtime.Exceptions.BadResponseException("bad response returned by group member " + rsp.Sender));
                        continue;
                    }
                }
            }
            //in case or partitioned caches search requests are broadcasted.
            //it is possible that tag index are defined on one node but not defined on some other node.
            //we will throw the exception back only if we receive exception from every node.
            try
            {
                if (parserExceptions.Count == results.size())
                {
                    if (parserExceptions[0] is ParserException)
                    {
                        throw parserExceptions[0] as ParserException;
                    }
                }
            }
            catch (Exception e)
            {
                if (NCacheLogger != null && NCacheLogger.IsErrorEnabled)
                {
                    NCacheLogger.Error("ClusterHelper.ValidateResponses()", "parserExceptions Count: " + parserExceptions.Count + " results Count: " + results.size() + " Error: " + e.ToString());
                }
                throw;
            }
            bool aggregateVerified = true;

            if (exceptions.Count == 1)
            {
                Exception e = exceptions[0] as Exception;
                if (e is CacheException)
                {
                    throw e;
                }
                else
                {
                    throw new RemoteException((Exception)exceptions[0]);
                }
            }
            else if (exceptions.Count > 0)
            {
                for (int i = 0; i < exceptions.Count; i++)
                {
                    Exception e = exceptions[i] as Exception;
                    if (e is LockingException)
                    {
                        throw e;
                    }
                    else if (e is CacheException)
                    {
                        continue;
                    }
                    else
                    {
                        exceptions[i] = new RemoteException(e);
                    }
                    if (i > 0)
                    {
                        if (!(exceptions[i] as Exception).Message.Equals((exceptions[i - 1] as Exception).Message))
                        {
                            aggregateVerified = false;
                        }
                    }
                }
                if (aggregateVerified)
                {
                    throw exceptions[0] as Exception;
                }
                throw new Runtime.Exceptions.AggregateException(exceptions);
            }
        }
Exemple #5
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);
        }
Exemple #6
0
        /// <summary> Sends a message to a single member (destination = msg.dest) and returns the response. The message's destination
        /// must be non-zero !
        /// </summary>
        public virtual object sendMessage(Message msg, byte mode, long timeout)
        {
            RspList      rsp_list = null;
            object       dest     = msg.Dest;
            Rsp          rsp;
            GroupRequest _req = null;

            if (dest == null)
            {
                return(null);
            }

            ArrayList mbrs = ArrayList.Synchronized(new ArrayList(1));

            mbrs.Add(dest);

            ArrayList clusterMembership = channel.View.Members != null ? (ArrayList)channel.View.Members.Clone() : null;

            _req = new GroupRequest(msg, corr, mbrs, clusterMembership, mode, timeout, 0, this._ncacheLog);

            _req.execute();

            if (mode == GroupRequest.GET_NONE)
            {
                return(null);
            }

            ((GroupChannel)channel).Stack.perfStatsColl.IncrementClusteredOperationsPerSecStats();

            rsp_list = _req.Results;

            if (rsp_list.size() == 0)
            {
                NCacheLog.Warn("MsgDispatcher.sendMessage()", " response list is empty");
                return(null);
            }
            if (rsp_list.size() > 1)
            {
                NCacheLog.Warn("MsgDispatcher.sendMessage()", "response list contains more that 1 response; returning first response !");
            }
            rsp = (Rsp)rsp_list.elementAt(0);
            if (rsp.wasSuspected())
            {
                throw new SuspectedException(dest);
            }
            if (!rsp.wasReceived())
            {
                //we verify for the destination whether it is still part of the cluster or not.
                if (corr.CheckForMembership((Address)rsp.Sender))
                {
                    throw new NCache.Runtime.Exceptions.TimeoutException("operation timeout");
                }

                else
                {
                    rsp.suspected = true;
                    throw new SuspectedException(dest);
                }
            }
            return(rsp.Value);
        }
Exemple #7
0
        public static ClusterOperationResult FindAtomicClusterOperationStatusReplicated(RspList results)
        {
            ClusterOperationResult res = null;

            if (results == null)
            {
                return(res);
            }
            int timeoutCount   = 0;
            int suspectedCount = 0;
            int successCount   = 0;

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

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

                res = rsp.Value as ClusterOperationResult;
                if (res.ExecutionResult == ClusterOperationResult.Result.Completed)
                {
                    successCount++;
                }
            }
            if (suspectedCount > 0 && successCount > 0 && (suspectedCount + successCount == results.size()))
            {
                //as operation is successfull on all other nodes other than suspected node(s).
                return(res);
            }
            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.ExecutionResult = ClusterOperationResult.Result.ParitalTimeout;
                    return(res);
                }
                else
                {
                    //operation timed out on all of the node; no need to rollback.
                    res = new OpenStreamResult(ClusterOperationResult.Result.FullTimeout, false);
                    return(res);
                }
            }
            if (timeoutCount > 0 && suspectedCount > 0)
            {
                if (successCount > 0)
                {
                    res.ExecutionResult = ClusterOperationResult.Result.ParitalTimeout;
                    return(res);
                }
                else
                {
                    res = new OpenStreamResult(ClusterOperationResult.Result.FullTimeout, false);
                    return(res);
                }
            }

            return(res);
        }
Exemple #8
0
        /// <summary> Cast a message to all members, and wait for <code>mode</code> responses. The responses are returned in a response
        /// list, where each response is associated with its sender.<p> Uses <code>GroupRequest</code>.
        ///
        /// </summary>
        /// <param name="dests">  The members to which the message is to be sent. If it is null, then the message is sent to all
        /// members
        /// </param>
        /// <param name="msg">    The message to be sent to n members
        /// </param>
        /// <param name="mode">   Defined in <code>GroupRequest</code>. The number of responses to wait for: <ol> <li>GET_FIRST:
        /// return the first response received. <li>GET_ALL: wait for all responses (minus the ones from
        /// suspected members) <li>GET_MAJORITY: wait for a majority of all responses (relative to the grp
        /// size) <li>GET_ABS_MAJORITY: wait for majority (absolute, computed once) <li>GET_N: wait for n
        /// responses (may block if n > group size) <li>GET_NONE: wait for no responses, return immediately
        /// (non-blocking) </ol>
        /// </param>
        /// <param name="timeout">If 0: wait forever. Otherwise, wait for <code>mode</code> responses <em>or</em> timeout time.
        /// </param>
        /// <returns> RspList A list of responses. Each response is an <code>Object</code> and associated to its sender.
        /// </returns>
        public virtual RspList castMessage(ArrayList dests, Message msg, byte mode, long timeout)
        {
            GroupRequest _req = null;
            ArrayList    real_dests;

            ArrayList clusterMembership = channel.View.Members != null ? (ArrayList)channel.View.Members.Clone() : null;

            // we need to clone because we don't want to modify the original
            // (we remove ourselves if LOCAL is false, see below) !
            real_dests = dests != null ? (ArrayList)dests.Clone() : clusterMembership;

            // if local delivery is off, then we should not wait for the message from the local member.
            // therefore remove it from the membership
            if (channel != null && channel.getOpt(Channel.LOCAL).Equals(false))
            {
                real_dests.Remove(channel.LocalAddress);
            }

            // don't even send the message if the destination list is empty
            if (NCacheLog.IsInfoEnabled)
            {
                NCacheLog.Info("MsgDispatcher.castMessage()", "real_dests=" + Global.CollectionToString(real_dests));
            }

            if (real_dests == null || real_dests.Count == 0)
            {
                if (NCacheLog.IsInfoEnabled)
                {
                    NCacheLog.Info("MsgDispatcher.castMessage()", "destination list is empty, won't send message");
                }
                return(new RspList());                // return empty response list
            }

            _req = new GroupRequest(msg, corr, real_dests, clusterMembership, mode, timeout, 0, this._ncacheLog);


            _req.execute();


            if (mode != GroupRequest.GET_NONE)
            {
                ((GroupChannel)channel).Stack.perfStatsColl.IncrementClusteredOperationsPerSecStats();
            }


            RspList rspList = _req.Results;


            if (rspList != null)
            {
                for (int i = 0; i < rspList.size(); i++)
                {
                    Rsp rsp = rspList.elementAt(i) as Rsp;
                    if (rsp != null)
                    {
                        if (!rsp.wasReceived() && !rsp.wasSuspected())
                        {
                            if (corr.CheckForMembership((Address)rsp.sender))
                            {
                                rsp.suspected = true;
                            }
                        }
                    }
                }
            }
            return(rspList);
        }
Exemple #9
0
        /// <summary>
        /// Remove the objects from the cluster.
        /// </summary>
        /// <param name="keys">keys of the entries.</param>
        /// <returns>list of failed keys</returns>
        /// <remarks>
        /// This method invokes <see cref="handleRemove"/> on every server node in the cluster.
        /// </remarks>
        protected Hashtable Clustered_Remove(Address dest, object[] keys, ItemRemoveReason ir, Caching.Notifications notification, string taskId, string providerName, bool notify, OperationContext operationContext)
        {
            if (ServerMonitor.MonitorActivity)
            {
                ServerMonitor.LogClientActivity("PartCacheBase.RemoveBlk", "");
            }

            Hashtable removedEntries = new Hashtable();
            ArrayList dests          = new ArrayList();

            dests.Add(dest);
            try
            {
                Function func = new Function((int)OpCodes.Remove, new object[] { keys, ir, notify, notification, taskId, providerName, operationContext }, false);
                func.Cancellable = true;
                RspList results = Cluster.Multicast(dests, func, GetFirstResponse, false);

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

                if (results.SuspectedMembers.Count == dests.Count)
                {
                    //All the members of this group has gone down.
                    //we must try this operation on some other group.
                    throw new Runtime.Exceptions.SuspectedException("operation failed because the group member was suspected");
                }

                ClusterHelper.ValidateResponses(results, typeof(Hashtable), Name);
                IList rspList = ClusterHelper.GetAllNonNullRsp(results, typeof(Hashtable));

                if (rspList.Count <= 0)
                {
                    return(removedEntries);
                }

                IEnumerator ia = rspList.GetEnumerator();
                while (ia.MoveNext())
                {
                    if (operationContext.CancellationToken != null && operationContext.CancellationToken.IsCancellationRequested)
                    {
                        throw new OperationCanceledException(ExceptionsResource.OperationFailed);
                    }

                    Rsp       rsp     = (Rsp)ia.Current;
                    Hashtable removed = (Hashtable)rsp.Value;

                    IDictionaryEnumerator ide = removed.GetEnumerator();
                    while (ide.MoveNext())
                    {
                        if (!removedEntries.ContainsKey(ide.Key))
                        {
                            removedEntries.Add(ide.Key, ide.Value);
                        }
                    }
                }
            }
            catch (CacheException e)
            {
                throw;
            }
            catch (Exception e)
            {
                throw new GeneralFailureException(e.Message, e);
            }
            return(removedEntries);
        }
Exemple #10
0
        protected CacheInsResultWithEntry Clustered_Insert(ArrayList dests, object key, CacheEntry cacheEntry, object lockId, LockAccessType accessType, OperationContext operationContext)
        {
            try
            {
                if (ServerMonitor.MonitorActivity)
                {
                    ServerMonitor.LogClientActivity("RepCacheBase.Insert", "enter");
                }


                /// Ask every server to update the object, except myself.
                Function func        = new Function((int)OpCodes.Insert, new object[] { key, cacheEntry, _statusLatch.IsAnyBitsSet(NodeStatus.Initializing), lockId, accessType, operationContext }, false, key);
                Array    userPayLoad = null;
                if (cacheEntry.Value is CallbackEntry)
                {
                    CallbackEntry cbEntry = ((CallbackEntry)cacheEntry.Value);
                    userPayLoad = cbEntry.UserData;
                }
                else
                {
                    userPayLoad = cacheEntry.UserData;
                }

                func.UserPayload = userPayLoad;
                RspList results = Cluster.BroadcastToMultiple(dests,
                                                              func,
                                                              GroupRequest.GET_ALL, _asyncOperation);

                ClusterHelper.ValidateResponses(results, typeof(OperationResponse), Name);

                //Bug Fixed, during state transfer (one node up with the exisiting one) of replicated cache,
                //while client doing insert operaion continously, which incrementing the add/sec counter while the client only performing insert
                //means no need to incrment add/sec counter, need only updat/sec to be incremented
                //so after discussing with QA, we modify the code here.
                CacheInsResultWithEntry retVal = ClusterHelper.FindAtomicInsertStatusReplicated(results);
                if (retVal != null && retVal.Result == CacheInsResult.Success && results != null)
                {
                    for (int i = 0; i < results.Results.Count; i++)
                    {
                        if (((CacheInsResultWithEntry)((OperationResponse)results.Results[i]).SerializablePayload).Result == CacheInsResult.SuccessOverwrite)
                        {
                            retVal.Result = CacheInsResult.SuccessOverwrite;
                            break;
                        }
                    }
                }
                return(retVal);
            }
            catch (CacheException e)
            {
                throw;
            }
            catch (Exception e)
            {
                throw new GeneralFailureException(e.Message, e);
            }
            finally
            {
                if (ServerMonitor.MonitorActivity)
                {
                    ServerMonitor.LogClientActivity("RepCacheBase.Insert", "exit");
                }
            }
        }
Exemple #11
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)
        {
            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(local != null && local.CompareTo(rsp.Sender) == 0)
                //				{
                //					continue;
                //				}
                if (!rsp.wasReceived() && !rsp.wasSuspected())
                {
                    //throw new Alachisoft.NGroups.TimeoutException();
                    timeoutCount++;
                    continue;
                }

                if (rsp.wasSuspected())
                {
                    //throw new Alachisoft.NGroups.SuspectedException(rsp.Sender);
                    suspectedCount++;
                    continue;
                }


                res = (CacheInsResultWithEntry)((OperationResponse)rsp.Value).SerializablePayload;
                if (res.Result == CacheInsResult.Success || res.Result == CacheInsResult.SuccessOverwrite)
                {
                    successCount++;
                }
                if (res.Result != CacheInsResult.Success && res.Result != CacheInsResult.SuccessOverwrite && res.Result != CacheInsResult.NeedsEviction)
                {
                    //return res;
                }

                /* 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 (suspectedCount > 0 && successCount > 0 && (suspectedCount + successCount == results.size()))
            {
                //as operation is successfull on all other nodes other than suspected node(s).
                //res.Result = CacheInsResult.Success;
            }
            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);
        }
Exemple #12
0
        public static void ValidateResponses(RspList results, Type type, string serializationContext, bool throwSuspected = false)
        {
            if (results == null)
            {
                return;
            }


            ArrayList parserExceptions = new ArrayList();
            ArrayList exceptions       = new ArrayList(11);

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

                if (rsp.wasSuspected())
                {
                    if (throwSuspected)
                    {
                        throw new Alachisoft.NGroups.SuspectedException(rsp.Sender);
                    }
                    continue;
                }

                if (!rsp.wasReceived())
                {
                    continue;
                }

                if (rsp.Value != null)
                {
                    object rspValue = rsp.Value;

                    if ((rspValue as Exception) is Alachisoft.NCache.Runtime.Exceptions.InvalidReaderException)
                    {
                        Exception invlidReader = rspValue as Exception;
                        throw invlidReader;
                    }
                    if (rspValue is ParserException)
                    {
                        parserExceptions.Add((Exception)rspValue);
                        continue;
                    }
                    if (((rspValue as Exception) is Alachisoft.NCache.Parser.AttributeIndexNotDefined) || ((rspValue as Exception) is Alachisoft.NCache.Parser.TypeIndexNotDefined))
                    {
                        parserExceptions.Add((Exception)rspValue);
                        continue;
                    }
                    if (rspValue is Exception)
                    {
                        exceptions.Add((Exception)rspValue);
                        continue;
                    }

                    if (type != null && !rspValue.GetType().Equals(type))
                    {
                        exceptions.Add(new BadResponseException("bad response returned by group member " + rsp.Sender));
                        continue;
                    }
                }
            }
            //in case or partitioned caches search requests are broadcasted.
            //it is possible that tag index are defined on one node but not defined on some other node.
            //we will throw the exception back only if we receive exception from every node.
            if (parserExceptions.Count == results.size())
            {
                Exception e = parserExceptions[0] as Exception;
                throw e;
            }

            if (exceptions.Count == 1)
            {
                Exception e = exceptions[0] as Exception;
                if (e is CacheException)
                {
                    throw e;
                }
                else
                {
                    throw new RemoteException((Exception)exceptions[0]);
                }
            }
            else if (exceptions.Count > 0)
            {
                for (int i = 0; i < exceptions.Count; i++)
                {
                    Exception e = exceptions[i] as Exception;
                    if (e is LockingException)
                    {
                        throw e;
                    }
                    else if (e is CacheException)
                    {
                        continue;
                    }
                    else
                    {
                        exceptions[i] = new RemoteException(e);
                    }
                }
                throw new Runtime.Exceptions.AggregateException(exceptions);
            }
        }