private RaftResponseMessage randomResponse(int source, long term){ RaftResponseMessage response = new RaftResponseMessage(); response.setMessageType(this.randomMessageType()); response.setAccepted(this.random.nextBoolean()); response.setDestination(source); response.setSource(this.random.nextInt()); response.setTerm(term); response.setNextIndex(this.random.nextLong()); return response; } }
public static byte[] messageToBytes(RaftResponseMessage response){ ByteBuffer buffer = ByteBuffer.allocate(RAFT_RESPONSE_HEADER_SIZE); buffer.put(response.getMessageType().toByte()); buffer.put(intToBytes(response.getSource())); buffer.put(intToBytes(response.getDestination())); buffer.put(longToBytes(response.getTerm())); buffer.put(longToBytes(response.getNextIndex())); buffer.put(booleanToByte(response.isAccepted())); return buffer.array(); }
private void handleVotingResponse(RaftResponseMessage response){ if(this.votedServers.contains(response.getSource())) { this.logger.info("Duplicate vote from %d form term %d", response.getSource(), this.state.getTerm()); return; } this.votedServers.add(response.getSource()); if(this.electionCompleted){ this.logger.info("Election completed, will ignore the voting result from this server"); return; } if(response.isAccepted()){ this.votesGranted += 1; } if(this.votedServers.size() >= this.peers.size() + 1){ this.electionCompleted = true; } // got a majority set of granted votes if(this.votesGranted > (this.peers.size() + 1) / 2){ this.logger.info("Server is elected as leader for term %d", this.state.getTerm()); this.electionCompleted = true; this.becomeLeader(); } }
private void handleAppendEntriesResponse(RaftResponseMessage response){ PeerServer peer = this.peers.get(response.getSource()); if(peer == null){ this.logger.info("the response is from an unkonw peer %d", response.getSource()); return; if(response.isAccepted()){ synchronized(peer){ peer.setNextLogIndex(response.getNextIndex()); peer.setMatchedIndex(response.getNextIndex() - 1); needToCatchup = peer.clearPendingCommit() || response.getNextIndex() < this.logStore.getFirstAvailableIndex(); }else{ synchronized(peer){ if(response.getNextIndex() > 0 && peer.getNextLogIndex() > response.getNextIndex()){ peer.setNextLogIndex(response.getNextIndex()); }else{ peer.setNextLogIndex(peer.getNextLogIndex() - 1);
getOrCreateRpcClient().send(request).whenCompleteAsync((RaftResponseMessage response, Throwable error) -> { if(error == null){ logger.debug("response from remote server, leader: %d, accepted: %s", response.getDestination(), String.valueOf(response.isAccepted())); if(response.isAccepted()){ future.complete(true); }else{ if(this.leaderId == response.getDestination() && !this.randomLeader){ future.complete(false); }else{ this.randomLeader = false; this.leaderId = response.getDestination(); tryCurrentLeader(request, future, rpcBackoff, retry);
return CompletableFuture.completedFuture(this.server.processRequest(request).isAccepted()); result.complete(false); }else{ result.complete(response.isAccepted());
private void handleAppendEntriesResponse(RaftResponseMessage response){ PeerServer peer = this.peers.get(response.getSource()); if(peer == null){ this.logger.info("the response is from an unkonw peer %d", response.getSource()); return; if(response.isAccepted()){ synchronized(peer){ peer.setNextLogIndex(response.getNextIndex()); peer.setMatchedIndex(response.getNextIndex() - 1); needToCatchup = peer.clearPendingCommit() || response.getNextIndex() < this.logStore.getFirstAvailableIndex(); }else{ synchronized(peer){ if(response.getNextIndex() > 0 && peer.getNextLogIndex() > response.getNextIndex()){ peer.setNextLogIndex(response.getNextIndex()); }else{ peer.setNextLogIndex(peer.getNextLogIndex() - 1);
getOrCreateRpcClient().send(request).whenCompleteAsync((RaftResponseMessage response, Throwable error) -> { if(error == null){ logger.debug("response from remote server, leader: %d, accepted: %s", response.getDestination(), String.valueOf(response.isAccepted())); if(response.isAccepted()){ future.complete(true); }else{ if(this.leaderId == response.getDestination() && !this.randomLeader){ future.complete(false); }else{ this.randomLeader = false; this.leaderId = response.getDestination(); tryCurrentLeader(request, future, rpcBackoff, retry);
private void handleVotingResponse(RaftResponseMessage response){ this.votesResponded += 1; if(this.electionCompleted){ this.logger.info("Election completed, will ignore the voting result from this server"); return; } if(response.isAccepted()){ this.votesGranted += 1; } if(this.votesResponded >= this.peers.size() + 1){ this.electionCompleted = true; } // got a majority set of granted votes if(this.votesGranted > (this.peers.size() + 1) / 2){ this.logger.info("Server is elected as leader for term %d", this.state.getTerm()); this.electionCompleted = true; this.becomeLeader(); } }
private RaftResponseMessage randomResponse(int source, long term){ RaftResponseMessage response = new RaftResponseMessage(); response.setMessageType(this.randomMessageType()); response.setAccepted(this.random.nextBoolean()); response.setDestination(source); response.setSource(this.random.nextInt()); response.setTerm(term); response.setNextIndex(this.random.nextLong()); return response; } }
public static byte[] messageToBytes(RaftResponseMessage response){ ByteBuffer buffer = ByteBuffer.allocate(RAFT_RESPONSE_HEADER_SIZE); buffer.put(response.getMessageType().toByte()); buffer.put(intToBytes(response.getSource())); buffer.put(intToBytes(response.getDestination())); buffer.put(longToBytes(response.getTerm())); buffer.put(longToBytes(response.getNextIndex())); buffer.put(booleanToByte(response.isAccepted())); return buffer.array(); }
private void handleAppendEntriesResponse(RaftResponseMessage response){ PeerServer peer = this.peers.get(response.getSource()); if(peer == null){ this.logger.info("the response is from an unkonw peer %d", response.getSource()); return; if(response.isAccepted()){ synchronized(peer){ peer.setNextLogIndex(response.getNextIndex()); peer.setMatchedIndex(response.getNextIndex() - 1); needToCatchup = peer.clearPendingCommit() || response.getNextIndex() < this.logStore.getFirstAvailableIndex(); }else{ synchronized(peer){ if(response.getNextIndex() > 0 && peer.getNextLogIndex() > response.getNextIndex()){ peer.setNextLogIndex(response.getNextIndex()); }else{ peer.setNextLogIndex(peer.getNextLogIndex() - 1);
getOrCreateRpcClient().send(request).whenCompleteAsync((RaftResponseMessage response, Throwable error) -> { if(error == null){ logger.debug("response from remote server, leader: %d, accepted: %s", response.getDestination(), String.valueOf(response.isAccepted())); if(response.isAccepted()){ future.complete(true); }else{ if(this.leaderId == response.getDestination() && !this.randomLeader){ future.complete(false); }else{ this.randomLeader = false; this.leaderId = response.getDestination(); tryCurrentLeader(request, future, rpcBackoff, retry);
private void handleVotingResponse(RaftResponseMessage response){ this.votesResponded += 1; if(this.electionCompleted){ this.logger.info("Election completed, will ignore the voting result from this server"); return; } if(response.isAccepted()){ this.votesGranted += 1; } if(this.votesResponded >= this.peers.size() + 1){ this.electionCompleted = true; } // got a majority set of granted votes if(this.votesGranted > (this.peers.size() + 1) / 2){ this.logger.info("Server is elected as leader for term %d", this.state.getTerm()); this.electionCompleted = true; this.becomeLeader(); } }
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; }
response.getMessageType().toString(), response.getSource(), String.valueOf(response.isAccepted()), response.getTerm(), response.getNextIndex()); if(this.updateTerm(response.getTerm())){ return; if(response.getTerm() < this.state.getTerm()){ this.logger.info("Received a peer response from %d that with lower term value %d v.s. %d", response.getSource(), response.getTerm(), this.state.getTerm()); return; if(response.getMessageType() == RaftMessageType.RequestVoteResponse){ this.handleVotingResponse(response); }else if(response.getMessageType() == RaftMessageType.AppendEntriesResponse){ this.handleAppendEntriesResponse(response); }else if(response.getMessageType() == RaftMessageType.InstallSnapshotResponse){ this.handleInstallSnapshotResponse(response); }else{ this.logger.error("Received an unexpected message %s for response, system exits.", response.getMessageType().toString()); this.stateMachine.exit(-1);
private void handleInstallSnapshotResponse(RaftResponseMessage response){ PeerServer peer = this.peers.get(response.getSource()); if(peer == null){ this.logger.info("the response is from an unkonw peer %d", response.getSource()); return; if(response.isAccepted()){ synchronized(peer){ SnapshotSyncContext context = peer.getSnapshotSyncContext(); needToCatchup = false; }else{ if(response.getNextIndex() >= context.getSnapshot().getSize()){ this.logger.debug("snapshot sync is done"); peer.setNextLogIndex(context.getSnapshot().getLastLogIndex() + 1); peer.setMatchedIndex(context.getSnapshot().getLastLogIndex()); peer.setSnapshotInSync(null); needToCatchup = peer.clearPendingCommit() || response.getNextIndex() < this.logStore.getFirstAvailableIndex(); }else{ this.logger.debug("continue to sync snapshot at offset %d", response.getNextIndex()); context.setOffset(response.getNextIndex());
return CompletableFuture.completedFuture(this.server.processRequest(request).isAccepted()); result.complete(false); }else{ result.complete(response.isAccepted());
public static RaftResponseMessage bytesToResponseMessage(byte[] data){ if(data == null || data.length != RAFT_RESPONSE_HEADER_SIZE){ throw new IllegalArgumentException(String.format("data must have %d bytes for a raft response message", RAFT_RESPONSE_HEADER_SIZE)); } ByteBuffer buffer = ByteBuffer.wrap(data); RaftResponseMessage response = new RaftResponseMessage(); response.setMessageType(RaftMessageType.fromByte(buffer.get())); response.setSource(buffer.getInt()); response.setDestination(buffer.getInt()); response.setTerm(buffer.getLong()); response.setNextIndex(buffer.getLong()); response.setAccepted(buffer.get() == 1); return response; }
response.getMessageType().toString(), response.getSource(), String.valueOf(response.isAccepted()), response.getTerm(), response.getNextIndex()); if(this.updateTerm(response.getTerm())){ return; if(response.getTerm() < this.state.getTerm()){ this.logger.info("Received a peer response from %d that with lower term value %d v.s. %d", response.getSource(), response.getTerm(), this.state.getTerm()); return; if(response.getMessageType() == RaftMessageType.RequestVoteResponse){ this.handleVotingResponse(response); }else if(response.getMessageType() == RaftMessageType.AppendEntriesResponse){ this.handleAppendEntriesResponse(response); }else if(response.getMessageType() == RaftMessageType.InstallSnapshotResponse){ this.handleInstallSnapshotResponse(response); }else{ this.logger.error("Received an unexpected message %s for response, system exits.", response.getMessageType().toString()); this.stateMachine.exit(-1);