Mnesia autoclustering made easy!
Docs can be found at https://hexdocs.pm/mnesiac.
Simply add mnesiac to your list of dependencies in mix.exs:
def deps do
[
{:mnesiac, "~> 0.3"}
]
endEdit your app's config.exs to add the list of mnesia stores:
config :mnesiac,
stores: [Mnesiac.ExampleStore, ...],
schema_type: :disc_copies, # defaults to :ram_copies
table_load_timeout: 600_000 # milliseconds, default is 600_000Then add mnesiac to your supervision tree:
- With
libclusterusing theCluster.Strategy.Epmdstrategy:
...
topology = Application.get_env(:libcluster, :topologies)
hosts = topology[:myapp][:config][:hosts]
children = [
{Cluster.Supervisor, [topology, [name: MyApp.ClusterSupervisor]]},
{Mnesiac.Supervisor, [hosts, [name: MyApp.MnesiacSupervisor]]},
...
]
...- Without
libcluster:
...
children = [
{
Mnesiac.Supervisor,
[
[:"[email protected]", :"[email protected]"],
[name: MyApp.MnesiacSupervisor]
]
},
...
]
...Create a table store, use Mnesiac.Store, and add it to your app's config.exs.
All stores MUST implement its own store_options/0, which returns a keyword list of table options.
There are three optional callbacks which can be implemented:
init_store/0, which allows users to implement custom table initialisation logic.copy_store/0, which allows users to implement a custom call to copy a store.resolve_conflict/1, which allows a user to implement logic when table data is found on both the remote node and local node when connecting to a cluster. This currently has no default implementation.
defmodule MyApp.ExampleStore do
@moduledoc false
require Record
use Mnesiac.Store
Record.defrecord(
:example,
__MODULE__,
id: nil,
topic_id: nil,
event: nil
)
@type example ::
record(
:example,
id: String.t(),
topic_id: String.t(),
event: String.t()
)
@impl true
def store_options,
do: [
attributes: example() |> example() |> Keyword.keys(),
index: [:topic_id],
ram_copies: [node()]
]
endIf you are using libcluster or another clustering library just ensure that clustering library starts earlier than mnesiac. That's all, you don't need to do anything else.
If you are not using libcluster or similar clustering library then:
- When a node joins to an erlang/elixir cluster, run the
Mnesiac.init_mnesia()function on the new node. This will initialize and copy table contents from the other online nodes.
Ensure you have the proper language versions installed. To do this, an asdf tools file is provided. Run the following:
git clone https://github.com/beardedeagle/mnesiac.git
git checkout -b MyFeature
asdf install
mix local.hex --force
mix local.rebar --force
mix deps.get --force
mix deps.compile --force
mix compile --force
mix checkNOTICE: You can find the asdf tool here.
Before you run any tests, ensure that you have cleaned up mnesia:
mix purge.dbTest results and coverage reports are generated by running the following:
mix coveralls.html --trace --slowest 10 --no-startThis library was built standing on the shoulders of giants. A big thanks goes out to Mustafa Turan. The original library this was forked from can be found here: https://github.com/mustafaturan/mnesiam.
Happy coding!