use of org.apache.catalina.tribes.membership.Membership in project tomcat70 by apache.
the class NonBlockingCoordinator method startElection.
// ============================================================================================================
// COORDINATION HANDLING
// ============================================================================================================
public void startElection(boolean force) throws ChannelException {
synchronized (electionMutex) {
MemberImpl local = (MemberImpl) getLocalMember(false);
MemberImpl[] others = membership.getMembers();
fireInterceptorEvent(new CoordinationEvent(CoordinationEvent.EVT_START_ELECT, this, "Election initiated"));
if (others.length == 0) {
this.viewId = new UniqueId(UUIDGenerator.randomUUID(false));
this.view = new Membership(local, AbsoluteOrder.comp, true);
this.handleViewConf(this.createElectionMsg(local, others, local), local, view);
// the only member, no need for an election
return;
}
if (suggestedviewId != null) {
if (view != null && Arrays.diff(view, suggestedView, local).length == 0 && Arrays.diff(suggestedView, view, local).length == 0) {
suggestedviewId = null;
suggestedView = null;
fireInterceptorEvent(new CoordinationEvent(CoordinationEvent.EVT_ELECT_ABANDONED, this, "Election abandoned, running election matches view"));
} else {
fireInterceptorEvent(new CoordinationEvent(CoordinationEvent.EVT_ELECT_ABANDONED, this, "Election abandoned, election running"));
}
// election already running, I'm not allowed to have two of them
return;
}
if (view != null && Arrays.diff(view, membership, local).length == 0 && Arrays.diff(membership, view, local).length == 0) {
fireInterceptorEvent(new CoordinationEvent(CoordinationEvent.EVT_ELECT_ABANDONED, this, "Election abandoned, view matches membership"));
// already have this view installed
return;
}
int prio = AbsoluteOrder.comp.compare(local, others[0]);
// am I the leader in my view?
MemberImpl leader = (prio < 0) ? local : others[0];
if (local.equals(leader) || force) {
CoordinationMessage msg = createElectionMsg(local, others, leader);
suggestedviewId = msg.getId();
suggestedView = new Membership(local, AbsoluteOrder.comp, true);
Arrays.fill(suggestedView, msg.getMembers());
fireInterceptorEvent(new CoordinationEvent(CoordinationEvent.EVT_PROCESS_ELECT, this, "Election, sending request"));
sendElectionMsg(local, others[0], msg);
} else {
try {
coordMsgReceived.set(false);
fireInterceptorEvent(new CoordinationEvent(CoordinationEvent.EVT_WAIT_FOR_MSG, this, "Election, waiting for request"));
electionMutex.wait(waitForCoordMsgTimeout);
} catch (InterruptedException x) {
Thread.interrupted();
}
if (suggestedviewId == null && (!coordMsgReceived.get())) {
// no message arrived, send the coord msg
// fireInterceptorEvent(new CoordinationEvent(CoordinationEvent.EVT_WAIT_FOR_MSG,this,"Election, waiting timed out."));
// startElection(true);
fireInterceptorEvent(new CoordinationEvent(CoordinationEvent.EVT_ELECT_ABANDONED, this, "Election abandoned, waiting timed out."));
} else {
fireInterceptorEvent(new CoordinationEvent(CoordinationEvent.EVT_ELECT_ABANDONED, this, "Election abandoned, received a message"));
}
}
// end if
}
}
use of org.apache.catalina.tribes.membership.Membership in project tomcat70 by apache.
the class NonBlockingCoordinator method handleViewConf.
protected void handleViewConf(CoordinationMessage msg, Member sender, Membership merged) throws ChannelException {
// we already have this view
if (viewId != null && msg.getId().equals(viewId))
return;
view = new Membership((MemberImpl) getLocalMember(false), AbsoluteOrder.comp, true);
Arrays.fill(view, msg.getMembers());
viewId = msg.getId();
if (viewId.equals(suggestedviewId)) {
suggestedView = null;
suggestedviewId = null;
}
if (suggestedView != null && AbsoluteOrder.comp.compare(suggestedView.getMembers()[0], merged.getMembers()[0]) < 0) {
suggestedView = null;
suggestedviewId = null;
}
viewChange(viewId, view.getMembers());
fireInterceptorEvent(new CoordinationEvent(CoordinationEvent.EVT_CONF_RX, this, "Accepted View"));
if (suggestedviewId == null && hasHigherPriority(merged.getMembers(), membership.getMembers())) {
startElection(false);
}
}
use of org.apache.catalina.tribes.membership.Membership in project tomcat70 by apache.
the class NonBlockingCoordinator method handleMyToken.
protected void handleMyToken(MemberImpl local, CoordinationMessage msg, Member sender, Membership merged) throws ChannelException {
if (local.equals(msg.getLeader())) {
// no leadership change
if (Arrays.sameMembers(msg.getMembers(), merged.getMembers())) {
msg.type = COORD_CONF;
super.sendMessage(Arrays.remove(msg.getMembers(), local), createData(msg, local), null);
handleViewConf(msg, local, merged);
} else {
// membership change
suggestedView = new Membership(local, AbsoluteOrder.comp, true);
suggestedviewId = msg.getId();
Arrays.fill(suggestedView, merged.getMembers());
msg.view = merged.getMembers();
sendElectionMsgToNextInline(local, msg);
}
} else {
// leadership change
suggestedView = null;
suggestedviewId = null;
msg.view = merged.getMembers();
sendElectionMsgToNextInline(local, msg);
}
}
use of org.apache.catalina.tribes.membership.Membership in project tomcat70 by apache.
the class NonBlockingCoordinator method createElectionMsg.
private CoordinationMessage createElectionMsg(MemberImpl local, MemberImpl[] others, MemberImpl leader) {
Membership m = new Membership(local, AbsoluteOrder.comp, true);
Arrays.fill(m, others);
MemberImpl[] mbrs = m.getMembers();
m.reset();
CoordinationMessage msg = new CoordinationMessage(leader, local, mbrs, new UniqueId(UUIDGenerator.randomUUID(true)), COORD_REQUEST);
return msg;
}
use of org.apache.catalina.tribes.membership.Membership in project tomcat70 by apache.
the class NonBlockingCoordinator method processCoordMessage.
protected void processCoordMessage(CoordinationMessage msg, Member sender) throws ChannelException {
if (!coordMsgReceived.get()) {
coordMsgReceived.set(true);
synchronized (electionMutex) {
electionMutex.notifyAll();
}
}
msg.timestamp = System.currentTimeMillis();
Membership merged = mergeOnArrive(msg, sender);
if (isViewConf(msg))
handleViewConf(msg, sender, merged);
else
handleToken(msg, sender, merged);
}
Aggregations