Eiji

Eiji

Amnesia problems and workarounds

Hey, today I give amnesia library a try and found a few problems. I would like describe how to setup it properly and solve problems which could occur due to using it in my specific situation.

Problem with Elixir 1.7

It’s not easy even at start. When I have added {:amnesia, "~> 0.2.7"} to my dependencies then exquisite (amnesia dependecy) gives me such error:

==> exquisite
Compiling 1 file (.ex)

== Compilation error in file lib/exquisite.ex ==
** (CompileError) lib/exquisite.ex:103: __CALLER__ is available only inside defmacro and defmacrop
    lib/exquisite.ex:103: (module)
could not compile dependency :exquisite, "mix compile" failed. You can recompile this dependency with "mix deps.compile exquisite", update it with "mix deps.update exquisite" or clean it with "mix deps.clean exquisite"

Fortunately it’s already solved in master branch (just no new hex package), so solution is as easy as adding: {:exquisite, "~> 0.1.8", github: "meh/exquisite", override: true} to project dependencies. This will force mix to use github version (defaults to master branch) by ignoring amnesia dependency declaration.

Weird database compilation problem

The next problem occurs also at compilation. However both exquisite and amnesia compiles correctly. The error looks like:

Compiling … files (.ex)

== Compilation error in file lib/my_app/database.ex ==
** (UndefinedFunctionError) function Kernel.Typespec.defines_type?/3 is undefined or private. Did you mean one of:

      * defines_type?/2

    (elixir) Kernel.Typespec.defines_type?(Database.TableName, :t, 0)
    lib/my_app/database.ex:…: (module)
    lib/my_app/database.ex:…: (module)

This error occurs, because amnesia is using Elixir private API. Such code could change really often and developers should not depend on it. Fortunately fixing it is pretty easy. Simply navigate to: deps/amnesia/lib/amnesia/table/definition.ex and replace line 938:

        unless Kernel.Typespec.defines_type?(__MODULE__, :t, 0) do

with this one:

        unless Kernel.Typespec.defines_type?(__MODULE__, {:t, 0}) do

Note: Don’t forget to run mix deps.compile to force recompile our change. Without it command error would occur again, because this dependency is already compiled and such old compiled version is used instead. Of course it’s not a good production solution, but temporary tip which allow use it now without waiting on package owner.

Multiple nodes in test environment

Last problem which I found is how to properly use amnesia in test environment. We are able to create simple cluster without any extra commands, but amnesia would fail lots of times. For example:

Calling Amnesia.Schema.create(nodes) would give us:

{:error,
 {'Cannot install fallback',
  {'No disc resident schema on local node',
   …}}}

Calling Database.create!(disk: nodes) would even freeze our prompt without any warning and/or error.

This could be solved by using amnesia on any slave nodes instead master node.

Helpful resources

  1. Compilation error after upgrading elixir #10 issue at meh/ exquisite
    This is related to first problem I described.

  2. PSA: Do not use private APIs, request a feature instead
    This is related to second problem I described. @josevalim describes the problem with lots of dependencies and projects when trying to update to Elixir version 1.7

  3. Starting multiple named nodes locally for ExUnit tests
    Here @beardedeagle summaries answers in his topic and is giving of cluster example which could cause some troubles with amnesia for newbies.

  4. Finally here is Elixir + Phoenix + Amnesia + Multi-node article written by @jmerriweather which inspires me to give amnesia a try and write this topic.

Hope that I have explained everything correctly. Let me know if you have any questions. I would like to say thank you for everyone which helps community. Without all of you such problems would definitely took me much more time than I spend today in this topic.

Most Liked

Eiji

Eiji

I can’t edit this post, so I will just link one question I have posted:

This topic has described solution to automatically adding new nodes (standard way described in linked tutorial assumes that all nodes are already prepared).

sztosz

sztosz

I gave Amnesia a try few months ago, with a distributed setup involving at least 2 nodes on production at any given time. Since then i rewrote those parts of app to simply use mnesia directly. IMHO Amnesia is too little convenience and way too much hassle.

Also i couldn’t get rid of some dialyzer errors when using Mnesia, I have a feeling either I didn’t understand what some functions/macros do, or there are some typespec problems in Mnesia itself.

Just my 2 cents.

Where Next?

Popular in Guides/Tuts Top

Logan
Here is an example of a Mix application that utilizes Cowboy to handle websocket connections. If anyone has an idea about making this wor...
New
OndrejValenta
Me and my boys started a new website specifically designed for other ASP.NET programmers that struggle, as we do, with their transformati...
New
zachallaun
Hey friends, wanted to share a tiny shell script I’ve been using to start Livebook with easy access to either a running production server...
New
New
njwest
In the process of developing a Phx-based multiplayer experience, I found myself with so many browser tabs open with Elixir gaming resourc...
New
bluegene
Hi guys, I’ve been on a personal journey to learn Elixir for the past two years. During this journey I’ve been using the spaced repetiti...
New
Zurga
In a quest to optimize the amount of data sent between the server and client I recently decided to try to use MessagePack instead of JSON...
New
AstonJ
This blog post hit my timeline earlier, and I’ve also been learning about some fantastic Elixir related tips via @pragdave’s new online c...
New
KoviRobi
Hi, I’ve written the following to debug function calls, not sure if it’s useful for anyone else, and if so should I put it somewhere? i...
New
kevinlang
Hey all, With Phoenix 1.6 just around the corner, I figured I’d make a tutorial on how to add Bulma to a new Phoenix 1.6 project. By lev...
New

Other popular topics Top

pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
ycv005
I have followed this StackOverflow post to install the specific version of Erlang. And When I am running mix ecto.setup then getting fol...
New
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
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 ...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
siddhant3030
Hi, I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
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

We're in Beta

About us Mission Statement