/// <summary>
        /// Sends a leave request to the coordinator
        /// </summary>
        /// <param name="coord">Address of the coordinator</param>
        /// <param name="mbr">Local Address</param>
        private void sendLeaveMessage(Address coord, Address mbr)
        {
            Message   msg = new Message(coord, null, null);
            GmsHeader hdr = new GmsHeader(GmsHeader.LEAVE_REQ, mbr);

            msg.putHeader(gms.getName(), hdr);
            gms.passDown(new Event(Event.MSG, msg));
        }
示例#2
0
        /// <summary>
        /// Acknowledges leave response.
        /// </summary>
        /// <param name="mbr"></param>
        private void sendLeaveResponse(Address mbr)
        {
            Message   msg = new Message(mbr, null, null);
            GmsHeader hdr = new GmsHeader(GmsHeader.LEAVE_RSP);

            msg.putHeader(getName(), hdr);
            passDown(new Event(Event.MSG, msg));
        }
示例#3
0
        /// <summary>
        /// Deals with incoming join requests. If we are a coordinator then a response will be sent.
        /// </summary>
        /// <param name="mbr"></param>
        void handleJoinRequest(Address mbr)
        {
            JoinRsp   join_rsp;
            Message   m;
            GmsHeader hdr;
            ArrayList new_mbrs = new ArrayList();

            if (mbr == null)
            {
                if (Trace.trace)
                {
                    Trace.error("GMS.handleJoinRequest()", "mbr is null");
                }
                return;
            }

            if (Trace.trace)
            {
                Trace.info("GMS.handleJoinRequest()", "mbr=" + mbr);
            }

            // 1. Get the new view and digest
            join_rsp = impl.handleJoin(mbr);
            if (join_rsp == null)
            {
                if (Trace.trace)
                {
                    Trace.error("GMS.handleJoinRequest()", impl.getName() + ".handleJoin(" + mbr +
                                ") returned null: will not be able to multicast new view");
                }
            }

            // 2. Send down a local TMP_VIEW event. This is needed by certain layers (e.g. NAKACK) to compute correct digest
            //    in case client's next request reaches us *before* our own view change multicast.
            if (join_rsp != null && join_rsp.getView() != null)
            {
                passDown(new Event(Event.TMP_VIEW, join_rsp.getView()));
            }

            // 3. Return result to client
            m   = new Message(mbr, null, null);
            hdr = new GmsHeader(GmsHeader.JOIN_RSP, join_rsp);
            m.putHeader(getName(), hdr);
            passDown(new Event(Event.MSG, m));

            // 4. Bcast the new view
            if (join_rsp != null)
            {
                castViewChange(join_rsp.getView());
            }
        }
示例#4
0
        /// <summary>
        /// Multicasts a new view.
        /// </summary>
        /// <param name="new_view">New View to send</param>
        /// <param name="digest">Digest associated with View</param>
        public void castViewChange(View new_view, Digest digest)
        {
            Message   view_change_msg;
            GmsHeader hdr;

            if (Trace.trace)
            {
                Trace.info("GMS.castViewChange()", "mcasting view {" + new_view + "} (" + new_view.size() + " mbrs)\n");
            }
            view_change_msg = new Message(null, null, null);         // bcast to all members
            hdr             = new GmsHeader(GmsHeader.VIEW, new_view);
            hdr.digest      = digest;
            view_change_msg.putHeader(getName(), hdr);
            passDown(new Event(Event.MSG, view_change_msg));
        }
示例#5
0
 /// <summary>
 /// Acknowledges leave response.
 /// </summary>
 /// <param name="mbr"></param>
 private void sendLeaveResponse(Address mbr)
 {
     Message   msg=new Message(mbr, null, null);
     GmsHeader hdr=new GmsHeader(GmsHeader.LEAVE_RSP);
     msg.putHeader(getName(), hdr);
     passDown(new Event(Event.MSG, msg));
 }
示例#6
0
        /// <summary>
        /// Deals with incoming join requests. If we are a coordinator then a response will be sent.
        /// </summary>
        /// <param name="mbr"></param>
        void handleJoinRequest(Address mbr)
        {
            JoinRsp   join_rsp;
            Message   m;
            GmsHeader hdr;
            ArrayList    new_mbrs=new ArrayList();

            if(mbr == null)
            {
                if(Trace.trace)
                    Trace.error("GMS.handleJoinRequest()", "mbr is null");
                return;
            }

            if(Trace.trace)
                Trace.info("GMS.handleJoinRequest()", "mbr=" + mbr);

            // 1. Get the new view and digest
            join_rsp=impl.handleJoin(mbr);
            if(join_rsp == null)
                if(Trace.trace)
                    Trace.error("GMS.handleJoinRequest()", impl.getName() + ".handleJoin(" + mbr +
                    ") returned null: will not be able to multicast new view");

            // 2. Send down a local TMP_VIEW event. This is needed by certain layers (e.g. NAKACK) to compute correct digest
            //    in case client's next request reaches us *before* our own view change multicast.
            if(join_rsp != null && join_rsp.getView() != null)
                passDown(new Event(Event.TMP_VIEW, join_rsp.getView()));

            // 3. Return result to client
            m=new Message(mbr, null, null);
            hdr=new GmsHeader(GmsHeader.JOIN_RSP, join_rsp);
            m.putHeader(getName(), hdr);
            passDown(new Event(Event.MSG, m));

            // 4. Bcast the new view
            if(join_rsp != null)
                castViewChange(join_rsp.getView());
        }
示例#7
0
        /// <summary>
        /// Multicasts a new view.
        /// </summary>
        /// <param name="new_view">New View to send</param>
        /// <param name="digest">Digest associated with View</param>
        public void castViewChange(View new_view, Digest digest)
        {
            Message   view_change_msg;
            GmsHeader hdr;

            if(Trace.trace)
                Trace.info("GMS.castViewChange()", "mcasting view {" + new_view + "} (" + new_view.size() + " mbrs)\n");
            view_change_msg=new Message(null,null,null); // bcast to all members
            hdr=new GmsHeader(GmsHeader.VIEW, new_view);
            hdr.digest=digest;
            view_change_msg.putHeader(getName(), hdr);
            passDown(new Event(Event.MSG, view_change_msg));
        }
示例#8
0
        /// <summary>
        /// Sends a join message to the coordinator of the group.
        /// </summary>
        /// <param name="coord">The Address of the Coordinator</param>
        /// <param name="mbr">The local Address (i.e. this member)</param>
        private void sendJoinMessage(Address coord, Address mbr)
        {
            Message			msg;
            GmsHeader		hdr;

            msg=new Message(coord, null, null);
            hdr=new GmsHeader(GmsHeader.JOIN_REQ, mbr);
            msg.putHeader(gms.getName(), hdr);
            gms.passDown(new Event(Event.MSG, msg));
        }
示例#9
0
        /// <summary>
        /// Processes <c>Events</c> travelling up the stack
        /// </summary>
        /// <param name="evt">The Event to be processed</param>
        public override void up(Event evt)
        {
            Object    obj;
            Message   msg;
            GmsHeader hdr;

            switch (evt.Type)
            {
            case Event.MSG:
                msg = (Message)evt.Arg;
                obj = msg.getHeader(getName());
                if (obj == null || !(obj is GmsHeader))
                {
                    break;
                }
                hdr = (GmsHeader)msg.removeHeader(getName());
                if (Trace.trace)
                {
                    Trace.info("GMS.up()", "Receieved Event " + GmsHeader.type2String(hdr.type));
                }
                if (hdr.type == GmsHeader.JOIN_REQ)
                {
                    handleJoinRequest(hdr.mbr);
                    break;
                }
                else if (hdr.type == GmsHeader.JOIN_RSP)
                {
                    impl.handleJoinResponse(hdr.join_rsp);
                    break;
                }
                else if (hdr.type == GmsHeader.LEAVE_REQ)
                {
                    if (Trace.trace)
                    {
                        Trace.info("GMS.up()", "received LEAVE_REQ " + hdr + " from " + msg.Source);
                    }

                    if (hdr.mbr == null)
                    {
                        if (Trace.trace)
                        {
                            Trace.error("GMS.up()", "LEAVE_REQ's mbr field is null");
                        }
                        return;
                    }
                    sendLeaveResponse(hdr.mbr);
                    impl.handleLeave(hdr.mbr, false);
                    break;
                }
                else if (hdr.type == GmsHeader.LEAVE_RSP)
                {
                    impl.handleLeaveResponse();
                    break;
                }
                else if (hdr.type == GmsHeader.VIEW)
                {
                    if (hdr.view == null)
                    {
                        if (Trace.trace)
                        {
                            Trace.error("GMS.up()", "[VIEW]: view == null");
                        }
                        return;
                    }
                    impl.handleViewChange(hdr.view, hdr.digest);
                    break;
                }
                else
                {
                    if (Trace.trace)
                    {
                        Trace.error("GMS.up()", "GmsHeader with type=" + hdr.type + " not known");
                    }
                    return;                              // don't pass up
                }

            case Event.CONNECT_OK:                         // sent by someone else, but WE are responsible for sending this !
            case Event.DISCONNECT_OK:                      // dito (e.g. sent by UDP layer). Don't send up the stack
                return;


            case Event.SET_LOCAL_ADDRESS:
                local_addr = (Address)evt.Arg;

                if (print_local_addr)
                {
                    Console.WriteLine("\n-------------------------------------------------------\n" +
                                      "GMS: address is " + local_addr +
                                      "\n-------------------------------------------------------");
                }
                break;                                                       // pass up

            case Event.SUSPECT:
                impl.suspect((Address)evt.Arg);
                break;                                                       // pass up

            case Event.UNSUSPECT:
                impl.unsuspect((Address)evt.Arg);
                return;                                                      // discard
            }

            if (impl.handleUpEvent(evt))
            {
                passUp(evt);
            }
        }