public boolean isCoordinator(){ return coordinator.isCoordinator(); }
@Override public void memberAdded(Member member) { memberAdded(member,true); }
@Override public void start(int svc) throws ChannelException { if (membership == null) setupMembership(); if (started)return; fireInterceptorEvent(new CoordinationEvent(CoordinationEvent.EVT_START, this, "Before start")); super.start(startsvc); started = true; if (view == null) view = new Membership(super.getLocalMember(true), AbsoluteOrder.comp, true); fireInterceptorEvent(new CoordinationEvent(CoordinationEvent.EVT_START, this, "After start")); startElection(false); }
public boolean isCoordinator() { Member coord = getCoordinator(); return coord != null && getLocalMember(false).equals(coord); }
protected void handleToken(CoordinationMessage msg, Membership merged) throws ChannelException { Member local = getLocalMember(false); if ( local.equals(msg.getSource()) ) { //my message msg.src=local handleMyToken(local, msg, merged); } else { handleOtherToken(local, msg, merged); } }
protected Membership mergeOnArrive(CoordinationMessage msg) { fireInterceptorEvent(new CoordinationEvent(CoordinationEvent.EVT_PRE_MERGE,this,"Pre merge")); Member local = getLocalMember(false); Membership merged = new Membership(local,AbsoluteOrder.comp,true); Arrays.fill(merged,msg.getMembers()); Arrays.fill(merged,getMembers()); Member[] diff = Arrays.diff(merged,membership,local); for ( int i=0; i<diff.length; i++ ) { if (!alive(diff[i])) merged.removeMember(diff[i]); else memberAdded(diff[i],false); } fireInterceptorEvent(new CoordinationEvent(CoordinationEvent.EVT_POST_MERGE,this,"Post merge")); return merged; }
public void startElection(boolean force) throws ChannelException { synchronized (electionMutex) { Member local = getLocalMember(false); Member[] others = membership.getMembers(); fireInterceptorEvent(new CoordinationEvent(CoordinationEvent.EVT_START_ELECT,this,"Election initated")); if ( others.length == 0 ) { this.viewId = new UniqueId(UUIDGenerator.randomUUID(false)); this.view = new Membership(local,AbsoluteOrder.comp, true); this.handleViewConf(createElectionMsg(local,others,local), view); return; //the only member, no need for an election 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")); fireInterceptorEvent(new CoordinationEvent(CoordinationEvent.EVT_ELECT_ABANDONED,this,"Election abandoned, view matches membership")); return; //already have this view installed Member leader = ( prio < 0 )?local:others[0];//am I the leader in my view? 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 {
protected void handleViewConf(CoordinationMessage msg, Member sender,Membership merged) throws ChannelException { if ( viewId != null && msg.getId().equals(viewId) ) return;//we already have this view 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); } }
@Override public void memberDisappeared(Member member) { membership.removeMember(member); super.memberDisappeared(member); try { fireInterceptorEvent(new CoordinationEvent(CoordinationEvent.EVT_MBR_DEL,this,"Member remove("+member.getName()+")")); if (started && (isCoordinator() || isHighest())) startElection(true); //to do, if a member disappears, only the coordinator can start } catch (ChannelException x) { log.error(sm.getString("nonBlockingCoordinator.memberDisappeared.failed"),x); } }
public void heartbeat() { try { MemberImpl local = (MemberImpl)getLocalMember(false); if ( view != null && (Arrays.diff(view,membership,local).length != 0 || Arrays.diff(membership,view,local).length != 0) ) { if ( isHighest() ) { fireInterceptorEvent(new CoordinationEvent(CoordinationEvent.EVT_START_ELECT, this, "Heartbeat found inconsistency, restart election")); startElection(true); } } } catch ( Exception x ){ log.error("Unable to perform heartbeat.",x); } finally { super.heartbeat(); } }
public void stop(int svc) throws ChannelException { try { halt(); synchronized (electionMutex) { if (!started)return; started = false; fireInterceptorEvent(new CoordinationEvent(CoordinationEvent.EVT_STOP, this, "Before stop")); super.stop(startsvc); this.view = null; this.viewId = null; this.suggestedView = null; this.suggestedviewId = null; this.membership.reset(); fireInterceptorEvent(new CoordinationEvent(CoordinationEvent.EVT_STOP, this, "After stop")); } }finally { release(); } }
protected void handleMyToken(Member local, CoordinationMessage msg, 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, 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); } }
protected void sendElectionMsg(Member local, Member next, CoordinationMessage msg) throws ChannelException { fireInterceptorEvent(new CoordinationEvent(CoordinationEvent.EVT_SEND_MSG,this,"Sending election message to("+next.getName()+")")); super.sendMessage(new Member[] {next}, createData(msg, local), null); }
@Override public void messageReceived(ChannelMessage msg) { if ( Arrays.contains(msg.getMessage().getBytesDirect(),0,COORD_ALIVE,0,COORD_ALIVE.length) ) { //ignore message, its an alive message fireInterceptorEvent(new CoordinationEvent(CoordinationEvent.EVT_MSG_ARRIVE,this,"Alive Message")); } else if ( Arrays.contains(msg.getMessage().getBytesDirect(),0,COORD_HEADER,0,COORD_HEADER.length) ) { try { CoordinationMessage cmsg = new CoordinationMessage(msg.getMessage()); Member[] cmbr = cmsg.getMembers(); fireInterceptorEvent(new CoordinationEvent(CoordinationEvent.EVT_MSG_ARRIVE,this,"Coord Msg Arrived("+Arrays.toNameString(cmbr)+")")); processCoordMessage(cmsg); }catch ( ChannelException x ) { log.error("Error processing coordination message. Could be fatal.",x); } } else { super.messageReceived(msg); } }
public boolean isHighest() { Member local = getLocalMember(false); if ( membership.getMembers().length == 0 ) return true; else return AbsoluteOrder.comp.compare(local,membership.getMembers()[0])<=0; }
public CoordinationEvent(int type,ChannelInterceptor interceptor, String info) { this.type = type; this.interceptor = interceptor; this.coord = ((NonBlockingCoordinator)interceptor).getCoordinator(); this.mbrs = ((NonBlockingCoordinator)interceptor).membership.getMembers(); this.info = info; this.view = ((NonBlockingCoordinator)interceptor).view; this.suggestedView = ((NonBlockingCoordinator)interceptor).suggestedView; }
protected Membership mergeOnArrive(CoordinationMessage msg, Member sender) { fireInterceptorEvent(new CoordinationEvent(CoordinationEvent.EVT_PRE_MERGE,this,"Pre merge")); MemberImpl local = (MemberImpl)getLocalMember(false); Membership merged = new Membership(local,AbsoluteOrder.comp,true); Arrays.fill(merged,msg.getMembers()); Arrays.fill(merged,getMembers()); Member[] diff = Arrays.diff(merged,membership,local); for ( int i=0; i<diff.length; i++ ) { if (!alive(diff[i])) merged.removeMember((MemberImpl)diff[i]); else memberAdded(diff[i],false); } fireInterceptorEvent(new CoordinationEvent(CoordinationEvent.EVT_POST_MERGE,this,"Post merge")); return merged; }
public void startElection(boolean force) throws ChannelException { synchronized (electionMutex) { Member local = getLocalMember(false); Member[] 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(createElectionMsg(local,others,local), view); return; //the only member, no need for an election 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")); fireInterceptorEvent(new CoordinationEvent(CoordinationEvent.EVT_ELECT_ABANDONED,this,"Election abandoned, view matches membership")); return; //already have this view installed Member leader = ( prio < 0 )?local:others[0];//am I the leader in my view? 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 {
protected void handleViewConf(CoordinationMessage msg, Member sender,Membership merged) throws ChannelException { if ( viewId != null && msg.getId().equals(viewId) ) return;//we already have this view 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); } }
@Override public void memberDisappeared(Member member) { try { membership.removeMember(member); super.memberDisappeared(member); try { fireInterceptorEvent(new CoordinationEvent(CoordinationEvent.EVT_MBR_DEL,this,"Member remove("+member.getName()+")")); if ( started && (isCoordinator() || isHighest()) ) startElection(true); //to do, if a member disappears, only the coordinator can start }catch ( ChannelException x ) { log.error("Unable to start election when member was removed.",x); } }finally { } }