[erlang-questions] "calling" a gen_fsm
Wed Sep 23 15:25:30 CEST 2015
An opposing view...
On 2015年9月23日 水曜日 16:26:21 Theepan wrote:
> I don't think it is a good idea to separate the state maintenance from the
> real work that is happening, unless you have a strong reason for it. What
> happens if you separate them is that you are keeping a process just for
> state maintenance, and most of the time the gen_fsm process is going to be
> idle. Other drawback is that the worker process will have to constantly
> check the state machine to ensure that it doing work at the correct state.
> There is a chance of off state processing and it is hardware hungry.
I almost completely disagree with this view. I find gen_fsm to be useful specifically so that I can use an OTP process "just for state maintenance" -- sometimes this means a system composed mostly of tiny fsms, but more often it just means fsms are acting as logical gateways to control processing flow throughout the system (the valves and gateways of my digital kingdom).
I *like* this separation because it makes the overall system much easier to reason about and modify. Some really huge system-wide behaviors can be modified very simply this way.
As for being "hardware hungry"... I've never run into this problem. My gen_fsms tend to be really tiny, take up very little memory (generally ending with very close to the same number of bits as they started), and hardly running at all (sometimes good candidates for hiberation -- but usually there isn't any call for this). I really have a hard time understanding performance arguments (in terms of memory or processing time) against spawning temporary processes to get work done and terminating them when they are complete, as I have *never* encountered a case where this was actually a performance problem (at least not a noticeable one). Perhaps I'm just doing very different things with Erlang than everyone else -- but in any case without knowing the context *any* effort to deliberately increase instead of decrease the number of responsibilities a process has for performance reasons is headed in the wrong direction.
At the very least when hacking around a problem I find it most useful to segregate as many responsibilites as possible early on, and that means gen_fsms are *only* finite-state machines, and they control processing flow based on their state. Any points of extended work are things I *want* to put in other processes, if for no other reason than an "idle" gen_fsm is a *highly responsive* gen_fsm. This helps me know more about the way a system responds under load (if this is even a concern) because I can just see what work is being spawned and how long bits of it is sticking around instead of trying to figure out how busy a given pack of fsms is. Sometimes (usually?) after some initial development I wind up moving things into a very different configuration because I understand the problem better, the needs of the system solidify a bit, any bottlenecks become obvious (and finding ways to avoid having them to begin with is usually pretty easy once the system is better understood), etc. But to start out with, ghah, putting more duties into a process than less has just never worked out very well for me.
> There are places where you will separate the state maintenance, for
> instance many workers depending on a single state. At the low level gen_fsm
> and gen_tcp are just Erlang process, and what you are trying to do right
> now is good for what you are doing.
"Many workers depending on a single state." I'm trying to see where this is meaningful without an elaboration.
More information about the erlang-questions