protected void retransmit(long first_seqno, long last_seqno, Address sender) { if(first_seqno <= last_seqno) retransmit(first_seqno,last_seqno,sender,false); }
/** * Compares the sender's highest seqno with my highest seqno: if the sender's is higher, ask sender for retransmission * @param sender The sender * @param seqno The highest seqno sent by sender */ protected void handleHighestSeqno(Address sender, long seqno) { // check whether the highest seqno received from sender is > highest seqno received for sender in my digest. // If yes, request retransmission (see "Last Message Dropped" topic in DESIGN) Table<Message> buf=xmit_table.get(sender); if(buf == null) return; long my_highest_received=buf.getHighestReceived(); if(my_highest_received >= 0 && seqno > my_highest_received) { log.trace("%s: my_highest_rcvd (%s#%d) < highest received (%s#%d): requesting retransmission", local_addr, sender, my_highest_received, sender, seqno); retransmit(seqno,seqno,sender); } }
protected void retransmit(long first_seqno, long last_seqno, final Address sender, boolean multicast_xmit_request) { SeqnoList list=new SeqnoList((int)(last_seqno - first_seqno +1), first_seqno).add(first_seqno, last_seqno); retransmit(list,sender,multicast_xmit_request); }
@ManagedOperation(description="Triggers the retransmission task, asking all senders for missing messages") public void triggerXmit() { SeqnoList missing; for(Map.Entry<Address,Table<Message>> entry: xmit_table.entrySet()) { Address target=entry.getKey(); // target to send retransmit requests to Table<Message> buf=entry.getValue(); if(buf != null && buf.getNumMissing() > 0 && (missing=buf.getMissing(max_xmit_req_size)) != null) { // getNumMissing() is fast long highest=missing.getLast(); Long prev_seqno=xmit_task_map.get(target); if(prev_seqno == null) { xmit_task_map.put(target, highest); // no retransmission } else { missing.removeHigherThan(prev_seqno); // we only retransmit the 'previous batch' if(highest > prev_seqno) xmit_task_map.put(target, highest); if(!missing.isEmpty()) retransmit(missing, target, false); } } else if(!xmit_task_map.isEmpty()) xmit_task_map.remove(target); // no current gaps for target } if(resend_last_seqno && last_seqno_resender != null) last_seqno_resender.execute(seqno.get()); }
if(their_high > my_high) { log.trace("%s: fetching %d-%d from %s", local_addr, my_high, their_high, member); retransmit(my_high+1, their_high, member, true); // use multicast to send retransmit request xmitted=true;
log.trace("%s: my_highest_rcvd (%d) < stability_highest_rcvd (%d): requesting retransmission of %s", local_addr, my_hr, hr, member + "#" + hr); retransmit(hr, hr, member);
protected void retransmit(long first_seqno, long last_seqno, Address sender) { if(first_seqno <= last_seqno) retransmit(first_seqno,last_seqno,sender,false); }
protected void retransmit(long first_seqno, long last_seqno, final Address sender, boolean multicast_xmit_request) { SeqnoList list=new SeqnoList((int)(last_seqno - first_seqno +1), first_seqno).add(first_seqno, last_seqno); retransmit(list,sender,multicast_xmit_request); }
/** * Compares the sender's highest seqno with my highest seqno: if the sender's is higher, ask sender for retransmission * @param sender The sender * @param seqno The highest seqno sent by sender */ protected void handleHighestSeqno(Address sender, long seqno) { // check whether the highest seqno received from sender is > highest seqno received for sender in my digest. // If yes, request retransmission (see "Last Message Dropped" topic in DESIGN) Table<Message> buf=xmit_table.get(sender); if(buf == null) return; long my_highest_received=buf.getHighestReceived(); if(my_highest_received >= 0 && seqno > my_highest_received) { log.trace("%s: my_highest_rcvd (%s#%d) < highest received (%s#%d): requesting retransmission", local_addr, sender, my_highest_received, sender, seqno); retransmit(seqno,seqno,sender); } }
@ManagedOperation(description="Triggers the retransmission task, asking all senders for missing messages") public void triggerXmit() { SeqnoList missing; for(Map.Entry<Address,Table<Message>> entry: xmit_table.entrySet()) { Address target=entry.getKey(); // target to send retransmit requests to Table<Message> buf=entry.getValue(); if(buf != null && buf.getNumMissing() > 0 && (missing=buf.getMissing(max_xmit_req_size)) != null) { // getNumMissing() is fast long highest=missing.getLast(); Long prev_seqno=xmit_task_map.get(target); if(prev_seqno == null) { xmit_task_map.put(target, highest); // no retransmission } else { missing.removeHigherThan(prev_seqno); // we only retransmit the 'previous batch' if(highest > prev_seqno) xmit_task_map.put(target, highest); if(!missing.isEmpty()) retransmit(missing, target, false); } } else if(!xmit_task_map.isEmpty()) xmit_task_map.remove(target); // no current gaps for target } if(resend_last_seqno && last_seqno_resender != null) last_seqno_resender.execute(seqno.get()); }
if(their_high > my_high) { log.trace("%s: fetching %d-%d from %s", local_addr, my_high, their_high, member); retransmit(my_high+1, their_high, member, true); // use multicast to send retransmit request xmitted=true;
log.trace("%s: my_highest_rcvd (%d) < stability_highest_rcvd (%d): requesting retransmission of %s", local_addr, my_hr, hr, member + "#" + hr); retransmit(hr, hr, member);