Packages

A distributed, cluster-wide key-value store implemented on the BEAM.

Current section

Files

Jump to
paxos_kv lib mix tasks node.ex
Raw

lib/mix/tasks/node.ex

defmodule Mix.Tasks.Node do
@shortdoc "Starts the node in distributed mode with a numbered node name schema."
@moduledoc """
#{@shortdoc}
Every node has a number started from 0. The name of the nodes gonna be just
simply `:node0`, `:node1`, etc.
It also tries to connect to other nodes that are already alive. For instance,
if you start `:node4` with the `node` task, it will try to connect to
`:node0`, `:node1`, `:node2`, `:node3` and also some nodes like `:node5`,
`:node6`, `:node7` and so on. That means starting `:nodeN` will try to
connect to the previous N nodes and the next N nodes. Starting `:node0` does
not trigger any connections. The `node` task uses long names.
In production you must have a more sophisticated clustering strategy, like
`libcluster`, but for development and testing the `node` task will help you
simplify your daily tasks.
## Usage:
Start an IEx shell in distributed mode with the name `node4`:
```bash
$ iex -S mix node 4
```
Start node number 3 without the IEx shell:
```bash
$ mix node 3
```
"""
use Mix.Task
@impl true
def run([]) do
"Enter a node number:"
|> Mix.shell().prompt()
|> String.trim()
|> List.wrap()
|> run()
end
def run([node_number | rest] = args) do
node_number = String.to_integer(node_number)
System.cmd("epmd", ["-daemon"])
Node.start(node_name(node_number), :longnames)
for i <- 0..(3 * node_number + 2), i != node_number do
Node.connect(node_name(i))
end
Mix.Tasks.Run.run(args(rest))
catch
_, _ ->
Mix.Tasks.Run.run(args(args))
end
defp args(args) do
# if iex?() do
# args
# else
args ++ ["--no-halt"]
# end
end
# defp iex? do
# Code.ensure_loaded?(IEx) and IEx.started?()
# end
def node_name(n) do
{fqdn, _} = System.cmd("hostname", ["-f"])
:"node#{n}@#{String.trim(fqdn)}"
end
end