defmodule Runbox.Runtime.ComponentNetwork do
@moduledoc group: :internal
@moduledoc """
Component network builds and validates run component dependency network.
To build this network, module uses dependencies defined by the scenario.
"""
alias Runbox.Scenario.Type
alias Runbox.ScenarioTemplate
@type t :: any()
@type component :: any()
@callback create([ScenarioTemplate.t()], Keyword.t()) :: {:ok, t} | {:error, term}
@callback convert_to_network([ScenarioTemplate.t()]) :: t
@callback input_topics(t) :: [String.t()]
@doc """
Main function. Given list of template modules,
expands them into components network with input streams, timezips etc...
## Options
* `:direct_ticking` - if true (default), creates network using direct ticking
"""
@spec create(Type.t(), [ScenarioTemplate.t()], Keyword.t()) :: {:ok, t} | {:error, term}
def create(scenario_type, scenario_templates, opts \\ []) do
get_impl(scenario_type).create(scenario_templates, opts)
end
@doc """
Creates base network with only template nodes
"""
@spec convert_to_network(Type.t(), [ScenarioTemplate.t()]) :: t
def convert_to_network(scenario_type, scenario_templates) do
get_impl(scenario_type).convert_to_network(scenario_templates)
end
@doc """
Return all input topic names that are being subscribed to in component network.
"""
@spec input_topics(Type.t(), t) :: [String.t()]
def input_topics(scenario_type, component_network) do
get_impl(scenario_type).input_topics(component_network)
end
@stage Type.stage()
@simple Type.simple()
@spec topology_sort(Type.t(), t) :: [component]
def topology_sort(@stage, network) do
Runbox.Runtime.Stage.ComponentNetwork.topology_sort(network)
end
defp get_impl(@stage), do: Runbox.Runtime.Stage.ComponentNetwork
defp get_impl(@simple), do: Runbox.Runtime.Simple.ComponentNetwork
end