예제 #1
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);             // dummy membership (of destination address)

            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 Runtime.Exceptions.TimeoutException("operation timeout");
                }

                else
                {
                    rsp.suspected = true;
                    throw new SuspectedException(dest);
                }
            }
            return(rsp.Value);
        }
예제 #2
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;
            //real_dests = dests != null ? (ArrayList) dests.Clone():null;

            // 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");
                }
                //((GroupChannel)channel).MsgProvider.SubmittObject(msg);
                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);
        }