<div>
            <div>
                <span>That makes a good deal of sense.  I guess the point that something should get promoted up to a supervision tree rather than being start-linked is when it starts getting to a complexity level such that it may have issues if multiple instances of the process are running simultaneously.  At that point it stops sound like a trivial helper process and something that should be managed more actively.<br>
                </span></div><div><span><br></span></div><div>
                <span>Completely agree on the fact that having the gen_event register wasn't a useful thing, and that not doing so would solve the problem - that was pretty obvious as soon as I spotted the issue, this thread was more to get opinion on how things should be best structured.<br><div><br></div>-- <br>Steve Strong, Director, id3as<br><div>twitter.com/srstrong</div><br></span>
                
                <p style="color: #a0a0a0;">On Thursday, 2 June 2011 at 11:53, Mazen Harake wrote:</p>
                <blockquote type="cite" style="border-left-style:solid;border-width:1px;margin-left:0px;padding-left:10px;">
                    <span><div><div>Steve,<br><br>I wouldn't say that you are wrong. I think that you are reasoning good<br>about not putting the gen_event module under a supervisor because<br>*that is what links are for*. Just because you have a supervisor<br>doesn't mean the you shove everything underneath there! If the<br>gen_server and the gen_event are truly linked (meaning: gen_server<br>doesn't act as a "supervisor" keeping track of its gen_event process<br>and restarts it all the time but rather that they really are linked<br>and they crash together) then your approach, in my opinion, is good.<br><br>There are great benefits in doing it in that way. Many will claim that<br>it is best practice to put *everything* under a supervisor but this is<br>simply not true. 90% of cases it *is* the best thing to do and many<br>times it is more about how you designed your application rather than<br>where to put the supervisors and their children but doing it the way<br>you did is not necessarily wrong.<br><br>The only problem I see with your approach is that you have registered<br>the gen_event process which clearly isn't useful (since only the<br>gen_server should know about it, after all, it started it). Other than<br>that, this approach is extremely helpful and a nice way to clean up<br>things after they die/shutdown (Again: assuming truly linked).<br><br>There is a big misconception in the community that everything<br>should/must look like the supervisor-tree model which shows how<br>gen_servers are put under supervisors and more supervisors under the<br>"top" supervisor but that is not enforced and the design principles<br>doesn't take many cases into account where this setup actually brings<br>more headache to the table than to just exit and clean up using linked<br>processes (because they do exist).<br><br>/M<br><br>On 1 June 2011 21:26, Steve Strong <<a href="mailto:steve@srstrong.com">steve@srstrong.com</a>> wrote:<br><blockquote type="cite"><div>Hi,<br><br>I've got some strange behaviour with gen_event within a supervision tree<br>which I don't fully understand.  Consider the following supervisor<br>(completely standard, feel free to skip over):<br><snip><br>-module(sup).<br>-behaviour(supervisor).<br>-export([start_link/0, init/1]).<br>-define(SERVER, ?MODULE).<br>start_link() -><br>    supervisor:start_link({local, ?SERVER}, ?MODULE, []).<br>init([]) -><br>    Child1 = {child, {child, start_link, []}, permanent, 2000, worker,<br>[child]},<br>    {ok, {{one_for_all, 1000, 3600}, [Child1]}}.<br></snip><br>and corresponding gen_server (interesting code in bold):<br><snip><br>-module(child).<br>-behaviour(gen_server).<br>-export([start_link/0, init/1, handle_call/3, handle_cast/2,<br>handle_info/2, terminate/2, code_change/3]).<br>start_link() -><br>    gen_server:start_link({local, child}, child, [], []).<br>init([]) -><br>    io:format("about to start gen_event~n"),<br>    X = gen_event:start_link({local, my_gen_event}),<br>    io:format("gen_event started with ~p~n", [X]),<br>    {ok, _Pid} = X,<br>    {ok, {}, 2000}.<br>handle_call(_Request, _From, State) -><br>    {reply, ok, State}.<br>handle_cast(_Msg, State) -><br>    {noreply, State}.<br>handle_info(_Info, State) -><br>    io:format("about to crash...~n"),<br>    1 = 2,<br>    {noreply, State}.<br>terminate(_Reason, _State) -><br>    ok.<br>code_change(_OldVsn, State, _Extra) -><br>    {ok, State}.<br></snip><br>If I run this from an erl shell like this:<br><snip><br>--> erl<br>Erlang R14B01 (erts-5.8.2) [source] [64-bit] [smp:2:2] [rq:2]<br>[async-threads:0] [hipe] [kernel-poll:false]<br>Eshell V5.8.2  (abort with ^G)<br>1> application:start(sasl), supervisor:start_link(sup, []).<br></snip><br><br>Then the supervisor & server start as expected.  After 2 seconds the server<br>gets a timeout message and crashes itself; the supervisor obviously spots<br>this and restarts it.  Within the init of the gen_server, it also does a<br>start_link on a gen_event process.  By my understanding, whenever the<br>gen_server process exits, the gen_event will also be terminated.<br>However, every now and then I see the following output (a ton of sasl trace<br>omitted for clarity!):<br><snip><br>about to crash...<br>about to start gen_event<br>gen_event started with {error,{already_started,<0.79.0>}}<br>about to start gen_event<br>gen_event started with {error,{already_started,<0.79.0>}}<br>about to start gen_event<br></snip><br>What is happening is that the gen_server is crashing but on its restart the<br>gen_event process is still running - hence the gen_server fails in its init<br>and gets restarted again.  Sometimes this loop clears after a few<br>iterations, other times it can continue until the parent supervisor gives<br>up, packs its bags and goes home.<br>So, my question is whether this is expected behaviour or not.  I assume that<br>the termination of the linked child is happening asynchronously, and that<br>the supervisor is hence restarting its children before things have cleaned<br>up correctly - is that correct?<br>I can fix this particular scenario by trapping exits within the gen_server,<br>and then calling gen_event:stop within the terminate.  Is this type of<br>processing necessary whenever a process is start_link'ed within a supervisor<br>tree, or is what I'm doing considered bad practice?<br>Thanks for your time,<br>Steve<br>--<br>Steve Strong, Director, id3as<br><a href="http://twitter.com/srstrong">twitter.com/srstrong</a><br><br><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">http://erlang.org/mailman/listinfo/erlang-questions</a><br></div></blockquote></div></div></span>
                
                
                
                
                </blockquote>
                
                <div>
                    <br>
                </div>
            </div>
        </div>