programacion - Erlang: iniciar un hijo desde el módulo supervisor
erlang telecomunicaciones (2)
Estoy tratando de crear un supervisor que se encargue de agregar gen_servers dinámicos. por alguna razón, algo está fallando y no estoy muy seguro de qué.
-module(supervisor_mod).
-behaviour(supervisor).
-export([start_link/0, add_child/1]).
-export([init/1]).
start_link() ->
Pid=supervisor:start_link({local, ?MODULE} , ?MODULE, []),
{ok,Pid}.
init(_Args) ->
{ok, {{simple_one_for_one, 10, 60},
[{example_proc, {example_proc, start_link, []},
permanent, brutal_kill, worker, [example_proc]}]}}.
add_child(Name)->
supervisor:start_child(supervisor_mod,
{example_proc, {example_proc, start_link, []},
permanent, brutal_kill, worker, [example_proc]}).
y
-module(example_proc).
-behaviour(gen_server).
-export([start_link/0]).
-export([init/1, handle_call/3, handle_cast/2]).
start_link() ->
gen_server:start_link(?MODULE, [], []).
init(Args) ->
io:format("~p (~p) started...~n", [Args, self()]),
{ok, []}.
handle_call(alloc, From, State) ->
{reply, From, State}.
handle_cast({free, _Ch}, State) ->
{noreply, State}.
en shell Erl:
Eshell V5.8.2 (abort with ^G)
1> supervisor_mod:start_link().
{ok,{ok,<0.33.0>}}
2> supervisor_mod:add_child(aa).
{error,{''EXIT'',{badarg,[{erlang,apply,
[example_proc,start_link,
{example_proc,{example_proc,start_link,[]},
permanent,brutal_kill,worker,
[example_proc]}]},
{supervisor,do_start_child_i,3},
{supervisor,handle_call,3},
{gen_server,handle_msg,5},
{proc_lib,init_p_do_apply,3}]}}}
Cualquier ayuda / explicación / solución es apreciada, / s.
Cuando use simple_one_for_one
todos los niños usarán la misma ChildSpec, la que se proporciona en la devolución init/1
llamada init/1
y esta inicialización solo puede devolver un ChildSpec. También en este caso, el segundo argumento para el supervisor:start_child/2
debe ser una lista y NO una ChildSpec. Esta lista es una lista de argumentos adicionales que se anexa a la lista de argumentos dada en la ChildSpec por defecto y es esta lista de argumentos combinados la que se usa cuando se llama a la función de inicio del niño. Así es como todos los niños simples_un_para_uno pueden usar el mismo ChildSpec y aún así pueden obtener argumentos específicos para ellos.
En su caso, ya que había una lista vacía en el ChildSpec y llamó a start_child/2
con una lista vacía, el número total de argumentos para la función de inicio fue 0
. Que coincide con cómo se start_link/0
su función start_link/0
.
En su caso, una alternativa es usar one_for_one
y comenzar cada hijo con su propia ChildSpec. Más complejo pero también más versátil.
Lamentablemente, este uso dual del supervisor:start_child/2
ha hecho que sea inconsistente en sus argumentos.
Lea el OTP Doc: en el caso de una estrategia simple uno a uno, en la función start_child puede pasar argumentos como una lista para la función child start_link del niño.