/// <summary> /// Installs new NakReceiverWindows with the values specified in the Digest. /// </summary> /// <param name="d"></param> void setDigest(Digest d) { Address sender; NakReceiverWindow win; long initial_seqno; clear(); if (d == null || d.senders == null) { if (Trace.trace) { Trace.error("NAKACK.setDigest()", "digest or digest.senders is null"); } return; } for (int i = 0; i < d.size(); i++) { sender = d.senderAt(i); if (sender == null) { if (Trace.trace) { Trace.error("NAKACK.setDigest()", "sender at index " + i + " in digest is null"); } continue; } initial_seqno = d.highSeqnoAt(i); win = new NakReceiverWindow(sender, this, initial_seqno, timer); win.setRetransmitTimeouts(retransmit_timeout); received_msgs.Add(sender, win); } }
/// <remarks> /// Finds the corresponding NakReceiverWindow and adds the message to it (according to seqno). Then removes /// as many messages as possible from the NRW and passes them up the stack. Discards messages from non-members. /// </remarks> /// <summary> /// Results in all possible messages from sender being delivered up the stacks /// </summary> /// <param name="msg"></param> /// <param name="hdr"></param> void handleMessage(Message msg, NakAckHeader hdr) { NakReceiverWindow win = null; Message msg_to_deliver; Address sender; if (msg == null || hdr == null) { if (Trace.trace) { Trace.error("NAKACK.handleMessage()", "msg or header is null"); } return; } sender = msg.Source; if (sender == null) { if (Trace.trace) { Trace.error("NAKACK.handleMessage()", "sender of message is null"); } return; } if (Trace.trace) { Trace.info("NAKACK.handleMessage()", "[" + local_addr + "] received <" + sender + "#" + hdr.seqno + ">"); } // msg is potentially re-sent later as result of XMIT_REQ reception; that's why hdr is added ! msg.putHeader(getName(), hdr); win = (NakReceiverWindow)received_msgs[sender]; if (win == null) { // discard message if there is no entry for sender if (leaving) { return; } if (Trace.trace) { Trace.warn("NAKACK.handleMessage()", "[" + local_addr + "] discarded message from non-member " + sender); } return; } win.add(hdr.seqno, msg); // add in order, then remove and pass up as many msgs as possible while ((msg_to_deliver = win.remove()) != null) { msg_to_deliver.removeHeader(getName()); passUp(new Event(Event.MSG, msg_to_deliver)); } }
/// <summary> /// Removes all old members and creates NakReceiverWindows for all new members /// </summary> void adjustReceivers() { Address newSender; NakReceiverWindow win; Hashtable oldSenders = new Hashtable(); // 1. Remove all senders in received_msgs that are not members anymore foreach (Address sender in received_msgs.Keys) { if (!members.Contains(sender)) { oldSenders.Add(sender, received_msgs[sender]); } } foreach (Address sender in oldSenders.Keys) { win = (NakReceiverWindow)received_msgs[sender]; win.reset(); if (Trace.trace) { Trace.info("NAKACK.adjustReceivers()", "removing " + sender + " from received_msgs (not member anymore)"); } received_msgs.Remove(sender); } // 2. Add newly joined members to received_msgs (starting seqno=0) for (int i = 0; i < members.Count; i++) { newSender = (Address)members[i]; if (!received_msgs.ContainsKey(newSender)) { win = new NakReceiverWindow(newSender, this, 0, timer); win.setRetransmitTimeouts(retransmit_timeout); received_msgs.Add(newSender, win); } } }
public void init() { nak = new NakReceiverWindow(remoteAddr, this, 0); nak.setRetransmitTimeouts(retransmit_timeout); }