Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -module(observer).
- -behaviour(gen_server).
- % API
- -export([start_link/1, register/3, unregister/3, register/2, unregister/2,
- notify/3]).
- % gen_server callbacks
- -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2,
- code_change/3]).
- handle_cast({notify, Event, Data}, Table) ->
- Recipients = ets:lookup(Table, Event),
- lists:foreach(fun({_, P, _}) -> P ! {Event, Data} end, Recipients),
- {noreply, Table}.
- handle_call({register, Event, Pid}, _From, Table) ->
- Mon = erlang:monitor(process, Pid),
- ets:insert(Table, {Event, Pid, Mon}),
- {reply, ok, Table};
- handle_call({unregister, Event, Pid}, _From, Table) ->
- Monitors = ets:match(Table, {Event, Pid, '$1'}),
- lists:foreach(fun([X|[]]) -> io:format("~p~n", [X]) end, Monitors),
- lists:foreach(fun([X|[]]) -> erlang:demonitor(X) end, Monitors),
- ets:match_delete(Table, {Event, Pid, '_'}),
- {reply, ok, Table}.
- start_link(Name) -> gen_server:start_link({local, Name}, ?MODULE, [], []).
- register(Name, Event) ->
- gen_server:call(Name, {register, Event, self()}).
- register(Name, Event, Pid) ->
- gen_server:call(Name, {register, Event, Pid}).
- unregister(Name, Event) ->
- gen_server:call(Name, {unregister, Event, self()}).
- unregister(Name, Event, Pid) ->
- gen_server:call(Name, {unregister, Event, Pid}).
- notify(Name, Event, Data) ->
- gen_server:cast(Name, {notify, Event, Data}).
- init(_) -> {ok, ets:new(observer, [private, duplicate_bag])}.
- handle_info({'DOWN', _, _, Pid, _}, Table) ->
- io:format("~p died. removing registrations~n", [Pid]),
- ets:match_delete(Table, {'_', Pid, '_'}),
- {noreply, Table}.
- terminate(_Reason, _Table) -> ok.
- code_change(_OldVersion, Table, _Extra) -> {ok, Table}.
Add Comment
Please, Sign In to add comment