Skip to content

Instantly share code, notes, and snippets.

@wpcarro
Created April 25, 2017 14:43
Show Gist options
  • Save wpcarro/aee744b4a35cfeb1ee4b0fe355065e61 to your computer and use it in GitHub Desktop.
Save wpcarro/aee744b4a35cfeb1ee4b0fe355065e61 to your computer and use it in GitHub Desktop.
An alternative registry implementation in Elixir
defmodule DriverRegistry do
@moduledoc """
Most key-value registries in Elixir can and perhaps should be created with a
`GenServer`. This module illustrates an alternative implementation of a
registry using macros that eliminates the need for a `GenServer`. This removes
OTP dependencies like a supervision tree and also reduces unnecessary
"process noise" in your application.
The use-case for such a registry is a driver registry where consumers opt-in
to drivers by declaring which drivers they would like to use in the
`config.exs` file under the key, `:additional_drivers`.
Note: each driver module implements a `behaviour` with a `callback` of
`supported_schemes/0`, which returns a `[String.t]`. These are used to
generate function heads at compile-time against which inputs are
pattern-matched. This simulates an in-memory KV store.
The key takeaway here is that `GenServer` processes are not always necessary.
When a registry is populated on application initialization and remains fixed
throughout the application's lifetime, a KV registry can be created with
functions defined at compile time.
"""
@default_drivers [Driver.Local, Driver.HTTP]
@additional_drivers Application.get_env(:driver_registry, :additional_drivers)
for driver <- @default_drivers ++ @additional_drivers do
for scheme <- driver.supported_schemes() do
def get_driver(unquote(scheme)), do: unquote(driver)
end
end
def get_driver(scheme), do: raise("No driver registered that supports the scheme: \"#{scheme}\"")
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment