[erlang-questions] Best practices in gen_fsm usage
Vance Shipley
vances@REDACTED
Wed Dec 7 09:00:17 CET 2011
On Wed, Dec 07, 2011 at 01:31:42PM +0700, Maxim Treskin wrote:
} 1. gen_fsm incompatible with gen_server. We cannot use synchronous call
} from gen_server for gen_fsm because it different.
Are you suggesting that you should be able to write:
Reply = Module:call(Ref, Request)
Where Ref is a reference to either a gen_server a or gen_fsm?
You still need to use the correct module. I don't see how much
that helps you over:
Reply = case Module of
gen_server ->
gen_server:call(Ref, Request);
gen_fsm ->
gen_fsm:sync_send_event(Ref, Request)
end
} 2. Two different actions: send_event и send_all_state_event with different
} handlers. Why? If we want to send message to FSM, we just send message to
} process without knowledge of its internal state-related issues, right?
When you call gen_fsm:send_event/2 to send an event the function
StateName/2 in your callback module will be called for any state.
You don't need to use send_all_state_event/2 at all. If you do
it is processed in your callback module's handle_event/3 function
and not the individual state's event handler StateName/2.
} 3. For complex protocols and when one message emits almost equal actions in
} various process states, code of gen_fsm-process becomes pumpkinized. Every
} time I start writing a new gen_fsm module, I think that this time the code
} will not become pumpkinized, but this wrong. Large number of pattern
} matching with records in events and internal state of process in various
} state handlers makes code duplicated and unreadable.
How can it be any other way? You say "_almost_ equal actions in
_various_ process states". So it's not all states and not the same
action. Therefore you need to uniquely handle events in states.
} Is there any best practices in gen_fsm usage? May be I and other people
} uses gen_fsm improperly?
Obviously putting common processing in seperate functions and calling
them from the state handlers is the way to handle 3.
If you still have a problem with 1 or 2 you might want to just simply
send messages ('Ref ! Request') and handle them in
gen_server:handle_info/2 and gen_fsm:handle_info/3.
If you are still unsatisfied you could implement your own FSM
behaviour in place of gen_fsm. You may find this thread interesting:
http://erlang.org/pipermail/erlang-questions/2005-April/015097.html
--
-Vance
More information about the erlang-questions
mailing list