# Raft

Raft provides users with an api for building consistent (as defined by CAP),
distributed state machines. It does this using the raft leader election and
concensus protocol as described in the [original paper](
Logs are persisted using rocksdb and provides an adapter for using alternative
storage mechanisms.

## Installation

def deps do
    {:raft, "~> 0.2.0"},

## Example

Lets create a distributed key value store. The first thing that we'll need is
a state machine:

defmodule KVStore do
  use Raft.StateMachine

  @initial_state %{}

  def set(name, key, value) do
    Raft.write(name, {:set, key, value})

  def get(name, key) do, {:get, key})

  def init(_name) do
    {:ok, @initial_state} 

  def handle_write({:set, key, value}, state) do
    {{:ok, key, value}, put_in(state, [key], value)}

  def handle_read({:get, key}, state) do
    case get_in(state, [key]) do
      nil ->
        {{:error, :key_not_found}, state}

      value ->
        {{:ok, value}, state}

Now we can start our peers:

{:ok, _pid} = Raft.start_peer(KVStore, name: :s1)
{:ok, _pid} = Raft.start_peer(KVStore, name: :s2)
{:ok, _pid} = Raft.start_peer(KVStore, name: :s3)

Each node must be given a unique name within the cluster. At this point our
nodes are started but they're all followers and don't know anything about each
other. We need to set the configuration so that they can communicate:

Raft.set_configuration(:s1, [:s1, :s2, :s3])

Once this runs the peers will start an election and elect a leader. You can
check the current leader like so:

leader = Raft.leader(:s1)

Once we have the leader we can read and write to our state machine:

{:error, :key_not_found} = KVStore.get(leader, :foo)
{:ok, :foo, :bar} = KVStore.write(leader, :foo, :bar)
{:ok, :bar} =, :foo)

We can now shutdown our leader and ensure that a new leader has been elected
and our state is replicated across all nodes:


# wait for election...

new_leader = Raft.leader(:s2)
{:ok, :bar} =, :foo)

We now have a consistent, replicated key-value store. If you want to read more
about the internals of the project or read up on the raft protocol please check out
the [hex docs](

### Caution

This project is not quite ready for production use. If you would like to help
test out the implementation that would be greatly appreciated.


* [ ] - Configuration changes
* [ ] - Snapshotting
* [ ] - Jepsen testing