views:

145

answers:

3

Is it possible to cascade supervisors inside an application?

E.g. supervisor sup1 spawning a child process which creates a supervisor sup2 ?

+7  A: 

You probably want to add the child as supervisor.

It is an entry in the childspec of a child of a supervisor. The "type" of the child can be set to "supervisor":

http://www.erlang.org/doc/design%5Fprinciples/sup%5Fprinc.html#spec

Probably you can do it via the child starting a supervisor itself too but it is at least less elegant and it is less evident what you are doing.

HTH, h.

haavee
+3  A: 

Yes, you can simply add supervisors as children of a supervisor. Or mix and match. I do something like this usually:

(in my top level supervisor)

init([]) ->
    Args = [],
    ModuleArray = [get_info(Module, Args)
        || Module
        <- [emx_nodestate, emx_sup_data, emx_sup_util, emx_sup_api,
            emx_flow]],
    {ok, {{one_for_one, 3, 1}, ModuleArray}}.

get_info(Module, Args) ->
    {Module, {Module, start_link, [Args]}, permanent, 10000,
     worker, [Module]}.

And then something like emx_sup_data (behaviour supervisor) contains:

init([]) ->
    Args = [],
    ModuleArray = [get_info(Module, Args)
        || Module <- [job_housekeep]],
    {ok, {{one_for_all, 3, 1}, ModuleArray}}.

get_info(Module, Args) ->
    {Module, {Module, start_link, [Args]}, permanent, 10000,
     worker, [Module]}.

and something like emx_nodestate (behaviour gen_server)

init([]) ->
    {ok, #state{status=starting, interested=[]}}.

Works like a dream...!

Alan Moore
This is exactly what I meant by saying it is not _quite_ what you might want to do.Take the "emx_sup_data" top-level supervisor child. In its childspec (as returned by toplevelsupervisor:get_info/2) it is defined to be a child of type "worker" whilst in reality it is, as you yourself claim, of the "supervisor behaviour" persuasion.In that case it is better to mark it as such in the childspec of the top-level supervisor by setting Type=supervisor rather than worker.
haavee
Yes you're certainly right that it should be marked as supervisor, even if it's only just good for documentation. But that setting doesn't change the behavior of the top level supervisor at all - the above fragment is from a real application that works exactly as desired. In the current OTP release, either is actually valid and it simplified my code above to hard code them to workers...!
Alan Moore
+2  A: 

To see how other folks structure their apps why dont you fire up a shell and run the toolbar:

toolbar:start()

That gives you a graphical view of a supervisor heirarchy. A quick look at the kernel supervisor tree, or mnesia or yaws, will show you what a 'normal' supervisor tree looks like.

You compose an application of sub-systems supervised by an application supervisor. Each sub-system can be many sub-sub-systems under the sub-system supervisor (continue applying pattern in recursive functional manner until you run out of granularity...)

Gordon Guthrie
Thanks for this suggestion!
jldupont