Skip to content

Instantly share code, notes, and snippets.

@mgwidmann
Last active December 20, 2018 17:34
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mgwidmann/8c21fb8e852f04f5e1c9 to your computer and use it in GitHub Desktop.
Save mgwidmann/8c21fb8e852f04f5e1c9 to your computer and use it in GitHub Desktop.
Simple distributed greeting system
# machine 1
# start up with `iex --name m1@127.0.0.1 --cookie greeter`
# This isn't really necessary but it won't hurt anything
Node.connect :"m1@127.0.0.1"
# All `Node.connect/1` calls can go to the same machine and every machine
# in the cluster will automatically be connected.
# machine 2
# start up with `iex --name m2@127.0.0.1 --cookie greeter`
Node.connect :"m1@127.0.0.1"
# machine 3
# start up with `iex --name m3@127.0.0.1 --cookie greeter`
Node.connect :"m1@127.0.0.1"
# Back on machine 1
greeter = fn ->
name = node() |> to_string |> String.split("@") |> List.first
System.cmd "say", ["hello", name]
end
# Everyone says hello at the same time
Node.list |> Enum.each(fn n -> Node.spawn(n, greeter) end)
# Need custom code to make the machines work together
defmodule Greeter do
use GenServer
# Start up pointing at the next greeter in the ring
def start_link(next) do
GenServer.start_link __MODULE__, next
end
def handle_cast(:greet, next) do
name = node() |> to_string |> String.split("@") |> List.first
System.cmd "say", ["Hi my name is", name]
GenServer.cast next, :greet
{:noreply, next}
end
end
# On iex console, grab bytecode (number 33 will vary)
{:module, Greeter, bytecode, _} = v(33)
# Need to load bytecode on all remote machines
# GOTCHA: Ensure to use single quotes when dealing with erlang!
:rpc.multicall :code, :load_binary, [Greeter, 'greeter.ex', bytecode]
# End of the chain will be the current machine
{:ok, greeter_pid} = Greeter.start_link nil
# Start up a greeter on every machine
Node.list |> Enum.reduce(greeter_pid, fn(n, pid)->
me = self
Node.spawn(n, fn ->
{:ok, p} = Greeter.start_link(pid)
send(me, p)
end)
receive do
p -> p
end
end)
# Now to have everyone introduce themselves one after another...
# (number 44 will vary, should be the returned pid from above)
GenServer.cast v(44), :greet
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment