graft.state module

Figure 4: Server states. Followers only respond to requests from other servers. If a follower receives no communication, it becomes a candidate and initiates an election. A candidate that receives votes from a majority of the full cluster becomes the new leader. Leaders typically operate until they fail.

exception graft.state.TargetIsSenderError[source]

Bases: ValueError

Raised by BaseController.send when sender is receiver

class graft.state.BaseController(peer_id)[source]

Bases: abc.ABC

A controller needs to be frozen and provide a send method.

abstract send(target_peer, message)[source]
peer_id: int = None
abstract property peers
Return type

set

class graft.state.Roles[source]

Bases: enum.Enum

An enumeration.

CANDIDATE = 2
FOLLOWER = 1
LEADER = 3
class graft.state.State[source]

Bases: object

append(control, item)[source]

If command received from client: append entry to local log, respond after entry applied to state machine (§5.3)

Parameters
  • control

  • item

Returns

become_follower()[source]

Respond to RPCs from candidates and leaders

become_leader(control)[source]
heartbeat(control)[source]
Upon election: send initial empty AppendEntries RPCs

(heartbeat) to each server; repeat during idle periods to prevent election timeouts (§5.2)

Parameters

control

Returns

on_append_entries_reply(control, msg)[source]
on_append_entries_request(control, msg)[source]
  1. Reply false if term < currentTerm (§5.1)

2. Reply false if log doesn’t contain an entry at prevLogIndex whose term matches prevLogTerm (§5.3) 3. If an existing entry conflicts with a new one (same index but different terms), delete the existing entry and all that follow it (§5.3) 4. Append any new entries not already in the log 5. If leaderCommit > commitIndex, set commitIndex = min(leaderCommit, index of last new entry)

on_election_reply(control, msg)[source]

A candidate that receives votes from a majority of the full cluster becomes the new leader

  1. Reply false if term < currentTerm (§5.1)

2. If votedFor is null or candidateId, and candidate’s log is at least as up-to-date as receiver’s log, grant vote (§5.2, §5.4)

  • If votes received from majority of servers: become leader

  • If AppendEntries RPC received from new leader: convert to

follower

on_election_request(control, msg)[source]

May only vote for one candidate in a given term (subsequent requests denied)

  • Wont vote if candidate’s logger is not as up-to-date as oneself

  • Grant vote if last entry in candidate’s logger has a greater term than myself.

timeout(control)[source]

If a follower receives no communication, it becomes a candidate and initiates an election.

On conversion to candidate, start election:
  • Increment currentTerm

  • Vote for self

  • Reset election timer

  • Send RequestVote RPCs to all other servers

  • If votes received from majority of servers: become leader

  • If AppendEntries RPC received from new leader: convert to

follower • If election timeout elapses: start new election