* @param sender The sender of the gossip message (obviously :-))
*/
public void gossip(ViewId view_id, long gossip_round,
long[] gossip_seqnos, boolean[] heard, Object sender) {
Object[] params;
MethodCall call;
synchronized(this) {
if(log.isInfoEnabled()) log.info("sender=" + sender + ", round=" + gossip_round + ", seqnos=" +
Util.array2String(gossip_seqnos) + ", heard=" +
Util.array2String(heard));
if(vid == null || view_id == null || !vid.equals(view_id)) {
if(log.isInfoEnabled()) log.info("view ID s are different (" + vid + " != " + view_id +
"). Discarding gossip received");
return;
}
if(gossip_round < this.round) {
if(log.isInfoEnabled()) log.info("received a gossip from a previous round (" +
gossip_round + "); my round is " + round +
". Discarding gossip");
return;
}
if(gossip_seqnos == null || seqnos == null ||
seqnos.length != gossip_seqnos.length) {
if(warn) log.warn("size of seqnos and gossip_seqnos are not equal ! " +
"Discarding gossip");
return;
}
// (1) If round greater than local round:
// i. Adjust the local to the received round
//
// (2)
// i. local_seqnos = arrayMin(local_seqnos, gossip_seqnos)
// ii. local_heard = arrayMax(local_heard, gossip_heard)
// iii. If heard from all, bcast our seqnos (stability vector)
if(round == gossip_round) {
update(sender, gossip_seqnos, heard);
}
else if(round < gossip_round) {
if(log.isInfoEnabled()) log.info("received a gossip from a higher round (" +
gossip_round + "); adopting my round (" + round +
") to " + gossip_round);
round=gossip_round;
set(sender, gossip_seqnos, heard_from);
}
if(log.isInfoEnabled()) log.info("heard_from=" + Util.array2String(heard_from));
if(!heardFromAll())
return;
params=new Object[]{
vid.clone(),
new Long(gossip_round),
seqnos.clone(),
local_addr};
} // synchronized(this)
call=new MethodCall("stability", params,
new String[] {ViewId.class.getName(), long.class.getName(), long[].class.getName(), Object.class.getName()});
callRemoteMethods(null, call, GroupRequest.GET_NONE, 0);
}