Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added root app option #1

Merged
merged 1 commit into from
Sep 11, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 44 additions & 30 deletions lib/local_cluster.ex
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,21 @@ defmodule LocalCluster do
start_boot_server = fn ->
# voodoo flag to generate a "started" atom flag
:global_flags.once("local_cluster:started", fn ->
{ :ok, _ } = :erl_boot_server.start([
{ 127, 0, 0, 1 }
])
{:ok, _} =
:erl_boot_server.start([
{127, 0, 0, 1}
])
end)

:ok
end

# only ever handle the :erl_boot_server on the initial startup
case :net_kernel.start([ :"[email protected]" ]) do
case :net_kernel.start([:"[email protected]"]) do
# handle nodes that have already been started elsewhere
{ :error, { :already_started, _ } } -> start_boot_server.()
{:error, {:already_started, _}} -> start_boot_server.()
# handle the node being started
{ :ok, _ } -> start_boot_server.()
{:ok, _} -> start_boot_server.()
# pass anything else
anything -> anything
end
Expand All @@ -43,39 +45,51 @@ defmodule LocalCluster do
nodes are linked to the current process, and so will terminate when the
parent process does for automatic cleanup.
"""
@spec start_nodes(binary, integer, Keyword.t) :: [ atom ]
@spec start_nodes(binary, integer, Keyword.t()) :: [atom]
def start_nodes(prefix, amount, options \\ [])
when (is_binary(prefix) or is_atom(prefix)) and is_integer(amount) do
nodes = Enum.map(1..amount, fn idx ->
{ :ok, name } = :slave.start_link(
'127.0.0.1',
:"#{prefix}#{idx}",
'-loader inet -hosts 127.0.0.1 -setcookie "#{:erlang.get_cookie()}"'
)
name
end)
when (is_binary(prefix) or is_atom(prefix)) and is_integer(amount) do
root_app = Keyword.get(options, :root_app)

nodes =
Enum.map(1..amount, fn idx ->
{:ok, name} =
:slave.start_link(
'127.0.0.1',
:"#{prefix}#{idx}",
'-loader inet -hosts 127.0.0.1 -setcookie "#{:erlang.get_cookie()}"'
)

name
end)

rpc = &({ _, [] } = :rpc.multicall(nodes, &1, &2, &3))
rpc = &({_, []} = :rpc.multicall(nodes, &1, &2, &3))

rpc.(:code, :add_paths, [ :code.get_path() ])
rpc.(:code, :add_paths, [:code.get_path()])

rpc.(Application, :ensure_all_started, [ :mix ])
rpc.(Application, :ensure_all_started, [ :logger ])
rpc.(Application, :ensure_all_started, [:mix])
rpc.(Application, :ensure_all_started, [:logger])

rpc.(Logger, :configure, [ level: Logger.level() ])
rpc.(Mix, :env, [ Mix.env() ])
rpc.(Logger, :configure, level: Logger.level())
rpc.(Mix, :env, [Mix.env()])

for { app_name, _, _ } <- Application.loaded_applications() do
for { key, val } <- Application.get_all_env(app_name) do
rpc.(Application, :put_env, [ app_name, key, val ])
for {app_name, _, _} <- Application.loaded_applications() do
for {key, val} <- Application.get_all_env(app_name) do
rpc.(Application, :put_env, [app_name, key, val])
end
rpc.(Application, :ensure_all_started, [ app_name ])

unless root_app do
rpc.(Application, :ensure_all_started, [app_name])
end
end

if root_app do
rpc.(Application, :ensure_all_started, [root_app])
end

for file <- Keyword.get(options, :files, []) do
{ :ok, source } = File.read(file)
{:ok, source} = File.read(file)

for { module, binary } <- Code.compile_string(source, file) do
for {module, binary} <- Code.compile_string(source, file) do
rpc.(:code, :load_binary, [
module,
:unicode.characters_to_list(file),
Expand All @@ -90,14 +104,14 @@ defmodule LocalCluster do
@doc """
Stops a set of child nodes.
"""
@spec stop_nodes([ atom ]) :: :ok
@spec stop_nodes([atom]) :: :ok
def stop_nodes(nodes) when is_list(nodes),
do: Enum.each(nodes, &:slave.stop/1)

@doc """
Stops the current distributed node and turns it back into a local node.
"""
@spec stop :: :ok | { :error, atom }
@spec stop :: :ok | {:error, atom}
def stop,
do: :net_kernel.stop()
end