[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