Как я могу загрузить подмножество приложений в зонтичном приложении?
Предположим, у меня есть приложение-зонтик, содержащее несколько дочерних приложений.
Из корня зонтика, mix run
, или же iex -S mix
(что сокращенно от iex -S mix run
) запустит все дочерние приложения.
От apps/app_a
эти команды запустят только это дочернее приложение.
Есть ли способ, которым я могу запустить одну команду, чтобы запустить определенное подмножество дочерних приложений?
1 ответ
Если есть зависимость при загрузке
Обычно причиной запуска приложения A и приложения B является то, что A зависит от B и не должен запускаться до тех пор, пока не будет запущен B. В этом случае вы можете объявить зависимость в A mixfile.exs
:
defp deps do
[
{:app_b, in_umbrella: true}
]
end
Затем, из каталога приложения A, запуск приложения сначала запустит приложение B.
Если нет зависимости при загрузке
Иногда технически нет зависимости при загрузке между двумя приложениями, но имеет смысл запускать их вместе для разработки. Например, приложение A помещает данные в очередь, из которой их использует приложение B, но они работают на отдельных компьютерах в производственном процессе и не будут взаимодействовать напрямую.
В этом случае вы можете использовать Application.ensure_all_started/1
запустить каждое нужное приложение в смешанной задаче. Например:
defmodule Mix.Tasks.Boot do
@moduledoc """
Boots the given apps and keeps them running until killed.
## Examples
`mix boot app_a app_b`
"""
@allowed_app_names MapSet.new(~w[
app_a
app_b
app_c
])
use Mix.Task
@shortdoc "Boots the given apps"
def run(app_names) do
app_name_set = MapSet.new(app_names)
if MapSet.subset?(app_name_set, @allowed_app_names) do
app_names
|> Enum.map(&String.to_atom(&1))
|> Enum.each(fn app_name ->
start_app(app_name)
end)
# what `mix run --no-halt` does
# https://github.com/elixir-lang/elixir/blob/v1.6/lib/mix/lib/mix/tasks/run.ex#L77
Process.sleep(:infinity)
else
unknowns =
app_name_set
|> MapSet.difference(@allowed_app_names)
|> MapSet.to_list()
IO.puts("Unknown app names: #{inspect(unknowns)}")
end
end
defp start_app(:app_c = app_name) do
# Assuming app_c uses Phoenix
# what `mix phx.server` does
# https://github.com/phoenixframework/phoenix/blob/v1.3/lib/mix/tasks/phx.server.ex#L24
Application.put_env(:phoenix, :serve_endpoints, true, persistent: true)
do_start_app(app_name)
end
defp start_app(app_name) do
do_start_app(app_name)
end
defp do_start_app(app_name) do
{:ok, _apps} = Application.ensure_all_started(app_name)
end
end