Created
July 15, 2012 16:15
-
-
Save kuniyoshi/3117602 to your computer and use it in GitHub Desktop.
now learning Erlang's relaying message process to process.
This file contains 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
-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. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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>