Packages

A toolkit for data mapping and language integrated query for Elixir

Current section

Files

Jump to
ecto_tc lib ecto repo registry.ex
Raw

lib/ecto/repo/registry.ex

defmodule Ecto.Repo.Registry do
@moduledoc false
use GenServer
def start_link(_opts) do
GenServer.start_link(__MODULE__, :ok, name: __MODULE__)
end
def associate(pid, name, value) when is_pid(pid) do
GenServer.call(__MODULE__, {:associate, pid, name, value})
end
def all_running() do
for [pid, name] <- :ets.match(__MODULE__, {:"$1", :_, :"$2", :_}) do
name || pid
end
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()
end
def lookup(pid) when is_pid(pid) do
:ets.lookup_element(__MODULE__, pid, 4)
end
## Callbacks
@impl true
def init(:ok) do
table = :ets.new(__MODULE__, [:named_table, read_concurrency: true])
{:ok, table}
end
@impl true
def handle_call({:associate, pid, name, value}, _from, table) do
ref = Process.monitor(pid)
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)
:ets.delete(table, pid)
{:noreply, table}
end
end