Skip to content

Commit ee88753

Browse files
committed
simple cluster
0 parents  commit ee88753

File tree

11 files changed

+186
-0
lines changed

11 files changed

+186
-0
lines changed

simple_cluster/.formatter.exs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Used by "mix format"
2+
[
3+
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
4+
]

simple_cluster/.gitignore

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# The directory Mix will write compiled artifacts to.
2+
/_build/
3+
4+
# If you run "mix test --cover", coverage assets end up here.
5+
/cover/
6+
7+
# The directory Mix downloads your dependencies sources to.
8+
/deps/
9+
10+
# Where third-party dependencies like ExDoc output generated docs.
11+
/doc/
12+
13+
# Ignore .fetch files in case you like to edit your project deps locally.
14+
/.fetch
15+
16+
# If the VM crashes, it generates a dump, let's ignore it too.
17+
erl_crash.dump
18+
19+
# Also ignore archive artifacts (built via "mix archive.build").
20+
*.ez
21+
22+
# Ignore package tarball (built via "mix hex.build").
23+
simple_cluster-*.tar
24+
25+
26+
# Temporary files for e.g. tests
27+
/tmp

simple_cluster/README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# SimpleCluster
2+
3+
**TODO: Add description**
4+
5+
## Installation
6+
7+
If [available in Hex](https://hex.pm/docs/publish), the package can be installed
8+
by adding `simple_cluster` to your list of dependencies in `mix.exs`:
9+
10+
```elixir
11+
def deps do
12+
[
13+
{:simple_cluster, "~> 0.1.0"}
14+
]
15+
end
16+
```
17+
18+
Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc)
19+
and published on [HexDocs](https://hexdocs.pm). Once published, the docs can
20+
be found at [https://hexdocs.pm/simple_cluster](https://hexdocs.pm/simple_cluster).
21+

simple_cluster/lib/simple_cluster.ex

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
defmodule SimpleCluster do
2+
defdelegate ping, to: SimpleCluster.Ping
3+
end
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
defmodule SimpleCluster.Application do
2+
# See https://hexdocs.pm/elixir/Application.html
3+
# for more information on OTP Applications
4+
@moduledoc false
5+
6+
use Application
7+
8+
@impl true
9+
def start(_type, _args) do
10+
children = [
11+
SimpleCluster.Observer,
12+
SimpleCluster.Ping
13+
]
14+
15+
# See https://hexdocs.pm/elixir/Supervisor.html
16+
# for other strategies and supported options
17+
opts = [strategy: :one_for_one, name: SimpleCluster.Supervisor]
18+
Supervisor.start_link(children, opts)
19+
end
20+
end
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
defmodule SimpleCluster.Observer do
2+
@moduledoc """
3+
Simple process that monitors node changes in the
4+
current cluster.
5+
"""
6+
7+
use GenServer
8+
9+
require Logger
10+
11+
def start_link(_), do: GenServer.start_link(__MODULE__, Map.new())
12+
13+
@impl GenServer
14+
def init(state) do
15+
:net_kernel.monitor_nodes(true)
16+
17+
{:ok, state}
18+
end
19+
20+
@impl GenServer
21+
def handle_info({:nodedown, node}, state) do
22+
# A node left the cluster
23+
Logger.info("--- Node down: #{node}")
24+
25+
{:noreply, state}
26+
end
27+
28+
def handle_info({:nodeup, node}, state) do
29+
# A new node joined the cluster
30+
Logger.info("--- Node up: #{node}")
31+
32+
{:noreply, state}
33+
end
34+
end
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
defmodule SimpleCluster.Ping do
2+
@moduledoc """
3+
Process which listens to `:ping` messages from other
4+
nodes and responds with `:pong`.
5+
"""
6+
7+
use GenServer
8+
require Logger
9+
10+
def start_link(_) do
11+
GenServer.start_link(__MODULE__, Map.new(), name: __MODULE__)
12+
end
13+
14+
@doc """
15+
Takes all the existing nodes in the cluster and sends
16+
a `:ping` message to them, logging the result.
17+
"""
18+
def ping do
19+
Node.list()
20+
|> Enum.map(&GenServer.call({__MODULE__, &1}, :ping))
21+
|> Logger.info()
22+
end
23+
24+
@impl GenServer
25+
def init(state), do: {:ok, state}
26+
27+
@impl GenServer
28+
def handle_call(:ping, from, state) do
29+
Logger.info("--- Receiving ping from #{inspect(from)}")
30+
31+
{:reply, {:ok, node(), :pong}, state}
32+
end
33+
end

simple_cluster/mix.exs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
defmodule SimpleCluster.MixProject do
2+
use Mix.Project
3+
4+
def project do
5+
[
6+
app: :simple_cluster,
7+
version: "0.1.0",
8+
elixir: "~> 1.11",
9+
start_permanent: Mix.env() == :prod,
10+
deps: deps()
11+
]
12+
end
13+
14+
# Run "mix help compile.app" to learn about applications.
15+
def application do
16+
[
17+
extra_applications: [:logger],
18+
mod: {SimpleCluster.Application, []}
19+
]
20+
end
21+
22+
# Run "mix help deps" to learn about dependencies.
23+
defp deps do
24+
[
25+
# {:dep_from_hexpm, "~> 0.3.0"},
26+
# {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
27+
]
28+
end
29+
end

simple_cluster/sys.config

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[{kernel,
2+
[
3+
{sync_nodes_optional, ['n1@127.0.0.1', 'n2@127.0.0.1']},
4+
{sync_nodes_timeout, 5000}
5+
]}
6+
].
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
defmodule SimpleClusterTest do
2+
use ExUnit.Case
3+
doctest SimpleCluster
4+
5+
test "greets the world" do
6+
assert SimpleCluster.hello() == :world
7+
end
8+
end

simple_cluster/test/test_helper.exs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ExUnit.start()

0 commit comments

Comments
 (0)