[erlang-questions] object vs. actor (Re: Massive Numbers of Actors vs. Massive Numbers of Objects vs. ????)
Jeff Schultz
jws@REDACTED
Sun Mar 11 02:03:06 CET 2012
On Thu, Mar 01, 2012 at 02:42:34PM -0500, Miles Fidelman wrote:
> Garrett Smith wrote:
>> Erlang processes aren't persisted, but their state can be, quite easily.
>> A trivial example, in an Erlang shell:
>> 1> Add = fun(X, Y) -> X + Y end.
>> 2> Add(10, 10).
>> 100
>> 3> file:write_file("addfun", term_to_binary(Add)).
>> 4> init:stop().
>> And restart Erlang shell:
>> 1> {ok, Bin} = file:read_file("addfun").
>> 2> Add = binary_to_term(Bin).
>> 3> Add(10, 10).
>> 100
> That's not persisting a process' state, though. It's not so easy to say:
> 1. spawn, say, 10,000 gen_fsms,
> 2. run for a while
> 3. save the internal state of those 10,000 state machines
> 4. stop the shell (really the VM)
> 5. restart
> 6. restore those state machines, complete with their original PIDs
It's a small part of the overall application you're building, but
doing almost all of that is pretty easy, and rather fun. Here's a
simple example:
-module(per).
-export([start/1]).
loop(State) ->
io:format("Looping from ~p~n", [State]),
receive
{inc, X} ->
io:format("Incrementing ~p by ~p~n", [State, X]),
loop(State + X);
suspend ->
io:format("Suspending with state ~p~n", [State]),
fun() -> loop(State) end
end.
start(InitialValue) ->
outer(loop(InitialValue)).
outer(Computation) ->
outer(Computation()).
38> Pid = spawn(per, start, [10]).
Looping from 10
<0.121.0>
39> Pid ! {inc, 5}.
Incrementing 10 by 5
{inc,5}
Looping from 15
40> Pid ! suspend.
Suspending with state 15
suspend
Looping from 15
41> Pid ! {inc, 3}.
Incrementing 15 by 3
{inc,3}
Looping from 18
42> Pid ! suspend.
Suspending with state 18
suspend
Looping from 18
Note that the fun returned from loop/1 on receipt of the suspend
message captures the current State.
This doesn't do your point 6. The process running loop/1 gets a new
PID each time it's restarted, but if you're depending on Erlang PIDs
to find a *persistent* resource, you're going to have trouble the
first time something goes down anyway.
Jeff Schultz
> Fairly straightforward to:
> 1. spawn 10,000 gen_fsms
> 2. add their PIDs to a name-to-PID lookup table
> 3. include logic such that an inactive fsm
> - times out
> - writes it's state to a file
> - updates the name-to-PID table to point the file
> - kill itself
> 4. write a listener that takes incoming messages, identifies the associated
> fsm by name and either
> - passes the message to the file, or
> - loads and restarts the process, then passes the messages
> What I've really done is rewrite erlang's hibernation functionality.
More information about the erlang-questions
mailing list