Created
May 11, 2013 15:20
-
-
Save marcelog/5560239 to your computer and use it in GitHub Desktop.
gen_server that supervise and restarts event handlers (that implement the gen_event behavior) added with gen_event:add_sup_handler/3, suitable to be used in a standard otp supervision tree
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-module(event_handler_guard). | |
-author('[email protected]'). | |
-behavior(gen_server). | |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
%%% Types. | |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
-record(state, {}). | |
-type state():: #state{}. | |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
%%% Exports. | |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
%%% Public API. | |
-export([start_link/1]). | |
%%% gen_server callbacks. | |
-export([ | |
init/1, terminate/2, code_change/3, | |
handle_call/3, handle_cast/2, handle_info/2 | |
]). | |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
%%% Public API. | |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
%% @doc Starts the gen_server. Accepts a list of module names, which are the | |
%% event handlers needed to start and monitor. | |
-spec start_link([module()]) -> {ok, pid()} | ignore | {error, term()}. | |
start_link(EventHandlers) -> | |
gen_server:start_link({local, ?MODULE}, ?MODULE, EventHandlers, []). | |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
%%% gen_server API. | |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
-spec init([module()]) -> {ok, state()}. | |
init(EventHandlers) -> | |
[start(E) || E <- EventHandlers], | |
{ok, #state{}, hibernate}. | |
-spec handle_cast(any(), state()) -> {noreply, state()}. | |
handle_cast(Msg, State) -> | |
lager:error("Invalid cast: ~p", [Msg]), | |
{noreply, State, hibernate}. | |
%% @doc Expects a gen_event_EXIT message and re-starts the event handler. | |
-spec handle_info(any(), state()) -> {noreply, state()}. | |
handle_info({gen_event_EXIT, Handler, Reason}, State) -> | |
lager:error("Event Handler ~p died with: ~p", [Handler,Reason]), | |
start(Handler), | |
{noreply, State, hibernate}; | |
handle_info(Msg, State) -> | |
lager:error("Invalid msg: ~p", [Msg]), | |
{noreply, State, hibernate}. | |
-spec handle_call( | |
term(), {pid(), reference()}, state() | |
) -> {reply, term() | {invalid_request, term()}, state()}. | |
handle_call(Req, _From, State) -> | |
lager:error("Invalid request: ~p", [Req]), | |
{reply, invalid_request, State, hibernate}. | |
-spec terminate(atom(), state()) -> ok. | |
terminate(_Reason, _State) -> | |
ok. | |
-spec code_change(string(), state(), any()) -> {ok, state()}. | |
code_change(_OldVsn, State, _Extra) -> | |
{ok, State}. | |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
%%% Private API. | |
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
%% @doc Assuming that all the event handlers have a register/0 function, that | |
%% actually does the gen_event:add_sup_handler/3 call, just for convenience. | |
-spec start(module()) -> ok | {'EXIT', term()} | term(). | |
start(EventHandler) -> | |
EventHandler:register(). |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Lovely work. I am surprised I can't do this out of the box, but I can't see another way to do this given that supervision tree starts processes.