Skip to content

Commit

Permalink
Merge pull request #10 from sheharyarn/bugfix/mnesia-cyclic-exits
Browse files Browse the repository at this point in the history
Fix Mnesia's Cyclic Exits
  • Loading branch information
sheharyarn authored Mar 5, 2019
2 parents e1f9893 + 357e078 commit 9b239bf
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 16 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ Add `:memento` to your list of dependencies in your Mix file:

```elixir
def deps do
[{:memento, "~> 0.2.1"}]
[{:memento, "~> 0.3.0"}]
end
```

Expand Down
17 changes: 17 additions & 0 deletions lib/memento/mnesia.ex
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,23 @@ defmodule Memento.Mnesia do

@doc "Call an Mnesia function"
defmacro call(method, arguments \\ []) do
quote(bind_quoted: [fun: method, args: arguments]) do
apply(:mnesia, fun, args)
end
end



@doc """
Call an Mnesia function and catch any exits
Should ONLY be used with transaction methods, because catching
exits inside transactions seriously impacts the performance of
Mnesia.
Reference: https://github.com/sheharyarn/memento/issues/2
"""
defmacro call_and_catch(method, arguments \\ []) do
quote(bind_quoted: [fun: method, args: arguments]) do
require Memento.Error

Expand Down
8 changes: 4 additions & 4 deletions lib/memento/schema.ex
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ defmodule Memento.Schema do
end

:create_schema
|> Memento.Mnesia.call([nodes])
|> Memento.Mnesia.call_and_catch([nodes])
|> Memento.Mnesia.handle_result
end

Expand All @@ -83,7 +83,7 @@ defmodule Memento.Schema do
@spec delete(list(node)) :: :ok | {:error, any}
def delete(nodes) do
:delete_schema
|> Memento.Mnesia.call([nodes])
|> Memento.Mnesia.call_and_catch([nodes])
|> Memento.Mnesia.handle_result
end

Expand All @@ -96,7 +96,7 @@ defmodule Memento.Schema do
@spec info() :: :ok
def info do
:schema
|> Memento.Mnesia.call
|> Memento.Mnesia.call_and_catch
|> Memento.Mnesia.handle_result
end

Expand All @@ -109,7 +109,7 @@ defmodule Memento.Schema do
@spec info(Memento.Table.name) :: :ok
def info(table) do
:schema
|> Memento.Mnesia.call([table])
|> Memento.Mnesia.call_and_catch([table])
|> Memento.Mnesia.handle_result
end

Expand Down
4 changes: 2 additions & 2 deletions lib/memento/transaction.ex
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ defmodule Memento.Transaction do
@spec execute(fun, retries) :: {:ok, any} | {:error, any}
def execute(function, retries \\ :infinity) do
:transaction
|> Memento.Mnesia.call([function, retries])
|> Memento.Mnesia.call_and_catch([function, retries])
|> Memento.Mnesia.handle_result
end

Expand Down Expand Up @@ -102,7 +102,7 @@ defmodule Memento.Transaction do
@spec execute_sync(fun, retries) :: {:ok, any} | {:error, any}
def execute_sync(function, retries \\ :infinity) do
:sync_transaction
|> Memento.Mnesia.call([function, retries])
|> Memento.Mnesia.call_and_catch([function, retries])
|> Memento.Mnesia.handle_result
end

Expand Down
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ defmodule Memento.Mixfile do

@app :memento
@name "Memento"
@version "0.2.1"
@version "0.3.0"
@github "https://github.com/sheharyarn/#{@app}"
@author "Sheharyar Naseer"
@license "MIT"
Expand Down
14 changes: 11 additions & 3 deletions test/memento/mnesia_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@ defmodule Memento.Tests.Mnesia do


describe "#call" do
test "delegates method calls to the mnesia module" do
assert :yes == Mnesia.call(:system_info, [:is_running])
end
end



describe "#call_and_catch" do
setup do
Support.Mnesia.stop
:ok
Expand All @@ -16,15 +24,15 @@ defmodule Memento.Tests.Mnesia do
@func :system_info
@args [:is_running]
test "delegates method calls to the mnesia module" do
assert :no == Mnesia.call(@func, @args)
assert :no == Mnesia.call_and_catch(@func, @args)
end


@func :schema
@args []
test "re-raises mnesia exits as memento exceptions" do
assert_raise(MnesiaException, ~r/not running/i, fn ->
Mnesia.call(@func, @args)
Mnesia.call_and_catch(@func, @args)
end)
end

Expand All @@ -33,7 +41,7 @@ defmodule Memento.Tests.Mnesia do
@args [Tables.User, :all]
test "prints descriptions of the error" do
assert_raise(MnesiaException, ~r/tried to perform op on non-existing/i, fn ->
Mnesia.call(@func, @args)
Mnesia.call_and_catch(@func, @args)
end)
end
end
Expand Down
9 changes: 4 additions & 5 deletions test/support/support.ex
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ defmodule Memento.Support do
end


def transaction(fun) when is_function(fun) do
Memento.Transaction.execute(fun)
end

def transaction({module, method, args})
when is_atom(module) and is_atom(method) do
transaction(fn ->
Expand All @@ -43,10 +47,5 @@ defmodule Memento.Support do
end)
end


def transaction(fun) when is_function(fun) do
Memento.Transaction.execute(fun)
end

end
end

0 comments on commit 9b239bf

Please sign in to comment.