Packages

Configuration and infrastructure as code in Elixir

Current section

Files

Jump to
railyard lib railyard.ex
Raw

lib/railyard.ex

defmodule Railyard do
alias Railyard.Resource
alias Railyard.ResourceSpec
def ship(resource_specs, bindings \\ [])
def ship(%ResourceSpec{} = resource_spec, :delete) do
resource_id = ResourceSpec.id(resource_spec)
Registry.lookup(Railyard.Registry, resource_id)
|> Enum.map(fn {pid, nil} ->
Resource.delete(pid)
end)
end
def ship(%ResourceSpec{} = resource_spec, bindings) when is_list(bindings) do
resource_id = ResourceSpec.id(resource_spec)
Registry.lookup(Railyard.Registry, resource_id)
|> case do
[] ->
with {:ok, pid} <-
DynamicSupervisor.start_child(
Railyard.ResourceSupervisor,
%{
id: resource_id,
start: {Resource, :start_link, [resource_spec]},
restart: :transient
}
) do
Resource.ship(pid, bindings)
else
e -> e |> IO.inspect()
end
[{pid, nil}] ->
Resource.ship(pid, bindings)
end
end
def ship(resource_specs, bindings) when is_list(resource_specs) do
resource_specs
# |> sort_specs_by_dependencies
|> Enum.map(fn resource_spec -> ship(resource_spec, bindings) end)
end
defp sort_specs_by_dependencies(resource_specs) do
sort_specs_by_dependencies(
resource_specs,
resource_specs,
[]
)
end
defp sort_specs_by_dependencies(
all_specs,
[
%ResourceSpec{
attributes: [depends_on: dependency_names],
name: spec_name
} = spec
| rest_of_specs
] = resource_specs,
ordered_specs
) do
dependencies =
dependency_names
|> Enum.map(fn
%ResourceSpec{name: name} ->
name
{dependency_module, dependency_name} ->
apply(dependency_module, dependency_name)
dependency_name ->
all_specs
|> find_spec_by_name(dependency_name)
end)
dependencies =
(dependencies ++ ordered_specs)
|> Enum.uniq_by(fn
%ResourceSpec{name: name} -> name
end)
case ordered_specs |> find_spec_by_name(spec_name) do
nil ->
[spec | ordered_specs]
_ ->
ordered_specs
end
end
defp sort_specs_by_dependencies([], all_specs, ordered_specs), do: ordered_specs
defp find_spec_by_name(resource_specs, search_for_name) do
resource_specs
|> Enum.find(fn
%ResourceSpec{name: name} ->
search_for_name == name
end)
end
def via_tuple(name) do
{:via, Registry, {Railyard.Registry, name}}
end
end