[erlang-questions] Message send guarantees

Alex S. alex0player@REDACTED
Thu Jan 26 09:38:24 CET 2017


> 26 янв. 2017 г., в 10:14, Raimo Niskanen <raimo+erlang-questions@REDACTED> написал(а):
> 
> On Wed, Jan 25, 2017 at 11:06:05PM +0000, Dmitry Kakurin wrote:
>> Thanks Lukas, please see a couple of questions/comments below.
>> 
>> - Dmitry
>> 
>> ________________________________
>> From: Lukas Larsson <lukas@REDACTED <mailto:lukas@REDACTED>>
>> Sent: Wednesday, January 25, 2017 12:37 AM
>> 
>> Hello,
>> 
>> On Wed, Jan 25, 2017 at 12:38 AM, Dmitry Kakurin <dima_kakurin@REDACTED <mailto:dima_kakurin@REDACTED><mailto:dima_kakurin@REDACTED <mailto:dima_kakurin@REDACTED>>> wrote:
>> When I execute "pid ! msg" and it returns, what are the guarantees if pid and self are on the same node?
>> Can I assume that by the time it returns, msg is in the pid's queue? And as a result all messages sent to pid afterwards will be queued after msg?
>> 
>> No you cannot assume that. The message is considered "in transit" until the receiving process inspects it somehow.
>> 
>> What aspect of implementation can cause such reordering? Could you give an example how this could happen? Maybe I'll be able to artificially create conditions where it would not happen. Or work around it in some other way. Please see below why.
> 
> On a multi-threade system it is very hard to know in which order things
> happen, so there is no "reordering" since there is no temporal order
> to begin with.
> 
> Using the non-SMP virtual machine and erlang:yield/0 could do the trick,
> but depending on the computer you might loose boatloads of performance.
> 
> It is also _very_ bad programming practice to pretend that asynchronous
> message passing is not asynchronous.  It is solving a problem the
> wrong way…
I’d like to clarify that the order of messages *sent from A to B* is kept intact indeed, and later messages will arrive later.
> 
> 
>> 
>> 
>> The reason I'm asking is because I need a guarantee of proper message ordering in the following scenario when all processes involved are local to a node:
>> 1. A --msg1--> C (process A sends msg1 to process C)
>> 2. A --msg2--> B
>> 3. B --msg2--> C (process B simply proxies msg2 from A to C)
>> 
>> I need a guarantee that msg2 will always appear in C's queue after msg1.
>> 
>> You have to do this using messages or some other sync mechanism.
>> 
>> You are right, in general it's easy to devise a simple scheme for that.
>> Unfortunately I have a limitation. In my case A talks to C thru proxy B and would like to short-circuit the communication by getting rid of B and start talking to C directly. Process A needs to do that while messages thru B could be in flight. The limitation is that C is not aware of this proxy business, and cannot be changed (it's a regular GenServer that is not written by me).
>> With lack of cooperation from C I cannot think of a communication protocol to accomplish what I want.
> 
> If B can be modified as needed; you can get an ack from B so both A and B
> know about the bypass e.g to delay bypass until no messages are in flight,
> provided that the messages from B to C are acked.
> 
> Or, maybe you can only use messages where the order does not matter.
> 
> But without modifying your requirements as you state them I see no solution.
> 
> Why do you really need to bypass some messages and still keep message
> ordering - it is impossible!
I would recommend using synchronous calls, perhaps with a proxy «queue» process or whatnot.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20170126/c6b4f126/attachment.htm>


More information about the erlang-questions mailing list