Current section
Files
Jump to
Current section
Files
lib/agent/supervisor.ex
defmodule Kvasir.Agent.Supervisor do
# use Supervisor
alias Kvasir.Agent.PartitionSupervisor
require Logger
defmodule Monitor do
def start_link(agent) do
{:ok, spawn_link(__MODULE__, :monitor, [agent])}
end
def monitor(agent) do
Process.flag(:trap_exit, true)
Logger.info(fn -> "Kvasir Agents: Starting #{inspect(agent)} supervisor." end)
do_monitor(agent)
end
defp do_monitor(agent) do
receive do
{:EXIT, _, reason} ->
Logger.info(fn ->
"Kvasir Agents: Stopped<#{inspect(reason)}> #{inspect(agent)} supervisor."
end)
_ ->
do_monitor(agent)
end
end
end
@spec start_link(%{agent: any, source: any, topic: any}) :: :ignore | {:error, any} | {:ok, pid}
def start_link(config = %{agent: agent, source: source, topic: topic}) do
# Supervisor.start_link(__MODULE__, config, name: :"#{agent}.Supervisor")
publisher = Module.concat([agent, "Client"])
pool_size = String.to_integer(System.get_env("KVASIR_AGENT_PUBLISHER_POOL_SIZE", "10"))
partitions = source.__topics__()[topic].partitions
with {:ok, pid} <-
DynamicSupervisor.start_link(strategy: :one_for_one, name: :"#{agent}.Supervisor"),
:ok <- source.generate_dedicated_publisher(publisher, topic, pool_size: pool_size),
{:ok, _} <-
DynamicSupervisor.start_child(pid, %{
id: :monitor,
start: {Monitor, :start_link, [agent]},
type: :worker
}),
{:ok, _} = DynamicSupervisor.start_child(pid, publisher) do
Enum.each(0..(partitions - 1), fn p ->
DynamicSupervisor.start_child(pid, %{
id: :"supervisor#{p}",
start: {PartitionSupervisor, :start_link, [config, p]},
type: :supervisor
})
end)
{:ok, pid}
end
end
def open(registry, agent, partition, id) do
registry.start_child(agent, partition, id)
end
def preload(registry, agent, partition, id, offset, state, cache) do
registry.start_child(agent, partition, id, offset, state, cache)
end
def count(agent, partitions) do
0..(partitions - 1)
|> Enum.map(&PartitionSupervisor.count(agent, &1))
|> Enum.sum()
end
def list(agent, partitions) do
Enum.flat_map(
0..(partitions - 1),
fn p ->
p
|> agent.__registry__()
|> Registry.select([{{:"$1", :"$2", :"$3"}, [], [{{:"$1", :"$2", :"$3"}}]}])
|> Enum.map(&(&1 |> elem(0)))
end
)
end
def whereis(agent, partition, id) do
case partition |> agent.__registry__() |> Registry.lookup(id) do
[{pid, _}] -> pid
_ -> nil
end
end
def alive?(config, partition, id), do: whereis(config, partition, id) != nil
# def init(config = %{source: source}) do
# partitions = source.__topics__()[config.topic].partitions
# children =
# Enum.map(0..(partitions - 1), fn p ->
# %{
# id: :"supervisor#{p}",
# start: {PartitionSupervisor, :start_link, [config, p]},
# type: :supervisor
# }
# end)
# Supervisor.init(children, strategy: :one_for_one)
# end
end