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