Channels: call the pid, not the registry name, and retry once

96a50ad · Gabriel Morell · 2026-10-27 17:23

4 files +17 -3
Message
{commit_body(@commit)}

Files changed

modified lib/oh_my_ex_oh_ircd/irc/channel.ex
+17 −3
@@ -191,9 +191,23 @@ defmodule OhMyExOhIrcd.IRC.Channel do
191 191
192 192 def topic_topic(name), do: "channel:" <> normalize(name)
193 193
194 − defp call(name, msg) do
195 − {:ok, _pid} = ensure_started(name)
196 − GenServer.call(HordeRegistry.via({:channel, normalize(name)}), msg)
194 + # Calls the pid ensure_started/1 found or started, not the registry name
195 + # again: Horde's registry is synced between nodes as a CRDT, so right
196 + # after a channel starts (or moves) on another node the local copy may
197 + # not have the name yet, and a lookup by name exits with :noproc — which
198 + # took the caller's IRC connection down with it ("JOIN #jamz" on
199 + # 2026-10-27, the first day the pods were clustered). Once more if the
200 + # process went away under the call: a channel being handed to another
201 + # node exits while we hold its old pid.
202 + defp call(name, msg, attempts \\ 2) do
203 + {:ok, pid} = ensure_started(name)
204 + GenServer.call(pid, msg)
205 + catch
206 + :exit, {reason, _} when attempts > 1 and reason in [:noproc, :normal] ->
207 + call(name, msg, attempts - 1)
208 +
209 + :exit, {{:shutdown, _}, _} when attempts > 1 ->
210 + call(name, msg, attempts - 1)
197 211 end
198 212
199 213 ## Server

Parents: 01f0c81