neiam
/oh-my-ex-oh-ircd
public · Issues · Pulls · Labels · Forks · Compare · Actions success · Badges · Packages
⭐
Log in to mark this repository.
Channels: call the pid, not the registry name, and retry once
96a50ad · Gabriel Morell · 2026-10-27 17:23
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