gms.initState(); // in case connect() is called again
}
return;
}
gms.up(new Event(Event.PREPARE_VIEW,new_view));
gms.down(new Event(Event.PREPARE_VIEW,new_view));
if(log.isDebugEnabled())
log.debug("new=" + new_mbrs + ", suspected=" + suspected_mbrs + ", leaving=" + leaving_mbrs +
", new view: " + new_view);
JoinRsp join_rsp=null;
boolean hasJoiningMembers=!new_mbrs.isEmpty();
try {
boolean successfulFlush =!useFlushIfPresent || gms.startFlush(new_view);
if(!successfulFlush && hasJoiningMembers){
// Don't send a join response if the flush fails (http://jira.jboss.org/jira/browse/JGRP-759)
// The joiner should block until the previous FLUSH completed
sendLeaveResponses(leaving_mbrs); // we still have to send potential leave responses
// but let the joining client timeout and send another join request
return;
}
// we cannot garbage collect during joining a new member *if* we're the only member
// Example: {A}, B joins, after returning JoinRsp to B, A garbage collects messages higher than those
// in the digest returned to the client, so the client will *not* be able to ask for retransmission
// of those messages if he misses them
if(hasJoiningMembers) {
gms.getDownProtocol().down(new Event(Event.SUSPEND_STABLE, MAX_SUSPEND_TIMEOUT));
Digest tmp=gms.getDigest(); // get existing digest
MutableDigest join_digest=null;
if(tmp == null){
log.error("received null digest from GET_DIGEST: will cause JOIN to fail");
}
else {
// create a new digest, which contains the new member
join_digest=new MutableDigest(tmp.size() + new_mbrs.size());
join_digest.add(tmp); // add the existing digest to the new one
for(Address member:new_mbrs)
join_digest.add(member, 0, 0); // ... and add the new members. their first seqno will be 1
}
join_rsp=new JoinRsp(new_view, join_digest != null? join_digest.copy() : null);
}
sendLeaveResponses(leaving_mbrs); // no-op if no leaving members
gms.castViewChangeWithDest(new_view, join_rsp != null? join_rsp.getDigest() : null, join_rsp,new_mbrs);
}
finally {
if(hasJoiningMembers)
gms.getDownProtocol().down(new Event(Event.RESUME_STABLE));
if(!joinAndStateTransferInitiated && useFlushIfPresent)
gms.stopFlush();
if(leaving) {
gms.initState(); // in case connect() is called again
}