From cd52961b4b625d2aa1c135303845d91bcb8fc66b Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Thu, 21 May 2020 09:19:21 -0600 Subject: [PATCH] efficient event execution on prefix lookup --- src/telemetry_handler_table.erl | 8 ++++---- test/telemetry_SUITE.erl | 24 ++++++++++++++---------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/telemetry_handler_table.erl b/src/telemetry_handler_table.erl index 8fd1eab..d8b16c6 100644 --- a/src/telemetry_handler_table.erl +++ b/src/telemetry_handler_table.erl @@ -45,7 +45,7 @@ delete(HandlerId) -> -spec list_for_event(telemetry:event_name()) -> [#handler{}]. list_for_event(EventName) -> try - ets:lookup(?MODULE, EventName) + ets:match_object(?MODULE, match_pattern_for_prefix(EventName)) catch error:badarg -> ?LOG_WARNING("Failed to lookup telemetry handlers. " @@ -67,7 +67,7 @@ handle_call({insert, HandlerId, EventNames, Function, Config}, _From, State) -> _='_'}) of [] -> Objects = [#handler{id=HandlerId, - event_name=EventName, + event_name=EventName ++ [HandlerId], function=Function, config=Config} || EventName <- EventNames], ets:insert(?MODULE, Objects), @@ -77,7 +77,7 @@ handle_call({insert, HandlerId, EventNames, Function, Config}, _From, State) -> end; handle_call({delete, HandlerId}, _From, State) -> case ets:select_delete(?MODULE, [{#handler{id=HandlerId, - _='_'}, [], [true]}]) of + _='_'}, [], [true]}]) of 0 -> {reply, {error, not_found}, State}; _ -> @@ -99,7 +99,7 @@ terminate(_Reason, _State) -> %% create_table() -> - ets:new(?MODULE, [duplicate_bag, protected, named_table, + ets:new(?MODULE, [ordered_set, protected, named_table, {keypos, 3}, {read_concurrency, true}]). match_pattern_for_prefix(EventPrefix) -> diff --git a/test/telemetry_SUITE.erl b/test/telemetry_SUITE.erl index 6c1b878..d093fae 100644 --- a/test/telemetry_SUITE.erl +++ b/test/telemetry_SUITE.erl @@ -69,8 +69,9 @@ list_handlers(Config) -> HandlerFun = fun ?MODULE:echo_event/4, telemetry:attach(HandlerId, Event, HandlerFun, HandlerConfig), + EventName = Event ++ [HandlerId], ?assertMatch([#{id := HandlerId, - event_name := Event, + event_name := EventName, function := HandlerFun, config := HandlerConfig}], telemetry:list_handlers(Event)). @@ -86,8 +87,9 @@ list_for_prefix(Config) -> HandlerFun = fun ?MODULE:echo_event/4, telemetry:attach(HandlerId, Event, HandlerFun, HandlerConfig), + EventName = Event ++ [HandlerId], [?assertMatch([#{id := HandlerId, - event_name := Event, + event_name := EventName, function := HandlerFun, config := HandlerConfig}], telemetry:list_handlers(Prefix)) || Prefix <- [Prefix1, Prefix2, Prefix3]], @@ -101,8 +103,9 @@ detach_on_exception(Config) -> HandlerFun = fun ?MODULE:raise_on_event/4, telemetry:attach(HandlerId, Event, HandlerFun, []), + EventName = Event ++ [HandlerId], ?assertMatch([#{id := HandlerId, - event_name := Event, + event_name := EventName, function := HandlerFun, config := []}], telemetry:list_handlers(Event)), @@ -148,11 +151,11 @@ no_execute_on_prefix(Config) -> telemetry:execute(Prefix, Measurements, Metadata), receive - {event, Event, Measurements, Metadata, HandlerConfig} -> - ct:fail(prefix_executed) - after - 300 -> + {event, Prefix, Measurements, Metadata, HandlerConfig} -> ok + after + 1000 -> + ct:fail(timeout) end. %% handler is not invoked when event more specific than the one it's attached to is emitted @@ -233,10 +236,11 @@ list_handler_on_many(Config) -> telemetry:attach_many(HandlerId, [Event1, Event2, Event3], HandlerFun, HandlerConfig), lists:foreach(fun(Event) -> + EventName = Event ++ [HandlerId], ?assertMatch([#{id := HandlerId, - event_name := Event, + event_name := EventName, function := HandlerFun, - config := EventConfig}], + config := _EventConfig}], telemetry:list_handlers(Event)) end, [Event1, Event2, Event3]). @@ -295,7 +299,7 @@ default_metadata(Config) -> end. % Ensure calling execute is safe when the telemetry application is off -off_execute(Config) -> +off_execute(_Config) -> application:stop(telemetry), telemetry:execute([event, name], #{}, #{}), application:ensure_all_started(telemetry).