# C-Raft

C-Raft is a fully asynchronous C implementation of the Raft consensus protocol.

## Design

The library has modular design: its core part implements only the core Raft algorithm logic, in a fully platform independent way. On top of that, a pluggable interface defines the I/O implementation for networking and disk persistence.

A stock implementation of the I/O interface is provided when building the library with default options. It is based on libuv and should fit the vast majority of use cases.

## Features

C-Raft implements all the basic features described in the Raft dissertation:

- Leader election

- Log replication

- Log compaction

- Membership changes

It also includes a few optional enhancements:

- Optimistic pipelining to reduce log replication latency

- Writing to the leader’s disk in parallel

- Automatic stepping down when the leader loses quorum

- Leadership transfer extension

- Non-voting servers

## Quick start

Make sure that libuv is installed on your system, then run:

    1autoreconf -i
    2./configure --enable-example
    3make

Then create a `main.c` file with this simple test program that just runs a single raft server and implements a basic state machine for incrementing a counter:

     1#include <raft.h>
     2#include <raft/uv.h>
     3
     4static raft_id id = 12345;
     5static const char *address = "127.0.0.1:8080";
     6static const char *dir = "/tmp/raft-quick-start";
     7static struct uv_loop_s loop;
     8static struct raft_uv_transport transport;
     9static struct raft_io io;
    10static struct raft_fsm fsm;
    11static struct raft raft;
    12static struct raft_configuration conf;
    13static struct uv_timer_s timer;
    14static struct raft_apply apply;
    15static unsigned counter = 0;
    16static uint64_t command;
    17
    18static int applyCommand(struct raft_fsm *fsm,
    19                        const struct raft_buffer *buf,
    20                        void **result) {
    21    counter += *(uint64_t *)buf->base;
    22    printf("counter: %u\n", counter);
    23    return 0;
    24}
    25
    26static void submitCommand(uv_timer_t *timer) {
    27    struct raft_buffer buf;
    28    command = uv_now(timer->loop) % 10;
    29    buf.len = sizeof command;
    30    buf.base = &command;
    31    raft_apply(&raft, &apply, &buf, 1, NULL);
    32}
    33
    34int main() {
    35    mkdir(dir, 0755);
    36    uv_loop_init(&loop);
    37    raft_uv_tcp_init(&transport, &loop);
    38    raft_uv_init(&io, &loop, dir, &transport);
    39    fsm.apply = applyCommand;
    40    raft_init(&raft, &io, &fsm, id, address);
    41    raft_configuration_init(&conf);
    42    raft_configuration_add(&conf, id, address, RAFT_VOTER);
    43    raft_bootstrap(&raft, &conf);
    44    raft_start(&raft);
    45    uv_timer_init(&loop, &timer);
    46    uv_timer_start(&timer, submitCommand, 0, 1000);
    47    uv_run(&loop, UV_RUN_DEFAULT);
    48}

You can compile and run it with:

    1cc main.c -o main -lraft -luv && ./main

## Source

The source tree is available on github.

## Licence

This raft C library is released under a slightly modified version of LGPLv3, that includes a copyright exception letting users to statically link the library code in their project and release the final work under their own terms. See the full license text.

### toc

- C-Raft
- Getting started
- API reference
- Disk format