Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve cluster call #92

Merged
merged 1 commit into from
Nov 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 35 additions & 9 deletions lib/beacon/live_admin/cluster.ex
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
defmodule Beacon.LiveAdmin.Cluster do
use GenServer
require Logger
alias Beacon.LiveAdmin.PubSub

@name __MODULE__
@timeout :timer.minutes(1)
@one_minute :timer.minutes(1)
@ets_table :beacon_live_admin_sites

def start_link(opts) do
Expand All @@ -17,7 +18,7 @@ defmodule Beacon.LiveAdmin.Cluster do
end

def discover_sites do
GenServer.call(@name, :discover_sites, @timeout)
GenServer.call(@name, :discover_sites, @one_minute)
end

def maybe_discover_sites() do
Expand Down Expand Up @@ -50,14 +51,40 @@ defmodule Beacon.LiveAdmin.Cluster do
:ok

"""
def call(site, module, fun, args)
when is_atom(site) and is_atom(module) and is_atom(fun) and is_list(args) do
def call(site, mod, fun, args)
when is_atom(site) and is_atom(mod) and is_atom(fun) and is_list(args) do
case find_node(site) do
nil -> {:error, :nodedown}
node -> :erpc.call(node, module, fun, args)
nil ->
message = "no running node found for site #{inspect(site)}"
raise Beacon.LiveAdmin.ClusterError, message: message

node ->
do_call(node, mod, fun, args)
end
rescue
exception -> exception
exception ->
Logger.debug(
"failed to call #{Exception.format_mfa(mod, fun, args)} for site #{inspect(site)}"
)

message = """
failed to call #{Exception.format_mfa(mod, fun, args)} for site #{inspect(site)}

Got:

#{Exception.message(exception)}

"""

reraise Beacon.LiveAdmin.ClusterError, [message: message], __STACKTRACE__
end

defp do_call(node, mod, fun, args) do
if node == Node.self() do
apply(mod, fun, args)
else
:erpc.call(node, mod, fun, args)
end
end

if Code.ensure_loaded?(Mix.Project) and Mix.env() == :test do
Expand Down Expand Up @@ -86,8 +113,7 @@ defmodule Beacon.LiveAdmin.Cluster do
end

defp do_discover_sites do
# add or remove nodes from ets state when nodes changes
# instead of recreating everything
# TODO: add or remove nodes from ets state when nodes changes instead of recreating everything
:ets.delete_all_objects(@ets_table)

sites =
Expand Down
3 changes: 3 additions & 0 deletions lib/beacon/live_admin/exceptions.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
defmodule Beacon.LiveAdmin.ClusterError do
defexception message: "Error in cluster"
end
Loading