Current section
Files
Jump to
Current section
Files
lib/mix/tasks/run.cluster.ex
defmodule Mix.Tasks.Run.Cluster do
@moduledoc """
Run a project in a distributed environment.
This mix task starts up a cluster of nodes before running the `Mix.Tasks.Run`
mix task. The number of nodes to start (besides the master node) can be set
using the "-count #" switch (defaults to 4). Each slave node will have the code
and application environment from the master node loaded onto it. All switches
for the `mix run` task will be passed along to it.
"""
use Mix.Task
@shortdoc "Runs a project in a distributed environment"
@recursive true
@default_count 4
def run(params) do
app = Mix.Project.config[:app]
{switches, _, _} = OptionParser.parse(params, [switches: [count: :integer]])
params = case Keyword.has_key?(switches, :count) do
true -> remove_count(params)
false -> params
end
Mix.Tasks.Run.run(["--no-start"|params])
switches
|> Keyword.get(:count, @default_count)
|> DistributedEnv.start_link(app)
config_path = Mix.Project.config[:config_path]
:rpc.multicall(Node.list(), Mix.Tasks.Run.Distributed, :load_config, [config_path])
:rpc.eval_everywhere(Application, :ensure_all_started, [app])
end
def load_config(path) do
for {app, config} <- Mix.Config.read!(path),
do: Enum.each(config, fn {k, v} -> Application.put_env(app, k, v) end)
end
defp remove_count(params, acc \\ [])
defp remove_count([], acc), do: :lists.reverse(acc)
defp remove_count(["--count"|[_num|rem]], acc), do: :lists.reverse(acc) ++ rem
defp remove_count([head|rem], acc), do: remove_count(rem, [head|acc])
end