[erlang-questions] Message send guarantees

Dmitry Kakurin dima_kakurin@REDACTED
Tue Jan 31 02:43:07 CET 2017


On Thu, Jan 26, 2017 at 11:41 PM, Raimo Niskanen <raimo+erlang-questions@REDACTED<mailto:raimo+erlang-questions@REDACTED>> wrote:
Have you changed your question?  Previously the problem was to send
non-proxied messages after proxied messages.

I've used inserting proxy in my original email (as it was the smallest setup I can distill my question to), and removing proxy in followup. Sorry about confusion. The problems are actually isomorphic and have the same solution :-).


But if B is a message relay (receive Msg -> C ! Msg, loop() end),
and provided the ping/pong is a gen_server call (since the request
contains who should have the reply, then this should also work:
1. A --msg1---> B
2. A --req----> B
3. B --msg1---> C
4. B --req----> C
5. A <--reply-- C
6. A --msg2---> C

I had the same solution in mind. Also it's a good idea and optimization to reply directly from C to A in step 5 instead of going thru B. I didn't think of that, thanks.

> Now the only problem I have to solve is: what can be used as a benign message that I can send to any gen_server such that it would reply (to emulate ping/pong exchange above)?

sys:get_status/1,2 returns much more data including what sys:get_state/1,2
returns, so it is less suitable.

If you know anything more about your gen_server C, it may have some status
quering handle_call that can be used.

Maybe sys:statistics/2 can be good enough.  Mostly no statistics collection is
activated for a given gen_server so you will get just {ok,no_statistics} back
as pong, and if statistics collection should be activated the gen_server
does not much more than process_info(self(), reductions) and erlang:localtime(),
which may and may not be regarded as heavy, but compared to returning the whole
arbitrary gen_server state it may be better.

After digging thru sys module code a little more I've settled on using sys:remove(C,nil).
It's asking to remove debug function 'nil' that is of course bogus, but returns ok quickly and is a single list.remove operation from a list that's usually empty.

Thank you, Dmitry

________________________________
From: erlang-questions-bounces@REDACTED <erlang-questions-bounces@REDACTED> on behalf of Raimo Niskanen <raimo+erlang-questions@REDACTED>
Sent: Thursday, January 26, 2017 11:41 PM
To: erlang-questions@REDACTED
Subject: Re: [erlang-questions] Message send guarantees

On Fri, Jan 27, 2017 at 02:25:49AM +0000, Dmitry Kakurin wrote:
> From: Joe Armstrong <erlang@REDACTED>
>
> Sent: Thursday, January 26, 2017 5:29 AM
>
> On Wed, Jan 25, 2017 at 12:38 AM, Dmitry Kakurin
> <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?
> >
> > 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.
>
> This cannot be guaranteed
>
> Thanks Joe and others. I understand now that it's fruitless to pursue a direction where I'd try to somehow artificially establish this guarantee.
>
> I have to re-evaluate my constraints then. All along my main constraint was that C can be any gen_server, it's not owned by me and I cannot change it.
> If I could change C then the following would work:
> 1. A --msg1--> C
> 2. A --ping--> C
> 3. A <--pong-- C
> 4. A --msg2--> B
> 5. B --msg2--> C
>

Have you changed your question?  Previously the problem was to send
non-proxied messages after proxied messages.

But if B is a message relay (receive Msg -> C ! Msg, loop() end),
and provided the ping/pong is a gen_server call (since the request
contains who should have the reply, then this should also work:
1. A --msg1---> B
2. A --req----> B
3. B --msg1---> C
4. B --req----> C
5. A <--reply-- C
6. A --msg2---> C

> All we need from C is to respond "pong" to "ping" message. In this case A knows msg2 is enqueued after msg1 because A has observed "pong" in response to "ping" that was sent after msg1. The ordering is as desired here.
> Now the only problem I have to solve is: what can be used as a benign message that I can send to any gen_server such that it would reply (to emulate ping/pong exchange above)?
> Looking thru gen_server source code I see that it's processing sys messages. So I can use get_state message as "ping" and response with state as "pong". Except it may not be really benign perf-wise if amount of state kept by C is significant.
> There is also get_status, but I don't understand how it's processed and if I can use it for ping/pong purposes. Can I? Is there a better message?

sys:get_status/1,2 returns much more data including what sys:get_state/1,2
returns, so it is less suitable.

If you know anything more about your gen_server C, it may have some status
quering handle_call that can be used.

Maybe sys:statistics/2 can be good enough.  Mostly no statistics collection is
activated for a given gen_server so you will get just {ok,no_statistics} back
as pong, and if statistics collection should be activated the gen_server
does not much more than process_info(self(), reductions) and erlang:localtime(),
which may and may not be regarded as heavy, but compared to returning the whole
arbitrary gen_server state it may be better.

>
> Do you have a better idea for ping/pong messages on C? Or how to solve this in general?
>
> Thank you, Dmitry.
>
> P.S. I know that in this simplified example I could piggyback on msg1 if it returns something but in real code I cannot, so let's assume it's a one-way message (a cast, not a call). So I'm OK with ping/pong.
>


--

/ Raimo Niskanen, Erlang/OTP, Ericsson AB
_______________________________________________
erlang-questions mailing list
erlang-questions@REDACTED
http://erlang.org/mailman/listinfo/erlang-questions
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20170131/ee5263dc/attachment.htm>


More information about the erlang-questions mailing list