Current section
Files
Jump to
Current section
Files
lib/manager.ex
#
# Distribunator.Manager
defmodule Distribunator.Manager do
@moduledoc """
The Distribunator.Manager:
1. Makes sure all distributed nodes are `Node.connect()`ed
"""
use GenServer
require Distribunator.Distributed
##############################
# API
##############################
def start_link(absent_nodes \\ []) do
GenServer.start_link(__MODULE__, absent_nodes, [name: __MODULE__])
end
defmodule State do
@moduledoc false
defstruct [
absent_nodes: [],
]
end
##############################
# GenServer Callbacks
##############################
def init(absent_nodes) do
Distribunator.Distributed.register()
send(self(), :reconcile)
{:ok, %State{absent_nodes: absent_nodes}}
end
def handle_info(:reconcile, state) do
{:noreply, do_reconcile(state)}
end
def handle_info({:nodedown, n}, state) do
new_absent_nodes = [n| state.absent_nodes] |> Enum.uniq()
Process.send_after(self(), :reconcile, 5_000)
new_state = Map.put(state, :absent_nodes, new_absent_nodes)
{:noreply, new_state}
end
##############################
# Internal Calls
##############################
def do_reconcile(state) do
new_absent_nodes = Enum.reject(state.absent_nodes, fn(n) ->
Node.connect(n) && Node.monitor(n, true)
end)
if Enum.any?(new_absent_nodes) do
Process.send_after(self(), :reconcile, 5_000)
end
Map.put(state, :absent_nodes, new_absent_nodes)
end
end