private void askWhoIsTheLeader() { logger.info("Node " + conf.getNodeId() + " is searching for the leader"); MgmtHeader.Builder mhb = MgmtHeader.newBuilder(); mhb.setOriginator(conf.getNodeId()); mhb.setTime(System.currentTimeMillis()); mhb.setSecurityCode(-999); // TODO add security VectorClock.Builder rpb = VectorClock.newBuilder(); rpb.setNodeId(conf.getNodeId()); rpb.setTime(mhb.getTime()); rpb.setVersion(termId); mhb.addPath(rpb); LeaderElection.Builder elb = LeaderElection.newBuilder(); elb.setTermId(termId); elb.setLastLogIndex(lastLogIndex); elb.setAction(ElectAction.WHOISTHELEADER); elb.setDesc("Node " + this.leaderNode + " is asking who the leader is"); elb.setCandidateId(-1); elb.setExpires(-1); Management.Builder mb = Management.newBuilder(); mb.setHeader(mhb.build()); mb.setElection(elb.build()); // now send it to the requester ConnectionManager.broadcast(mb.build()); }
// gives back the current leader if the node is aware of who the leader is // else responds I do // not know who the leader is/ private void respondToWhoIsTheLeader(Management mgmt) { if (this.leaderNode == null) { logger.info("----> I cannot respond to who the leader is! I don't know!"); return; } logger.info( "Node " + conf.getNodeId() + " is replying to " + mgmt.getHeader().getOriginator() + "'s request who the leader is. Its Node " + this.leaderNode); MgmtHeader.Builder mhb = MgmtHeader.newBuilder(); mhb.setOriginator(conf.getNodeId()); mhb.setTime(System.currentTimeMillis()); mhb.setSecurityCode(-999); VectorClock.Builder rpb = VectorClock.newBuilder(); rpb.setNodeId(conf.getNodeId()); rpb.setTime(mhb.getTime()); rpb.setVersion(termId); mhb.addPath(rpb); LeaderElection.Builder elb = LeaderElection.newBuilder(); elb.setTermId(termId); elb.setLastLogIndex(lastLogIndex); elb.setAction(ElectAction.THELEADERIS); elb.setDesc("Node " + this.leaderNode + " is the leader"); elb.setCandidateId(this.leaderNode); elb.setExpires(-1); Management.Builder mb = Management.newBuilder(); mb.setHeader(mhb.build()); mb.setElection(elb.build()); // now send it to the requester try { ConnectionManager.getConnection(mgmt.getHeader().getOriginator(), true).write(mb.build()); } catch (Exception ex) { ex.printStackTrace(); } }
/** * initiate an election from within the server - most likely scenario is the heart beat manager * detects a failure of the leader and calls this method. * * <p>Depending upon the algo. used (bully, flood, lcr, hs) the manager.startElection() will * create the algo class instance and forward processing to it. If there was an election in * progress and the election ID is not the same, the new election will supplant the current * (older) election. This should only be triggered from nodes that share an edge with the leader. */ public void startElection() { System.out.println("Inside start election"); this.state = RState.Candidate; this.termId = electionInstance().createTermId(); LeaderElection.Builder elb = LeaderElection.newBuilder(); elb.setTermId(this.termId); elb.setLastLogIndex(this.lastLogIndex); elb.setAction(ElectAction.DECLAREELECTION); elb.setDesc("Node " + conf.getNodeId() + " detects no leader. Election!"); elb.setCandidateId(conf.getNodeId()); // promote self elb.setExpires(2 * 60 * 1000 + System.currentTimeMillis()); // 1 minute // bias the voting with my number of votes (for algos that use vote // counting) // TODO use voting int votes = conf.getNumberOfElectionVotes(); MgmtHeader.Builder mhb = MgmtHeader.newBuilder(); mhb.setOriginator(conf.getNodeId()); mhb.setTime(System.currentTimeMillis()); mhb.setSecurityCode(-999); // TODO add security VectorClock.Builder rpb = VectorClock.newBuilder(); rpb.setNodeId(conf.getNodeId()); rpb.setTime(mhb.getTime()); rpb.setVersion(termId); mhb.addPath(rpb); Management.Builder mb = Management.newBuilder(); mb.setHeader(mhb.build()); mb.setElection(elb.build()); // now send it out to all my edges logger.info("Election started by node " + conf.getNodeId()); ConnectionManager.broadcast(mb.build()); }