Current section

Files

Jump to
krug lib krug mnesia distributed_mnesia_sync.ex
Raw

lib/krug/mnesia/distributed_mnesia_sync.ex

defmodule Krug.DistributedMnesiaSync do
@moduledoc false
require Logger
alias Krug.MapUtil
alias Krug.DistributedMnesiaCreator
alias Krug.DistributedMnesiaCloner
def sync_tables(cluster_node,tables,storage_mode,connection_timeout) do
sync_tables(
tables,
storage_mode,
cluster_node,
connection_timeout,
get_table_cookies(node(),connection_timeout),
cluster_node
|> get_table_cookies(connection_timeout)
)
end
defp sync_tables(tables,storage_mode,_cluster_node,connection_timeout,{:ok, local_cookies},{:ok, remote_cookies}) do
Enum.each(
tables,
fn(table)
-> table
|> sync_table(storage_mode,connection_timeout,local_cookies,remote_cookies)
end
)
end
defp sync_tables(_tables,_storage_mode,cluster_node,_connection_timeout,{:error, reason},{:ok, _remote_cookies}) do
Logger.info(
"""
[Krug.DistributedMnesiaSync] =>
Error getting mnesia tables cookies for local node #{inspect(cluster_node)}, reason: #{inspect(reason)}
"""
)
end
defp sync_tables(_tables,_storage_mode,cluster_node,_connection_timeout,{:ok, _local_cookies},{:error, reason}) do
Logger.info(
"""
[Krug.DistributedMnesiaSync] =>
Error getting mnesia tables cookies for remote node #{inspect(cluster_node)}, reason: #{inspect(reason)}
"""
)
end
defp sync_tables(_tables,_storage_mode,cluster_node,_connection_timeout,{:error, local_reason},{:error, remote_reason}) do
Logger.info(
"""
[Krug.DistributedMnesiaSync] => Multiple errors:
Error getting mnesia tables cookies for local node #{inspect(node())}, reason: #{inspect(local_reason)}
Error getting mnesia tables cookies for remote node #{inspect(cluster_node)}, reason: #{inspect(remote_reason)}
"""
)
end
defp sync_table(table,storage_mode,connection_timeout,local_cookies,remote_cookies) do
tablename = table
|> MapUtil.get(:table_name)
table
|> sync_table(
storage_mode,
{local_cookies[tablename],remote_cookies[tablename]}
)
[tablename]
|> :mnesia.wait_for_tables(connection_timeout)
end
defp sync_table(table,storage_mode,{nil,nil}) do
table
|> DistributedMnesiaCreator.create_table(storage_mode)
end
defp sync_table(table,storage_mode,{nil,_}) do
table
|> DistributedMnesiaCloner.add_table_copy(storage_mode)
end
defp sync_table(table,_storage_mode,{_,nil}) do
Logger.info(
"""
[Krug.DistributedMnesiaSync] =>
[#{inspect(node())}] #{inspect(table)}: no remote data to copy found.
"""
)
end
defp sync_table(_table,_storage_mode,{_local,_remote}) do
#Logger.info(
# """
# [Krug.DistributedMnesiaSync] =>
# [#{inspect(node())}] #{inspect(table)}: table found on both sides, copy aborted.
# """
#)
end
defp get_table_cookies(node,connection_timeout) do
case :rpc.call(node, :mnesia, :system_info, [:local_tables],connection_timeout) do
{:badrpc, reason}
-> {:error, reason}
tables
-> node
|> get_table_cookies(tables,connection_timeout)
end
end
defp get_table_cookies(node,tables,connection_timeout) do
Enum.reduce_while(
tables,
{:ok, %{}},
fn(table,{:ok, acc})
-> node_table_cookie(node,table,connection_timeout,{:ok, acc})
end
)
end
defp node_table_cookie(node,table,connection_timeout,{:ok, acc}) do
case :rpc.call(node,:mnesia,:table_info,[table, :cookie],connection_timeout) do
{:badrpc, reason}
-> {:halt, {:error, reason}}
cookie
-> {:cont, {:ok, Map.put(acc, table, cookie)}}
end
end
end