1010-compile ({inline , [next / 2 ]}).
1111
1212-export ([init_cache_config /2 , get_cache_scope /1 , erase_cache_config /1 ]).
13- -export ([is_member_span /2 , get_entry_span /2 , put_entry_front /3 , merge_entry /3 ]).
13+ -export ([is_member /2 , get_entry /2 ]).
14+ -export ([put_entry_front /3 , merge_entry /3 ]).
1415-export ([delete_entry /2 , delete_pattern /2 ]).
1516-export ([purge_last_segment_and_rotate /1 ]).
1617
1718-record (segmented_cache , {
1819 scope :: segmented_cache :scope (),
1920 name :: segmented_cache :name (),
21+ telemetry_name :: [segmented_cache :name ()],
2022 strategy = fifo :: segmented_cache :strategy (),
2123 entries_limit = infinity :: segmented_cache :entries_limit (),
2224 index :: atomics :atomics_ref (),
2325 segments :: tuple (),
2426 merger_fun :: merger_fun (dynamic ())
2527}).
2628
27- -type span () :: fun (() -> {dynamic (), span_metadata ()}).
28- -type span_metadata () :: #{hit := boolean ()}.
2929-type merger_fun (Value ) :: fun ((Value , Value ) -> Value ).
3030-type iterative_fun (Key , Value ) :: fun ((ets :tid (), Key ) -> {continue | stop , Value }).
3131-type config () :: # segmented_cache {}.
@@ -43,15 +43,18 @@ init_cache_config(Name, Opts0) ->
4343 entries_limit := EntriesLimit ,
4444 segment_num := N ,
4545 ttl := TTL ,
46- merger_fun := MergerFun
47- } = Opts = assert_parameters (Opts0 ),
46+ merger_fun := MergerFun ,
47+ prefix := TelemetryPrefix
48+ } = Opts = assert_parameters (Name , Opts0 ),
4849 SegmentOpts = ets_settings (Opts ),
4950 SegmentsList = lists :map (fun (_ ) -> ets :new (undefined , SegmentOpts ) end , lists :seq (1 , N )),
5051 Segments = list_to_tuple (SegmentsList ),
5152 Index = atomics :new (1 , [{signed , false }]),
5253 atomics :put (Index , 1 , 1 ),
54+ TelemetryEventName = TelemetryPrefix ++ [request ],
5355 Config = # segmented_cache {
5456 scope = Scope ,
57+ telemetry_name = TelemetryEventName ,
5558 name = Name ,
5659 strategy = Strategy ,
5760 index = Index ,
@@ -83,19 +86,28 @@ persist_cache_config(Name, Config) ->
8386% % ETS checks
8487% %====================================================================
8588
86- -spec is_member_span (segmented_cache :name (), segmented_cache :key ()) -> span ().
87- is_member_span (Name , Key ) when is_atom (Name ) ->
88- fun () ->
89- Value = iterate_fun_in_tables (Name , Key , fun segmented_cache_callbacks :is_member_ets_fun /2 ),
90- {Value , #{hit => Value =:= true }}
91- end .
92-
93- -spec get_entry_span (segmented_cache :name (), segmented_cache :key ()) -> span ().
94- get_entry_span (Name , Key ) when is_atom (Name ) ->
95- fun () ->
96- Value = iterate_fun_in_tables (Name , Key , fun segmented_cache_callbacks :get_entry_ets_fun /2 ),
97- {Value , #{hit => Value =/= not_found }}
98- end .
89+ -spec is_member (segmented_cache :name (), segmented_cache :key ()) -> boolean ().
90+ is_member (Name , Key ) when is_atom (Name ) ->
91+ # segmented_cache {telemetry_name = Prefix } = SegmentRecord = get_cache_config (Name ),
92+ Span = fun () ->
93+ Value = iterate_fun_in_tables (
94+ SegmentRecord , Key , fun segmented_cache_callbacks :is_member_ets_fun /2
95+ ),
96+ {Value , #{name => Name , type => is_member , hit => Value =:= true }}
97+ end ,
98+ telemetry :span (Prefix , #{name => Name , type => is_member }, Span ).
99+
100+ -spec get_entry (segmented_cache :name (), segmented_cache :key ()) ->
101+ segmented_cache :value () | not_found .
102+ get_entry (Name , Key ) when is_atom (Name ) ->
103+ # segmented_cache {telemetry_name = Prefix } = SegmentRecord = get_cache_config (Name ),
104+ Span = fun () ->
105+ Value = iterate_fun_in_tables (
106+ SegmentRecord , Key , fun segmented_cache_callbacks :get_entry_ets_fun /2
107+ ),
108+ {Value , #{name => Name , type => get_entry , hit => Value =/= not_found }}
109+ end ,
110+ telemetry :span (Prefix , #{name => Name , type => get_entry }, Span ).
99111
100112% % Atomically compare_and_swap an entry, attempt three times, post-check front insert
101113-spec put_entry_front (segmented_cache :name (), segmented_cache :key (), segmented_cache :value ()) ->
@@ -115,7 +127,7 @@ merge_entry(Name, Key, Value) when is_atom(Name) ->
115127 false -> {continue , false }
116128 end
117129 end ,
118- case iterate_fun_in_tables (Name , Key , F ) of
130+ case iterate_fun_in_tables (SegmentRecord , Key , F ) of
119131 true -> true ;
120132 false -> do_put_entry_front (SegmentRecord , Key , Value , 3 )
121133 end .
@@ -133,24 +145,24 @@ delete_pattern(Name, Pattern) when is_atom(Name) ->
133145 Type :: entry | pattern ,
134146 IterativeFun :: iterative_fun (Key , dynamic ()).
135147delete_request (Name , Value , Type , Fun ) ->
148+ # segmented_cache {telemetry_name = Prefix } = SegmentRecord = get_cache_config (Name ),
136149 try
137- iterate_fun_in_tables (Name , Value , Fun )
150+ iterate_fun_in_tables (SegmentRecord , Value , Fun )
138151 catch
139152 Class :Reason ->
140153 Metadata = #{
141154 name => Name , delete_type => Type , value => Value , class => Class , reason => Reason
142155 },
143- telemetry :execute ([ segmented_cache , Name , delete_error ], #{}, Metadata )
156+ telemetry :execute (Prefix ++ [ delete_error ], #{}, Metadata )
144157 end .
145158
146159% %====================================================================
147160% % Internals
148161% %====================================================================
149162
150- -spec iterate_fun_in_tables (segmented_cache : name (), Key , IterativeFun ) -> Value when
163+ -spec iterate_fun_in_tables (config (), Key , IterativeFun ) -> Value when
151164 IterativeFun :: iterative_fun (Key , Value ).
152- iterate_fun_in_tables (Name , Key , IterativeFun ) ->
153- SegmentRecord = get_cache_config (Name ),
165+ iterate_fun_in_tables (SegmentRecord , Key , IterativeFun ) ->
154166 Segments = SegmentRecord # segmented_cache .segments ,
155167 Size = tuple_size (Segments ),
156168 CurrentIndex = atomics :get (SegmentRecord # segmented_cache .index , 1 ),
@@ -318,8 +330,8 @@ purge_last_segment_and_rotate(Name) ->
318330 atomics :put (SegmentRecord # segmented_cache .index , 1 , NewIndex ),
319331 NewIndex .
320332
321- -spec assert_parameters (segmented_cache :opts ()) -> segmented_cache :opts ().
322- assert_parameters (Opts0 ) when is_map (Opts0 ) ->
333+ -spec assert_parameters (segmented_cache :name (), segmented_cache : opts ()) -> segmented_cache :opts ().
334+ assert_parameters (Name , Opts0 ) when is_map (Opts0 ) ->
323335 #{
324336 scope := Scope ,
325337 strategy := Strategy ,
@@ -328,6 +340,8 @@ assert_parameters(Opts0) when is_map(Opts0) ->
328340 ttl := TTL0 ,
329341 merger_fun := MergerFun
330342 } = Opts = maps :merge (defaults (), Opts0 ),
343+ TelemetryEventName = maps :get (prefix , Opts0 , [segmented_cache , Name ]),
344+ true = is_list (TelemetryEventName ),
331345 TTL =
332346 case TTL0 of
333347 infinity -> infinity ;
@@ -343,7 +357,7 @@ assert_parameters(Opts0) when is_map(Opts0) ->
343357 true = (Strategy =:= fifo ) orelse (Strategy =:= lru ),
344358 true = is_function (MergerFun , 2 ),
345359 true = (undefined =/= whereis (Scope )),
346- Opts #{ttl := TTL }.
360+ Opts #{ttl := TTL , prefix => TelemetryEventName }.
347361
348362is_pos_int_or_infinity (Value ) ->
349363 (Value =:= infinity ) orelse (is_integer (Value ) andalso 0 < Value ).
0 commit comments