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 - #8 by beardedeagle
    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.

Last Post!

sztosz

sztosz

Sorry, I meant Amnesia, not Mnesia. I don’t know how I messed it up :joy: I have no problems with Mnesia, The Erlang one :wink: It simply works, is easy to set up, easy to use, don’t give me strange dialyzer errors. But i have problems with Amnesia, the wrapper wrote in Elixir :wink: I don’t know exactly what is it, but Mnesia seems simpler to use and more straightforward than Amnesia, when it comes to my use cases :slight_smile:

Where Next?

Popular in Guides/Tuts Top

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
Eiji
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...
New
niku
I write an article Parameterized testing with ExUnit.The key concept is using ExUnit.Case.register_test/4 such as ExUnit.start() defmod...
New
marcelo
I wrote a small article on how to use current_user with coherence on Phoenix. There are already a couple of blogposts about it but I thin...
New
water
I’ll post this here, It might help someone in the future. Feedback is greatly appreciated. I use it with direnv on NixOS, It should wor...
New
jshprentz
Geoffrey Lessel’s 2019 book, Phoenix in Action, was written for Phoenix 1.4. I found that the book’s code examples did not match the cur...
New
slouchpie
Warmest greetings, comrades. I recently started using :dns_cluster (GitHub - phoenixframework/dns_cluster: Simple DNS clustering for dis...
New

Other popular topics Top

Qqwy
Update: How to use the Blogs & Podcasts section You can post links to your blog posts or podcasts either in one of the Official Blog...
3271 130286 1222
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 54006 488
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
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New

We're in Beta

About us Mission Statement