[erlang-questions] Abusing OTP-8623 for high-priority messages

Tony Rogvall <>
Fri Apr 11 11:04:43 CEST 2014


Reacting (as always) when the word abuse is tagged in the subject line :-)

Reading the comments in beam_receive.erl (compiler) the layout of the code
using this "selective" feature must have the following layout:

1) Ref= make_ref(),    %% or monitor(process, Pid) / spawn_monitor(..)
...
receive
   2) _Mesg = {Ref, Data} -> do_some_stuff()
end.

The compiler will only put out the code you want (recv_mark) if it follows this pattern.
The actual reference created in 1) must be matched in a syntactic pattern
that contain the variable 'Ref'. The beam_receive optimization is done pretty
late in the compiler process so it is a bit more complicated that that.

Example

-module(beam_prio_msg).
-compile(export_all).

test1() ->
    Ref = make_ref(),
    receive
	{Ref, x} -> x
    after
	100 -> timeout
    end.

test2() ->
    Ref = make_ref(),
    Ref1 = Ref,
    receive
	{Ref1, x} -> x
    after
	100 -> timeout
    end.

test3() ->
    Ref = make_ref(),
    Ref1 = {Ref},
    receive
	{Ref1, x} -> x
    after
	100 -> timeout
    end.

Both test1 and test2 put out the (recv_mark) instruction even though test2 is matching on an
other variable Ref1. But test3 will not put out the (recv_mark) instruction, since the reference is put
into an other term and therefor is potentially not in a register anymore.

Anyway. If your plan is to work at all the code fragment must somehow send a message somewhere
saying that "now it is time to send a priority message to me" and then wait for that message.

PrioRef = make_ref(),
ManagerPid ! {send_me_prio_request_with_this_ref, PrioRef},

receive
    {PrioRef, From, Msg} -> handle_call(From, Msg, State)
after 0 ->
    receive
        Msg -> gen_server_like_dispatch_msg(Msg)
    end
end

This plan could almost work (theoretically), but would spam ManagerPid for every call to probe for 
high prio message. And you surly add latency since you need to wait more than 0
millis for a high prio response.

In other words, with my current mindset, the scheme is not really working.
But with some new and fresh input this may inspire to even more abuse :-)

/Tony


On 11 apr 2014, at 02:02, Dmitry Demeshchuk <> wrote:

> Hi list,
> 
> Today (yeah, just a couple years have passed since R14A) I learned about OTP-8623, which allows to do selective receive for messages that contain a known reference with O(1) complexity.
> 
> Which made me think: what if we make a gen_server'ish process that:
> 1. Creates a reference that is being passed along with the pid, meaning, our start_link returns {ok, {Pid, ManageRef}} or something like that. ManageRef is actually created within the new process inside init/1 or such.
> 2. Introduce an operation named priority_call, which, basically, sends something like {ManageRef, {Pid, Ref}, Msg}.
> 3. The process itself (on its own side) does a selective receive like that:
> 
> receive
>     {ManageRef, From, Msg} -> handle_call(From, Msg, State)
> after 0 ->
>     receive
>         Msg -> gen_server_like_dispatch_msg(Msg)
>     end
> end
> 
> This could potentially help with sending managing messages to the processes that may have overloaded inbox with thousands of messages. Say, we see that the process gets overloaded and we send an operational message of some kind ("discard the entire inbox", for example).
> 
> Thoughts?
> 
> -- 
> Best regards,
> Dmitry Demeshchuk
> _______________________________________________
> erlang-questions mailing list
> 
> http://erlang.org/mailman/listinfo/erlang-questions

"Installing applications can lead to corruption over time. Applications gradually write over each other's libraries, partial upgrades occur, user and system errors happen, and minute changes may be unnoticeable and difficult to fix"



-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20140411/cd4624c8/attachment.html>


More information about the erlang-questions mailing list