plain_fsm support for hibernation

Ulf Wiger (AL/EAB) ulf.wiger@REDACTED
Fri Jul 9 15:08:13 CEST 2004


I've added support for hibernation in plain_fsm.
It's checked into Jungerl, but it may be a while before the anonymous CVS is updated.

The first one to actually find a use for this in a commercial application wins a free beer at the SIGPLAN Erlang Workshop 2004 in Snowbird!  ;)

The idea is based on the rather unique feature of erlang:hibernate/3 that it calls a user function when a message arrives, but _before_ it is consumed. If one inserts some bootstrapping code in the "wakeup" call, it's possible to automatically transform state before entering the code containing receive clauses. This allows for cleaner state machines, and also makes it reasonably convenient to upgrade lots of dynamic processes on-demand (there are other issues to consider as well, of course.)

Example, from the fsm_example.erl module in plain_fsm:

idle(S) ->
    plain_fsm:extended_receive(
      receive
	  a ->
	      io:format("going to state a~n", []),
	      plain_fsm:hibernate(?MODULE,a,[S]);
	  b ->
	      io:format("going to state b~n", []),
	      b(S)
      after 10000 ->
	      io:format("timeout in idle~n", []),
	      idle(S)
      end).


a(S) ->
    receive
	b ->
	    io:format("going to state b~n", []),
	    plain_fsm:hibernate(?MODULE,b,[S]);
	idle ->
	    io:format("going to state idle~n", []),
	    idle(S)
    end.

The function plain_fsm:hibernate/3 is transformed during compilation to the following:

         erlang:hibernate(plain_fsm,wake_up,[data_vsn(),
                          fsm_example,fsm_example,a,[S]]);

(You can inspect this by compiling with the -P option.)

Combined with some helpful printouts from plain_fsm:wake_up/5 (commented out by default), we can get the following visualization:

17> P ! a.         
waking up, new code version - will call code_change().
messages: {messages,[a]}
OldState = {newstate,3}
a
New state = {newstate,4}
going to state a
18> l(fsm_example).
{module,fsm_example}
19> P ! b.         
going to state b
b
20> P ! b.
waking up, new code version - will call code_change().
messages: {messages,[b]}
OldState = {newstate,4}
b
New state = {newstate,5}


/Uffe



More information about the erlang-questions mailing list