-
Notifications
You must be signed in to change notification settings - Fork 1
/
sync.ex
88 lines (74 loc) · 2.03 KB
/
sync.ex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
defmodule SyncM.Sync do
@moduledoc false
use GenServer
alias :mnesia, as: Mnesia
def start_link(_) do
GenServer.start_link(__MODULE__, %{}, name: :sync_m)
end
def init(state) do
{:ok, state}
end
def handle_call({:check_nodes_and_join, [],_}, _, state) do
with :ok <- create_schema(node()),
:ok <- start_mnesia()
do
{:reply, {:ok}, state}
else
_ -> {:reply, {:error}, state}
end
end
def handle_call({:check_nodes_and_join, nodes, type}, _, state) do
with :ok <- start_mnesia(),
_ <- GenServer.multi_call([Enum.at(nodes,0)], :sync_m, {:request_join, node(),type})
do
{:reply, {:ok}, state}
else
_ -> {:reply, {:error}, state}
end
end
def handle_call({:request_join, remote_node, copy_type}, _, state) do
with {:ok, _} <- Mnesia.change_config(:extra_db_nodes, [remote_node]),
:ok <- Mnesia.system_info(:tables) |> copy_existing_tables(remote_node,copy_type)
do
{:reply, :ok, state}
else
_ -> {:reply, :ok, state}
end
end
defp copy_existing_tables(table_list,remote_node,type) do
Enum.map(table_list, &(Mnesia.add_table_copy(&1,remote_node,type)))
|> check_for_error()
end
defp create_schema(nodes) do
case Mnesia.create_schema([nodes]) do
{:error, {_, {:already_exists, _}}} -> :ok
:ok -> :ok
{:error, _} -> :error
end
end
defp start_mnesia() do
case Mnesia.start() do
:ok -> :ok
_ -> raise "Error starting Mnesia schema"
end
end
def add_table(name, attrs) do
case Mnesia.create_table(name, attrs) do
{:atomic, :ok} -> :ok
{:aborted, {:already_exists, _}} -> :ok
{:aborted, {:already_exists, _, _}} -> :ok
_ -> :error
end
end
defp check_for_error([h|t]) do
case h do
{:atomic, :ok} -> check_for_error(t)
{:aborted, {:already_exists, _, _}} -> :ok
{:aborted, {:already_exists, _}} -> check_for_error(t)
_ -> :error
end
end
defp check_for_error([]) do
:ok
end
end