README.md

# Reginald

Reginald is a simple distributed registry built in pure Elixir on top of the built-in Erlang `:pg` module.

## Motivations

I've recently started experimenting with distributed registries, after seeing various posts and examples of different Distributed Erlang/Elixir helpers, such as the built-in `:global` module, `syn`, and `horde`.

After reading a lot, I started benchmarking them in a similar way to what @ostinelli did almost a decade ago. The benchmarks can be seen here: [probably-not/regbench](https://www.github.com/probably-not/regbench). The benchmarks showed some drastically different details than what most people assume:
- `syn` is very (and likely the best choice to be honest), at the expense of being written in Erlang as opposed to Elixir (which makes it more difficult to understand and debug for people who aren't familiar with Erlang)
- `:pg` used to be slow back when it was first benchmarked by @ostinelli, however now it is blazing fast, at the level of `syn`. However, it isn't exactly a registry (although as you'll see with Reginald, it can easily be modified to be one)
- `:global` is slow, but not unreasonable so (unless you are working with a gigantic amount of registrations per second)
- `:horde` is by far the slowest, although for some reason people always immediately say "don't use global, use horde instead", which seems... insane to me... it doesn't look like there were any benchmarks between horde and any other option, but people immediately say to use it instead of anything else.

After doing these benchmarks, I decided that I wanted to build a Registry that would work with Distributed Elixir, and be written in pure Elixir, while being as fast as possible. The result is Reginald, your simple Distributed blazing-fast registry.

## Usage

Reginald can be either started directly with `Reginald.start_link/1` or started as part of a supervisor by adding `{Reginald, name: MyApp.Reginald}` to your supervision tree.

A `:name` option must be passed as the arguments to `Reginald.start_link/1`.

For usage as a Registry, simply use a via module like the following: `{:via, Reginald, {MyApp.Reginald, "any id"}}`, for example:

```elixir
defmodule ExampleGenServer do
  use GenServer

  def start_link(id) do
    GenServer.start_link(__MODULE__, id, name: via_tuple(id))
  end

  def via_tuple(id) do
    {:via, Reginald, {MyApp.Reginald, id}}
  end

  def hello(id) do
    GenServer.cast(via_tuple(id), :hello)
  end

  @impl true
  def init(id) do
    {:ok, id}
  end

  @impl true
  def handle_cast(:hello, id) do
    IO.puts("Got Hello!")
    {:noreply, id}
  end
end
```

## Installation

If [available in Hex](https://hex.pm/docs/publish), the package can be installed
by adding `reginald` to your list of dependencies in `mix.exs`:

```elixir
def deps do
  [
    {:reginald, ">= 0.0.0"}
  ]
end
```

Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc)
and published on [HexDocs](https://hexdocs.pm). Once published, the docs can
be found at <https://hexdocs.pm/reginald>.