Skip to content

Commit 87c1345

Browse files
authored
Persistent term optimisations (#148)
In `telemetry:attach_many/4`, we check if the function given to the config is an external function and log noisy errors if it is not, because the Erlang efficiency guide says these are more efficient. Enforce the same for the `telemetry_handler_table` module at least for the very hot path that looks up the handlers for an event. Also remove a case-of from the execution path for another picosecond shave off.
1 parent 11462db commit 87c1345

File tree

2 files changed

+26
-32
lines changed

2 files changed

+26
-32
lines changed

src/telemetry_handler_table.erl

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -46,60 +46,49 @@ delete(HandlerId) ->
4646
gen_server:call(?MODULE, {delete, HandlerId}).
4747

4848
persist() ->
49-
{Mod, State} = impl_get(),
49+
{Mod, _, State} = impl_get(),
5050
case Mod:persist(State) of
5151
{ok, NewState} ->
52-
persistent_term:put(telemetry, {telemetry_pt, NewState}),
53-
ok;
52+
ListForEventFun = fun telemetry_pt:list_for_event/2,
53+
persistent_term:put(telemetry, {telemetry_pt, ListForEventFun, NewState});
5454
_ ->
5555
ok
5656
end.
5757

58-
impl_get() -> persistent_term:get(telemetry, undefined).
58+
impl_get() ->
59+
persistent_term:get(telemetry, default_impl()).
5960

6061
-spec list_for_event(telemetry:event_name()) -> [#handler{}].
6162
list_for_event(EventName) ->
62-
case impl_get() of
63-
{Mod, State} ->
64-
Mod:list_for_event(State, EventName);
65-
undefined ->
66-
?LOG_WARNING("Failed to lookup telemetry handlers. "
67-
"Ensure the telemetry application has been started. ", []),
68-
[]
69-
end.
63+
{_Mod, ListForEventFun, State} = impl_get(),
64+
ListForEventFun(State, EventName).
7065

7166
-spec list_by_prefix(telemetry:event_prefix()) -> [#handler{}].
7267
list_by_prefix(EventPrefix) ->
73-
case impl_get() of
74-
{Mod, State} ->
75-
Mod:list_by_prefix(State, EventPrefix);
76-
undefined ->
77-
?LOG_WARNING("Failed to lookup telemetry handlers. "
78-
"Ensure the telemetry application has been started. ", []),
79-
[]
80-
end.
68+
{Mod, _ListForEventFun, State} = impl_get(),
69+
Mod:list_by_prefix(State, EventPrefix).
8170

8271
init([]) ->
72+
process_flag(trap_exit, true),
8373
TID = create_table(),
84-
85-
persistent_term:put(telemetry, {telemetry_ets, TID}),
86-
74+
ListForEventFun = fun telemetry_ets:list_for_event/2,
75+
persistent_term:put(telemetry, {telemetry_ets, ListForEventFun, TID}),
8776
{ok, []}.
8877

8978
handle_call({insert, HandlerId, EventNames, Function, Config}, _From, State) ->
90-
{Mod, MState} = impl_get(),
79+
{Mod, ListForEventFun, MState} = impl_get(),
9180
case Mod:insert(MState, HandlerId, EventNames, Function, Config) of
9281
{ok, NewState} ->
93-
persistent_term:put(telemetry, {Mod, NewState}),
82+
persistent_term:put(telemetry, {Mod, ListForEventFun, NewState}),
9483
{reply, ok, State};
9584
{error, _} = Error ->
9685
{reply, Error, State}
9786
end;
9887
handle_call({delete, HandlerId}, _From, State) ->
99-
{Mod, MState} = impl_get(),
88+
{Mod, ListForEventFun, MState} = impl_get(),
10089
case Mod:delete(MState, HandlerId) of
10190
{ok, NewState} ->
102-
persistent_term:put(telemetry, {Mod, NewState}),
91+
persistent_term:put(telemetry, {Mod, ListForEventFun, NewState}),
10392
{reply, ok, State};
10493
{error, _} = Error ->
10594
{reply, Error, State}
@@ -120,6 +109,10 @@ terminate(_Reason, _State) ->
120109

121110
%%
122111

112+
default_impl() ->
113+
ListForEventFun = fun(_, _) -> [] end,
114+
{telemetry_ets, ListForEventFun, #{}}.
115+
123116
create_table() ->
124117
ets:new(?MODULE, [duplicate_bag, protected,
125118
{keypos, #handler.event_name}, {read_concurrency, true}]).

src/telemetry_pt.erl

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,15 @@ starts_with(_Haystack, _Needle) -> false.
2929
insert(Map, _HandlerId, [], _Function, _Config) ->
3030
{ok, Map};
3131
insert(Map, HandlerId, [EventName | Rest], Function, Config) ->
32-
Handler = #handler{id=HandlerId,
33-
event_name=EventName,
34-
function=Function,
35-
config=Config},
3632
OldHandlers = maps:get(EventName, Map, []),
3733
case OldHandlers of
38-
#{HandlerId := _} -> {error, already_exists};
34+
#{HandlerId := _} ->
35+
{error, already_exists};
3936
_ ->
37+
Handler = #handler{id=HandlerId,
38+
event_name=EventName,
39+
function=Function,
40+
config=Config},
4041
case put_new(Handler, OldHandlers) of
4142
{ok, NewHandlers} ->
4243
NewMap = Map#{EventName => NewHandlers},

0 commit comments

Comments
 (0)