defmodule ALF.Introspection do use GenServer defstruct pipelines: MapSet.new(), pid: nil alias ALF.PerformanceStats @spec start_link([]) :: GenServer.on_start() def start_link([]) do GenServer.start_link(__MODULE__, %__MODULE__{}, name: __MODULE__) end @impl true def init(%__MODULE__{} = state) do state = %{state | pid: self()} {:ok, state} end @spec add(atom()) :: atom() def add(pipeline) when is_atom(pipeline) do GenServer.call(__MODULE__, {:add, pipeline}) end @spec remove(atom()) :: atom() def remove(pipeline) when is_atom(pipeline) do GenServer.call(__MODULE__, {:remove, pipeline}) end @spec pipelines() :: MapSet.t() def pipelines, do: GenServer.call(__MODULE__, :pipelines) @spec components(atom) :: list(map()) def components(pipeline) when is_atom(pipeline) do GenServer.call(__MODULE__, {:components, pipeline}) end @spec reset() :: :ok def reset(), do: GenServer.call(__MODULE__, :reset) @spec performance_stats(atom) :: map() def performance_stats(pipeline) when is_atom(pipeline) do GenServer.call(__MODULE__, {:performance_stats, pipeline}) end @impl true def handle_call({:add, pipeline}, _from, state) do state = %{state | pipelines: MapSet.put(state.pipelines, pipeline)} {:reply, pipeline, state} end def handle_call({:remove, pipeline}, _from, state) do state = %{state | pipelines: MapSet.delete(state.pipelines, pipeline)} {:reply, pipeline, state} end def handle_call(:pipelines, _from, state) do {:reply, state.pipelines, state} end def handle_call(:reset, _from, state) do state = %{state | pipelines: MapSet.new()} {:reply, :ok, state} end def handle_call({:components, pipeline}, _from, state) do unless MapSet.member?(state.pipelines, pipeline) do raise "No such pipeline: #{pipeline}" end components = pipeline |> ALF.Manager.reload_components_states() |> Enum.map(&Map.from_struct/1) {:reply, components, state} end def handle_call({:performance_stats, pipeline}, _from, state) do stats = PerformanceStats.stats_for(pipeline) {:reply, stats, state} end end