# Horde

Horde is an eventually-consistent distributed supervisor (`Horde.Supervisor`) and registry (`Horde.Registry`). 

Horde is built using a add-wins last-write-wins δ-CRDT map. By using a CRDT, Horde is guaranteed to eventually convergeon a single representation of the data.

`Horde.Supervisor` makes use of a hash ring to limit any possible race conditions to times when cluster membership is changing.

Horde attempts to replicate the public API of both `Supervisor` and `Registry` as much as possible. In some cases it will be a drop-in replacement. Some calls will also closely mirror functionality of their standard library counterparts but in some other cases this is not possible, given the distributed nature of Horde.

[![Hex pm](](

[![CircleCI badge](](

## Fault tolerance

If a node fails (or otherwise becomes unreachable) then Horde.Supervisor will redistribute processes among the remaining nodes.

## Installation

If [available in Hex](, the package can be installed
by adding `horde` to your list of dependencies in `mix.exs`:

def deps do
    {:horde, "~> 0.1.0"}

## Usage

See the full docs at [](

Putting `Horde.Supervisor` in a supervisor:

defmodule MyApp.Application do
  use Application
  def start(_type, _args) do
    children = [
      {Horde.Supervisor, [name: MyApp.DistributedSupervisor, strategy: :one_for_one]}
    Supervsior.start_link(children, strategy: :one_for_one)

Adding a child to the supervisor:

Horde.Supervisor.start_child(MyApp.DistributedSupervisor, %{id: :gen_server, start: {GenServer, :start_link, []}})

And so on. The public API should be the same as `Supervisor` (and please open an issue if it turns out not to be).

Joining supervisors into a single distributed supervisor can be done using `Horde.Tracker`:

{:ok, supervisor} = Horde.Supervisor.start_link([], name: :distributed_supervisor_1, strategy: :one_for_one)

Horde.Tracker.join_hordes(supervisor_1, supervisor_2)


If you tell `Horde.Supervisor` to leave the horde, then it will kill all processes and disassociate them (to be picked up by other nodes). This can be used to implement graceful shutdown / failover.

# Contributing

Contributions are welcome! Feel free to open an issue if you'd like to discuss a problem or a possible solution. Pull requests are much appreciated.

If you end up using `Horde` then feel free to ping me on twitter: @derekkraan.