RspList rsp_list;
FlushRsp retval=new FlushRsp();
Digest digest;
long[] min, max;
long[] lower[];
List unstable_msgs=new List();
boolean get_lower_msgs=false;
highest_delivered_msgs=new long[members.size()];
min=new long[members.size()];
max=new long[members.size()];
/* Determine the highest seqno (for each member) that was delivered to the application
(i.e., consumed by the application). Stores result in array 'highest_delivered_msgs' */
getHighestDeliveredSeqnos();
for(int i=0; i < highest_delivered_msgs.length; i++)
min[i]=max[i]=highest_delivered_msgs[i];
/* Call the handleFlush() method of all existing members. The highest seqnos seen by the coord
is the argument */
if(log.isInfoEnabled()) log.info("calling handleFlush(" + dests + ')');
passDown(new Event(Event.SWITCH_OUT_OF_BAND)); // we need out-of-band control for FLUSH ...
MethodCall call = new MethodCall("handleFlush", new Object[] {dests, highest_delivered_msgs.clone()},
new String[] {Vector.class.getName(), long[].class.getName()});
rsp_list=callRemoteMethods(dests, call, GroupRequest.GET_ALL, 0);
if(log.isInfoEnabled()) log.info("flush done");
/* Process all the responses (Digest): compute a range of messages (min and max seqno) for each
member that has to be re-broadcast; FlushRsp contains those messages. They will be re-braodcast
by the cordinator (in the GMS protocol). */
for(int i=0; i < rsp_list.size(); i++) {
Rsp rsp=(Rsp)rsp_list.elementAt(i);
if(rsp.wasReceived()) {
digest=(Digest)rsp.getValue();
if(digest != null) {
for(int j=0; j < digest.highest_seqnos.length && j < min.length; j++) {
min[j]=Math.min(min[j], digest.highest_seqnos[j]);
max[j]=Math.max(max[j], digest.highest_seqnos[j]);
}
if(digest.msgs.size() > 0) {
for(Enumeration e=digest.msgs.elements(); e.hasMoreElements();)
unstable_msgs.add(e.nextElement());
}
}
}
} // end for-loop
/* If any of the highest msgs of the flush replies were lower than the ones sent by this
coordinator, we have to re-broadcast them. (This won't occur often)
Compute the range between min and highest_delivered_msgs */
lower=new long[min.length][]; // stores (for each mbr) the range of seqnos (e.g. 20 24): send msgs
// 21, 22 and 23 and 24 (excluding lower and including upper range)
for(int i=0; i < min.length; i++) {
if(min[i] < highest_delivered_msgs[i]) { // will almost never be the case
lower[i]=new long[2];
lower[i][0]=min[i]; // lower boundary (excluding)
lower[i][1]=highest_delivered_msgs[i]; // upper boundary (including)
get_lower_msgs=true;
}
}
if(get_lower_msgs) {
get_msgs=null;
synchronized(get_msgs_mutex) {
passDown(new Event(Event.GET_MSGS, lower));
try {
get_msgs_mutex.wait(get_msgs_timeout);
}
catch(Exception e) {}
}
if(get_msgs != null) {
for(Enumeration e=get_msgs.elements(); e.hasMoreElements();)
unstable_msgs.add(e.nextElement());
}
}
retval.unstable_msgs=unstable_msgs.getContents();
if(rsp_list.numSuspectedMembers() > 0) {
retval.result=false;
retval.failed_mbrs=rsp_list.getSuspectedMembers();
}