lib/runbox/run_node.ex

defmodule Runbox.RunNode do
  @moduledoc """
  Module contains common functions called on run slave node.
  """

  alias Runbox.RunContext
  alias Runbox.RunStartContext
  alias Runbox.Scenario

  @doc """
  Starts supervisor for run.

  All components of run running on slave node will run under this supervisor.
  OneForAll strategy with 0 max restart stops supervisor if any component crashes.
  Because run manager process running on master is linked with this supervisor,
  it also crashes (and it what we want).
  """
  @spec start_run_sup(String.t()) :: Supervisor.on_start_child()
  def start_run_sup(run_id) do
    children = []
    opts = [strategy: :one_for_all, max_restarts: 0]

    spec = %{
      id: run_id,
      start: {Supervisor, :start_link, [children, opts]},
      restart: :temporary,
      type: :supervisor
    }

    Supervisor.start_child(Runbox.SlaveSup, spec)
  end

  @doc """
  Starts run component under run scenario.
  """
  @spec start_run_component(Scenario.component_def(), RunContext.t(), RunStartContext.t()) ::
          Supervisor.on_start_child()
  def start_run_component(%{id: id, mod: mod, fun: fun, args: args}, runbox_ctx, start_ctx) do
    child_spec = %{
      id: id,
      type: :worker,
      start: {mod, fun, [args, runbox_ctx, start_ctx]},
      restart: :transient
    }

    Supervisor.start_child(runbox_ctx.sup_pid, child_spec)
  end
end