Skip to main content

README.md

# WARaft

WARaft is an Erlang implementation of the Raft consensus protocol.

This repository is a FerricStore-maintained distribution of Meta Platforms'
Apache-2.0 licensed WARaft code. It preserves the original copyright notices,
license, OTP application name, module names, and public API surface.

FerricStore uses WARaft as its durable consensus engine dependency.

## Status

- Package name: `ferricstore_waraft`
- OTP application: `wa_raft`
- Current release: `v0.1.0`
- License: Apache-2.0
- Runtime dependencies: none beyond Erlang/OTP `kernel` and `stdlib`

This repository is intended to be a stable, packageable WARaft dependency for
FerricStore and other Erlang/Elixir systems that need a pluggable Raft engine.

## Features

- Raft consensus implementation for replicated state machines.
- Pluggable storage, log, state machine, and transport behavior interfaces.
- Single-node bootstrap and multi-node membership support.
- Erlang/OTP supervision integration.
- No NIFs and no Rust code in this repository.

FerricStore's high-performance log/storage adapters live in the FerricStore
repository, not in this `wa_raft` package.

## Installation

### Git dependency

Until the Hex package is published, use the Git tag:

```erlang
{deps, [
    {wa_raft, {git, "https://github.com/ferricstore/waraft.git", {tag, "v0.1.0"}}}
]}.
```

For Elixir/Mix projects:

```elixir
{:wa_raft, github: "ferricstore/waraft", tag: "v0.1.0", manager: :rebar3}
```

### Hex dependency

After the Hex package is published:

```erlang
{deps, [
    {wa_raft, "0.1.0", {pkg, ferricstore_waraft}}
]}.
```

For Elixir/Mix projects:

```elixir
{:wa_raft, "~> 0.1", hex: :ferricstore_waraft, manager: :rebar3}
```

## Quick start

The following example starts a single-node Raft partition and performs one write
and one read. It uses the built-in ETS log/storage path for demonstration.
Production systems should provide storage and log modules appropriate for their
durability and recovery requirements.

```erlang
rr(wa_raft_server).
application:ensure_all_started(wa_raft).
application:set_env(test_app, raft_database, ".").

Spec = wa_raft_sup:child_spec(test_app, [#{table => test, partition => 1}]).
supervisor:start_child(kernel_sup, Spec).

Config = wa_raft_server:make_config([
    #raft_identity{name = raft_server_test_1, node = node()}
]).

wa_raft_server:bootstrap(
    raft_server_test_1,
    #raft_log_pos{index = 1, term = 1},
    Config,
    #{}
).

wa_raft_server:status(raft_server_test_1).
wa_raft_acceptor:commit(raft_acceptor_test_1, {make_ref(), {write, test, key, 1000}}).
wa_raft_acceptor:read(raft_acceptor_test_1, {read, test, key}).
```

Expected read result:

```erlang
{ok, 1000}
```

## Public API orientation

The main modules are:

- `wa_raft_sup`: builds supervisor child specs for Raft tables/partitions.
- `wa_raft_server`: bootstrap, membership, status, promotion, and Raft server operations.
- `wa_raft_acceptor`: commit/read entry point used by clients.
- `wa_raft_storage`: behavior/API for state machine storage.
- `wa_raft_log`: behavior/API for Raft log implementations.
- `wa_raft_transport`: behavior/API for network transport.

Headers are included with:

```erlang
-include_lib("wa_raft/include/wa_raft.hrl").
```

That include path works for both Git and Hex dependencies because the OTP app is
named `wa_raft`.

## Development

```bash
rebar3 compile
rebar3 xref
rebar3 dialyzer
rebar3 edoc
```

Common local check:

```bash
rebar3 do compile,xref
```

## Versioning

This repository starts at `0.1.0` because it is a maintained distribution used by
FerricStore. The original upstream app version was not used as the package
release version here.

## License and attribution

WARaft is licensed under Apache-2.0. See [LICENSE](./LICENSE) and
[NOTICE](./NOTICE).

This repository preserves Meta Platforms' original copyright notices. FerricStore
maintains this distribution but does not claim Meta endorsement.