548708 (3) [Avatar] Offline
Since there is no guarantee on which order messages will arrive in the mailbox, doesn't the code in listings 5.7 and 5.8 introduce a race condition? It seems to me that the order in which the messages arrive in the mailbox is absolutely critical because subtraction and division are not commutative operations. For example:

(((0 + 10) - 5) * 3) / 5 => 3.0


(((0 + 10) * 3) - 5) / 5 => 5.0

Shouldn't the add, sub, mul, div functions be made synchronous just like value?
sjuric (90) [Avatar] Offline
From the standpoint of the single client process, the messages will arrive in the order they are sent in. So in the code snippet in the book we have the following sequence:

Calculator.add(calculator_pid, 10)
Calculator.sub(calculator_pid, 5)
Calculator.mul(calculator_pid, 3)
Calculator.div(calculator_pid, 5)

Since these functions are invoked from the same process, then it's indeed guaranteed that the server process will first receive the message in the order add, sub, mul, div, value. Therefore, the arithmetic operations don't need to be made synchronous, because they will be processed in the desired order.

In other words, there's no way that a message issued by a process will somehow "overtake" a previous message issued by that same process.

In contrast, if you had 5 client processes issuing one message each, then you wouldn't be able to reason about the order, simply because you can't know the exact order of execution of these processes.
548708 (3) [Avatar] Offline
I agree that if the client and server processes are both on the same BEAM, then the order of arrival is guaranteed to be correct. I'm thinking of the distributed case where the client and server run on two different BEAMs that are say connected by the Internet. Even in this case the messages will almost always arrive in the correct order, but there would be no guarantee then right?

I apologize if this sounds argumentative. That is not my intention. I just want to make sure I understand things correctly.

I'm thinking about "Internet of Things" applications where you have lots of small devices distributed around the world all talking to a remote server. It seems to me that Elixir/Erlang might be a good fit for such a scenario.
sjuric (90) [Avatar] Offline
The same guarantee holds in a distributed setting. Messages sent by one client process are received in the order in which they have been sent. Here's a quote from official docs: The only signal ordering guarantee given is the following: if an entity sends multiple signals to the same destination entity, the order is preserved; that is, if A sends a signal S1 to B, and later sends signal S2 to B, S1 is guaranteed not to arrive after S2.
548708 (3) [Avatar] Offline
Thank you for answering my question Sasa!

The fact that the order is guaranteed is pretty cool! I also found my question answered on the Erlang FAQ.