[erlang-questions] "calling" a gen_fsm

zxq9 zxq9@REDACTED
Wed Sep 23 06:31:24 CEST 2015


On 2015年9月23日 水曜日 00:01:07 Garry Hodgson wrote:
> On 9/22/15 3:02 PM, Roger Lipscombe wrote:
> > On 22 September 2015 at 18:37, Garry Hodgson <garry@REDACTED> wrote:
> >> thanks to both of you for your quick and helpful answers.
> >> gotta love this list.
> > Both Theepan and Vance are correct in that this is a useful way to
> > build this kind of thing. In fact, there's a good example (using a
> > gen_server, rather than a gen_fsm) here:
> > https://erlangcentral.org/wiki/index.php?title=Building_Non_Blocking_Erlang_apps
> very nice.
> > I'd just add one point, though: I recently built something similar,
> > and I found it simpler to separate the client into two processes: one
> > gen_fsm to handle the state machine, and a separate gen_server to
> > handle the decoding and framing.
> i briefly considered that, but it wasn't obvious how to divide the
> work between the two. i'd be interested in how you did, if you'd
> care to elaborate.

When I have two identical processes that need to speak synchronously or when I have something like a gen_fsm that must remain responsive while something other activity it initiates is carried out I tend to spawn_link or spawn_monitor a one-off process to do the work and let it exit(normal) when the task is done. This sidesteps some obvious deadlocks in synch communications and lets an fsm control flow without getting tied down in execution.

To use the fsm movie ticket counter example, the ticket counter accepts tickets or not based on its state, but it isn't concerned with the verification of the tickets or what the newly authorized folks do once they enter. Those extended tasks can be independent processes. If they are their own conceptual tasks (people entering the theater, for example) they should be under their own supervisor; if its non-blocking verification you need then it may make sense to just spawn_link or spawn_monitor a tiny task that knows where to send an {auth_message, #ref} when it is complete -- but this could very well be rolled into session management and the fsm spawns a new session which then makes sense to be under its own supervisor.

The choice is up to you. I think the trend is to build bigger processes and try to make everything a gen_* -- even when that's an awkward fit (like socket handling, imo, is a better fit for a pure Erlang process started via proc_lib).

>From the perspective of the supervisor tree a one-off process is part of the gen_fsm; the choice to link or monitor is based on how task failure fits in with your concept of state -- with an fsm guiding things this choice is usually pretty obvious (hence the choice of an fsm...). Don't make the mistake of making the gen_fsm become a supervisor, though -- that is the path to madness; when you need supervision do it for real.

This idea of spawning short-lived processes to handle one-off tasks is occasionally viewed as heresy. YMMV.

-Craig



More information about the erlang-questions mailing list