Last active
December 26, 2015 02:09
-
-
Save rubysolo/7075970 to your computer and use it in GitHub Desktop.
Ring of message passing processes in Elixir (see http://benjamintanweihao.github.io/blog/2013/10/09/elixir-by-example-ring/)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule Ring do | |
def run(member_count, loop_count, message) do | |
log(:ringleader, "building ring with #{ member_count - 1 } more nodes...") | |
next_pid = spawn_link(__MODULE__, :build_ring, [member_count - 2, self]) | |
log(:ringleader, "sending initial message to #{ inspect(next_pid) }...") | |
next_pid <- {:message, message, loop_count} | |
message_loop(next_pid) | |
end | |
def message_loop(next_pid) do | |
receive do | |
{:message, message, 0} -> | |
log(:ringleader, "got last message: #{ message }; terminating...") | |
:ok | |
{:message, message, m} -> | |
log(:ringleader, "got message: #{ message }; forwarding to #{ inspect(next_pid) }; #{ m - 1 } loops to go...") | |
next_pid <- {:message, message, m - 1} | |
message_loop(next_pid) | |
end | |
end | |
def relay(next_pid) do | |
receive do | |
{:message, message, m} -> | |
log(:node, "got message: #{ message }; forwarding to #{ inspect(next_pid) }") | |
next_pid <- {:message, message, m} | |
if m > 0, do: relay(next_pid) | |
end | |
:ok | |
end | |
def build_ring(0, ringleader_pid) do | |
log(:final, "ring is complete; connecting back to ringleader (#{ inspect(ringleader_pid) })") | |
relay(ringleader_pid) | |
end | |
def build_ring(remaining, ringleader_pid) do | |
log(:node, "extending ring; #{ remaining } more nodes to go...") | |
next = spawn_link(__MODULE__, :build_ring, [remaining - 1, ringleader_pid]) | |
relay(next) | |
end | |
def log(role, message) do | |
IO.puts "[#{ inspect(self) }][#{ role }] #{ message }" | |
end | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
iex(1)> Ring.run 5, 3, "hello" | |
[#PID<0.41.0>][ringleader] building ring with 4 more nodes... | |
[#PID<0.41.0>][ringleader] sending initial message to #PID<0.44.0>... | |
[#PID<0.44.0>][node] extending ring; 3 more nodes to go... | |
[#PID<0.44.0>][node] got message: hello; forwarding to #PID<0.45.0> | |
[#PID<0.45.0>][node] extending ring; 2 more nodes to go... | |
[#PID<0.45.0>][node] got message: hello; forwarding to #PID<0.46.0> | |
[#PID<0.46.0>][node] extending ring; 1 more nodes to go... | |
[#PID<0.46.0>][node] got message: hello; forwarding to #PID<0.47.0> | |
[#PID<0.47.0>][final] ring is complete; connecting back to ringleader (#PID<0.41.0>) | |
[#PID<0.47.0>][node] got message: hello; forwarding to #PID<0.41.0> | |
[#PID<0.41.0>][ringleader] got message: hello; forwarding to #PID<0.44.0>; 2 loops to go... | |
[#PID<0.44.0>][node] got message: hello; forwarding to #PID<0.45.0> | |
[#PID<0.45.0>][node] got message: hello; forwarding to #PID<0.46.0> | |
[#PID<0.46.0>][node] got message: hello; forwarding to #PID<0.47.0> | |
[#PID<0.47.0>][node] got message: hello; forwarding to #PID<0.41.0> | |
[#PID<0.41.0>][ringleader] got message: hello; forwarding to #PID<0.44.0>; 1 loops to go... | |
[#PID<0.44.0>][node] got message: hello; forwarding to #PID<0.45.0> | |
[#PID<0.45.0>][node] got message: hello; forwarding to #PID<0.46.0> | |
[#PID<0.46.0>][node] got message: hello; forwarding to #PID<0.47.0> | |
[#PID<0.47.0>][node] got message: hello; forwarding to #PID<0.41.0> | |
[#PID<0.41.0>][ringleader] got message: hello; forwarding to #PID<0.44.0>; 0 loops to go... | |
[#PID<0.44.0>][node] got message: hello; forwarding to #PID<0.45.0> | |
[#PID<0.45.0>][node] got message: hello; forwarding to #PID<0.46.0> | |
[#PID<0.46.0>][node] got message: hello; forwarding to #PID<0.47.0> | |
[#PID<0.47.0>][node] got message: hello; forwarding to #PID<0.41.0> | |
[#PID<0.41.0>][ringleader] got last message: hello; terminating... | |
:ok |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment