| 1 |
|
defmodule Elita.Boot do |
| 2 |
|
import GenServer, only: [call: 3, cast: 2, start: 3] |
| 3 |
|
import Kernel, except: [spawn: 3] |
| 4 |
|
import Application, only: [get_env: 3] |
| 5 |
|
import Elita.Boot.Await, only: [handle: 2] |
| 6 |
|
import Utils.Normalize, only: [name: 1] |
| 7 |
21 |
def spawn(name, configs, opts \\ []) |
| 8 |
21 |
def spawn(name, configs, []), do: boot(name, configs, sender: name) |
| 9 |
38 |
def spawn(name, configs, opts), do: boot(name, configs, opts) |
| 10 |
|
|
| 11 |
1 |
def prime, do: spawn("el", ["el"], skip_logs: true) |
| 12 |
|
|
| 13 |
|
def dispatch(name, msg) do |
| 14 |
42 |
cast(via(name), {:act, msg}) |
| 15 |
|
end |
| 16 |
|
|
| 17 |
|
def request(name, msg) do |
| 18 |
59 |
call(via(name), {:act, msg}, :infinity) |
| 19 |
|
end |
| 20 |
|
|
| 21 |
|
defp boot(name, configs, opts) do |
| 22 |
59 |
boot(name, configs, opts, ready?()) |
| 23 |
|
end |
| 24 |
|
|
| 25 |
|
defp boot(name, configs, opts, true) do |
| 26 |
:-( |
there(name, configs, opts, get_env(:elita, :clock_override, nil)) |
| 27 |
|
end |
| 28 |
|
|
| 29 |
|
defp boot(name, configs, opts, false) do |
| 30 |
59 |
local(name, configs, opts) |
| 31 |
|
end |
| 32 |
|
|
| 33 |
:-( |
defp there(name, configs, opts, nil), do: fetch(addr(), name, configs, opts) |
| 34 |
|
|
| 35 |
|
defp there(name, configs, opts, val), |
| 36 |
:-( |
do: addr() |> tap(&push(&1, val)) |> fetch(name, configs, opts) |
| 37 |
|
|
| 38 |
:-( |
defp fetch(addr, name, configs, opts) do |
| 39 |
:-( |
addr |> post(spec(name, configs, opts), name) |> handle(name) |
| 40 |
|
catch |
| 41 |
:-( |
_, _ -> local(name, configs, opts) |
| 42 |
|
end |
| 43 |
|
|
| 44 |
:-( |
defp push(addr, val) do |
| 45 |
:-( |
:erpc.call(addr, Application, :put_env, [:elita, :clock_override, val], 5000) |
| 46 |
|
catch |
| 47 |
:-( |
_, _ -> :ok |
| 48 |
|
end |
| 49 |
|
|
| 50 |
|
defp spec(name, configs, opts), |
| 51 |
:-( |
do: %{ |
| 52 |
|
id: name, |
| 53 |
|
start: launch(name, configs, opts), |
| 54 |
|
restart: :transient, |
| 55 |
|
type: :supervisor |
| 56 |
|
} |
| 57 |
|
|
| 58 |
|
defp launch(name, configs, opts), |
| 59 |
:-( |
do: {Agent.Tree, :start_link, [{name, configs, opts, via(name)}]} |
| 60 |
|
|
| 61 |
|
defp post(addr, spec, n), |
| 62 |
:-( |
do: :erpc.call(addr, Elita.Place, :put, [spec, n], 90_000) |
| 63 |
|
|
| 64 |
:-( |
defp addr, do: :"elita-#{get_env(:elita, :run, "")}@127.0.0.1" |
| 65 |
|
|
| 66 |
|
defp local(n, configs, opts) do |
| 67 |
59 |
start(Elita, {n, configs, opts}, name: via(n)) |> join() |
| 68 |
|
end |
| 69 |
|
|
| 70 |
59 |
defp ready?, do: get_env(:elita, :run, "") != "" |
| 71 |
|
|
| 72 |
58 |
defp join({:ok, p}), do: {:ok, p} |
| 73 |
1 |
defp join({:error, {:already_started, p}}), do: {:ok, p} |
| 74 |
|
|
| 75 |
:-( |
defp join({:error, {exc, _stack}}) when is_exception(exc) do |
| 76 |
:-( |
{:error, {:init_failed, exc.message}} |
| 77 |
|
end |
| 78 |
|
|
| 79 |
:-( |
defp join({:error, _}), do: {:error, :init_failed} |
| 80 |
|
|
| 81 |
|
defp via(n) do |
| 82 |
160 |
{:via, Registry, {ElitaRegistry, name(n), %{kind: :native, folder: nil}}} |
| 83 |
|
end |
| 84 |
|
end |