From 2b7c1e6a4f894a18bbbff4dd748a2239f60b1fe9 Mon Sep 17 00:00:00 2001 From: Steve Cohen Date: Fri, 6 Sep 2024 13:31:27 -0700 Subject: [PATCH] Added manager node monitor Occasionally, our script that's designed to clean up after the project node port doesn't seem to work correctly. Because of this, it makes sense to monitor the manager node for the project node and to shut down when the manager node dies. --- .../lib/lexical/remote_control/application.ex | 1 + .../remote_control/manager_node_monitor.ex | 43 +++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 apps/remote_control/lib/lexical/remote_control/manager_node_monitor.ex diff --git a/apps/remote_control/lib/lexical/remote_control/application.ex b/apps/remote_control/lib/lexical/remote_control/application.ex index 907fc43d4..d02edf4b8 100644 --- a/apps/remote_control/lib/lexical/remote_control/application.ex +++ b/apps/remote_control/lib/lexical/remote_control/application.ex @@ -11,6 +11,7 @@ defmodule Lexical.RemoteControl.Application do children = if RemoteControl.project_node?() do [ + RemoteControl.ManagerNodeMonitor, RemoteControl.Api.Proxy, RemoteControl.Commands.Reindex, RemoteControl.Module.Loader, diff --git a/apps/remote_control/lib/lexical/remote_control/manager_node_monitor.ex b/apps/remote_control/lib/lexical/remote_control/manager_node_monitor.ex new file mode 100644 index 000000000..737e69b7d --- /dev/null +++ b/apps/remote_control/lib/lexical/remote_control/manager_node_monitor.ex @@ -0,0 +1,43 @@ +defmodule Lexical.RemoteControl.ManagerNodeMonitor do + @moduledoc """ + A node monitor that monitors the manager node for this project, and shuts down + the system if that node dies. + """ + use GenServer + require Logger + + def start_link(_) do + GenServer.start_link(__MODULE__, nil, name: __MODULE__) + end + + @impl true + def init(_) do + case fetch_manager_node() do + {:ok, manager_node} -> + Node.monitor(manager_node, true) + {:ok, manager_node} + + :error -> + Logger.warning("Could not determine manager node for monitoring.") + :ignore + end + end + + @impl true + def handle_info({:nodedown, _}, state) do + spawn(fn -> System.stop() end) + {:noreply, state} + end + + defp fetch_manager_node do + Enum.find_value(Node.list(), :error, fn node_name -> + string_name = Atom.to_string(node_name) + + if String.starts_with?(string_name, "manager-") do + {:ok, node_name} + else + false + end + end) + end +end