Current section
Files
Jump to
Current section
Files
lib/pet_snake_manager.ex
defmodule Venomous.PetSnakeManager do
@moduledoc "SnakeManager but for pets..."
use GenServer
require Logger
alias Venomous.PetSnakeSupervisor
def start_link(args) do
GenServer.start_link(__MODULE__, args, name: __MODULE__)
end
def init(state) do
Logger.info("Started Pet Snake Manager")
{:ok, state}
end
def handle_info({:reject_pet, name, style}, state) do
case state.table |> :ets.lookup(name) do
[] ->
:ok
[{_name, pid, pypid, os_pid}] ->
:python.stop(pypid)
DynamicSupervisor.terminate_child(PetSnakeSupervisor, pid)
if style == :brutal, do: System.cmd("kill", ["-9", "#{os_pid}"])
:ets.delete(state.table, name)
end
{:noreply, state}
end
defp adopt_snake({:error, message}, _name, _table), do: {:error, message}
defp adopt_snake({:ok, pid}, name, table) do
worker = GenServer.call(pid, :get_pypid)
:ets.insert(table, {name, worker.pid, worker.pypid, worker.os_pid})
{:ok, name}
end
defp adopt_snake(true, _name, _opts, _table), do: {:error, :exists}
defp adopt_snake(false, name, opts, table) do
PetSnakeSupervisor.deploy_snake_pet(opts) |> adopt_snake(name, table)
end
def handle_call({:adopt_snake, name, opts}, _from, state) do
exists? = state.table |> :ets.lookup(name) |> Kernel.!=([])
{:reply, adopt_snake(exists?, name, opts, state.table), state}
end
def handle_call({:get_snake, name}, _from, state) do
snake =
case state.table |> :ets.lookup(name) do
[] ->
{:error, :not_found}
[{_name, pid, _pypid, _os_pid}] ->
pid
end
{:reply, snake, state}
end
end