[erlang-questions] gen_fsm + handle_info = spaghetti code?

Jachym Holecek freza@REDACTED
Mon Aug 5 20:32:53 CEST 2013


# Fred Hebert 2013-08-05:
> I would consider having a middle-man process whose role is to deal with
> the NIF code, and turns messages received into gen_fsm events.

Notice that the return convention of handle_info/3 and State_name/2 is
the same, so you can just do:

  handle_info(Info, State_name, State_data) ->
      ?MODULE:State_name(Info, State_data);

No middleman process needed, and you still get your full-on state machine.

That said, I find gen_fsm's event wrapping habit annoying in maybe half of
the cases where I do want a FSM, so I wrote a 'fsm' behaviour which is very
close to gen_fsm but avoids the wrapping. Can publish that after a little
bit of polishing if there's interest (it has some other extra niceties, but
nothing major).

BTW you'll sometimes see people doing this to "solve" the same problem:

  handle_info(Info, State_name, State_data) ->
      gen_fsm:send_event(self(), Info);

Which is obviously incredibly broken -- for one it reorders messages and
for other it does so unpredictably!

> Alternatively, the NIF could cheat and use the internal gen_fsm wrapping
> of messages ({'gen_event', Event}, where Event is the original message).
> the gen_fsm process will receive that message and think of it as if it
> were sent as an asynchronous event through the regular gen_fsm
> functions, and call your own custom states.
> 
> This is a bit messier given you break the abstraction, but should be
> faster at run time than having a middle-man just forward stuff.

That strikes me as a clean approach also: it solves the problem in a very
simple and straightforward way, it doesn't introduce any undue (and, more
importantly, any realistic) risks, and the question of "breaking the abs-
traction" could be argued to be largely a matter of perception in this
case and also to be somewhat overrated in general. Overall, what's there
not to like?

[Here I'm speaking as someone who's doing gen_server:reply/2 shamelessly
from a NIF thread in one project. :-) It was the best way to get the flow
control I needed in given circumstances, abstractions broken or not...]

BR,
	-- Jachym



More information about the erlang-questions mailing list