Current section
Files
Jump to
Current section
Files
lib/test_server/instance_manager.ex
defmodule TestServer.InstanceManager do
@moduledoc false
use GenServer
alias TestServer.{Instance, InstanceSupervisor}
def start_link(options) do
GenServer.start_link(__MODULE__, options, name: __MODULE__)
end
def start_instance(caller, stacktrace, options) do
options =
options
|> Keyword.put_new(:caller, caller)
|> Keyword.put_new(:stacktrace, stacktrace)
caller = Keyword.fetch!(options, :caller)
case DynamicSupervisor.start_child(InstanceSupervisor, Instance.child_spec(options)) do
{:ok, instance} -> GenServer.call(__MODULE__, {:register, {caller, instance}})
{:error, error} -> {:error, error}
end
end
@spec stop_instance(pid()) :: :ok | {:error, :not_found}
def stop_instance(instance) do
:ok = TestServer.HTTPServer.stop(Instance.get_options(instance))
res = DynamicSupervisor.terminate_child(InstanceSupervisor, instance)
GenServer.call(__MODULE__, {:remove, instance})
res
end
@spec get_by_caller(pid()) :: nil | [pid()]
def get_by_caller(caller) do
GenServer.call(__MODULE__, {:get_by_caller, caller})
end
@impl true
def init(_options) do
{:ok, %{instances: []}}
end
@impl true
def handle_call({:register, {caller, instance}}, _from, state) do
state = %{state | instances: state.instances ++ [%{caller: caller, instance: instance}]}
{:reply, {:ok, instance}, state}
end
def handle_call({:get_by_caller, caller}, _from, state) do
instance =
case Enum.filter(state.instances, &(&1.caller == caller)) do
[] -> nil
instances -> Enum.map(instances, & &1.instance)
end
{:reply, instance, state}
end
def handle_call({:alive?, instance}, _from, state) do
instance = Enum.find(state.instances, &(&1.instance == instance))
{:reply, not is_nil(instance)}
end
def handle_call({:remove, instance}, _from, state) do
state = %{state | instances: Enum.reject(state.instances, &(&1.instance == instance))}
{:reply, :ok, state}
end
end