[erlang-questions] preserving state through a gen_server restart
James Aimonetti
james@REDACTED
Sat Oct 20 07:59:34 CEST 2012
On Sat, 20 Oct 2012 00:04:31 -0400
Siraaj Khandkar <siraaj.khandkar@REDACTED> wrote:
> On Oct 19, 2012, at 11:03 AM, Ivan Uemlianin wrote:
>
> > Dear All
> >
> > I have an erlang/OTP application consisting mostly of gen_servers. One
> > repeated pattern is having a gateway/aggregate gen_server process that
> > provides access (and other management) to individual gen_server processes,
> > e.g.:
> >
> > my_sup
> > |
> > my_lambs
> > / \ \
> > my_lamb my_lamb my_lamb ...
In the interest of a non-ETS idea, perhaps consider changing your hierarchy to
something like this:
my_sup
/ \
my_lambs_sup my_lambs_srv
/ \
my_lamb my_lamb
I don't know how the name->pid mapping occurs, but assuming the my_lamb process
knows its name (as part of its state) you can do a couple things, I think.
1) In my_lambs_sup, have a start_lamb function that, after starting the my_lamb
process, sends the pid() to my_lambs_srv:add_lamb.
2) When my_lambs:add_lamb is called, ask the my_lamb process for its name
(again, assuming it knows its name), and do a gen_server:cast(Srv, {add_lamb,
Pid, Name}) to update the dict.
3) Should the my_lambs process die, you could do something like this in init/1:
init([]) ->
... do stuff ...
[my_lambs_srv:add_lamb(P)
|| {_,P,_,_} <- supervisor:which_children(my_lambs_sup)
],
... do other stuff
{ok, #state{}}.
Since add_lamb/1 is a cast, you won't have a weird deadlock in the gen_server's
init. As long as you structure your my_sup to start the my_lambs_sup supervisor
first, it will be able to respond to the which_children/1 call as well. Should
allow you to rebuild the state fairly quickly and accurately on restart of the
my_lambs_srv process (and should work on clean start too).
Anyway, rudimentary attempt here but might be useful or instructive?
> >
> > my_lambs' state variable holds a dictionary {LambName: LambPid} and among
> > other functions it allows me to call lambs by name instead of my Pid.
> >
> > If my_lambs terminates normally --- e.g., if the whole application is
> > closing down --- its terminate/s function can call my:lamb:stop for each of
> > the processes in its care.
> >
> > However, if my_lambs terminates abnormally, and is restarted by my_sup, I
> > think I'd like to preserve its state variable --- at least the Pids of the
> > my_lamb processes --- so that it can be passed on to the new version of
> > my_lambs.
> >
> > I'd like to avoid losing all of the my_lamb processes, if the my_lambs
> > process crashes.
> >
> > Can state be passed to the supervisor, to be used when it restarts its
> > child?
> >
> > Could I park the state variable in some kind of holding process, so that
> > the new my_lambs can retrieve it?
> >
> > Or is there another way of doing this?
>
>
> Seems like ETS is the natural choice for this sort of thing.
>
>
--
James Aimonetti
Distributed Systems Engineer / DJ MC_
2600hz | http://2600hz.com
sip:james@REDACTED
tel: 415.886.7905
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 490 bytes
Desc: not available
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20121019/83a89f2d/attachment.bin>
More information about the erlang-questions
mailing list