type_supervisor.ex (1184B)
1 defmodule Postgrex.TypeSupervisor do 2 @moduledoc false 3 4 use Supervisor 5 6 @manager Postgrex.TypeManager 7 @supervisor Postgrex.TypeSupervisor 8 9 @doc """ 10 Starts a type supervisor with a manager and a simple 11 one for one supervisor for each server. 12 """ 13 def start_link(_) do 14 Supervisor.start_link(__MODULE__, :ok) 15 end 16 17 @doc """ 18 Locates a type server for the given module-key pair. 19 """ 20 def locate(module, key) do 21 pair = {module, key} 22 23 case Registry.lookup(@manager, pair) do 24 [{pid, _}] -> if Process.alive?(pid), do: pid, else: start_server(module, pair) 25 [] -> start_server(module, pair) 26 end 27 end 28 29 defp start_server(module, pair) do 30 opts = [name: {:via, Registry, {Postgrex.TypeManager, pair}}] 31 32 case DynamicSupervisor.start_child(@supervisor, {Postgrex.TypeServer, {module, self(), opts}}) do 33 {:ok, pid} -> pid 34 {:error, {:already_started, pid}} -> pid 35 end 36 end 37 38 # Callbacks 39 40 def init(:ok) do 41 manager = {Registry, keys: :unique, name: @manager} 42 server_sup = {DynamicSupervisor, strategy: :one_for_one, name: @supervisor} 43 Supervisor.init([manager, server_sup], strategy: :rest_for_one) 44 end 45 end