patternMinor
Erlang concurrency in circles
Viewed 0 times
concurrencyerlangcircles
Problem
I am new to erlang (2 days to be honest) and I would highly appreciate some peer review. I am doing these exercises and was a bit stuck at this point:
2) Write a function which starts N processes in a ring, and sends a
message M times around all the processes in the ring. After the
messages have been sent the processes should terminate gracefully.
With some help from SO, I came up with a working solution, but I am not sure about its quality in any aspect: Language comprehension, Coding style, Efficiency, etc.
I will be grateful for any comment you have.
2) Write a function which starts N processes in a ring, and sends a
message M times around all the processes in the ring. After the
messages have been sent the processes should terminate gracefully.
With some help from SO, I came up with a working solution, but I am not sure about its quality in any aspect: Language comprehension, Coding style, Efficiency, etc.
I will be grateful for any comment you have.
-module (concur).
-export ( [pingCircle/3, pingCircle/2] ).
pingCircle (Names, Message, TTL) ->
Processes = lists:map (fun (Name) -> spawn (?MODULE, pingCircle, [Name, nobody] ) end, Names),
ProcessPairs = lists:zip (Processes, rot1 (Processes) ),
lists:map (fun ( {Process, Recipient} ) -> Process ! {setRecipient, Recipient} end, ProcessPairs),
Circle = lists:map (fun ( {Process, _} ) -> Process end, ProcessPairs),
hd (Circle) ! {Message, TTL - 1, lists:last (Circle) }.
rot1 ( [] ) -> [];
rot1 ( [Head | Tail] ) -> Tail ++ [Head].
pingCircle (Name, Recipient) ->
receive
{setRecipient, NewRecipient} ->
pingCircle (Name, NewRecipient);
{Message, 0, Originator} ->
io:format ("~s received ~p with TTL 0 and dying.~n", [Name, Message] ),
if
Originator == self () -> io:format ("All dead.~n");
true -> Recipient ! {Message, 0, Originator}
end;
{Message, TTL, Originator} ->
io:format ("~s received ~p with TTL ~p.~n", [Name, Message, TTL] ),
if
Originator == self () -> Recipient ! {Message, TTL - 1, Originator};
true -> Recipient ! {Message, TTL, Originator}
end,
pingCircle (Name, Recipient)
end.Solution
You can replace
with
This action allows do not export
It is also recommended to use
spawn (?MODULE, pingCircle, [Name, nobody] )with
spawn (fun() -> pingCircle(Name, nobody) end)This action allows do not export
pingCircle/2 from the module.It is also recommended to use
spawn_link instead of spawn, because it helps to avoid lost processes.Code Snippets
spawn (?MODULE, pingCircle, [Name, nobody] )spawn (fun() -> pingCircle(Name, nobody) end)Context
StackExchange Code Review Q#3745, answer score: 6
Revisions (0)
No revisions yet.