# Gen\_statem receiving data

**URL:** <https://erlangforums.com/t/gen-statem-receiving-data/1830>\
**Category:** Questions / Help\
**Tags:** gen\_statem\
**Created:** [September 10, 2022, 8:05pm UTC](https://erlangforums.com/t/gen-statem-receiving-data/1830 "2022-09-10T20:05:17Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Abdelghani](https://erlangforums.com/letter_avatar_proxy/v4/letter/a/49beb7/32.png) [@Abdelghani](https://erlangforums.com/u/Abdelghani)\
**Post date:** [September 10, 2022, 8:05pm UTC](https://erlangforums.com/t/gen-statem-receiving-data/1830/1 "2022-09-10T20:05:17Z")

</div>

Hello, consider we have a function that communicate with a remote server and returns its data as follows :

```erlang
send_to_server(Msg) ->
erlang:send(RemoteRef , Msg),
receive
Reply -> Reply
end. 

```

and we should use it constantly in our program, for example :

```erlang
Reply0 = send_to_server(Msg0), 
Res0 = handle(Reply0), 
Reply1 = send_to_server(Res0), 
.... 

```

how can we implement this function within a `gen_statem` since `receive` is not authorised in any `gen_*` behaviour ?

---

<div class="post-metadata">

**Author:** ![starbelly](https://erlangforums.com/user_avatar/erlangforums.com/starbelly/32/209_2.png) [@starbelly](https://erlangforums.com/u/starbelly)\
**Post date:** [September 10, 2022, 11:54pm UTC](https://erlangforums.com/t/gen-statem-receiving-data/1830/2 "2022-09-10T23:54:37Z")

</div>

I’m not sure I fully understand. You can indeed you `receive` inside any gen\_\* behavour, whether or not that’s a good idea or not is another question. You can use send and receive, gen, erpc, etc. You can do things asynchronously as well, as to not block (i,e, do a send, then handle the reply in a catch all handle\_event clause). You can also spawn a process to do this for you, get the reply, and send it back to your gen\_statem, once again mostly likely handling in a handle\_event catch all.

Without knowing what it is you’re trying to build it’s hard to say what a good pattern here it, what’s more what you’re trying to do may dictate that gen\_statem is not a good fit here, but simply can’t say without details.

---

<div class="post-metadata">

**Author:** ![Abdelghani](https://erlangforums.com/letter_avatar_proxy/v4/letter/a/49beb7/32.png) [@Abdelghani](https://erlangforums.com/u/Abdelghani)\
**Post date:** [September 11, 2022, 1:13am UTC](https://erlangforums.com/t/gen-statem-receiving-data/1830/3 "2022-09-11T01:13:32Z")

</div>

Thank you @starbelly,  
But if I changed the current state to catch the message how can I return to the rest of code ? I just want a portable function like that I mentionned to call it when I need  
Spawning another process don’t resolve the problem because you still need to receive from it

---

<div class="post-metadata">

**Author:** ![NAR](https://erlangforums.com/user_avatar/erlangforums.com/nar/32/1363_2.png) [@NAR](https://erlangforums.com/u/NAR)\
**Post date:** [September 11, 2022, 11:05am UTC](https://erlangforums.com/t/gen-statem-receiving-data/1830/4 "2022-09-11T11:05:32Z")

</div>

Fist of all, you _can_ use `receive` in a `gen_statem`, just make sure you don’t consume the “internal” `gen_*` messages, so probably it’s better to send `{my_msg, Msg}` instead of `Msg` and receive `{my_msg, Reply}` instead of `Reply`.

You can receive messages in a `gen_statem` with the `Module:Statename/3` or `Module:handle_event/4` function where the first parameter is `info` too - maybe this is what you’re after.

---

<div class="post-metadata">

**Author:** ![starbelly](https://erlangforums.com/user_avatar/erlangforums.com/starbelly/32/209_2.png) [@starbelly](https://erlangforums.com/u/starbelly)\
**Post date:** [September 11, 2022, 3:21pm UTC](https://erlangforums.com/t/gen-statem-receiving-data/1830/5 "2022-09-11T15:21:33Z")

</div>

I think what is not understand is whether the send and recv needs to be blocking. As pointed out, this is generally not the best way to handle a situation like this, but as is tradition it depends.

However, let’s say for arguments sake, this is what must be done and we need to do it using primitives vs gen\*. or erpc, pg, etc.

```erlang
handle_event({call,From}, some_event, State) ->
    erlang:whereis(some_server) ! {self(), ping},
    receive
        pong ->
            {keep_state,State,[{reply,From,hello]};
        _ -> 
             %% This is dangerous, a system message could come in and get dropped on the floor. 
             %% A better form would be without the catch all, but we'd still be blocking for 
             %% up to 5 seconds, which could have a nasty ripple effect across the system. 
             {keep_state,State, [{reply, From, {error, "Unexpected message for ping from remote server"}}]}
    after
        5000 ->
            {keep_state,State, [{reply, From, {error, "timeout waiting for remote pong"}}]}
    end;

```

You could also change state here if you liked.

Then in our `some_server`…

```erlang
handle_info({From, ping}, State) ->
    From ! pong,
    {noreply, State};

```

Mission accomplished. As mentioned by others, you may need / want to handle this async, in which case you can do a send, don’t send a reply in the handle\_event/4, then handle the reply from the remote later on (if one comes at all), and finally do a reply to the client.

You can spawn a process to do this which sends the message to the remote than sends a message, awaits the reply, then sends it back to your gen\_statem process. You can also simply send the message via send, gen\_server:cast/3, etc. All depends.

Either way, it’s still impossible to say what’s best for your situation without knowing what it is you’re trying to build and what you’re trying to do in this specific scenario. Further, what is it your sending a message to remotely? Is it a bare bones process? Is it a gen\_server? The answer to that question really dictates the best way to actually do the send itself (e.g., if it’s a gen\_server, you gen\_server:call/3 etc.)

---

<div class="post-metadata">

**Author:** ![Abdelghani](https://erlangforums.com/letter_avatar_proxy/v4/letter/a/49beb7/32.png) [@Abdelghani](https://erlangforums.com/u/Abdelghani)\
**Post date:** [September 11, 2022, 3:41pm UTC](https://erlangforums.com/t/gen-statem-receiving-data/1830/6 "2022-09-11T15:41:03Z")

</div>

No I don’t need to block, it was just an example but the real code include of course timeouts.  
You can’t use `receive` in standard behaviours

---

<div class="post-metadata">

**Author:** ![starbelly](https://erlangforums.com/user_avatar/erlangforums.com/starbelly/32/209_2.png) [@starbelly](https://erlangforums.com/u/starbelly)\
**Post date:** [September 11, 2022, 3:47pm UTC](https://erlangforums.com/t/gen-statem-receiving-data/1830/7 "2022-09-11T15:47:22Z")

</div>

You in fact can, but doesn’t mean you should, as pointed out as an example, here’s an async example (contrived), utilizing the push button example from the docs:

```erlang
-module(pushbutton).
-behaviour(gen_statem).

-export([start/0,push/0,get_count/0,stop/0]).
-export([terminate/3,code_change/4,init/1,callback_mode/0]).
-export([on/3,off/3]).

name() -> pushbutton_statem. % The registered server name

%% API. This example uses a registered name name()
%% and does not link to the caller.
start() ->
    gen_statem:start({local,name()}, ?MODULE, [], []).
push() ->
    gen_statem:call(name(), push).
get_count() ->
    gen_statem:call(name(), get_count).
stop() ->
    gen_statem:stop(name()).

%% Mandatory callback functions
terminate(_Reason, _State, _Data) ->
    void.
code_change(_Vsn, State, Data, _Extra) ->
    {ok,State,Data}.
init([]) ->
    %% Set the initial state + data. Data is used only as a counter.
    State = off, Data = 0,
    {ok,State,Data}.
callback_mode() -> state_functions.

%%% state callback(s)

off({call,From}, push, Data) ->
    %% Go to 'on', increment count and reply
    %% that the resulting status is 'on'
    {next_state,on,Data+1,[{reply,From,on}]};
off(EventType, EventContent, Data) ->
    handle_event(EventType, EventContent, Data).

on({call,From}, push, Data) ->
    %% Go to 'off' and reply that the resulting status is 'off'
    {next_state,off,Data,[{reply,From,off}]};
on(EventType, EventContent, Data) ->
    handle_event(EventType, EventContent, Data).

%% Handle events common to all states
handle_event({call, From}, get_count, Data) ->
    erlang:whereis(ping_pong) ! {self(), ping, From},
    {keep_state,Data};
handle_event(info, {pong, OrigFrom}, Data) ->
    gen_statem:reply(OrigFrom, Data),
    {keep_state, Data};
handle_event(_, _, Data) ->
    %% Ignore all other events
    {keep_state, Data}.

```

This is a bad example, but demonstrates a thing none the less. Particularly bad because we’re relying on passing the client pid to the `ping_pong` process and getting it back later so we can reply to the client, but yeah, demonstrates a thing.

Likewise, you can do the same thing but spawn a proc you pass the client pid to, does a send/recv, then signals back to your gen\_statem using send again.

---

<div class="post-metadata">

**Author:** ![Maria-12648430](https://erlangforums.com/user_avatar/erlangforums.com/maria-12648430/32/604_2.png) [@Maria-12648430](https://erlangforums.com/u/Maria-12648430)\
**Post date:** [September 11, 2022, 4:24pm UTC](https://erlangforums.com/t/gen-statem-receiving-data/1830/8 "2022-09-11T16:24:53Z")

</div>

> [@starbelly](#):
>
> This is a bad example

… especially because it does not work as posted (omits the `on/3` and `off/3` callbacks). Here is the link to the docs that contains the full example: [https://www.erlang.org/doc/man/gen\_statem.html#example](https://www.erlang.org/doc/man/gen_statem.html#example)  
But I don’t see what it _is_ that it should demonstrate, in the context of this discussion?

> [@Abdelghani](#):
>
> You can’t use `receive` in standard behaviours

… but you _ **can** _, what makes you think you can’t? I just happen to be taking part [in an PR to OTP](https://github.com/erlang/otp/pull/6256) that happens to [do just that](https://github.com/erlang/otp/pull/6256/files#diff-26aac4a760c0de9211152f00eefa4d9b581135c65961e784cc811bad509bdb2dR551): a `receive` in a standard behavior (albeit in a `gen_server`, not a `gen_statem`).

However, because you _can_ doesn’t mean you _should_, not unless you know what you’re doing. If you’re not careful, you may steal messages that were meant for some entirely different purpose, but that is a slightly different topic.

Be that as it may, I too find it very difficult to answer your question, because I simply don’t understand what you are trying to do, and how 😅 It would help a lot if you could be more elaborate, maybe show some code even.

---

<div class="post-metadata">

**Author:** ![starbelly](https://erlangforums.com/user_avatar/erlangforums.com/starbelly/32/209_2.png) [@starbelly](https://erlangforums.com/u/starbelly)\
**Post date:** [September 11, 2022, 4:30pm UTC](https://erlangforums.com/t/gen-statem-receiving-data/1830/9 "2022-09-11T16:30:28Z")

</div>

> [@Maria-12648430](#):
>
> especially because it does not work as posted (omits the `on/3` and `off/3` callbacks). Here is the link to the docs that contains the full example: [Erlang – gen\_statem](https://www.erlang.org/doc/man/gen_statem.html#example)  
> But I don’t see what it _is_ that it should demonstrate, in the context of this discussion?

It merely demonstrates you can use `receive` in callback on gen\_statem, that’s it. You can do it in a blocking manor or a non blocking manor… and yes it was pointed out this is probably a bad idea.

P.S. I just stuck in on get\_count event for absolutely no particular reason.

> [@Maria-12648430](#):
>
> However, because you _can_ doesn’t mean you _should_, not unless you know what you’re doing

Exactly.

> [@Maria-12648430](#):
>
> Be that as it may, I too find it very difficult to answer your question, because I simply don’t understand what you are trying to do, and how 😅 It would help a lot if you could be more elaborate, maybe show some code even.

Ditto.

---

<div class="post-metadata">

**Author:** ![Maria-12648430](https://erlangforums.com/user_avatar/erlangforums.com/maria-12648430/32/604_2.png) [@Maria-12648430](https://erlangforums.com/u/Maria-12648430)\
**Post date:** [September 11, 2022, 4:44pm UTC](https://erlangforums.com/t/gen-statem-receiving-data/1830/10 "2022-09-11T16:44:02Z")

</div>

> [@starbelly](#):
>
> It merely demonstrates you can use `receive` in callback on gen\_statem, that’s it. You can do it in a blocking manor or a non blocking manor… and yes it was pointed out this is probably a bad idea.

Oh, so that refers to code given in your _earlier_ post. That confused me (since there is no `receive` in the `pushbutton` example) 😅

---

<div class="post-metadata">

**Author:** ![starbelly](https://erlangforums.com/user_avatar/erlangforums.com/starbelly/32/209_2.png) [@starbelly](https://erlangforums.com/u/starbelly)\
**Post date:** [September 11, 2022, 4:45pm UTC](https://erlangforums.com/t/gen-statem-receiving-data/1830/11 "2022-09-11T16:45:20Z")

</div>

> [@Maria-12648430](#):
>
> Oh, so that refers to code given in your _earlier_ post. That confused me (since there is no `receive` in the `pushbutton` example) 😅

hehe yeah, I suppose that wasn’t helpful 🙂 Maybe I should put a more proper example for future readers, I was attempting to expend as little effort as possible : copy → pasta → puke to show mechanics 😆

---

<div class="post-metadata">

**Author:** ![Maria-12648430](https://erlangforums.com/user_avatar/erlangforums.com/maria-12648430/32/604_2.png) [@Maria-12648430](https://erlangforums.com/u/Maria-12648430)\
**Post date:** [September 11, 2022, 4:46pm UTC](https://erlangforums.com/t/gen-statem-receiving-data/1830/12 "2022-09-11T16:46:50Z")

</div>

Maybe if @Abdelghani could provide more information, we could answer more to the point 😉 I have to admit that I still don’t know what we’re really talking about here 😅

---

<div class="post-metadata">

**Author:** ![starbelly](https://erlangforums.com/user_avatar/erlangforums.com/starbelly/32/209_2.png) [@starbelly](https://erlangforums.com/u/starbelly)\
**Post date:** [September 11, 2022, 4:55pm UTC](https://erlangforums.com/t/gen-statem-receiving-data/1830/13 "2022-09-11T16:55:41Z")

</div>

I think I blame myself… After trying to nudge that information out, I resorted to infer, and everything went wrong there 😛

---

<div class="post-metadata">

**Author:** ![Abdelghani](https://erlangforums.com/letter_avatar_proxy/v4/letter/a/49beb7/32.png) [@Abdelghani](https://erlangforums.com/u/Abdelghani)\
**Post date:** [September 11, 2022, 5:06pm UTC](https://erlangforums.com/t/gen-statem-receiving-data/1830/14 "2022-09-11T17:06:51Z")

</div>

Thank you all for your help but I don’t know how can the official guide of the `gen_statem` not been read by the most of erlang developers that have used that engine before ? sorry but Iam just wonder.  
Okey I think I found the answer to this, I will just include system messages and parent exit in the receive block

```erlang
do_receive(Parent) -> %% Parent is the pid of the process's parent
receive
        Reply ->
                Reply;
        {'EXIT', Parent, Reason} ->
                {stop, Reason};
        {system, From, Request} ->
                sys:handle_system_msg(Request, From, 
                Parent,?MODULE, [], Parent)
after 5000 ->
        .... 
end. 

system_continue( _ , _ , Parent) ->
do_receive(Parent). 
system_terminate( Reason , _ , _ , _) ->
{stop, Reason}. 
system_code_change(Misc, _ , _ , _) ->
{ok, Misc}. 

send_to_server(Req, ServerRef, Parent) ->
erlang:send(ServerRef, Req), 
do_receive(Parent). 

```

Now we can use this portable function freely

```erlang
Reply0 = send_to_server(Req0, ServerRef, Parent), 
Reply1 = send_to_server(Req1, ServetRef, Parent), 
.... 

```

From [erlang.org](http://erlang.org)  
" A selective receive cannot be used from a gen\_statem behaviour (or from any gen\_\* behaviour), as the receive statement is within the gen\_\* engine itself. It must be there because all sys compatible behaviours must respond to system messages and therefore do that in their engine receive loop, passing non-system messages to the callback module" .

---

<div class="post-metadata">

**Author:** ![Maria-12648430](https://erlangforums.com/user_avatar/erlangforums.com/maria-12648430/32/604_2.png) [@Maria-12648430](https://erlangforums.com/u/Maria-12648430)\
**Post date:** [September 11, 2022, 6:02pm UTC](https://erlangforums.com/t/gen-statem-receiving-data/1830/15 "2022-09-11T18:02:43Z")

</div>

> [@Abdelghani](#):
>
> but I don’t know how can the official guide of the `gen_statem` not been read by the most of erlang developers that have used that engine before ?

Heh 😉 I don’t think even a _pastor_ would know each and every passage of the bible by heart, that’s what the book is for 😁

> [@Abdelghani](#):
>
> sorry but Iam just wonder.

_We know better! 😇_ (just joking 😁)

> [@Abdelghani](#):
>
> From [erlang.org](http://erlang.org)

(Specifically: [Erlang -- gen\_statem Behaviour](https://www.erlang.org/doc/design_principles/statem.html#selective-receive))

> [@Abdelghani](#):
>
> " A selective receive cannot be used from a gen\_statem behaviour (or from any gen\_\* behaviour), as the receive statement is within the gen\_\* engine itself. It must be there because all sys compatible behaviours must respond to system messages and therefore do that in their engine receive loop, passing non-system messages to the callback module" .

You’re right, that _is_ written there 😉

But also, strictly speaking that is wrong. `receive`, selective or not, _can_ be used in a `gen_statem` (and any `gen_*` behavior for that matter). Otherwise, that process simply could not talk to anything else, whatever it may be. For example, if you call something like `timer:apply_after(1000, erlang, make_ref, [])` (pointless as that may be, I use it just to illustrate a point) in your `gen_statem`, yes, you’re not _writing_ a `receive` _there_, but nevertheless there will be one. `timer:apply_after/4` ultimately does a [`gen_server:call/4`](https://github.com/erlang/otp/blob/d7eca6e790633834603185b26e083afa68591264/lib/stdlib/src/gen_server.erl#L365) (to the timer server), which defers to [`gen:call`](https://github.com/erlang/otp/blob/d7eca6e790633834603185b26e083afa68591264/lib/stdlib/src/gen.erl#L211), which in turn defers to [`gen:do_call`](https://github.com/erlang/otp/blob/d7eca6e790633834603185b26e083afa68591264/lib/stdlib/src/gen.erl#L225). And `gen:do_call` sets up a monitor (with alias, since OTP 24) on the target process, wraps its Pid (as the reply target) (or the reply alias, since OTP 24) and monitor reference (as a tag) in a tuple, sends that to the target process, and then does a (selective) `receive`, waiting for either a reply tuple containing the tag, a `'DOWN'` message containing the monitor reference, or a timeout.

Sorry for the lengthy explanation 😅 I just want to avoid further misunderstandings.

So you see, there are `receive`s happening _all the time_, but they’re usually hidden behind several layers of API. It’ s simply not a good idea to use them directly (that’s what the `handle_info` or `handle_event(info, ...)` callbacks are for), as it is easy to mess up things that way, which is not trivial to debug…

---

<div class="post-metadata">

**Author:** ![starbelly](https://erlangforums.com/user_avatar/erlangforums.com/starbelly/32/209_2.png) [@starbelly](https://erlangforums.com/u/starbelly)\
**Post date:** [September 11, 2022, 6:52pm UTC](https://erlangforums.com/t/gen-statem-receiving-data/1830/16 "2022-09-11T18:52:31Z")

</div>

The docs should probably be updated to say “should not in general”, as well as provide examples of why you should not (my first example here is a good candidate for that), and if you do here is a good form for doing so, yet you should still prefer x,y,z.

Edit:

There’s one other thing to point about that particular section in gen\_statem doc. The context seems to be around an selective receive with no timeout. Doing so in a callback would of course block forever, thus preventing system messages and the like from ever arriving.

---

<div class="post-metadata">

**Author:** ![Abdelghani](https://erlangforums.com/letter_avatar_proxy/v4/letter/a/49beb7/32.png) [@Abdelghani](https://erlangforums.com/u/Abdelghani)\
**Post date:** [September 11, 2022, 7:10pm UTC](https://erlangforums.com/t/gen-statem-receiving-data/1830/17 "2022-09-11T19:10:15Z")

</div>

@Maria-12648430 you have right, I didn’t pay attention that some of OTP internal functions contain `receive` block like `gen_server:call` but here this is not my mistake I have just followed what the documentation said

---

<div class="post-metadata">

**Author:** ![Maria-12648430](https://erlangforums.com/user_avatar/erlangforums.com/maria-12648430/32/604_2.png) [@Maria-12648430](https://erlangforums.com/u/Maria-12648430)\
**Post date:** [September 11, 2022, 7:13pm UTC](https://erlangforums.com/t/gen-statem-receiving-data/1830/18 "2022-09-11T19:13:02Z")

</div>

> [@Abdelghani](#):
>
> but here this is not my mistake

Of course not, and I didn’t mean it that way 🤗

---

<div class="post-metadata">

**Author:** ![Maria-12648430](https://erlangforums.com/user_avatar/erlangforums.com/maria-12648430/32/604_2.png) [@Maria-12648430](https://erlangforums.com/u/Maria-12648430)\
**Post date:** [September 11, 2022, 7:27pm UTC](https://erlangforums.com/t/gen-statem-receiving-data/1830/19 "2022-09-11T19:27:03Z")

</div>

> [@starbelly](#):
>
> There’s one other thing to point about that particular section in gen\_statem doc. The context seems to be around an selective receive with no timeout. Doing so in a callback would of course block forever, thus preventing system messages and the like from ever arriving.

Hm, yes, but there is still more to it…

Even if there is a timeout, it may be a quite long one, so even if you would not wait forever, it could still be for a long time.

Another thing that I find misleading about the paragraph is that it seems to imply that `receive`s are ok (like, “nothing can go wrong”) as long as they are _not_ selective. But that is not the case, a non-selective `receive` could lead to system messages to be ignored/lost instead. For example…

```erlang
handle_event(...) ->
    receive
        expected_message -> do_stuff();
        _Unexpected -> ok
    end,
    keep_state_and_data.

```

System messages (and whatever `gen_statem`-internal messages are zipping around, no idea what makes that monster tick 😅) would end up in the second clause, and be lost.

So I guess the general advice should be, don’t use (manual) `receive` inside `gen_*` behaviors unless (you think) you know what you’re doing and there is no other way, otherwise absolutely stick to the callbacks.

---

<div class="post-metadata">

**Author:** ![Abdelghani](https://erlangforums.com/letter_avatar_proxy/v4/letter/a/49beb7/32.png) [@Abdelghani](https://erlangforums.com/u/Abdelghani)\
**Post date:** [September 11, 2022, 7:30pm UTC](https://erlangforums.com/t/gen-statem-receiving-data/1830/20 "2022-09-11T19:30:54Z")

</div>

But the appropriate answer to such situation was that the `gen_statem` returns to handle system messages or parent exit after finishing the `receive` block in its natural engine loop.

[Next page](https://erlangforums.com/t/gen-statem-receiving-data/1830.md?page=2)
