njwest

njwest

Best way to start Mnesia in Elixir/Phoenix application

We’ve just started using mnesia (only mnesia, no Memento or Amnesia) in our Phoenix 1.5 application, and we’re starting it like this on application startup:

lib/my_app/application.ex

   def start(_type, _args) do
    :mnesia.stop
    :mnesia.create_schema([node()])
    :mnesia.start()
    :mnesia.create_table(:rps, attributes: [:uuid, :gamestate], disc_copies: [node()])

    children = [
       # code emitted

I added :mnesia.stop as the first argument as I had a situation in which I deleted the Mnesia.node@host file and :mnesia.screate_schema would not recreate the directory without the prior stop function.

Marked As Solved

Exadra37

Exadra37

As per the docs you need to stop Mnesia in order to create the schema:

mnesia:create_schema(NodeList) initializes a new, empty schema. This is a mandatory requirement before Mnesia can be started. Mnesia is a truly distributed DBMS and the schema is a system table that is replicated on all nodes in a Mnesia system. This function fails if a schema is already present on any of the nodes in NodeList. The function requires Mnesia to be stopped on the all db_nodes contained in parameter NodeList. Applications call this function only once, as it is usually a one-time activity to initialize a new database.

When starting Mnesia you must wait for all the tables to be ready, like it is said in the docs:

Table initialization is asynchronous. The function call mnesia:start() returns the atom ok and then starts to initialize the different tables. Depending on the size of the database, this can take some time, and the application programmer must wait for the tables that the application needs before they can be used. This is achieved by using the function mnesia:wait_for_tables(TabList, Timeout), which suspends the caller until all tables specified in TabList are properly initiated.


A word of caution:

Also Liked

slashdotdash

slashdotdash

Event sourcing is persisting application state changes as domain specific, intention revealing events (e.g. UserRegistered). Current state is built by reducing the list or stream of events, similar to Enum.reduce/3 in Elixir. For event sourcing you ideally want to use a proper event store, such as EventStoreDB or the Elixir EventStore library I wrote which uses Postgres for persistence.

Event streaming is where events are published to interested subscribers for loosely-coupled processing, service integration, etc. Kafka is designed exactly for this. It would be more similar to Elixir’s Registry module when used for pub-sub or using Stream.each/2 or the Broadway library. Often consumers use ack/nack to guarantee at-least-once message delivery so that they cannot miss any events. They may store their current processing position to a durable store so they can stop and resume processing safely. It’s possible to use change data capture to publish updates from a data store, such as table UPDATEs but unlike event sourcing these changes are not domain specific, but instead are general insert/update/delete operations.

There are two varieties of events used with event streaming: Event Notification and Event-Carried State Transfer (ECST). Event notification is used to indicate when something in an application has occured, such as a user registration, but the event contains minimal information (“thin” events). ECST is where more information about the current state is included in the event (“fat” events). You can also combine both event sourcing and event streaming by publishing domain events used for event sourcing to consumers for event streaming.

See What do you mean by “Event-Driven”? by Martin Fowler.

njwest

njwest

Thanks for the tips, especially the bit about starting tables

Regarding the thread you posted, and actually reading your thread in-depth really enriched my mnesia research :stuck_out_tongue:

I’m using mnesia right now for saving/loading GenServer state for multiplayer gamestate, and at the moment we don’t need the persistence to be so reliable, but I have an eye towards a RocksDB-like or somesuch solution for persistence reliability should the need arise

vans163

vans163

@njwest we used mnesia for gaming too (its great for storing persistent state, as the lookup speed is ets (5m+ reads per second, from multiple schedulers) and the write is fairly fast 800k~ish, for a small server.

The way you do it is pretty much the way we did it (dont use mnesia anymore). Even if mnesia is not started as an extra_application, that :mnesia.stop ensures nothing weird happens.

Where Next?

Popular in Questions Top

Tee
can someone please explain to me how Enum.reduce works with maps
New
greenz1
I have a phoenix application from which a user can download multiple(5-6) files of size 1MB. I couldn’t find anything related to sending ...
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lists...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set? Thanks.
New
shahryarjb
Hello, I get Persian date from my client and convert it to normal calendar like this: def jalali_string_to_miladi_english_number(persi...
New
vac
Hi, I’m quite new in Elixir and I’m trying to format a string to a PEM format. I have the certificate value like MIIDBTCCAe2...... and I...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
dotdotdotPaul
Okay, I’m having a heck of a time trying to figure out how to best handle the validation of belongs_to associations in Ecto. I’m sure I’...
New

Other popular topics Top

danschultzer
None of the current solutions worked well for me, so I went ahead and built a user management system from scratch. This project took far...
548 29377 241
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
chrismccord
This release brings a number of exciting features, including integration with the new Phoenix LiveDashboard and Phoenix LiveView. There h...
New
josevalim
Hi everyone, One of the features added to Elixir early on to help integration with Erlang code was the idea of overridable function defi...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
axelson
This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!) This post collects co...
239 47930 226
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New

Latest on Elixir Forum

We're in Beta

About us Mission Statement