Can a process have two receive blocks - process

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.

Related

Handling PENDING messages from Redis Stream with Spring Data Redis

When using StreamMessageListenerContainer a subscription for a consumer group can be created by calling:
receive(consumer, readOffset, streamListener)
Is there a way to configure the container/subscription so that it will always attempt to re-process any PENDING messages before moving on to polling for new messages?
The goal would be to keep retrying any message that wasn't acknowledged until it succeeds, to ensure that the stream of events is always processed in exactly the order it was produced.
My understanding is if we specify the readOffset as '>' then on every poll it will use '>' and it will never see any messages from the PENDING list.
If we provide a specific message id, then it can see messages from the PENDING list, but the way the subscription updates the lastMessageId is like this:
pollState.updateReadOffset(raw.getId().getValue());
V record = convertRecord(raw);
listener.onMessage(record);
So even if the listener throws an exception, or just doesn't acknowledge the message id, the lastMessageId in pollState is still updated to this message id and won't be seen again on the next poll.

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 make rabbitmq to refuses messages when a queue is full?

I have a http server which receives some messages and must reply 200 when a message is successfully stored in a queue and 500 is the message is not added to the queue.
I would like rabbitmq to refuse my messages when the queue reach a size limit.
How can I do it?
actually you can't configure RabbitMq is such a way. but you may programatically check queue size like:
`DeclareOk queueOkStatus = channel.queueDeclare(queueOutputName, true, false, false, null);
if(queueOkStatus.getMessageCount()==0){//your logic here}`
but be careful, because this method returns number of non-acked messages in queue.
If you want to be aware of this , you can check Q count before inserting. It sends request on the same channel. Asserting Q returns messageCount which is Number of 'Ready' Messages. Note : This does not include the messages in unAcknowledged state.
If you do not wish to be aware of the Q length, then as specified in 1st comment of the question:
x-max-length :
How many (ready) messages a queue can contain before it starts to drop them from its head.
(Sets the "x-max-length" argument.)

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, …}}