Current section

Files

Jump to
strom lib composite start_stop.ex
Raw

lib/composite/start_stop.ex

defmodule Strom.Composite.StartStop do
@moduledoc "Utility module. There are functions for starting and stopping composites"
alias Strom.Composite
alias Strom.Renamer
@spec start(Composite.t()) :: pid()
def start(%Composite{} = composite) do
supervisor_name = Composite.supervisor_name(composite.name)
component_supervisor_name = Composite.component_supervisor_name(composite.name)
task_supervisor_name = Composite.task_supervisor_name(composite.name)
{:ok, _supervisor_pid} =
DynamicSupervisor.start_child(
Strom.DynamicSupervisor,
%{
id: supervisor_name,
start: {DynamicSupervisor, :start_link, [[name: supervisor_name]]},
restart: :temporary
}
)
{:ok, _supervisor_pid} =
DynamicSupervisor.start_child(
supervisor_name,
%{
id: component_supervisor_name,
start: {DynamicSupervisor, :start_link, [[name: component_supervisor_name]]},
restart: :temporary
}
)
{:ok, _task_supervisor_pid} =
DynamicSupervisor.start_child(
supervisor_name,
%{
id: task_supervisor_name,
start: {DynamicSupervisor, :start_link, [[name: task_supervisor_name]]},
restart: :temporary
}
)
{:ok, pid} =
DynamicSupervisor.start_child(
Strom.DynamicSupervisor,
%{id: Composite, start: {Composite, :start_link, [composite]}, restart: :temporary}
)
pid
end
def stop(%Composite{name: name}) do
pid = Process.whereis(name)
Process.unlink(pid)
GenServer.call(name, :stop_components)
GenServer.call(name, :stop)
end
def start_components(components, name) do
components
|> Enum.reduce([], fn
%{__struct__: Renamer} = component, acc ->
[Renamer.start(component) | acc]
%{__struct__: module} = component, acc ->
component = %{component | composite: name}
component = module.start(component)
Process.monitor(component.pid)
[component | acc]
end)
|> Enum.reverse()
end
def generate_name(components) do
components
|> Enum.map(fn %{__struct__: struct} -> to_string(struct) end)
|> Enum.map_join("", &String.at(&1, 13))
|> String.slice(0..15)
|> then(&(&1 <> "_" <> timestamp_postfix()))
|> String.to_atom()
end
defp timestamp_postfix do
:erlang.system_time()
|> rem(round(1.0e9))
|> to_string()
end
end