Hi, all,<br><br>I hope I can explain my question adequately clear.<br><br>I am working on a solution in which a supervisor will monitor a number of generic workers. <br><br>To most messages, the worker will respond with an answer, but it may exit if certain conditions are true. I want the supervisor to kill all existing worker and restart them in case of any worker failure. Hence the use of "all_for_one".<br>
<br>I tried to illustrated this problem with a simplified version of the implementation. See the attached files.<br><br>sup.erl - the supervisor<br>worker.erl - the worker process. Implemented using gen_server. Whenever message "stupid_question" is received, it will exit.<br>
<br>Because I want to have several instance of the worker, so,<br><br>1) I used an auxiliary function to create an ad-hoc server name for each instance (process):<br><br><span style="font-family: courier new,monospace;">start(Name) -></span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">  ServerName = get_worker_id(Name),</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">  gen_server:start({local, ServerName}, ?MODULE, [ServerName], []).</span><br style="font-family: courier new,monospace;">
<br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">get_worker_id(Id) when is_integer(Id) -></span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">   list_to_atom(?SERVER_FAMILY ++ integer_to_list(Id));</span><br>
<br>2) I construct the following child process spec in my supervisor<br><br><span style="font-family: courier new,monospace;">{ok, {{all_for_one, 3, 10},</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">[{w1,{worker,start_link,[1]},</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">     permanent,brutal_kill,worker,</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">     [worker]},</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> {w2,{worker,start_link,[2]},</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">     permanent,brutal_kill,worker,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">     [worker]},</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;"> {w3,{worker,start_link,[3]},</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">     permanent,brutal_kill,worker,</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">     [worker]},</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;"> {w4,{worker,start_link,[4]},</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">     permanent,brutal_kill,worker,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">     [worker]}]</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">}}.</span><br style="font-family: courier new,monospace;">
<br><br><br>I have defined two test functions in sup.erl to facilitate testing (test1 and test2 respectively). <b>test1</b> is for testing in bash shell. <b>test2</b> is for testing within erl.<br><br>If I run test1 as such,<br>
<br><span style="font-family: courier new,monospace;">erl -pa . -boot start_sasl -s sup test1  -run init stop -config log -noshell</span><br><br>I got the following errors:<br><br><br><span style="font-family: courier new,monospace;">in start/0</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">superviosr PID: <0.37.0></span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">Asking worker_1 a {good_question}</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">in worker:start_link/1. Param worker_1</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">reply: {answer}</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">Asking worker_1 a {stupid_question}</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">signal {noproc,{gen_server,call,</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">                           [worker_1,{ask_something,{stupid_question}}]}}</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">Asking worker_1 a {good_question}</span><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">{"init terminating in do_boot",{noproc,{gen_server,call,[worker_1,{ask_something,{good_question}}]}}}</span><br style="font-family: courier new,monospace;"><br style="font-family: courier new,monospace;">
<span style="font-family: courier new,monospace;">Crash dump was written to: erl_crash.dump</span><br style="font-family: courier new,monospace;"><span style="font-family: courier new,monospace;">init terminating in do_boot ()</span><br style="font-family: courier new,monospace;">
<br><br>So, from what I can work out, when the worker process is dead after getting a stupid_question, it is not started by the supervisor at all. Therefore got a  noproc exception when the worker_1 is asked a good_question again.<br>
<br>If I changed the test case to use worker 2 instead of 1, then it is obvious that the worker 2 to 4 are not started at all.<br><br>So, the questions I want to ask are<br>1) what mistakes I have made in this code?<br>2) Why worker 1 is not restarted?<br>
3) Why worker 2 to 4 are not started at all?<br>4) the worker instance and gen_server: I used list_to_atom() to create unique processes of worker. Is it a valid approach?<br><br>Cheers, <br><br>Anthony<br>-- <br>/*--*/<br>
Don't EVER make the mistake that you can design something better than what you get from ruthless massively parallel trial-and-error with a feedback cycle. That's giving your intelligence _much_ too much credit.<br><br>- Linus Torvalds<br>