From e75c32af70bb2d7024f95c66356343543e8c4eb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sun, 6 Oct 2024 23:57:11 +0200 Subject: [PATCH] Use persistent_term for faster adapter config lookups (#4521) --- lib/ecto/repo/registry.ex | 9 +++++---- lib/ecto/repo/supervisor.ex | 10 +++------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/lib/ecto/repo/registry.ex b/lib/ecto/repo/registry.ex index 88f9cd3bc8..0c6d0bea99 100644 --- a/lib/ecto/repo/registry.ex +++ b/lib/ecto/repo/registry.ex @@ -18,9 +18,8 @@ defmodule Ecto.Repo.Registry do end def lookup(repo) when is_atom(repo) do - GenServer.whereis(repo) - |> Kernel.||(raise "could not lookup Ecto repo #{inspect repo} because it was not started or it does not exist") - |> lookup() + :persistent_term.get(repo, nil) || + raise "could not lookup Ecto repo #{inspect(repo)} because it was not started or it does not exist" end def lookup(pid) when is_pid(pid) do @@ -38,13 +37,15 @@ defmodule Ecto.Repo.Registry do @impl true def handle_call({:associate, pid, name, value}, _from, table) do ref = Process.monitor(pid) + name && :persistent_term.put(name, value) true = :ets.insert(table, {pid, ref, name, value}) {:reply, :ok, table} end @impl true def handle_info({:DOWN, ref, _type, pid, _reason}, table) do - [{^pid, ^ref, _, _}] = :ets.lookup(table, pid) + [{^pid, ^ref, name, _}] = :ets.lookup(table, pid) + name && :persistent_term.erase(name) :ets.delete(table, pid) {:noreply, table} end diff --git a/lib/ecto/repo/supervisor.ex b/lib/ecto/repo/supervisor.ex index dcb5826ea8..1be968d816 100644 --- a/lib/ecto/repo/supervisor.ex +++ b/lib/ecto/repo/supervisor.ex @@ -187,9 +187,6 @@ defmodule Ecto.Repo.Supervisor do @doc false def init({name, repo, otp_app, adapter, opts}) do - # Normalize name to atom, ignore via/global names - name = if is_atom(name), do: name, else: nil - case init_config(:supervisor, repo, otp_app, opts) do {:ok, opts} -> :telemetry.execute( @@ -199,6 +196,9 @@ defmodule Ecto.Repo.Supervisor do ) {:ok, child, meta} = adapter.init([repo: repo] ++ opts) + + # Normalize name to atom, ignore via/global names + name = if is_atom(name), do: name, else: nil cache = Ecto.Query.Planner.new_query_cache(name) meta = Map.merge(meta, %{repo: repo, cache: cache}) child_spec = wrap_child_spec(child, [name, adapter, meta]) @@ -221,10 +221,6 @@ defmodule Ecto.Repo.Supervisor do end end - defp wrap_child_spec({id, start, restart, shutdown, type, mods}, args) do - {id, {__MODULE__, :start_child, [start | args]}, restart, shutdown, type, mods} - end - defp wrap_child_spec(%{start: start} = spec, args) do %{spec | start: {__MODULE__, :start_child, [start | args]}} end