Using application behaviour to just change a gen event handler

Martin Bjorklund mbj@REDACTED
Mon Oct 25 17:05:33 CEST 1999


Sean Hinde <Sean.Hinde@REDACTED> wrote:
> Hi Everyone,
> 
> I have a requirement for an "application" which doesn't have any processes
> of its own but has a set of library type functions and installs an event
> handler in the local alarm_handler gen_event process.
> 
> The application behaviour appears to require the Pid of the top level
> supervisor to be returned but I won't have one in my case.
> 
> Any suggestions as to how to install the new event handler during
> application startup while maintaining the API rules of application?

Here are two alternatives:

1) Make the application "code-only", and provide an API function for
   others to use, which installs you handler in alarm_handler.

2) Create a 'supervisor' with one child which receives a message from
   alarm_handler if your module crashes.  If this happens, this child
   process calls exit/1, and the supervisor restarts the child, which
   reinstalls the handler module in alarm_handler.

   Here's some code to do the trick:


/martin





%%%-----------------------------------------------------------------
%%% Handler supervisor
%%%-----------------------------------------------------------------
start_link() ->
    proc_lib:start_link(?MODULE, init, [self(), self()]).

init(Caller, Parent) ->
    process_flag(trap_exit, true),
    register(?MY_NAME, self()),
    Handler = install(),
    link(Handler),
    proc_lib:init_ack(Caller, {ok, self()}),
    loop(Parent, Handler).

loop(Parent, Handler) ->
    receive
	{'EXIT', Parent, Reason} ->
	    %% Parent orders shutdown
	    uninstall(),
	    exit(Reason);
	{gen_event_EXIT, ?MY_HANDLER_MODULE, Reason} ->
            %% My handler module crashed
	    exit(Reason);
        {'EXIT', Handler, Reason} ->
            %% The gen_event manager crashed
            exit(Reason);
	{system, From, Req} ->
	    sys:handle_system_msg(Req, From, Parent, ?MODULE, [], Handler);
	_ ->
	    loop(Parent)
    end.

%%-----------------------------------------------------------------
%% Callback functions for system messages handling.
%%-----------------------------------------------------------------
system_continue(Parent, _, Handler) ->
    loop(Parent, Handler).
system_terminate(Reason, _Parent, _, _Handler) ->
    uninstall(),
    exit(Reason).
system_code_change(Handler, _Module, OldVsn, Extra) ->
    {ok, Handler}.

install() ->
    Pid = whereis(?HANDLER_NAME),
    ok = gen_event:add_sup_handler(Pid, ?MY_HANDLER_MODULE, []),
    Pid.

uninstall() ->
    gen_event:delete_handler(?HANDLER_NAME, ?MY_HANDLER_MODULE, []).




More information about the erlang-questions mailing list