# 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:** 2

<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, 7:30pm UTC](https://erlangforums.com/t/gen-statem-receiving-data/1830/21 "2022-09-11T19:30:56Z")

</div>

Yeah, I just added all that as notes to my first example right before you posted this 😄

> [@Maria-12648430](#):
>
> 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 ther way, otherwise absolutely stick to the callbacks.

Yeah, it’s conflicting… on one hand, it seems best to say “Don’t ever do that”, OTOH yet there’s room for sharp knifes, and valid at that.

That’s why I think we can probably make a chapter on the dos and donts of gen\_\* and using primitives in them.

---

<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, 7:33pm UTC](https://erlangforums.com/t/gen-statem-receiving-data/1830/22 "2022-09-11T19:33:06Z")

</div>

This is where async comes in handy. So you send a message… (optimally not using send/2), then you can handle that as misc info event later (that’s only one way to do it).

But I guess that begs the question… in what you were trying to acheive is the call to a remote process (and perhaps on another node) just a side effect or should it effect state in the state machine? That was not clear.

---

<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, 8:04pm UTC](https://erlangforums.com/t/gen-statem-receiving-data/1830/23 "2022-09-11T20:04:55Z")

</div>

> [@Abdelghani](#):
>
> 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.

That just doesn’t feel right (no offense). Manually receiving and handling the parent `EXIT` and system messages, and having to implement the `system_*` callbacks appears to belong to a level _below_ `gen_*`, in the realm of special processes and such, something `gen_*` was made to build on and abstract from.  
(For context, I didn’t even _know_ about system messages and the like before I happened to fiddle around in `ranch`, where `ranch_conns_sup` is some sort of streamlined custom supervisor implemented as a special process, which accordingly has to deal with system messages itself.)

Btw, I just noticed that there is a flaw in the code that you posted above.

> [@Abdelghani](#):
>
> ```erlang
> receive
> Reply ->
> Reply;
> {'EXIT', Parent, Reason} ->
> {stop, Reason};
> {system, From, Request} ->
> sys:handle_system_msg(Request, From, 
> Parent,?MODULE, [], Parent)
> after 5000 ->
> .... 
> end. 
> 
> ```

The second and third clauses are superseded by the first, and can never be reached. But this shows just how error-prone this approach is, so I’m pretty sure this is not the way how things _should_ be done.

---

<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, 8:10pm UTC](https://erlangforums.com/t/gen-statem-receiving-data/1830/24 "2022-09-11T20:10:52Z")

</div>

A starting point : [Adjust language around the usage of receive in a gen\_statem. by starbelly · Pull Request #6294 · erlang/otp · GitHub](https://github.com/erlang/otp/pull/6294)

---

<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, 9:00pm UTC](https://erlangforums.com/t/gen-statem-receiving-data/1830/25 "2022-09-11T21:00:37Z")

</div>

@Maria-12648430 it was just an example, of course in real code I will let Reply to be the last clause

---

<div class="post-metadata">

**Author:** ![raimo](https://erlangforums.com/user_avatar/erlangforums.com/raimo/32/867_2.png) [@raimo](https://erlangforums.com/u/raimo)\
**Post date:** [September 12, 2022, 8:10am UTC](https://erlangforums.com/t/gen-statem-receiving-data/1830/26 "2022-09-12T08:10:11Z")

</div>

I just want to confirm @Maria-12648430’s and @starbelly’s conclusions.

The documentation that states that you “cannot use selective receive” is over-simplifying trying to convey the mindset that when using a `gen_`\* behaviour you should handle general received messages as `info` messages in a behaviour callback.

It is also a confusing wording since it uses “selective receive” as a name for the Erlang language receive mechanism, when, actually, _selective_ receive is the receive variant that is _possible_ to use (and that is used whenever you call some other `gen_`\* behaviour client API using e.g `gen_statem:call/2` which sends a message and does a selective receive). You can do almost anything that does not block too long.

You **cannot** call `sys:handle_system_message/6,7` from your behaviour callback. It is supposed to only be called from the `proc_lib` process’ (in this case `gen_statem`’s) receive loop. If called from your callback module you hijack the receive loop and get an utter mess.

So, as said, it is “receive all” that cannot be used in a `gen_`\* behaviour callback.

I suspect you either should use selective receive in the same manner as e.g `gen_statem:call/2` or that you want to implement something like `gen_statem:send_request/2,4`, `gen_statem:check_response/2,3` and friends that solve the problem of how to call a server that blocks too long, by doing it asynchronously. Send a request which returns a request id, record the request id your state, later when handling an `info` message check if it is the response corresponding to the request id. With `gen_statem` you have the possibility to `postpone` a message that is not the response you were looking for.

---

<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 12, 2022, 10:08am UTC](https://erlangforums.com/t/gen-statem-receiving-data/1830/27 "2022-09-12T10:08:14Z")

</div>

The conclusion that I had from this topic is the answer to the question : why erlang atom ? it’s not simple to know the exact answer

---

<div class="post-metadata">

**Author:** ![raimo](https://erlangforums.com/user_avatar/erlangforums.com/raimo/32/867_2.png) [@raimo](https://erlangforums.com/u/raimo)\
**Post date:** [September 12, 2022, 11:10am UTC](https://erlangforums.com/t/gen-statem-receiving-data/1830/28 "2022-09-12T11:10:10Z")

</div>

> [@Abdelghani](#):
>
> why erlang atom

You lost me 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 12, 2022, 11:24am UTC](https://erlangforums.com/t/gen-statem-receiving-data/1830/29 "2022-09-12T11:24:00Z")

</div>

> [@raimo](#):
>
> You lost me there

trust me, it’s a tricky question, I mean everything know atoms and how to use them but why atom is so deeper I hope you can understand that

---

<div class="post-metadata">

**Author:** ![dischoen](https://erlangforums.com/user_avatar/erlangforums.com/dischoen/32/695_2.png) [@dischoen](https://erlangforums.com/u/dischoen)\
**Post date:** [September 12, 2022, 11:57am UTC](https://erlangforums.com/t/gen-statem-receiving-data/1830/30 "2022-09-12T11:57:33Z")

</div>

As a (so far) read-only member of this thread my takeaway would be

- if using behaviours, do not mess with the receive loop
- if non-behaviour receives are needed, handle them with info

And, not completely serious, the answer to why erlang atom is 42.

---

<div class="post-metadata">

**Author:** ![raimo](https://erlangforums.com/user_avatar/erlangforums.com/raimo/32/867_2.png) [@raimo](https://erlangforums.com/u/raimo)\
**Post date:** [September 12, 2022, 12:12pm UTC](https://erlangforums.com/t/gen-statem-receiving-data/1830/31 "2022-09-12T12:12:00Z")

</div>

> [@dischoen](#):
>
> if non-behaviour receives are needed, handle them with info

and

- Selective receive where you receive only exactly the message you want and do not wait for “too long” is ok.

---

<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 12, 2022, 12:29pm UTC](https://erlangforums.com/t/gen-statem-receiving-data/1830/32 "2022-09-12T12:29:32Z")

</div>

> [@dischoen](#):
>
> And, not completely serious, the answer to why erlang atom

No Iam serious, if you see that not serious I think @dischoen you should answer this : why not using strings (list of bytes) to represent what we represent as atom for example : `reply` will be `"reply"` and we have more perfomance using binaries ?

---

<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 12, 2022, 4:37pm UTC](https://erlangforums.com/t/gen-statem-receiving-data/1830/33 "2022-09-12T16:37:41Z")

</div>

I’m curious 🤔  
I’ll bite 🎣  
_Why_?

---

<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 12, 2022, 4:50pm UTC](https://erlangforums.com/t/gen-statem-receiving-data/1830/34 "2022-09-12T16:50:18Z")

</div>

As my understanding, it’s the atom of an erlang message, it’s the only thing that can’t be found on 2 differents erlang messages

---

<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 12, 2022, 4:52pm UTC](https://erlangforums.com/t/gen-statem-receiving-data/1830/35 "2022-09-12T16:52:18Z")

</div>

@Maria-12648430 I will upload a little server in github within few days that may help me to get a job, I want your support and all my brothers here

---

<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 12, 2022, 8:15pm UTC](https://erlangforums.com/t/gen-statem-receiving-data/1830/36 "2022-09-12T20:15:59Z")

</div>

> [@Abdelghani](#):
>
> As my understanding, it’s the atom of an erlang message, it’s the only thing that can’t be found on 2 differents erlang messages

Hm, not… exactly… (but I may just misunderstand, correct me if so).

Atoms are nice to tag a message to indicate the purpose or type of a message, but they certainly do _not_ make a message _unique_. In a nutshell, this means that they are not the best fit to (reliably) correlate requests and responses.

For the purpose of tagging requests and the respective replies, you should use references. References are, for all practical reasons, created unique (not _strictly_, but even if a scheduler thread did create a new reference every nanosecond, they would be reused only after about half a millennium, IIRC).

For example, imagine the following (contrived):

```erlang
F=fun() -> receive {request, ReplyTo, {A, B}} -> ReplyTo ! {reply, A+B} end end,
P1=spawn(F),
P2=spawn(F),
P1 ! {request, self(), {1, 2}},
P2 ! {request, self(), {3, 4}},
Sum1 = receive {reply, S1} -> S1 end,
Sum2 = receive {reply, S2} -> S2 end.

```

In the example above, it could be that `Sum1` is `3` and `Sum2` is `7`, but it could just as well turn out the other way round. It is indistinguishable what requests the replies belong to.

It is better done like this (equally contrived):

```erlang
F=fun() -> receive {request, {ReplyTo, Tag}, {A, B}} -> ReplyTo ! {reply, Tag, A+B} end end,
P1=spawn(F),
P2=spawn(F),
Tag1=make_ref(),
Tag2=make_ref(),
P1 ! {request, {self(), Tag1}, {1, 2}},
P2 ! {request, {self(), Tag2}, {3, 4}},
Sum1 = receive {reply, Tag1, S1} -> S1 end,
Sum2 = receive {reply, Tag2, S2} -> S2 end.

```

This way, the replies can be correlated to the requests using their `Tag*` references, so `Sum1` is always `3` (reply to the first request), and `Sum2` is always `7` (reply to the second request), even if they arrive in reverse order.

Btw, you don’t have to restrict yourself to either atoms or references, you can mix and mingle as needed.

`gen:call` is a nice example for all the above.

Finally, why do we like to use atoms (vs lists or binaries), here and everywhere else in Erlang? Because atoms are tiny and fast by design (and easily recognizable in code, other than integers would be), just 1 machine word. @garazdawi explained it nicely [here](https://erlangforums.com/t/on-garbage-collecting-atoms/1476/4). Lists and binaries are much more expensive to throw around.

---

<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 12, 2022, 11:19pm UTC](https://erlangforums.com/t/gen-statem-receiving-data/1830/37 "2022-09-12T23:19:09Z")

</div>

@Maria-12648430 You misunderstand me or maybe I hadn’t describe it as I thinked, you see I said that it’s not simple as appear 😀  
I mean by differents erlang messages the messages that are differents in their atom (I mean by atom here the real atom and not erlang atom),  
Of course I didn’t mean each erlang message have it’s atom that’s not logic but when using the `reply` atom that means that the message is a reply, it can’t be a request or a system message or last will from parent, the receive will catch always `reply` messages and postpone other messages, and when we use the `ack packet` atom we will catch only acknowledge packets and postpone everything else I can see how erlang is beautiful in it’s way to handle that… so 2 differents messages means two atom-different messages, that is, we can receive from a server differents types of messages but using atoms will be the golden way to never catch something by mistake, I hope this will clarify things

---

<div class="post-metadata">

**Author:** ![domi](https://erlangforums.com/user_avatar/erlangforums.com/domi/32/263_2.png) [@domi](https://erlangforums.com/u/domi)\
**Post date:** [September 13, 2022, 1:38am UTC](https://erlangforums.com/t/gen-statem-receiving-data/1830/38 "2022-09-13T01:38:16Z")

</div>

> [@Abdelghani](#):
>
> why not using strings (list of bytes) to represent what we represent as atom for example : `reply` will be `"reply"` and we have more perfomance using binaries ?

An atom is a reference to a constant. It’s just one word in size, and very fast to test for equality. Binaries are bigger, and to test for equality you need to compare the characters one by one. So pattern matching binaries (or charlists) is slower than atoms.

---

<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 13, 2022, 3:27am UTC](https://erlangforums.com/t/gen-statem-receiving-data/1830/39 "2022-09-13T03:27:36Z")

</div>

Excellent as usual, thank you @domi, I think I should get a minimal learning to machine structure and memory representation (I did it at the university but I forgot everything about)

---

<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 13, 2022, 3:32am UTC](https://erlangforums.com/t/gen-statem-receiving-data/1830/40 "2022-09-13T03:32:49Z")

</div>

Just another thing if you can answer @domi, `"reply" ` as string is coded via 5 bytes each byte represent the ASCII code of each character but I can’t imagine how the atom `reply` is coded if we don’t code it as above ?

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

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