zf

zenflows testing
git clone https://s.sonu.ch/~srfsh/zf.git
Log | Files | Refs | Submodules | README | LICENSE

telemetry_handler_table.erl (3498B)


      1 %%%-------------------------------------------------------------------
      2 %% @private ETS table for handlers.
      3 %%
      4 %% Each handler is stored in the table. A key is an event name the
      5 %% handler is attached to. All writes to a table go through a single
      6 %% Agent process to make sure that we don't get duplicate handler IDs.
      7 %%
      8 %% Reads (`list_handlers_...') are executed by the calling process.
      9 %% @end
     10 %%%-------------------------------------------------------------------
     11 -module(telemetry_handler_table).
     12 
     13 -behaviour(gen_server).
     14 
     15 -export([start_link/0,
     16          insert/4,
     17          delete/1,
     18          list_for_event/1,
     19          list_by_prefix/1]).
     20 
     21 -export([init/1,
     22          handle_call/3,
     23          handle_cast/2,
     24          handle_info/2,
     25          code_change/3,
     26          terminate/2]).
     27 
     28 -include("telemetry.hrl").
     29 
     30 start_link() ->
     31     gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
     32 
     33 -spec insert(HandlerId, EventNames, Function, Config) -> ok | {error, already_exists} when
     34       HandlerId :: telemetry:handler_id(),
     35       EventNames :: [telemetry:event_name()],
     36       Function :: telemetry:handler_function(),
     37       Config :: telemetry:handler_config().
     38 insert(HandlerId, EventNames, Function, Config) ->
     39     gen_server:call(?MODULE, {insert, HandlerId, EventNames, Function, Config}).
     40 
     41 -spec delete(telemetry:handler_id()) -> ok | {error, not_found}.
     42 delete(HandlerId) ->
     43     gen_server:call(?MODULE, {delete, HandlerId}).
     44 
     45 -spec list_for_event(telemetry:event_name()) -> [#handler{}].
     46 list_for_event(EventName) ->
     47     try
     48         ets:lookup(?MODULE, EventName)
     49     catch
     50         error:badarg ->
     51             ?LOG_WARNING("Failed to lookup telemetry handlers. "
     52                          "Ensure the telemetry application has been started. ", []),
     53             []
     54     end.
     55 
     56 -spec list_by_prefix(telemetry:event_prefix()) -> [#handler{}].
     57 list_by_prefix(EventPrefix) ->
     58     Pattern = match_pattern_for_prefix(EventPrefix),
     59     ets:match_object(?MODULE, Pattern).
     60 
     61 init([]) ->
     62     _ = create_table(),
     63     {ok, []}.
     64 
     65 handle_call({insert, HandlerId, EventNames, Function, Config}, _From, State) ->
     66     case ets:match(?MODULE, #handler{id=HandlerId,
     67                                      _='_'}) of
     68         [] ->
     69             Objects = [#handler{id=HandlerId,
     70                                 event_name=EventName,
     71                                 function=Function,
     72                                 config=Config} || EventName <- EventNames],
     73             ets:insert(?MODULE, Objects),
     74             {reply, ok, State};
     75         _ ->
     76             {reply, {error, already_exists}, State}
     77     end;
     78 handle_call({delete, HandlerId}, _From, State) ->
     79     case ets:select_delete(?MODULE, [{#handler{id=HandlerId,
     80                                               _='_'}, [], [true]}]) of
     81         0 ->
     82             {reply, {error, not_found}, State};
     83         _ ->
     84             {reply, ok, State}
     85     end.
     86 
     87 handle_cast(_Msg, State) ->
     88     {noreply, State}.
     89 
     90 handle_info(_Msg, State) ->
     91     {noreply, State}.
     92 
     93 code_change(_, State, _) ->
     94     {ok, State}.
     95 
     96 terminate(_Reason, _State) ->
     97     ok.
     98 
     99 %%
    100 
    101 create_table() ->
    102     ets:new(?MODULE, [duplicate_bag, protected, named_table,
    103                       {keypos, 3}, {read_concurrency, true}]).
    104 
    105 match_pattern_for_prefix(EventPrefix) ->
    106     #handler{event_name=match_for_prefix(EventPrefix),
    107              _='_'}.
    108 
    109 -dialyzer({nowarn_function, match_for_prefix/1}).
    110 match_for_prefix([]) ->
    111     '_';
    112 match_for_prefix([Segment | Rest]) ->
    113     [Segment | match_for_prefix(Rest)].