Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (c) 2002-2016 "Neo Technology,"
* Network Engine for Objects in Lund AB [http://neotechnology.com]
*
* This file is part of Neo4j.
*
* Neo4j is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*/
package org.neo4j.coreedge.core.consensus.outcome;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import org.neo4j.coreedge.messaging.Message;
import org.neo4j.coreedge.core.consensus.RaftMessages;
import org.neo4j.coreedge.core.consensus.roles.Role;
import org.neo4j.coreedge.core.consensus.state.ReadableRaftState;
import org.neo4j.coreedge.core.consensus.roles.follower.FollowerStates;
import org.neo4j.coreedge.identity.MemberId;
/**
* Holds the outcome of a RAFT role's handling of a message. The role handling logic is stateless
* and responds to RAFT messages in the context of a supplied state. The outcome is later consumed
* to update the state and do operations embedded as commands within the outcome.
*
* A state update could be to change role, change term, etc.
* A command could be to append to the RAFT log, tell the log shipper that there was a mismatch, etc.
*/
public class Outcome implements Message, ConsensusOutcome
{
/* Common */
private Role nextRole;
private long term;
private MemberId leader;
private long leaderCommit;
private Collection logCommands = new ArrayList<>();
private Collection outgoingMessages = new ArrayList<>();
private long commitIndex;
/* Follower */
private MemberId votedFor;
private boolean renewElectionTimeout;
private boolean needsFreshSnapshot;
/* Candidate */
private Set votesForMe;
private long lastLogIndexBeforeWeBecameLeader;
/* Leader */
private FollowerStates followerStates;
private Collection shipCommands = new ArrayList<>();
private boolean electedLeader;
private boolean steppingDown;
public Outcome( Role currentRole, ReadableRaftState ctx )
{
defaults( currentRole, ctx );
}
public Outcome( Role nextRole, long term, MemberId leader, long leaderCommit, MemberId votedFor,
Set votesForMe, long lastLogIndexBeforeWeBecameLeader,
FollowerStates followerStates, boolean renewElectionTimeout,
Collection logCommands, Collection outgoingMessages,
Collection shipCommands, long commitIndex )
{
this.nextRole = nextRole;
this.term = term;
this.leader = leader;
this.leaderCommit = leaderCommit;
this.votedFor = votedFor;
this.votesForMe = new HashSet<>( votesForMe );
this.lastLogIndexBeforeWeBecameLeader = lastLogIndexBeforeWeBecameLeader;
this.followerStates = followerStates;
this.renewElectionTimeout = renewElectionTimeout;
this.logCommands.addAll( logCommands );
this.outgoingMessages.addAll( outgoingMessages );
this.shipCommands.addAll( shipCommands );
this.commitIndex = commitIndex;
}
private void defaults( Role currentRole, ReadableRaftState ctx )
{
nextRole = currentRole;
term = ctx.term();
leader = ctx.leader();
leaderCommit = ctx.leaderCommit();
votedFor = ctx.votedFor();
renewElectionTimeout = false;
needsFreshSnapshot = false;
votesForMe = (currentRole == Role.CANDIDATE) ? new HashSet<>( ctx.votesForMe() ) : new HashSet<>();
lastLogIndexBeforeWeBecameLeader = (currentRole == Role.LEADER) ? ctx.lastLogIndexBeforeWeBecameLeader() : -1;
followerStates = (currentRole == Role.LEADER) ? ctx.followerStates() : new FollowerStates<>();
commitIndex = ctx.commitIndex();
}
public void setNextRole( Role nextRole )
{
this.nextRole = nextRole;
}
public void setNextTerm( long nextTerm )
{
this.term = nextTerm;
}
public void setLeader( MemberId leader )
{
this.leader = leader;
}
public void setLeaderCommit( long leaderCommit )
{
this.leaderCommit = leaderCommit;
}
public void addLogCommand( RaftLogCommand logCommand )
{
this.logCommands.add( logCommand );
}
public void addOutgoingMessage( RaftMessages.Directed message )
{
this.outgoingMessages.add( message );
}
public void setVotedFor( MemberId votedFor )
{
this.votedFor = votedFor;
}
public void renewElectionTimeout()
{
this.renewElectionTimeout = true;
}
public void markNeedForFreshSnapshot()
{
this.needsFreshSnapshot = true;
}
public void addVoteForMe( MemberId voteFrom )
{
this.votesForMe.add( voteFrom );
}
public void setLastLogIndexBeforeWeBecameLeader( long lastLogIndexBeforeWeBecameLeader )
{
this.lastLogIndexBeforeWeBecameLeader = lastLogIndexBeforeWeBecameLeader;
}
public void replaceFollowerStates( FollowerStates followerStates )
{
this.followerStates = followerStates;
}
public void addShipCommand( ShipCommand shipCommand )
{
shipCommands.add( shipCommand );
}
public void electedLeader()
{
assert !steppingDown;
this.electedLeader = true;
}
public void steppingDown()
{
assert !electedLeader;
this.steppingDown = true;
}
@Override
public String toString()
{
return "Outcome{" +
"nextRole=" + nextRole +
", term=" + term +
", leader=" + leader +
", leaderCommit=" + leaderCommit +
", logCommands=" + logCommands +
", outgoingMessages=" + outgoingMessages +
", commitIndex=" + commitIndex +
", votedFor=" + votedFor +
", renewElectionTimeout=" + renewElectionTimeout +
", needsFreshSnapshot=" + needsFreshSnapshot +
", votesForMe=" + votesForMe +
", lastLogIndexBeforeWeBecameLeader=" + lastLogIndexBeforeWeBecameLeader +
", followerStates=" + followerStates +
", shipCommands=" + shipCommands +
", electedLeader=" + electedLeader +
", steppingDown=" + steppingDown +
'}';
}
public Role getRole()
{
return nextRole;
}
public long getTerm()
{
return term;
}
public MemberId getLeader()
{
return leader;
}
public long getLeaderCommit()
{
return leaderCommit;
}
public Collection getLogCommands()
{
return logCommands;
}
public Collection getOutgoingMessages()
{
return outgoingMessages;
}
public MemberId getVotedFor()
{
return votedFor;
}
public boolean electionTimeoutRenewed()
{
return renewElectionTimeout;
}
@Override
public boolean needsFreshSnapshot()
{
return needsFreshSnapshot;
}
public Set getVotesForMe()
{
return votesForMe;
}
public long getLastLogIndexBeforeWeBecameLeader()
{
return lastLogIndexBeforeWeBecameLeader;
}
public FollowerStates getFollowerStates()
{
return followerStates;
}
public Collection getShipCommands()
{
return shipCommands;
}
public boolean isElectedLeader()
{
return electedLeader;
}
public boolean isSteppingDown()
{
return steppingDown;
}
@Override
public long getCommitIndex()
{
return commitIndex;
}
public void setCommitIndex( long commitIndex )
{
this.commitIndex = commitIndex;
}
}