Skip to content

Instantly share code, notes, and snippets.

@kuniyoshi
Created July 15, 2012 16:15
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 kuniyoshi/3117602 to your computer and use it in GitHub Desktop.
Save kuniyoshi/3117602 to your computer and use it in GitHub Desktop.
now learning Erlang's relaying message process to process.
-module(rmessage).
%-compile(export_all).
-export([start/1, stop/0, chain/2, loop/1, init/1]).
%% for interface
start(Count) ->
io:format("start, count[~p].~n", [Count]),
[FirstPid | _] = make_pids(Count),
register(?MODULE, spawn(?MODULE, loop, [FirstPid])).
stop() ->
io:format("stop, ~s.~n", [?MODULE]),
?MODULE ! stop,
unregister(?MODULE).
make_pids(Count) ->
io:format("make_pids, count[~p].~n", [Count]),
make_pids(Count, []).
make_pids(0, Pids) ->
io:format("make_pids, no more pid.~n"),
Pids;
make_pids(Count, []) ->
io:format("make_pids, spawn last.~n"),
Pid = spawn(?MODULE, init, [{last}]),
make_pids(Count - 1, [Pid]);
make_pids(Count, [Last | []]) ->
io:format("make_pids, spawn booby.~n"),
Pid = spawn(?MODULE, init, [{remain, Last}]),
make_pids(Count - 1, [Pid, Last]);
make_pids(Count, [After | Pids]) ->
io:format("make_pids, spawn remain ~p.~n", [Count]),
Pid = spawn(?MODULE, init, [{remain, After}]),
make_pids(Count - 1, [Pid, After | Pids]).
chain(Message, Count) ->
rpc({chain_message, Message, Count}).
rpc({chain_message, _, _}=T) ->
?MODULE ! T.
loop(Pid) ->
receive
{chain_message, Message, Count} ->
chain_message(Pid, Message, Count),
loop(Pid);
stop ->
Pid ! stop
end.
chain_message(_, Message, 0) ->
{chain_message, Message};
chain_message(Pid, Message, Count) ->
Self = self(),
Pid ! {relay, Message, Self},
receive
{done, Self} -> ok
end,
chain_message(Pid, Message, Count - 1).
%% for kids
init({last}) ->
relay(last);
init({remain, After}) ->
relay(After).
relay(last) ->
receive
{relay, Message, From} ->
io:format("relay, receive last.~n"),
echo(Message),
From ! {done, From},
relay(last);
stop ->
io:format("relay, stop last.~n")
end;
relay(After) ->
receive
{relay, Message, From} ->
Self = self(),
echo(Message),
After ! {relay, Message, Self},
receive
{done, Self} ->
io:format("relay, done ~p.~n", [Self]),
ok
end,
From ! {done, From},
relay(After);
stop ->
io:format("relay, stop ~p.~n", [self()]),
After ! stop
end.
echo(M) ->
io:format("echo, ~s.~n", [M]),
M.
@kuniyoshi
Copy link
Author

example of output.

109> c(rmessage).
{ok,rmessage}
110> rmessage:start(3).
start, count[3].
make_pids, count[3].
make_pids, spawn last.
make_pids, spawn booby.
make_pids, spawn remain 1.
make_pids, no more pid.
true
111> rmessage:chain(foo_bar_baz, 2).
echo, foo_bar_baz.
{chain_message,foo_bar_baz,2}
echo, foo_bar_baz.
relay, receive last.
echo, foo_bar_baz.
relay, done <0.21947.0>.
relay, done <0.21948.0>.
echo, foo_bar_baz.
echo, foo_bar_baz.
relay, receive last.
echo, foo_bar_baz.
relay, done <0.21947.0>.
relay, done <0.21948.0>.
112> rmessage:stop().
stop, rmessage.
relay, stop <0.21948.0>.
true
relay, stop <0.21947.0>.
relay, stop last.
113>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment