From 51ac63304c640af4d93811bd0b67268c8a4b4fa4 Mon Sep 17 00:00:00 2001 From: Steffen Deusch Date: Sat, 9 Nov 2024 18:06:48 +0100 Subject: [PATCH] erase from persistent_term without blocking registry This was an interesting problem. It started with me updating the dependencies in phoenix_live_dashboard and noticing test failures related to our test of the Ecto Stats page. The stats page calls `Ecto.Repo.all_running` to get a list of repos. The problem was that the test case still got an old repo as running, even though the previous test already stopped it (using start_supervised). It turns out that the :persistent_term.erase was slowing the registry GenServer down too much, therefore it wasn't processing the DOWN messages fast enough and not deleting the old repo entries from ets before the new test was already running. --- lib/ecto/repo/registry.ex | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/ecto/repo/registry.ex b/lib/ecto/repo/registry.ex index 0c6d0bea99..d5dc28c61a 100644 --- a/lib/ecto/repo/registry.ex +++ b/lib/ecto/repo/registry.ex @@ -45,7 +45,10 @@ defmodule Ecto.Repo.Registry do @impl true def handle_info({:DOWN, ref, _type, pid, _reason}, table) do [{^pid, ^ref, name, _}] = :ets.lookup(table, pid) - name && :persistent_term.erase(name) + # we call :persistent_term.erase inside a new process to prevent + # the possibly slow erase call from blocking us from processing + # other messages + name && spawn(:persistent_term, :erase, [name]) :ets.delete(table, pid) {:noreply, table} end