Current section
Files
Jump to
Current section
Files
lib/strategy/strategy.ex
defmodule Cluster.Strategy do
@moduledoc """
This module defines the behaviour for implementing clustering strategies.
"""
defmacro __using__(_) do
quote do
@behaviour Cluster.Strategy
end
end
@type bad_nodes :: [{node(), reason :: term()}]
# Starts the strategy
@callback start_link() :: {:ok, pid} | :ignore | {:error, reason :: term}
@doc """
Returns a worker specification for the selected cluster strategy.
"""
@spec spec() :: Supervisor.Spec.spec()
def spec(), do: Supervisor.Spec.worker(selected_strategy(), [])
@doc """
Starts the selected cluster strategy process.
"""
@spec start_link() :: {:ok, pid} | :ignore | {:error, reason :: term}
def start_link(), do: apply(selected_strategy(), :start_link, [])
@doc false
@spec selected_strategy() :: module()
def selected_strategy(),
do: Application.get_env(:libcluster, :strategy, Cluster.Strategy.Epmd)
@doc """
Given a list of node names, attempts to connect to all of them.
Returns `:ok` if all nodes connected, or `{:error, [{node, reason}, ..]}`
if we failed to connect to some nodes.
All failures are logged.
"""
@spec connect_nodes([atom()]) :: :ok | {:error, bad_nodes}
def connect_nodes(nodes) when is_list(nodes) do
bad_nodes = Enum.reduce(nodes, [], fn n, acc ->
case :net_kernel.connect_node(n) do
true ->
Cluster.Logger.info "connected to #{inspect n}"
acc
reason ->
Cluster.Logger.warn "attempted to connect to node (#{inspect n}), but failed with #{reason}."
[{n, reason}|acc]
end
end)
case bad_nodes do
[] -> :ok
_ -> {:error, bad_nodes}
end
end
end