//JAVA TO C# CONVERTER WARNING: Method 'throws' clauses are not available in C#: //ORIGINAL LINE: public org.neo4j.causalclustering.core.consensus.outcome.Outcome handle(org.neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Response response) throws java.io.IOException public override Outcome Handle(Org.Neo4j.causalclustering.core.consensus.RaftMessages_AppendEntries_Response response) { if (response.Term() < Ctx.term()) { /* Ignore responses from old terms! */ return(Outcome); } else if (response.Term() > Ctx.term()) { Outcome.NextTerm = response.Term(); StepDownToFollower(Outcome, Ctx); Log.info("Moving to FOLLOWER state after receiving append response at term %d (my term is " + "%d) from %s", response.Term(), Ctx.term(), response.From()); Outcome.replaceFollowerStates(new FollowerStates <MemberId>()); return(Outcome); } FollowerState follower = Ctx.followerStates().get(response.From()); if (response.Success()) { Debug.Assert(response.MatchIndex() <= Ctx.entryLog().appendIndex()); bool followerProgressed = response.MatchIndex() > follower.MatchIndex; Outcome.replaceFollowerStates(Outcome.FollowerStates.onSuccessResponse(response.From(), max(response.MatchIndex(), follower.MatchIndex))); Outcome.addShipCommand(new ShipCommand.Match(response.MatchIndex(), response.From())); /* * Matches from older terms can in complicated leadership change / log truncation scenarios * be overwritten, even if they were replicated to a majority of instances. Thus we must only * consider matches from this leader's term when figuring out which have been safely replicated * and are ready for commit. * This is explained nicely in Figure 3.7 of the thesis */ bool matchInCurrentTerm = Ctx.entryLog().readEntryTerm(response.MatchIndex()) == Ctx.term(); /* * The quorum situation may have changed only if the follower actually progressed. */ if (followerProgressed && matchInCurrentTerm) { // TODO: Test that mismatch between voting and participating members affects commit outcome long quorumAppendIndex = Followers.quorumAppendIndex(Ctx.votingMembers(), Outcome.FollowerStates); if (quorumAppendIndex > Ctx.commitIndex()) { Outcome.LeaderCommit = quorumAppendIndex; Outcome.CommitIndex = quorumAppendIndex; Outcome.addShipCommand(new ShipCommand.CommitUpdate()); } } } else // Response indicated failure. { if (response.AppendIndex() > -1 && response.AppendIndex() >= Ctx.entryLog().prevIndex()) { // Signal a mismatch to the log shipper, which will serve an earlier entry. Outcome.addShipCommand(new ShipCommand.Mismatch(response.AppendIndex(), response.From())); } else { // There are no earlier entries, message the follower that we have compacted so that // it can take appropriate action. RaftMessages_LogCompactionInfo compactionInfo = new RaftMessages_LogCompactionInfo(Ctx.myself(), Ctx.term(), Ctx.entryLog().prevIndex()); Org.Neo4j.causalclustering.core.consensus.RaftMessages_Directed directedCompactionInfo = new Org.Neo4j.causalclustering.core.consensus.RaftMessages_Directed(response.From(), compactionInfo); Outcome.addOutgoingMessage(directedCompactionInfo); } } return(Outcome); }