I have been reading ‘Erlang Programming‘ , like a good student, I decided to solve the ring exercise:
Here is the problem in my words:
Create a linked list of N Ring where each Ring is an erlang process. When you pass a message to the head Ring , it should propagate the message to the next Ring and that propagates to the next ring and so on. I added additional clause — “Each ring should report its successful message delivery to the previous ring and the previous ring should print successful message delivery from its child rings.
Here is the code:
-module(ring). -compile(export_all). createRing(N) -> Self = self(), Head = spawn(fun() -> ring(N, Self) end), Head. ring(N, PreviousRing) when N > 0 -> Self = self(), io:format('~w #ring created PID: [~w] ListenerPid: [~w] ~n',[N, Self, PreviousRing]), NextRing = spawn(fun() -> ring(N-1 , Self) end), loop(N ,NextRing, PreviousRing); ring(N, PreviousRing) -> io:format('last ring reached! ~w ~n',[N]), NullRing = spawn(fun() -> receive Any -> io:format('dummy ring received ~w ~n', Any) end end), loop(N, NullRing, PreviousRing). loop(N, NextRing, PreviousRing) -> receive {send_message, Message} -> io:format('ring # ~w with pid: #~w received ~w ~n',[N, self(), Message]), NextRing ! {send_message, Message}, PreviousRing ! {ok, self()}, loop(N, NextRing, PreviousRing); {ok, NextRing} -> io:format('~w with pid# ~w successfully sent message ~n',[N-1, NextRing]), loop(N, NextRing, PreviousRing); {quit} -> io:format('quiting ring: ~w with Pid: ~w ~n',[N, self()]) end. sendMessage(Head, M) when M > 0 -> Head ! {send_message, M}, sendMessage(Head, M - 1); sendMessage(Head, M) -> io:format('sending last message ~n'), Head ! {send_message, M}.
I have had my share of multi-threaded programming in Java, thanks to the telephony applications I’v worked on. Just imagine the pain you would have to go through to implement this in Java / C++ !