Skip to content

Commit

Permalink
Merge pull request #88 from beardedeagle/0.3.11
Browse files Browse the repository at this point in the history
Enumerable fix for :badrpc
  • Loading branch information
beardedeagle committed May 6, 2023
2 parents a83fed4 + 7f8a781 commit e0ce918
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 28 deletions.
12 changes: 11 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,22 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [[0.3.11]] - 2023-05-04
### ADDED
- Added test to ensure `get_table_cookies/1` returns error when node is not reachable.

### Fixed
- Fixed handling of `:badrpc` errors in `copy_tables/1` and `get_table_cookies/1` not being enumerable.

## [[0.3.10]] - 2023-05-04
### Changed
- Changed `get_table_cookies/1` to use `:local_tables` instead of `:tables` to properly identify table copies that don't exist locally to a given node.
- Assert that `Mnesiac.init_mnesia/1` is called successfully.
- Updated dependencies.
- Updated GitHub repo files.

### FIXED
- Updated `get_table_cookies/1` to use `:local_tables` instead of `:tables` to properly identify table copies that don't exist locally to a given node, closes #84.

## [[0.3.9]] - 2021-02-21
### Changed
- Bumped OTP version.
Expand Down Expand Up @@ -99,6 +108,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added
- Initial release.

[0.3.11]: https://github.com/beardedeagle/mnesiac/compare/v0.3.10...v0.3.11
[0.3.10]: https://github.com/beardedeagle/mnesiac/compare/v0.3.9...v0.3.10
[0.3.9]: https://github.com/beardedeagle/mnesiac/compare/v0.3.8...v0.3.9
[0.3.8]: https://github.com/beardedeagle/mnesiac/compare/v0.3.7...v0.3.8
Expand Down
67 changes: 41 additions & 26 deletions lib/mnesiac/store_manager.ex
Original file line number Diff line number Diff line change
Expand Up @@ -50,29 +50,30 @@ defmodule Mnesiac.StoreManager do
Copy tables
"""
def copy_tables(cluster_node) do
local_cookies = get_table_cookies()
remote_cookies = get_table_cookies(cluster_node)

Enum.each(stores(), fn data_mapper ->
cookie = Keyword.get(data_mapper.store_options(), :record_name, data_mapper)

case {local_cookies[cookie], remote_cookies[cookie]} do
{nil, nil} ->
apply(data_mapper, :init_store, [])

{nil, _} ->
apply(data_mapper, :copy_store, [])

{_, nil} ->
Logger.info("[mnesiac:#{node()}] #{inspect(data_mapper)}: no remote data to copy found.")
{:error, :no_remote_data_to_copy}

{_local, _remote} ->
apply(data_mapper, :resolve_conflict, [cluster_node])
end
end)

:ok
with {:ok, local_cookies} <- get_table_cookies(),
{:ok, remote_cookies} <- get_table_cookies(cluster_node) do
Enum.each(stores(), fn data_mapper ->
case {local_cookies[data_mapper], remote_cookies[data_mapper]} do
{nil, nil} ->
apply(data_mapper, :init_store, [])

{nil, _} ->
apply(data_mapper, :copy_store, [])

{_, nil} ->
Logger.info("[mnesiac:#{node()}] #{inspect(data_mapper)}: no remote data to copy found.")
{:error, :no_remote_data_to_copy}

{_local, _remote} ->
apply(data_mapper, :resolve_conflict, [cluster_node])
end
end)

:ok
else
{:error, reason} ->
{:error, reason}
end
end

@doc """
Expand Down Expand Up @@ -125,10 +126,24 @@ defmodule Mnesiac.StoreManager do
This function returns a map of tables and their cookies.
"""
def get_table_cookies(node \\ node()) do
tables = :rpc.call(node, :mnesia, :system_info, [:local_tables])
case :rpc.call(node, :mnesia, :system_info, [:local_tables], 5_000) do
{:badrpc, reason} ->
{:error, reason}

Enum.reduce(tables, %{}, fn t, acc ->
Map.put(acc, t, :rpc.call(node, :mnesia, :table_info, [t, :cookie]))
tables ->
get_table_cookies(node, tables)
end
end

defp get_table_cookies(node, tables) do
Enum.reduce_while(tables, {:ok, %{}}, fn table, {:ok, acc} ->
case :rpc.call(node, :mnesia, :table_info, [table, :cookie], 5_000) do
{:badrpc, reason} ->
{:halt, {:error, reason}}

cookie ->
{:cont, {:ok, Map.put(acc, table, cookie)}}
end
end)
end
end
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ defmodule Mnesiac.MixProject do
def project do
[
app: :mnesiac,
version: "0.3.10",
version: "0.3.11",
elixir: "~> 1.8",
elixirc_paths: elixirc_paths(Mix.env()),
test_coverage: [tool: ExCoveralls],
Expand Down
10 changes: 10 additions & 0 deletions test/store_manager_test.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
defmodule StoreManagerTest do
@moduledoc false
use ExUnit.Case

describe "get_table_cookies" do
test "returns an error when the node is not reachable" do
assert {:error, _} = Mnesiac.StoreManager.get_table_cookies(:missing_node@missing_host)
end
end
end

0 comments on commit e0ce918

Please sign in to comment.