<div>
            <div>
                <span>Hi,<br>
                </span></div><div><span><br></span></div><div><span>I've got some strange behaviour with gen_event within a supervision tree which I don't fully understand.  Consider the following supervisor (completely standard, feel free to skip over):</span></div><div><span><br></span></div><div><snip></div><div><br></div><div><span><div>-module(sup).</div><div>-behaviour(supervisor).</div><div>-export([start_link/0, init/1]).</div><div>-define(SERVER, ?MODULE).</div><div><br></div><div>start_link() -></div><div>    supervisor:start_link({local, ?SERVER}, ?MODULE, []).</div><div><br></div><div>init([]) -></div><div>    Child1 = {child, {child, start_link, []}, permanent, 2000, worker, [child]},</div><div>    {ok, {{one_for_all, 1000, 3600}, [Child1]}}.</div><div><br></div><div></snip></div><div><br></div><div>and corresponding gen_server (interesting code in bold):</div></span></div><div><span><br></span></div><div><span><snip></span></div><div><span><br></span></div><div><span><div>-module(child).</div><div>-behaviour(gen_server).</div><div>-export([start_link/0, init/1, handle_call/3, handle_cast/2, </div><div><span class="Apple-tab-span" style="white-space:pre">        </span> handle_info/2, terminate/2, code_change/3]).</div><div><br></div><div>start_link() -></div><div>    gen_server:start_link({local, child}, child, [], []).</div><div><br></div><div><b>init([]) -></b></div><div> <b>   io:format("about to start gen_event~n"),</b></div><div><b>    X = gen_event:start_link({local, my_gen_event}),</b></div><div><b>    io:format("gen_event started with ~p~n", [X]),</b></div><div><b>    {ok, _Pid} = X,</b></div><div><b><br></b></div><div><b>    {ok, {}, 2000}.</b></div><div><br></div><div>handle_call(_Request, _From, State) -></div><div>    {reply, ok, State}.</div><div><br></div><div>handle_cast(_Msg, State) -></div><div>    {noreply, State}.</div><div><br></div><div><b>handle_info(_Info, State) -></b></div><div><b>    io:format("about to crash...~n"),</b></div><div><b>    1 = 2,</b></div><div><b>    {noreply, State}.</b></div><div><br></div><div>terminate(_Reason, _State) -></div><div>    ok.</div><div><br></div><div>code_change(_OldVsn, State, _Extra) -></div><div>    {ok, State}.</div><div><br></div><div></snip></div><div><br></div><div>If I run this from an erl shell like this:</div><div><br></div><div><snip></div><div><br></div><div><div>--> erl</div><div>Erlang R14B01 (erts-5.8.2) [source] [64-bit] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false]</div><div><br></div><div>Eshell V5.8.2  (abort with ^G)</div><div>1> application:start(sasl), supervisor:start_link(sup, []).</div></div><div><br></div></span></div><div>
                <span></snip><br><div><br></div><div>Then the supervisor & server start as expected.  After 2 seconds the server gets a timeout message and crashes itself; the supervisor obviously spots this and restarts it.  Within the init of the gen_server, it also does a start_link on a gen_event process.  By my understanding, whenever the gen_server process exits, the gen_event will also be terminated.</div><div><br></div><div>However, every now and then I see the following output (a ton of sasl trace omitted for clarity!):</div><div><br></div><div><snip></div><div><br></div><div><div>about to crash...</div><div>about to start gen_event</div><div>gen_event started with {error,{already_started,<0.79.0>}}</div><div>about to start gen_event</div><div>gen_event started with {error,{already_started,<0.79.0>}}</div><div>about to start gen_event</div></div><div><br></div><div></snip></div><div><br></div><div>What is happening is that the gen_server is crashing but on its restart the gen_event process is still running - hence the gen_server fails in its init and gets restarted again.  Sometimes this loop clears after a few iterations, other times it can continue until the parent supervisor gives up, packs its bags and goes home.</div><div><br></div><div>So, my question is whether this is expected behaviour or not.  I assume that the termination of the linked child is happening asynchronously, and that the supervisor is hence restarting its children before things have cleaned up correctly - is that correct?</div><div><br></div><div>I can fix this particular scenario by trapping exits within the gen_server, and then calling gen_event:stop within the terminate.  Is this type of processing necessary whenever a process is start_link'ed within a supervisor tree, or is what I'm doing considered bad practice?</div><div><br></div><div>Thanks for your time,</div><div><br></div><div>Steve</div><div><br></div><div>-- </div>Steve Strong, Director, id3as<br><div>twitter.com/srstrong</div><br></span></div><div><span><br></span></div><div>
            </div>
        </div>