use return from gen_server:send_request/2 to match directly in handle_info/2

Andreas Schultz andreas.schultz@REDACTED
Tue Jun 22 18:05:24 CEST 2021


send_request and friends are unusable in their current form.

What is required would be the ability to the RequestId returned from
gen_server:send_request/2 to match the returned message (for example in the
header of handle_info/2 method).
Something like this:

    handle_call(Call, From, #state{other = Other} = State) ->
        ReqId = gen_server:send_request(Other, Call),
        {noreply, State#state{pending = {ReqId, From}}}.

    handle_info({ReqId, Reply}, #state{pending = {ReqId, From}} = State) ->
        gen_server:reply(From, Reply),
       {noreply, State}.

This is currently not possible, because the internal structure of the reply
message is undocumented and even changed between OTP 23 and 24.
Currently the only way to do this would be something like this for multiple
outstanding requests:

    handle_info(Msg, #state{pending1 = {ReqId1, From1}, pending1 = {ReqId2,
From2}, pending1 = {ReqId3, From3}} = State) ->
        case check_response(Msg, ReqId1) of
            {reply, Reply} ->
                gen_server:reply(From1, Reply);
            no_reply ->
                case check_response(Msg, ReqId2) of
                    {reply, Reply} ->
                        gen_server:reply(From2, Reply);
                    no_reply ->
                        case check_response(Msg, ReqId3) of
                            {reply, Reply} ->
                                gen_server:reply(From3, Reply);
                            no_reply ->

This could be optimized by using a map or list for the pending requests,
but it would still require one to iterate over the values and check the
message against each request id.


Andreas Schultz
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the erlang-questions mailing list