I am new to Erlang, so please go easy on me.
I am confused as to how a receive statement is executed in erlang, for instance:
loop() ->
receive
MessageA -> handlerA();
MessageB -> handlerB()
end
If a MessageA is received, and handlerA executed, after a while, MessageB is received in the processes' inbox, does handlerB gets executed?
I guess not, since I see a lot of code that recurse to execute the receive statement again:
loop() ->
receive
MessageA ->
handlerA(),
loop();
MessageB ->
handlerB(),
loop()
end
But here is a problem, if messageA's handler includes another receive statement like this:
loop() ->
receive
MessageA ->
loop2(),
MessageB ->
handlerB(),
loop()
end
loop2() ->
receive
MessageC ->
handlerC()
loop2()
MessageD ->
handlerD()
loop2()
end
In this case, does it mean if I enter MessageA's hander, I can never handle MessageB?
And how can I resolve this? By putting MessageB's handler into loop2? This doesn't look very graceful, especially when there are multiple levels of receive statements.
Is there a better way to do this?
The following code means "execute receiving a single message", so if you want to receive more than one, you need to loop. The typical way of doing that in Erlang is to tail-call yourself.
loop() ->
receive
MessageA -> handlerA();
MessageB -> handlerB()
end
In your last example, it looks like you have some sort of state machine, where A changes to another state, whereas B stays in the same state. It is not necessarily a problem that you can no longer receive A messages when you're in the state where you expect C and D messages, but that would depend on the problem domain.