Hi Angel!<div><br></div><div>Thanks for pointing out this problem!</div><div><br></div><div>While one might agree that the design decision was not very good here, it is, as Robert points out, a totally backwards incompatible change you wish to do. And even though simple_one_for_one is not the most used supervisor type, it is for sure used and it is not an option for us to do such a change.</div>
<div><br></div><div>However, I do agree that the documentation could be better here, and I will write a ticket to make sure the issue is not forgotten. As always, a user contribution might very well make this change happen faster than our own priorities else would allow :)</div>
<div><br></div><div>Best regards</div><div>/siri@otp<br><br><br><div class="gmail_quote">2012/6/22 Angel J. Alvarez Miguel <span dir="ltr"><<a href="mailto:clist@uah.es" target="_blank">clist@uah.es</a>></span><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
i did'nt find any example of mixing args from the supervirsor childspec<br>
and start_child(...) so im going to make my own digging in this issue:<br>
<br>
Let see How the simple_one_by_one works...<br>
<br>
handle_call({start_child, EArgs}, _From, State) when ?is_simple(State) -><br>
Child = hd(State#state.children),<br>
#child{mfargs = {M, F, A}} = Child,<br>
Args = A ++ EArgs,<br>
case do_start_child_i(M, F, Args) of<br>
<------>{ok, undefined} when Child#child.restart_type =:= temporary -><br>
<------> {reply, {ok, undefined}, State};<br>
<------>{ok, Pid} -><br>
<------> NState = save_dynamic_child(Child#child.restart_type, Pid, Args, State),<br>
<------> {reply, {ok, Pid}, NState};<br>
<------>{ok, Pid, Extra} -><br>
<------> NState = save_dynamic_child(Child#child.restart_type, Pid, Args, State),<br>
<------> {reply, {ok, Pid, Extra}, NState};<br>
<------>What -><br>
<------> {reply, What, State}<br>
end;<br>
<br>
<br>
Shouldnt be do_start_child_i(M,F,EArgs) of the form :<br>
<br>
do_start_child(M,F,[EArgs]) ??<br>
<br>
or the inner call apply(M,F,[A])?<br>
<br>
Provided the docs state that your unique exported funcion must be of arity one you should<br>
expect that code will take measures in order to enforce arity one, enclosing whatever you pass it in a List on the apply phase.<br>
<br>
The semanctics of apply use a list to KNOW how many args the target call has, while the<br>
semantics of sup childspec + sup start_child use a list ++ op to know how many args will be passed<br>
to your callback of arity ONE.<br>
<br>
So for the apply part all your functions are arity ONE<br>
<br>
Without the ability to join Args from the ChildSpec and from the start child call i would concur that you should<br>
enclose in a list whatever you want to be as a sole argument and this code be ok, but as soon as you can put<br>
two or more args one on the ChildSpec and one on the call Sup code must enforce that only one arg APPLY<br>
call is made so you end calling start_link/1 whatever you pass on the args...<br>
<br>
Even the DOCS state "[ term() ]" as the MFA on the ChildSpec<br>
<br>
<br>
My stdlib-1.18.1.pdf says (Pag 369)<br>
<br>
"start_child(SupRef, ChildSpec) -> startchild_ret()<br>
Types:<br>
SupRef = sup_ref()<br>
ChildSpec = child_spec() | (List :: [term()])<br>
...<br>
...<br>
<br>
...If the case of a simple_one_for_one supervisor, the child specification defined in Module:init/1 will be<br>
used and ChildSpec should instead be an arbitrary list of terms List. The child process will then be started by<br>
appending List to the existing start function arguments, i.e. by calling apply(M, F, A++List) where {M,F,A}<br>
is the start function defined in the child specification."<br>
<br>
Here IMHO lies the error, as A is a list we have [any()...] ++ [any()...] is a list [any()...,any()...] and thats get us an apply<br>
call of arity > 1 ALWAYS even when you chilkdspec has a {M,F,[]} and you try provide a [..] in your start_child it will fail<br>
unless both argslists are void.<br>
<br>
So a combination of:<br>
<br>
init(Opts) -><br>
io:format("[GROUP SUP] Ready to manage MuC with opts: ~p\'s\n",[Opts]),<br>
<br>
{ok, {<br>
{simple_one_for_one, 1, 60},<br>
[<br>
{mucfsm, {sim_group_fsm, start_link, [arg1,arg2]}, transient, 60, worker, [sim_group]}<br>
]<br>
}<br>
}.<br>
<br>
<br>
and a client that makes a call like:<br>
...<br>
{ok,ChildPid} = supervisor:start_child(SupPid,[arg3,arg4]),<br>
...<br>
<br>
Gets you a final apply call {M,F,A} where A is in the form [arg1,arg2,arg3,arg4]<br>
not [[arg1,arg2,argf3,arg4]] at is should be when you intent to call a start_link/1....<br>
<br>
<br>
<br>
Erlang R15B01 (erts-5.9.1) [source] [64-bit] [smp:4:4] [async-threads:0] [hipe] [kernel-poll:false]<br>
<br>
[QuickCheck] [PropEr] [Erl0MQ]<br>
Starting simple_one_by_one group supervisor...<br>
[GROUP SUP] staring with argument: [{option1,40}]<br>
Eshell V5.9.1 (abort with ^G)<br>
1> [GROUP SUP] Ready to manage MuC with opts: [{option1,40}]'s<br>
Adding a child dynamically...<br>
{"init terminating in do_boot",{{badmatch,{error,{'EXIT',{undef,[{sim_group_fsm,start_link,[arg1,arg2,arg3,arg4],[]},{supervisor,do_start_child_i,3,[{file,"supervisor.erl"},{line,319}]},{supervisor,handle_call,3,[{file,"supervisor.erl"},{line,344}]},<br>
{gen_server,handle_msg,5,[{file,"gen_server.erl"},{line,588}]},{proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,227}]}]}}}},[{test,main,0,[{file,"test.erl"},{line,11}]},{init,start_it,1,[]},{init,start_em,1,[]}]}}<br>
<br>
<br>
/Angel<br>
<br>
On Jueves, 21 de Junio de 2012 09:30:15 Angel J. Alvarez Miguel escribió:<br>
> That's right...<br>
><br>
> But start_link it is expected to be or arity 3 and Opts is a property list.<br>
><br>
> but then on test:main/0 when i do supervisor:start_child(SupPid,Opts2)<br>
><br>
> being Opts2 another property list, then suppervisor should call:<br>
><br>
> apply(sim_group_fsm,start_link,Opts ++ Opts2) on its line 319 which in turn<br>
> calls gen_fsm:start_link, thus providing a Pid in the end...<br>
><br>
> but what it really does is apply(sim_group_fsm,start_link,Opts ++ Opts2,[<br>
> ]) and then crashes unless i declare a start_link/2 on my gen_fsm...<br>
><br>
> {<br>
> {badmatch,<br>
> {error,<br>
> {'EXIT',<br>
> {undef,<br>
> [<br>
> {sim_group_fsm,start_link,[[{option1,40}],[{option29,100}]],[]},<br>
> {supervisor,do_start_child_i,3,[<br>
> {file,"supervisor.erl"},<br>
> {line,319}<br>
> ]}......<br>
><br>
> i dont see why i finish having a apply/4 call in supervisor: 319 instead of<br>
> an apply/3...<br>
><br>
> I want the sup to propagate one property list to children specs while i<br>
> will provide another during children spawns providing that sup combines<br>
> two in any way children will manage to demunge ...both property lists<br>
><br>
> So cant just see what im doing wrong....<br>
><br>
> /angel<br>
><br>
><br>
> PS: i changed a bit the test code to force sup crash<br>
><br>
> On Jueves, 21 de Junio de 2012 06:22:54 Vance Shipley escribió:<br>
> > On Thu, Jun 21, 2012 at 12:30:08AM +0200, Angel J. Alvarez Miguel wrote:<br>
> > } While calling a simple_one_by_one supervisor to start a gen fsm I<br>
> > found } it causes calling a start_link/2 function on the callback<br>
> > module of the } gen_fsm.<br>
> ><br>
> > You are specifying that function to be called to start the worker<br>
> > yourself. In your module group_supervisor.erl you provide a child_spec()<br>
> > in the<br>
> ><br>
> > return value of init/1:<br>
> > {mucfsm, {sim_group_fsm, start_link, [Opts]}, transient, 60, worker,<br>
> ><br>
> > [sim_group]}<br>
> ><br>
> > The form of which is:<br>
> > {Id, StartFunc, Restart, Shutdown, Type, Modules}<br>
> ><br>
> > The second argument, StartFunc, has the form:<br>
> > {Module, Function, Arguments}<br>
> ><br>
> > You provided:<br>
> > {sim_group_fsm, start_link, [Opts]}<br>
_______________________________________________<br>
erlang-questions mailing list<br>
<a href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a><br>
<a href="http://erlang.org/mailman/listinfo/erlang-questions" target="_blank">http://erlang.org/mailman/listinfo/erlang-questions</a><br>
</blockquote></div><br></div>