Pass Data between two Nodes erlang - process

I have recently started learning Erlang and I am trying to implement a server-client sample program. I have created a registered process and I would like to send data to it from another process. The code is as follows.
-module(mine).
-export([alice/0, bob/2, startAlice/0, startBob/1]).
alice() ->
receive
{message, BobNode} ->
io:fwrite("Alice got a message \n"),
BobNode ! message,
alice()
finished -> io:fwrite("Alice is finished\n")
end.
bob(0, AliceNode) ->
{alice, AliceNode} ! finished,
io:fwrite("Bob is finished\n");
bob(N, AliceNode) ->
{alice, AliceNode} ! {message, self()},
receive
message -> io:fwrite("Bob got a message ~w \n",[N])
end,
bob(N-1, AliceNode).
startAlice() ->
register(alice, spawn(mine, alice, [])).
startBob(AliceNode) ->
spawn(mine, bob, [30000, AliceNode]).
Here, I would like to send some value say N, from bob to alice. I tried sending the data as
{alice, AliceNode, Nvalue} ! {message, self(), N} in bob(N, AliceNode) function, but got the error variable 'Nvalue' is unbound erl. I am sure I am missing something trivial here. Any help would be appreciated. Thanks in advance.

Related

Wait on the reply of a process Erlang

Is it possible to spawn a process p in a function funct1 of a module module1, to send a message to p in a function funct2 of module1 and to wait for a reply of p inside funct2, without having to spawn f2 that is therefore considered as self()? If so, what is the best way to implement the waiting part? You can see the code below to have an overview of what I am looking for.
Thanks in advance.
-module(module1)
...
funct1(...)
->
Pid = spawn(module2, function3, [[my_data]]),
...
funct2(...)
->
...
Pid ! {self(), {data1, data2}},
% wait here for the reply from Pid
% do something here based on the reply.
The Answer
Yes.
The Real Problem
You are conflating three concepts:
Process (who is self() and what is pid())
Function
Module
A process is a living thing. A process has its own memory space. These processes are the things making calls. This is the only identity that really matters. When you think about "who is self() in this case" you are really asking "what is the calling context?" If I spawn two instances of a process, they both might call the same function at some point in their lives -- but the context of those calls are completely different because the processes have their own lives and their own memory spaces. Just because Victor and Victoria are both jumping rope at the same time doesn't make them the same person.
Where people get mixed up about calling context the most is when writing module interface functions. Most modules are, for the sake of simplicity, written in a way that they define just a single process. There is no rule that mandates this, but it is pretty easy to understand what a module does when it is written this way. Interface functions are exported and available for any process to call -- and they are calling in the context of the processes calling them, not in the context of a process spawned to "be an instance of that module" and run the service loop defined therein.
There is nothing trapping a process "within" that module, though. I could write a pair of modules, one that defines the AI of a lion and another that defines the AI of a shark, and have a process essentially switch identities in the middle of its execution -- but this is almost always a really bad idea (because it gets confusing).
Functions are just functions. That's all they are. Modules are composed of functions. There is nothing more to say than this.
How to wait for a message
We wait for messages using the receive construct. It matches on the received message (which will always be an Erlang term) and selects what to do based on the shape and/or content of the message.
Read the following very carefully:
1> Talker =
1> fun T() ->
1> receive
1> {tell, Pid, Message} ->
1> ok = io:format("~p: sending ~p message ~p~n", [self(), Pid, Message]),
1> Pid ! {message, Message, self()},
1> T();
1> {message, Message, From} ->
1> ok = io:format("~p: from ~p received message ~p~n", [self(), From, Message]),
1> T();
1> exit ->
1> exit(normal)
1> end
1> end.
#Fun<erl_eval.44.87737649>
2> {Pid1, Ref1} = spawn_monitor(Talker).
{<0.64.0>,#Ref<0.1042362935.2208301058.9128>}
3> {Pid2, Ref2} = spawn_monitor(Talker).
{<0.69.0>,#Ref<0.1042362935.2208301058.9139>}
4> Pid1 ! {tell, Pid2, "A CAPITALIZED MESSAGE! RAAAR!"}.
<0.64.0>: sending <0.69.0> message "A CAPITALIZED MESSAGE! RAAAR!"
{tell,<0.69.0>,"A CAPITALIZED MESSAGE! RAAAR!"}
<0.69.0>: from <0.64.0> received message "A CAPITALIZED MESSAGE! RAAAR!"
5> Pid2 ! {tell, Pid1, "a lower cased message..."}.
<0.69.0>: sending <0.64.0> message "a lower cased message..."
{tell,<0.64.0>,"a lower cased message..."}
<0.64.0>: from <0.69.0> received message "a lower cased message..."
6> Pid1 ! {tell, Pid1, "Sending myself a message!"}.
<0.64.0>: sending <0.64.0> message "Sending myself a message!"
{tell,<0.64.0>,"Sending myself a message!"}
<0.64.0>: from <0.64.0> received message "Sending myself a message!"
7> Pid1 ! {message, "A direct message from the shell", self()}.
<0.64.0>: from <0.67.0> received message "A direct message from the shell"
{message,"A direct message from the shell",<0.67.0>}
A standalone example
Now consider this escript of a ping-pong service. Notice there is only one kind of talker defined inside and it knows how to deal with target, ping and pong messages.
#! /usr/bin/env escript
-mode(compile).
main([CountString]) ->
Count = list_to_integer(CountString),
ok = io:format("~p: Starting pingpong script. Will iterate ~p times.~n", [self(), Count]),
P1 = spawn_link(fun talker/0),
P2 = spawn_link(fun talker/0),
pingpong(Count, P1, P2).
pingpong(Count, P1, P2) when Count > 0 ->
P1 ! {target, P2},
P2 ! {target, P1},
pingpong(Count - 1, P1, P2);
pingpong(_, P1, P2) ->
_ = erlang:send_after(1000, P1, {exit, self()}),
_ = erlang:send_after(1000, P2, {exit, self()}),
wait_for_exit([P1, P2]).
wait_for_exit([]) ->
ok = io:format("~p: All done, Returing.~n", [self()]),
halt(0);
wait_for_exit(Pids) ->
receive
{exiting, Pid} ->
ok = io:format("~p: ~p is done.~n", [self(), Pid]),
NewPids = lists:delete(Pid, Pids),
wait_for_exit(NewPids)
end.
talker() ->
receive
{target, Pid} ->
ok = io:format("~p: Sending ping to ~p~n", [self(), Pid]),
Pid ! {ping, self()},
talker();
{ping, From} ->
ok = io:format("~p: Received ping from ~p. Replying with pong.~n", [self(), From]),
From ! pong,
talker();
pong ->
ok = io:format("~p: Received pong.~n", [self()]),
talker();
{exit, From} ->
ok = io:format("~p: Received exit message from ~p. Retiring.~n", [self(), From]),
From ! {exiting, self()}
end.
There are some details there, like use of erlang:send_after/3 that are used because message sending is so fast that it will beat the speed of the calls to io:format/2 that slow down the actual talker processes and result in a weird situation where the exit messages (usually) arrive before the pings and pongs between the two talkers.
Here is what happens when it is run:
ceverett#changa:~/Code/erlang$ ./pingpong 2
<0.5.0>: Starting pingpong script. Will iterate 2 times.
<0.61.0>: Sending ping to <0.62.0>
<0.62.0>: Sending ping to <0.61.0>
<0.61.0>: Sending ping to <0.62.0>
<0.62.0>: Sending ping to <0.61.0>
<0.61.0>: Received ping from <0.62.0>. Replying with pong.
<0.62.0>: Received ping from <0.61.0>. Replying with pong.
<0.61.0>: Received ping from <0.62.0>. Replying with pong.
<0.62.0>: Received ping from <0.61.0>. Replying with pong.
<0.61.0>: Received pong.
<0.62.0>: Received pong.
<0.61.0>: Received pong.
<0.62.0>: Received pong.
<0.61.0>: Received exit message from <0.5.0>. Retiring.
<0.62.0>: Received exit message from <0.5.0>. Retiring.
<0.5.0>: <0.61.0> is done.
<0.5.0>: <0.62.0> is done.
<0.5.0>: All done, Returing.
If you run it a few times (or on a busy runtime) there is a chance that some of the output will be in different order. That is just the nature of concurrency.
If you are new to Erlang the above code might take a while to sink in. Play with that pingpong script yourself. Edit it. Make it do new things. Create a triangle of pinging processes. Spawn a random circuit of talkers that do weird things. This will make sense suddenly once you mess around with it.

How to print a message within a process when it gets the right from another process in erlang?

I'm all new to erlang, and i got this task:
Write a function "setalarm(T,Message)" what starts two processes at
the same time. After T miliseconds the first process sends a message
to the second process, and that message will be the Message arg.
It's forbidden to use function library, only primitives (send, receive, spawn)
Me as a novice useful to write more code, so I suggest such an option:
setalarm(T,Message)->
S = spawn(sotest,second,[]),
Pid = spawn(sotest,first,[S,T,Message]).
first(Pid,T,Message) ->
receive
after T -> Pid ! Message
end.
second() ->
receive
Message -> io:format("The message is ~p~n",[Message])
end.

eunit: How to test a simple process?

I'm currently writing a test for a module that runs in a simple process started with spawn_link(?MODULE, init, [self()]).
In my eunit tests, I have a setup and teardown function defined and a set of test generators.
all_tests_test_() ->
{inorder, {
foreach,
fun setup/0,
fun teardown/1,
[
fun my_test/1
]}
}.
The setup fun creates the process-under-test:
setup() ->
{ok, Pid} = protocol:start_link(),
process_flag(trap_exit,true),
error_logger:info_msg("[~p] Setting up process ~p~n", [self(), Pid]),
Pid.
The test looks like this:
my_test(Pid) ->
[ fun() ->
error_logger:info_msg("[~p] Sending to ~p~n", [self(), Pid]),
Pid ! something,
receive
Msg -> ?assertMatch(expected_result, Msg)
after
500 -> ?assert(false)
end
end ].
Most of my modules are gen_server but for this I figured it'll be easier without all gen_server boilerplate code...
The output from the test looks like this:
=INFO REPORT==== 31-Mar-2014::21:20:12 ===
[<0.117.0>] Setting up process <0.122.0>
=INFO REPORT==== 31-Mar-2014::21:20:12 ===
[<0.124.0>] Sending to <0.122.0>
=INFO REPORT==== 31-Mar-2014::21:20:12 ===
[<0.122.0>] Sending expected_result to <0.117.0>
protocol_test: my_test...*failed*
in function protocol_test:'-my_test/1-fun-0-'/0 (test/protocol_test.erl, line 37)
**error:{assertion_failed,[{module,protocol_test},
{line,37},
{expression,"false"},
{expected,true},
{value,false}]}
From the Pids you can see that whatever process was running setup (117) was not the same that was running the test case (124). The process under test however is the same (122). This results in a failing test case because the receive never gets the message und runs into the timeout.
Is that the expected behaviour that a new process gets spawned by eunit to run the test case?
An generally, is there a better way to test a process or other asynchronous behaviour (like casts)? Or would you suggest to always use gen_server to have a synchronous interface?
Thanks!
[EDIT]
To clarify, how protocol knows about the process, this is the start_link/0 fun:
start_link() ->
Pid = spawn_link(?MODULE, init, [self()]),
{ok, Pid}.
The protocol ist tightly linked to the caller. If the either of them crashes I want the other one to die as well. I know I could use gen_server and supervisors and actually it did that in parts of the application, but for this module, I thought it was a bit over the top.
did you try:
all_tests_test_() ->
{inorder, {
foreach,
local,
fun setup/0,
fun teardown/1,
[
fun my_test/1
]}
}.
From the doc, it seems to be what you need.
simple solution
Just like in Pascal answer, adding the local flag to test description might solve some your problem, but it will probably cause you some additional problems in future, especially when you link yourself to created process.
testing processes
General practice in Erlang is that while process abstraction is crucial for writing (designing and thinking about) programs, it is not something that you would expose to user of your code (even if it is you). Instead expecting someone to send you message with proper data, you wrap it in function call
get_me_some_expected_result(Pid) ->
Pid ! something,
receive
Msg ->
Msg
after 500
timeouted
end
and then test this function rather than receiving something "by hand".
To distinguish real timeout from received timeouted atom, one can use some pattern matching, and let it fail in case of error
get_me_some_expected_result(Pid) ->
Pid ! something,
receive
Msg ->
{ok, Msg}
after 500
timeouted
end
in_my_test() ->
{ok, ValueToBeTested} = get_me_some_expected_result().
In addition, since your process could receive many different messages in meantime, you can make sure that you receive what you think you receive with little pattern-matching and local reference
get_me_some_expected_result(Pid) ->
Ref = make_ref(),
Pid ! {something, Ref},
receive
{Ref, Msg} ->
{ok, Msg}
after 500
timeouted
end
And now receive will ignore (leave for leter) all messages that will not have same Reg that you send to your process.
major concern
One thing that I do not really understand, is how does process you are testing know where to send back received message? Only logical solution would be getting pid of it's creator during initialization (call to self/0 inside protocol:start_link/0 function). But then our new process can communicate only with it's creator, which might not be something you expect, and which is not how tests are run.
So simplest solution would be sending "return address" with each call; which again could be done in our wrapping function.
get_me_some_expected_result(Pid) ->
Ref = make_ref(),
Pid ! {something, Ref, self()},
receive
{Ref, Msg} ->
{ok, Msg}
after 500
timeouted
end
Again, anyone who will use this get_me_some_expected_result/1 function will not have to worry about message passing, and testing such functions makes thing extremely easier.
Hope this helps at least a little.
Maybe it's simply because you are using the foreach EUnit fixture in place of the setup one.
There, try the setup fixture: the one that uses {setup, Setup, Cleanup, Tests} instead of {inorder, {foreach, …}}

Erlang process event error

I'm basically following the tutorial on this site Learn you some Erlang:Designing a concurrent application and I tried to run the code below with the following commands and got an error on line 48. I did turn off my firewall just in case that was the problem but no luck. I'm on windows xp SP3.
9> c(event).
{ok,event}
10> f().
ok
11> event:start("Event",0).
=ERROR REPORT==== 9-Feb-2013::15:05:07 ===
Error in process <0.61.0> with exit value: {function_clause,[{event,time_to_go,[0],[{file,"event.erl"},{line,48}]},{event,init,3,[{file,"event.erl"},{line,31}]}]}
<0.61.0>
12>
-module(event).
-export([start/2, start_link/2, cancel/1]).
-export([init/3, loop/1]).
-record(state, {server,
name="",
to_go=0}).
%%% Public interface
start(EventName, DateTime) ->
spawn(?MODULE, init, [self(), EventName, DateTime]).
start_link(EventName, DateTime) ->
spawn_link(?MODULE, init, [self(), EventName, DateTime]).
cancel(Pid) ->
%% Monitor in case the process is already dead
Ref = erlang:monitor(process, Pid),
Pid ! {self(), Ref, cancel},
receive
{Ref, ok} ->
erlang:demonitor(Ref, [flush]),
ok;
{'DOWN', Ref, process, Pid, _Reason} ->
ok
end.
%%% Event's innards
init(Server, EventName, DateTime) ->
loop(#state{server=Server,
name=EventName,
to_go=time_to_go(DateTime)}).
%% Loop uses a list for times in order to go around the ~49 days limit
%% on timeouts.
loop(S = #state{server=Server, to_go=[T|Next]}) ->
receive
{Server, Ref, cancel} ->
Server ! {Ref, ok}
after T*1000 ->
if Next =:= [] ->
Server ! {done, S#state.name};
Next =/= [] ->
loop(S#state{to_go=Next})
end
end.
%%% private functions
time_to_go(TimeOut={{_,_,_}, {_,_,_}}) ->
Now = calendar:local_time(),
ToGo = calendar:datetime_to_gregorian_seconds(TimeOut) -
calendar:datetime_to_gregorian_seconds(Now),
Secs = if ToGo > 0 -> ToGo;
ToGo =< 0 -> 0
end,
normalize(Secs).
%% Because Erlang is limited to about 49 days (49*24*60*60*1000) in
%% milliseconds, the following function is used
normalize(N) ->
Limit = 49*24*60*60,
[N rem Limit | lists:duplicate(N div Limit, Limit)].
It's running purely locally on your machine so the firewall will not affect it.
The problem is the second argument you gave when you started it event:start("Event",0).
The error reason:
{function_clause,[{event,time_to_go,[0],[{file,"event.erl"},{line,48}]},{event,init,3,[{file,"event.erl"},{line,31}]}]}
says that it is a function_clause error which means that there was no clause in the function definition which matched the arguments. It also tells you that it was the function event:time_to_go/1 on line 48 which failed and that it was called with the argument 0.
It you look at the function time_to_go/ you will see that it expects its argument to be a tuple of 2 elements where each element is a tuple of 3 elements:
time_to_go(TimeOut={{_,_,_}, {_,_,_}}) ->
The structure of this argument is {{Year,Month,Day},{Hour,Minute,Second}}. If you follow this argument backwards you that time_to_go/ is called from init/3 where the argument to time_to_go/1, DateTime, is the 3rd argument to init/3. Almost there now. Now init/3 is the function which the process spawned in start/2 (and start_link/2) and the 3rd argument toinit/3is the second argument tostart/2`.
So when you call event:start("Event",0). it is the 0 here which is passed into the call time_to_go/1 function in the new peocess. And the format is wrong. You should be calling it with something like event:start("Event", {{2013,3,24},{17,53,62}}).
To add background to rvirding's answer, you get the error because the
example works up until the final code snippet as far
as I know. The normalize function is used first, which deals with the
problem. Then the paragraph right after the example in the question
above, the text says:
And it works! The last thing annoying with the event module is that we
have to input the time left in seconds. It would be much better if we
could use a standard format such as Erlang's datetime ({{Year, Month,
Day}, {Hour, Minute, Second}}). Just add the following function that
will calculate the difference between the current time on your
computer and the delay you inserted:
The next snippet introduces the code bit that takes only a date/time and
changes it to the final time left.
I could not easily link to all transitional versions of the file, which
is why trying the linked file directly with the example doesn't work
super easily in this case. If the code is followed step by step, snippet
by snippet, everything should work fine. Sorry for the confusion.

Can a process have two receive blocks

My working environment is Erlang.
Can a process having 2 different functions have two receive blocks in the different functions.
receive
....
end.
request()
PID!(message)
%% Can i get the reply back here instead of the receive block above?
Yes, you can have many receive expressions. When one is evaluated it will take the first matching message out of the message queue/mailbox (take your pick of names) and leave the rest for the next receive. Sending a message, using the Pid ! Message syntax (the only way), is completely asynchronous and just adds the message to the end of the receiving processes message queue. receive is the only way to receive messages i.e. take them out of the message queue. You can never put them back.
There is no built-in synchronous message passing in Erlang, it is one by sending two messages:
The "requesting" process sends a message to the receiving process and then goes into a receive to wait for the reply.
The "receiving" process will itself get the message in a receive, process it, send the reply message back the the "requesting" process and then go into a receive to sit and wait for the next message.
Remember there is no inherent connection between processes, ever, and all communication is done using asynchronous message sending and receive.
So in reply to your second question: you can ONLY get a reply back in a receive expression. That is the only way!
Sorry to be a bit pedantic but Erlang doesn't have either blocks or statements. It is a functional language and only has expressions which always return a value even if the return value is sometimes ignored.
Of couse, you can.
Receives messages sent to the process using the send operator (!). The
patterns Pattern are sequentially matched against the first message in
time order in the mailbox, then the second, and so on. If a match
succeeds and the optional guard sequence GuardSeq is true, the
corresponding Body is evaluated. The matching message is consumed,
that is removed from the mailbox, while any other messages in the
mailbox remain unchanged.
The following code is from supervisor2.erl of rabbitmq project. It even uses nested receive statement. I have marked nested receive below.
terminate_simple_children(Child, Dynamics, SupName) ->
Pids = dict:fold(fun (Pid, _Args, Pids) ->
erlang:monitor(process, Pid),
unlink(Pid),
exit(Pid, child_exit_reason(Child)),
[Pid | Pids]
end, [], Dynamics),
TimeoutMsg = {timeout, make_ref()},
TRef = timeout_start(Child, TimeoutMsg),
{Replies, Timedout} =
lists:foldl(
fun (_Pid, {Replies, Timedout}) ->
{Reply, Timedout1} =
receive %% attention here
TimeoutMsg ->
Remaining = Pids -- [P || {P, _} <- Replies],
[exit(P, kill) || P <- Remaining],
receive {'DOWN', _MRef, process, Pid, Reason} -> %%attention here
{{error, Reason}, true}
end;
{'DOWN', _MRef, process, Pid, Reason} ->
{child_res(Child, Reason, Timedout), Timedout};
{'EXIT', Pid, Reason} ->
receive {'DOWN', _MRef, process, Pid, _} ->
{{error, Reason}, Timedout}
end
end,
{[{Pid, Reply} | Replies], Timedout1}
end, {[], false}, Pids),
timeout_stop(Child, TRef, TimeoutMsg, Timedout),
ReportError = shutdown_error_reporter(SupName),
[case Reply of
{_Pid, ok} -> ok;
{Pid, {error, R}} -> ReportError(R, Child#child{pid = Pid})
end || Reply <- Replies],
ok.