Skip to content

Commit

Permalink
GMS.castViewChangeWithDest(): if we're the only target member the VIE…
Browse files Browse the repository at this point in the history
…W is broadcast to, don't send the broadcast but install the view directly (saves N-1 receivers from having to handle the broadcast, only to discard it)
  • Loading branch information
belaban committed Nov 25, 2011
1 parent 41f714b commit 170591b
Showing 1 changed file with 28 additions and 22 deletions.
50 changes: 28 additions & 22 deletions src/org/jgroups/protocols/pbcast/GMS.java
Expand Up @@ -469,7 +469,7 @@ public View getNextView(Collection<Address> new_mbrs, Collection<Address> old_mb
* @param digest
* @param newMembers
*/
public void castViewChangeWithDest(View new_view, Digest digest, JoinRsp jr, Collection <Address> newMembers) {
public void castViewChangeWithDest(View new_view, Digest digest, JoinRsp jr, Collection<Address> newMembers) {
if(log.isTraceEnabled())
log.trace(local_addr + ": mcasting view {" + new_view + "} (" + new_view.size() + " mbrs)\n");

Expand All @@ -478,35 +478,41 @@ public void castViewChangeWithDest(View new_view, Digest digest, JoinRsp jr, Col
hdr.my_digest=digest;
view_change_msg.putHeader(this.id, hdr);

List<Address> ackMembers = new ArrayList<Address>(new_view.getMembers());
List<Address> ackMembers=new ArrayList<Address>(new_view.getMembers());
if(newMembers != null && !newMembers.isEmpty())
ackMembers.removeAll(newMembers);
if(!ackMembers.isEmpty())
ack_collector.reset(ackMembers);
else
ack_collector.reset(null);




// 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 (e.g. getState()) reaches us *before* our own view change multicast.
// Check NAKACK's TMP_VIEW handling for details
down_prot.up(new Event(Event.TMP_VIEW, new_view));
down_prot.down(new Event(Event.TMP_VIEW, new_view));
down_prot.down(new Event(Event.MSG, view_change_msg));

try {
if(!ackMembers.isEmpty()) {
ack_collector.waitForAllAcks(view_ack_collection_timeout);
if(log.isTraceEnabled())
log.trace(local_addr + ": received all ACKs (" + ack_collector.expectedAcks() +
") from existing members for view " + new_view.getVid());
}

// If we're the only member the VIEW is broadcast to, let's simply install the view directly, without
// sending the VIEW multicast ! Or else N-1 members drop the multicast anyway...
if(local_addr != null && ackMembers.size() == 1 && ackMembers.get(0).equals(local_addr)) {
// System.out.println("--->> " + local_addr + ": installing view " + new_view.getViewId() + " directly");
impl.handleViewChange(new_view, digest);
}
catch(TimeoutException e) {
if(log_collect_msgs && log.isWarnEnabled()) {
log.warn(local_addr + ": failed to collect all ACKs (expected=" + ack_collector.expectedAcks()
+ ") for view " + new_view.getViewId() + " after " + view_ack_collection_timeout + "ms, missing ACKs from "
+ ack_collector.printMissing());
else {
if(!ackMembers.isEmpty())
ack_collector.reset(ackMembers);
down_prot.down(new Event(Event.MSG, view_change_msg));
try {
if(!ackMembers.isEmpty()) {
ack_collector.waitForAllAcks(view_ack_collection_timeout);
if(log.isTraceEnabled())
log.trace(local_addr + ": received all ACKs (" + ack_collector.expectedAcks() +
") from existing members for view " + new_view.getVid());
}
}
catch(TimeoutException e) {
if(log_collect_msgs && log.isWarnEnabled()) {
log.warn(local_addr + ": failed to collect all ACKs (expected=" + ack_collector.expectedAcks()
+ ") for view " + new_view.getViewId() + " after " + view_ack_collection_timeout + "ms, missing ACKs from "
+ ack_collector.printMissing());
}
}
}

Expand Down

0 comments on commit 170591b

Please sign in to comment.