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