From 9886dff8bfd06d66365559bf9d2e3062d09e7c29 Mon Sep 17 00:00:00 2001 From: Aleksey Sabilin Date: Tue, 21 Jul 2026 22:14:16 +0300 Subject: [PATCH] fix: run observer_web as hidden node to stop OTP global splitting IFT Mnesia cluster. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Without --hidden, observer joins the visible mesh and prevent_overlapping_partitions disconnects eventhub-node1/2 (running_partitioned_network → admin verification-token 404 in e2e). --- docker/ObserverWeb.Dockerfile | 5 ++++- src/infra/cluster_discovery.erl | 19 +++++++++++++------ 2 files changed, 17 insertions(+), 7 deletions(-) mode change 100644 => 100755 docker/ObserverWeb.Dockerfile mode change 100644 => 100755 src/infra/cluster_discovery.erl diff --git a/docker/ObserverWeb.Dockerfile b/docker/ObserverWeb.Dockerfile old mode 100644 new mode 100755 index 2b249b1..a97be42 --- a/docker/ObserverWeb.Dockerfile +++ b/docker/ObserverWeb.Dockerfile @@ -39,4 +39,7 @@ COPY docker/observer_web/dev.exs ./dev.exs EXPOSE 4000 ENV RELEASE_COOKIE=eventhub_cookie -CMD elixir --sname observer_web@observer_web --cookie "${RELEASE_COOKIE}" -S mix run --no-halt dev.exs +# --hidden: observer must not join the visible global mesh. Without it, OTP +# prevent_overlapping_partitions disconnects eventhub-node1 <-> eventhub-node2 +# when observer connects to both (Mnesia running_partitioned_network → e2e 404). +CMD elixir --hidden --sname observer_web@observer_web --cookie "${RELEASE_COOKIE}" -S mix run --no-halt dev.exs diff --git a/src/infra/cluster_discovery.erl b/src/infra/cluster_discovery.erl old mode 100644 new mode 100755 index db1b3c6..9b357a5 --- a/src/infra/cluster_discovery.erl +++ b/src/infra/cluster_discovery.erl @@ -16,13 +16,20 @@ discover_loop() -> io:format("Checking epmd on ~s...~n", [IPStr]), case erl_epmd:names(IP) of {ok, List} -> + %% Only eventhub-node* — connecting to observer_web (same cookie) + %% triggers OTP prevent_overlapping_partitions and splits the mesh. lists:foreach(fun({Name, _Port}) -> - Node = list_to_atom(Name ++ "@" ++ Name), - io:format(" Trying net_kernel:connect_node(~s)...~n", [Node]), - case net_kernel:connect_node(Node) of - true -> io:format(" *** Connected to ~s ***~n", [Node]), join_and_replicate(Node); %io:format(" *** Connected to ~s ***~n", [Node]); - false -> io:format(" *** Failed to connect to ~s ***~n", [Node]); - ignored -> ok + case lists:prefix("eventhub-node", Name) of + false -> + ok; + true -> + Node = list_to_atom(Name ++ "@" ++ Name), + io:format(" Trying net_kernel:connect_node(~s)...~n", [Node]), + case net_kernel:connect_node(Node) of + true -> io:format(" *** Connected to ~s ***~n", [Node]), join_and_replicate(Node); + false -> io:format(" *** Failed to connect to ~s ***~n", [Node]); + ignored -> ok + end end end, List); {error, Reason} ->