private void requestAppendEntries(){ if(this.peers.size() == 0){ this.commit(this.logStore.getFirstAvailableIndex() - 1); return; } for(PeerServer peer : this.peers.values()){ this.requestAppendEntries(peer); } }
private void requestAppendEntries(){ if(this.peers.size() == 0){ this.commit(this.logStore.getFirstAvailableIndex() - 1); return; } for(PeerServer peer : this.peers.values()){ this.requestAppendEntries(peer); } }
private void requestAppendEntries(){ if(this.peers.size() == 0){ this.commit(this.logStore.getFirstAvailableIndex() - 1); return; } for(PeerServer peer : this.peers.values()){ this.requestAppendEntries(peer); } }
private void commit(long targetIndex){ if(targetIndex > this.quickCommitIndex){ this.quickCommitIndex = targetIndex; // if this is a leader notify peers to commit as well // for peers that are free, send the request, otherwise, set pending commit flag for that peer if(this.role == ServerRole.Leader){ for(PeerServer peer : this.peers.values()){ if(!this.requestAppendEntries(peer)){ peer.setPendingCommit(); } } } } if(this.logStore.getFirstAvailableIndex() - 1 > this.state.getCommitIndex() && this.quickCommitIndex > this.state.getCommitIndex()){ this.commitingThread.moreToCommit(); } }
private void commit(long targetIndex){ if(targetIndex > this.quickCommitIndex){ this.quickCommitIndex = targetIndex; // if this is a leader notify peers to commit as well // for peers that are free, send the request, otherwise, set pending commit flag for that peer if(this.role == ServerRole.Leader){ for(PeerServer peer : this.peers.values()){ if(!this.requestAppendEntries(peer)){ peer.setPendingCommit(); } } } } if(this.logStore.getFirstAvailableIndex() - 1 > this.state.getCommitIndex() && this.quickCommitIndex > this.state.getCommitIndex()){ this.commitingThread.moreToCommit(); } }
private void commit(long targetIndex){ if(targetIndex > this.quickCommitIndex){ this.quickCommitIndex = targetIndex; // if this is a leader notify peers to commit as well // for peers that are free, send the request, otherwise, set pending commit flag for that peer if(this.role == ServerRole.Leader){ for(PeerServer peer : this.peers.values()){ if(!this.requestAppendEntries(peer)){ peer.setPendingCommit(); } } } } if(this.logStore.getFirstAvailableIndex() - 1 > this.state.getCommitIndex() && this.quickCommitIndex > this.state.getCommitIndex()){ this.commitingThread.moreToCommit(); } }
private void becomeLeader(){ this.stopElectionTimer(); this.role = ServerRole.Leader; this.leader = this.id; this.serverToJoin = null; for(PeerServer server : this.peers.values()){ server.setNextLogIndex(this.logStore.getFirstAvailableIndex()); server.setSnapshotInSync(null); server.setFree(); this.enableHeartbeatForPeer(server); } // if current config is not committed, try to commit it if(this.config.getLogIndex() == 0){ this.config.setLogIndex(this.logStore.getFirstAvailableIndex()); this.logStore.append(new LogEntry(this.state.getTerm(), this.config.toBytes(), LogValueType.Configuration)); this.logger.info("add initial configuration to log store"); this.configChanging = true; } this.requestAppendEntries(); }
private void becomeLeader(){ this.stopElectionTimer(); this.role = ServerRole.Leader; this.leader = this.id; this.serverToJoin = null; for(PeerServer server : this.peers.values()){ server.setNextLogIndex(this.logStore.getFirstAvailableIndex()); server.setSnapshotInSync(null); server.setFree(); this.enableHeartbeatForPeer(server); } // if current config is not committed, try to commit it if(this.config.getLogIndex() == 0){ this.config.setLogIndex(this.logStore.getFirstAvailableIndex()); this.logStore.append(new LogEntry(this.state.getTerm(), this.config.toBytes(), LogValueType.Configuration)); this.logger.info("add initial configuration to log store"); this.configChanging = true; } this.requestAppendEntries(); }
private void becomeLeader(){ this.stopElectionTimer(); this.role = ServerRole.Leader; this.leader = this.id; this.serverToJoin = null; for(PeerServer server : this.peers.values()){ server.setNextLogIndex(this.logStore.getFirstAvailableIndex()); server.setSnapshotInSync(null); server.setFree(); this.enableHeartbeatForPeer(server); } // if current config is not committed, try to commit it if(this.config.getLogIndex() == 0){ this.config.setLogIndex(this.logStore.getFirstAvailableIndex()); this.logStore.append(new LogEntry(this.state.getTerm(), this.config.toBytes(), LogValueType.Configuration)); this.logger.info("add initial configuration to log store"); this.configChanging = true; } this.requestAppendEntries(); }
private void removeServerFromCluster(int serverId){ ClusterConfiguration newConfig = new ClusterConfiguration(); newConfig.setLastLogIndex(this.config.getLogIndex()); newConfig.setLogIndex(this.logStore.getFirstAvailableIndex()); for(ClusterServer server: this.config.getServers()){ if(server.getId() != serverId){ newConfig.getServers().add(server); } } this.logger.info("removed a server from configuration and save the configuration to log store at %d", newConfig.getLogIndex()); this.configChanging = true; this.logStore.append(new LogEntry(this.state.getTerm(), newConfig.toBytes(), LogValueType.Configuration)); this.requestAppendEntries(); }
private void removeServerFromCluster(int serverId){ ClusterConfiguration newConfig = new ClusterConfiguration(); newConfig.setLastLogIndex(this.config.getLogIndex()); newConfig.setLogIndex(this.logStore.getFirstAvailableIndex()); for(ClusterServer server: this.config.getServers()){ if(server.getId() != serverId){ newConfig.getServers().add(server); } } this.logger.info("removed a server from configuration and save the configuration to log store at %d", newConfig.getLogIndex()); this.configChanging = true; this.logStore.append(new LogEntry(this.state.getTerm(), newConfig.toBytes(), LogValueType.Configuration)); this.requestAppendEntries(); }
private void removeServerFromCluster(int serverId){ ClusterConfiguration newConfig = new ClusterConfiguration(); newConfig.setLastLogIndex(this.config.getLogIndex()); newConfig.setLogIndex(this.logStore.getFirstAvailableIndex()); for(ClusterServer server: this.config.getServers()){ if(server.getId() != serverId){ newConfig.getServers().add(server); } } this.logger.info("removed a server from configuration and save the configuration to log store at %d", newConfig.getLogIndex()); this.configChanging = true; this.logStore.append(new LogEntry(this.state.getTerm(), newConfig.toBytes(), LogValueType.Configuration)); this.requestAppendEntries(); }
private RaftResponseMessage handleLeaveClusterRequest(RaftRequestMessage request){ RaftResponseMessage response = new RaftResponseMessage(); response.setSource(this.id); response.setDestination(request.getSource()); response.setTerm(this.state.getTerm()); response.setMessageType(RaftMessageType.LeaveClusterResponse); response.setNextIndex(this.logStore.getFirstAvailableIndex()); if(!this.configChanging){ this.steppingDown = 2; response.setAccepted(true); }else{ response.setAccepted(false); } return response; }
private RaftResponseMessage handleLeaveClusterRequest(RaftRequestMessage request){ RaftResponseMessage response = new RaftResponseMessage(); response.setSource(this.id); response.setDestination(request.getSource()); response.setTerm(this.state.getTerm()); response.setMessageType(RaftMessageType.LeaveClusterResponse); response.setNextIndex(this.logStore.getFirstAvailableIndex()); if(!this.configChanging){ this.steppingDown = 2; response.setAccepted(true); }else{ response.setAccepted(false); } return response; }
private RaftResponseMessage handleLeaveClusterRequest(RaftRequestMessage request){ RaftResponseMessage response = new RaftResponseMessage(); response.setSource(this.id); response.setDestination(request.getSource()); response.setTerm(this.state.getTerm()); response.setMessageType(RaftMessageType.LeaveClusterResponse); response.setNextIndex(this.logStore.getFirstAvailableIndex()); if(!this.configChanging){ this.steppingDown = 2; response.setAccepted(true); }else{ response.setAccepted(false); } return response; }
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()); }
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()); }
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()); }
private synchronized RaftResponseMessage handleVoteRequest(RaftRequestMessage request){ // we allow the server to be continue after term updated to save a round message this.updateTerm(request.getTerm()); // Reset stepping down value to prevent this server goes down when leader crashes after sending a LeaveClusterRequest if(this.steppingDown > 0){ this.steppingDown = 2; } RaftResponseMessage response = new RaftResponseMessage(); response.setMessageType(RaftMessageType.RequestVoteResponse); response.setSource(this.id); response.setDestination(request.getSource()); response.setTerm(this.state.getTerm()); boolean logOkay = request.getLastLogTerm() > this.logStore.getLastLogEntry().getTerm() || (request.getLastLogTerm() == this.logStore.getLastLogEntry().getTerm() && this.logStore.getFirstAvailableIndex() - 1 <= request.getLastLogIndex()); boolean grant = request.getTerm() == this.state.getTerm() && logOkay && (this.state.getVotedFor() == request.getSource() || this.state.getVotedFor() == -1); response.setAccepted(grant); if(grant){ this.state.setVotedFor(request.getSource()); this.context.getServerStateManager().persistState(this.state); } return response; }
private synchronized RaftResponseMessage handleVoteRequest(RaftRequestMessage request){ // we allow the server to be continue after term updated to save a round message this.updateTerm(request.getTerm()); // Reset stepping down value to prevent this server goes down when leader crashes after sending a LeaveClusterRequest if(this.steppingDown > 0){ this.steppingDown = 2; } RaftResponseMessage response = new RaftResponseMessage(); response.setMessageType(RaftMessageType.RequestVoteResponse); response.setSource(this.id); response.setDestination(request.getSource()); response.setTerm(this.state.getTerm()); boolean logOkay = request.getLastLogTerm() > this.logStore.getLastLogEntry().getTerm() || (request.getLastLogTerm() == this.logStore.getLastLogEntry().getTerm() && this.logStore.getFirstAvailableIndex() - 1 <= request.getLastLogIndex()); boolean grant = request.getTerm() == this.state.getTerm() && logOkay && (this.state.getVotedFor() == request.getSource() || this.state.getVotedFor() == -1); response.setAccepted(grant); if(grant){ this.state.setVotedFor(request.getSource()); this.context.getServerStateManager().persistState(this.state); } return response; }