/// <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)); }
/// <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)); }
/// <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()); } }
/// <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)); }
/// <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)); }
/// <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()); }
/// <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)); }
/// <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)); }
/// <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); } }