defmodule Runbox.Runtime.StateLoader do
@moduledoc """
Module handles run state load/initialization.
"""
alias Runbox.Scenario.StartParams
alias Runbox.Scenario.Type
alias Runbox.StateStore
require Logger
@callback load_existing_state(StartParams.t(), instance_ctx :: map(), start_recipe :: []) ::
{:ok, start_recipe :: []} | {:error, :no_savepoint}
@callback init_new_state(StartParams.t(), instance_ctx :: map(), start_recipe :: []) ::
{:ok, start_recipe :: []} | {:error, :no_savepoint}
@doc """
Fetches state into run start recipe.
"""
@spec load(StartParams.t(), map(), start_recipe :: []) ::
{:ok, start_recipe :: []} | {:error, :no_savepoint}
def load(%StartParams{} = start_params, instance_context, start_recipe) do
if StateStore.initialized?(instance_context.state_store_pid) do
{time, res} =
:timer.tc(fn ->
get_impl(start_params.scenario_type).load_existing_state(
start_params,
instance_context,
start_recipe
)
end)
Logger.info("Run #{start_params.run_id} existing state loaded in #{div(time, 1000)}ms.")
res
else
{time, res} =
:timer.tc(fn ->
get_impl(start_params.scenario_type).init_new_state(
start_params,
instance_context,
start_recipe
)
end)
Logger.info("Run #{start_params.run_id} new state loaded in #{div(time, 1000)}ms.")
res
end
end
@stage Type.stage()
@simple Type.simple()
defp get_impl(@stage), do: Runbox.Runtime.Stage.StateLoader
defp get_impl(@simple), do: Runbox.Runtime.Simple.StateLoader
end