Packages

Overseer is similar to OTP Supervisor, but it supervise the erlang/elixir nodes.

Current section

Files

Jump to
overseer lib types labor.ex
Raw

lib/types/labor.ex

defmodule Overseer.Labor do
@moduledoc """
Struct to track the running labor resources
"""
require Logger
alias Overseer.Labor
# TODO: how can we unify the type def of states and the states here?
@all_status [:disconnected, :connected, :loaded, :paired, :terminated]
@type status :: :disconnected | :connected | :loaded | :paired | :terminated
@type t :: %__MODULE__{
name: node,
pid: pid,
status: status,
timers: %{required(atom) => reference},
started_at: DateTime.t(),
adapter_data: any,
state: any
}
defstruct name: :noname,
pid: nil,
status: :disconnected,
timers: %{},
started_at: nil,
adapter_data: nil,
state: nil
def create(name, init_state, adapter_data) do
%Labor{
name: name,
state: init_state,
adapter_data: adapter_data,
started_at: DateTime.utc_now()
}
end
@doc """
Pair(link) the pid from remote node to overseer.
"""
def pair(labor, pid) do
case is_alive?(labor.name, pid) do
true ->
pair_pid(labor, pid)
_ ->
Logger.warn("Trying to pair to a dead process #{inspect(pid)} to #{inspect(labor)}")
labor
end
end
def update_state(labor, state), do: %{labor | state: state}
@all_status
|> Enum.map(fn status ->
def unquote(status)(labor), do: set_status(labor, unquote(status))
end)
@all_status
|> Enum.map(fn status ->
def unquote(:"is_#{status}")(labor), do: is_status(labor, unquote(status))
end)
defp set_status(labor, new_status) when is_atom(new_status), do: %{labor | status: new_status}
defp is_status(labor, status) when is_atom(status), do: labor.status == status
defp pair_pid(labor, pid) do
case labor.pid do
nil -> Process.link(pid)
old_pid -> pair_old_new(labor, old_pid, pid)
end
new_labor = Labor.paired(labor)
%{new_labor | pid: pid}
end
defp pair_old_new(labor, old_pid, pid) do
case is_alive?(labor.name, old_pid) do
false ->
Process.link(pid)
_ ->
Logger.warn("Trying to link a new pid to #{inspect(labor)}, while old #{pid} is alive")
Process.unlink(old_pid)
Process.link(pid)
end
end
defp is_alive?(node_name, pid), do: :rpc.call(node_name, Process, :alive?, [pid])
end