Skip to content

Instantly share code, notes, and snippets.

@szabba
Created July 20, 2016 16:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save szabba/6cac2ae11644d6a402366a044c6931a3 to your computer and use it in GitHub Desktop.
Save szabba/6cac2ae11644d6a402366a044c6931a3 to your computer and use it in GitHub Desktop.
-module(ring).
-export([start/3, member_init/1]).
% RING SETUP
start(N, M, Msg) ->
Pids = spawnN(N, { expecting, M, messages }),
initMembers(Pids),
withHead(
Pids,
fun(First) ->
times(M, fun() ->
io:format("Sending ~w to process ~w.~n", [ Msg, First ]),
First ! { [], Msg }
end),
io:format(
"Sending quit message to process ~w.~n",
[ First ]),
First ! quit
end).
spawnN(N, { expecting, ToSee, messages }) ->
lists:map(
fun(_) -> spawn(?MODULE, member_init, [ ToSee ]) end,
lists:duplicate(N, ok)).
initMembers(Pids) ->
NextPids =
case Pids of
[] -> [];
[ H | T ] -> T ++ [ H ]
end,
lists:foreach(
fun({Pid, Next}) -> Pid ! { next, Next} end,
lists:zip(Pids, NextPids)).
% MEMBER
member_init(ToSee) ->
receive
{ next, Next } ->
io:format(
"Process ~w will forward messages to process ~w.~n",
[ self(), Next ]),
member_loop(ToSee, Next)
end.
member_loop(ToSee, Next) when ToSee > 0 ->
receive
{ Pids, Msg } ->
io:format(
"Process ~w got message ~w.~n",
[ self(), Msg ]),
case lists:member(self(), Pids) of
true ->
io:format(
"Process ~w has already seen this message.~n", [ self() ]),
member_loop(ToSee, Next);
false ->
io:format(
"Process ~w sees the message for the first time. Passing it to ~w.~n",
[ self(), Next ]),
Next ! { [ self() | Pids ], Msg },
member_loop(ToSee - 1, Next)
end
end;
member_loop(0, Next) ->
receive
quit ->
io:format("Process ~w is done!~n", [ self() ]),
io:format(
"Process ~w saw all the messages it was supposed to.~n",
[ self() ]),
Next ! quit,
ok
end.
% HELPERS
withHead([], _) -> ok;
withHead([ H | _ ], F) -> F(H), ok.
times(0, _) -> ok;
times(N, Do) when N > 0 ->
Do(),
times(N - 1, Do).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment