private synchronized void handleHeartbeatTimeout(PeerServer peer){ this.logger.debug("Heartbeat timeout for %d", peer.getId()); if(this.role == ServerRole.Leader){ this.requestAppendEntries(peer); synchronized(peer){ if(peer.isHeartbeatEnabled()){ // Schedule another heartbeat if heartbeat is still enabled peer.setHeartbeatTask(this.context.getScheduledExecutor().schedule(peer.getHeartbeartHandler(), peer.getCurrentHeartbeatInterval(), TimeUnit.MILLISECONDS)); }else{ this.logger.debug("heartbeat is disabled for peer %d", peer.getId()); } } }else{ this.logger.info("Receive a heartbeat event for %d while no longer as a leader", peer.getId()); } }
private synchronized void handleHeartbeatTimeout(PeerServer peer){ this.logger.debug("Heartbeat timeout for %d", peer.getId()); if(this.role == ServerRole.Leader){ this.requestAppendEntries(peer); synchronized(peer){ if(peer.isHeartbeatEnabled()){ // Schedule another heartbeat if heartbeat is still enabled peer.setHeartbeatTask(this.context.getScheduledExecutor().schedule(peer.getHeartbeartHandler(), peer.getCurrentHeartbeatInterval(), TimeUnit.MILLISECONDS)); }else{ this.logger.debug("heartbeat is disabled for peer %d", peer.getId()); } } }else{ this.logger.info("Receive a heartbeat event for %d while no longer as a leader", peer.getId()); } }
private synchronized void handleHeartbeatTimeout(PeerServer peer){ this.logger.debug("Heartbeat timeout for %d", peer.getId()); if(this.role == ServerRole.Leader){ this.requestAppendEntries(peer); synchronized(peer){ if(peer.isHeartbeatEnabled()){ // Schedule another heartbeat if heartbeat is still enabled peer.setHeartbeatTask(this.context.getScheduledExecutor().schedule(peer.getHeartbeartHandler(), peer.getCurrentHeartbeatInterval(), TimeUnit.MILLISECONDS)); }else{ this.logger.debug("heartbeat is disabled for peer %d", peer.getId()); } } }else{ this.logger.info("Receive a heartbeat event for %d while no longer as a leader", peer.getId()); } }
private boolean requestAppendEntries(PeerServer peer){ if(peer.makeBusy()){ peer.SendRequest(this.createAppendEntriesRequest(peer)) .whenCompleteAsync((RaftResponseMessage response, Throwable error) -> { try{ handlePeerResponse(response, error); }catch(Throwable err){ this.logger.error("Uncaught exception %s", err.toString()); } }, this.context.getScheduledExecutor()); return true; } this.logger.debug("Server %d is busy, skip the request", peer.getId()); return false; }
private boolean requestAppendEntries(PeerServer peer){ if(peer.makeBusy()){ peer.SendRequest(this.createAppendEntriesRequest(peer)) .whenCompleteAsync((RaftResponseMessage response, Throwable error) -> { try{ handlePeerResponse(response, error); }catch(Throwable err){ this.logger.error("Uncaught exception %s", err.toString()); } }, this.context.getScheduledExecutor()); return true; } this.logger.debug("Server %d is busy, skip the request", peer.getId()); return false; }
private boolean requestAppendEntries(PeerServer peer){ if(peer.makeBusy()){ peer.SendRequest(this.createAppendEntriesRequest(peer)) .whenCompleteAsync((RaftResponseMessage response, Throwable error) -> { try{ handlePeerResponse(response, error); }catch(Throwable err){ this.logger.error("Uncaught exception %s", err.toString()); } }, this.context.getScheduledExecutor()); return true; } this.logger.debug("Server %d is busy, skip the request", peer.getId()); return false; }
private void requestVote(){ // vote for self this.logger.info("requestVote started with term %d", this.state.getTerm()); this.state.setVotedFor(this.id); this.context.getServerStateManager().persistState(this.state); this.votesGranted += 1; this.votedServers.add(this.id); // this is the only server? if(this.votesGranted > (this.peers.size() + 1) / 2){ this.electionCompleted = true; this.becomeLeader(); return; } for(PeerServer peer : this.peers.values()){ RaftRequestMessage request = new RaftRequestMessage(); request.setMessageType(RaftMessageType.RequestVoteRequest); request.setDestination(peer.getId()); request.setSource(this.id); request.setLastLogIndex(this.logStore.getFirstAvailableIndex() - 1); request.setLastLogTerm(this.termForLastLog(this.logStore.getFirstAvailableIndex() - 1)); request.setTerm(this.state.getTerm()); this.logger.debug("send %s to server %d with term %d", RaftMessageType.RequestVoteRequest.toString(), peer.getId(), this.state.getTerm()); peer.SendRequest(request).whenCompleteAsync((RaftResponseMessage response, Throwable error) -> { handlePeerResponse(response, error); }, this.context.getScheduledExecutor()); } }
private void requestVote(){ // vote for self this.logger.info("requestVote started with term %d", this.state.getTerm()); this.state.setVotedFor(this.id); this.context.getServerStateManager().persistState(this.state); this.votesGranted += 1; this.votesResponded += 1; // this is the only server? if(this.votesGranted > (this.peers.size() + 1) / 2){ this.electionCompleted = true; this.becomeLeader(); return; } for(PeerServer peer : this.peers.values()){ RaftRequestMessage request = new RaftRequestMessage(); request.setMessageType(RaftMessageType.RequestVoteRequest); request.setDestination(peer.getId()); request.setSource(this.id); request.setLastLogIndex(this.logStore.getFirstAvailableIndex() - 1); request.setLastLogTerm(this.termForLastLog(this.logStore.getFirstAvailableIndex() - 1)); request.setTerm(this.state.getTerm()); this.logger.debug("send %s to server %d with term %d", RaftMessageType.RequestVoteRequest.toString(), peer.getId(), this.state.getTerm()); peer.SendRequest(request).whenCompleteAsync((RaftResponseMessage response, Throwable error) -> { handlePeerResponse(response, error); }, this.context.getScheduledExecutor()); } }
private void requestVote(){ // vote for self this.logger.info("requestVote started with term %d", this.state.getTerm()); this.state.setVotedFor(this.id); this.context.getServerStateManager().persistState(this.state); this.votesGranted += 1; this.votesResponded += 1; // this is the only server? if(this.votesGranted > (this.peers.size() + 1) / 2){ this.electionCompleted = true; this.becomeLeader(); return; } for(PeerServer peer : this.peers.values()){ RaftRequestMessage request = new RaftRequestMessage(); request.setMessageType(RaftMessageType.RequestVoteRequest); request.setDestination(peer.getId()); request.setSource(this.id); request.setLastLogIndex(this.logStore.getFirstAvailableIndex() - 1); request.setLastLogTerm(this.termForLastLog(this.logStore.getFirstAvailableIndex() - 1)); request.setTerm(this.state.getTerm()); this.logger.debug("send %s to server %d with term %d", RaftMessageType.RequestVoteRequest.toString(), peer.getId(), this.state.getTerm()); peer.SendRequest(request).whenCompleteAsync((RaftResponseMessage response, Throwable error) -> { handlePeerResponse(response, error); }, this.context.getScheduledExecutor()); } }
this.logger.error("system is running into fatal errors, failed to find a snapshot for peer %d(snapshot null: %s, snapshot doesn't contais lastLogIndex: %s)", peer.getId(), String.valueOf(snapshot == null), String.valueOf(lastLogIndex > snapshot.getLastLogIndex())); this.stateMachine.exit(-1); return null; this.logger.info("trying to sync snapshot with last index %d to peer %d", snapshot.getLastLogIndex(), peer.getId()); peer.setSnapshotInSync(snapshot); requestMessage.setMessageType(RaftMessageType.InstallSnapshotRequest); requestMessage.setSource(this.id); requestMessage.setDestination(peer.getId()); requestMessage.setLastLogIndex(snapshot.getLastLogIndex()); requestMessage.setLastLogTerm(snapshot.getLastLogTerm());
this.logger.debug( "An AppendEntries Request for %d with LastLogIndex=%d, LastLogTerm=%d, EntriesLength=%d, CommitIndex=%d and Term=%d", peer.getId(), lastLogIndex, lastLogTerm, requestMessage.setMessageType(RaftMessageType.AppendEntriesRequest); requestMessage.setSource(this.id); requestMessage.setDestination(peer.getId()); requestMessage.setLastLogIndex(lastLogIndex); requestMessage.setLastLogTerm(lastLogTerm);
if(gap < this.context.getRaftParameters().getLogSyncStopGap()){ this.logger.info("LogSync is done for server %d with log gap %d, now put the server into cluster", this.serverToJoin.getId(), gap); ClusterConfiguration newConfig = new ClusterConfiguration(); newConfig.setLastLogIndex(this.config.getLogIndex()); request = new RaftRequestMessage(); request.setCommitIndex(this.quickCommitIndex); request.setDestination(this.serverToJoin.getId()); request.setSource(this.id); request.setTerm(this.state.getTerm());
private void inviteServerToJoinCluster(){ RaftRequestMessage request = new RaftRequestMessage(); request.setCommitIndex(this.quickCommitIndex); request.setDestination(this.serverToJoin.getId()); request.setSource(this.id); request.setTerm(this.state.getTerm()); request.setMessageType(RaftMessageType.JoinClusterRequest); request.setLastLogIndex(this.logStore.getFirstAvailableIndex() - 1); request.setLogEntries(new LogEntry[] { new LogEntry(this.state.getTerm(), this.config.toBytes(), LogValueType.Configuration) }); this.serverToJoin.SendRequest(request).whenCompleteAsync((RaftResponseMessage response, Throwable error) -> { this.handleExtendedResponse(response, error); }, this.context.getScheduledExecutor()); }
if(gap < this.context.getRaftParameters().getLogSyncStopGap()){ this.logger.info("LogSync is done for server %d with log gap %d, now put the server into cluster", this.serverToJoin.getId(), gap); ClusterConfiguration newConfig = new ClusterConfiguration(); newConfig.setLastLogIndex(this.config.getLogIndex()); request = new RaftRequestMessage(); request.setCommitIndex(this.quickCommitIndex); request.setDestination(this.serverToJoin.getId()); request.setSource(this.id); request.setTerm(this.state.getTerm());
private void inviteServerToJoinCluster(){ RaftRequestMessage request = new RaftRequestMessage(); request.setCommitIndex(this.quickCommitIndex); request.setDestination(this.serverToJoin.getId()); request.setSource(this.id); request.setTerm(this.state.getTerm()); request.setMessageType(RaftMessageType.JoinClusterRequest); request.setLastLogIndex(this.logStore.getFirstAvailableIndex() - 1); request.setLogEntries(new LogEntry[] { new LogEntry(this.state.getTerm(), this.config.toBytes(), LogValueType.Configuration) }); this.serverToJoin.SendRequest(request).whenCompleteAsync((RaftResponseMessage response, Throwable error) -> { this.handleExtendedResponse(response, error); }, this.context.getScheduledExecutor()); }
if(gap < this.context.getRaftParameters().getLogSyncStopGap()){ this.logger.info("LogSync is done for server %d with log gap %d, now put the server into cluster", this.serverToJoin.getId(), gap); ClusterConfiguration newConfig = new ClusterConfiguration(); newConfig.setLastLogIndex(this.config.getLogIndex()); request = new RaftRequestMessage(); request.setCommitIndex(this.quickCommitIndex); request.setDestination(this.serverToJoin.getId()); request.setSource(this.id); request.setTerm(this.state.getTerm());
private void inviteServerToJoinCluster(){ RaftRequestMessage request = new RaftRequestMessage(); request.setCommitIndex(this.quickCommitIndex); request.setDestination(this.serverToJoin.getId()); request.setSource(this.id); request.setTerm(this.state.getTerm()); request.setMessageType(RaftMessageType.JoinClusterRequest); request.setLastLogIndex(this.logStore.getFirstAvailableIndex() - 1); request.setLogEntries(new LogEntry[] { new LogEntry(this.state.getTerm(), this.config.toBytes(), LogValueType.Configuration) }); this.serverToJoin.SendRequest(request).whenCompleteAsync((RaftResponseMessage response, Throwable error) -> { this.handleExtendedResponse(response, error); }, this.context.getScheduledExecutor()); }
leaveClusterRequest.setDestination(peer.getId()); leaveClusterRequest.setLastLogIndex(this.logStore.getFirstAvailableIndex() - 1); leaveClusterRequest.setLastLogTerm(0);
leaveClusterRequest.setDestination(peer.getId()); leaveClusterRequest.setLastLogIndex(this.logStore.getFirstAvailableIndex() - 1); leaveClusterRequest.setLastLogTerm(0);
leaveClusterRequest.setDestination(peer.getId()); leaveClusterRequest.setLastLogIndex(this.logStore.getFirstAvailableIndex() - 1); leaveClusterRequest.setLastLogTerm(0);