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,17 @@ 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 := TelemetryEventName
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 ),
5354 Config = # segmented_cache {
5455 scope = Scope ,
56+ telemetry_name = TelemetryEventName ,
5557 name = Name ,
5658 strategy = Strategy ,
5759 index = Index ,
@@ -83,19 +85,28 @@ persist_cache_config(Name, Config) ->
8385% % ETS checks
8486% %====================================================================
8587
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 .
88+ -spec is_member (segmented_cache :name (), segmented_cache :key ()) -> boolean ().
89+ is_member (Name , Key ) when is_atom (Name ) ->
90+ # segmented_cache {telemetry_name = Prefix } = SegmentRecord = get_cache_config (Name ),
91+ Span = fun () ->
92+ Value = iterate_fun_in_tables (
93+ SegmentRecord , Key , fun segmented_cache_callbacks :is_member_ets_fun /2
94+ ),
95+ {Value , #{name => Name , type => is_member , hit => Value =:= true }}
96+ end ,
97+ telemetry :span (Prefix , #{name => Name , type => is_member }, Span ).
98+
99+ -spec get_entry (segmented_cache :name (), segmented_cache :key ()) ->
100+ segmented_cache :value () | not_found .
101+ get_entry (Name , Key ) when is_atom (Name ) ->
102+ # segmented_cache {telemetry_name = Prefix } = SegmentRecord = get_cache_config (Name ),
103+ Span = fun () ->
104+ Value = iterate_fun_in_tables (
105+ SegmentRecord , Key , fun segmented_cache_callbacks :get_entry_ets_fun /2
106+ ),
107+ {Value , #{name => Name , type => get_entry , hit => Value =/= not_found }}
108+ end ,
109+ telemetry :span (Prefix , #{name => Name , type => get_entry }, Span ).
99110
100111% % Atomically compare_and_swap an entry, attempt three times, post-check front insert
101112-spec put_entry_front (segmented_cache :name (), segmented_cache :key (), segmented_cache :value ()) ->
@@ -115,7 +126,7 @@ merge_entry(Name, Key, Value) when is_atom(Name) ->
115126 false -> {continue , false }
116127 end
117128 end ,
118- case iterate_fun_in_tables (Name , Key , F ) of
129+ case iterate_fun_in_tables (SegmentRecord , Key , F ) of
119130 true -> true ;
120131 false -> do_put_entry_front (SegmentRecord , Key , Value , 3 )
121132 end .
@@ -133,24 +144,24 @@ delete_pattern(Name, Pattern) when is_atom(Name) ->
133144 Type :: entry | pattern ,
134145 IterativeFun :: iterative_fun (Key , dynamic ()).
135146delete_request (Name , Value , Type , Fun ) ->
147+ # segmented_cache {telemetry_name = Prefix } = SegmentRecord = get_cache_config (Name ),
136148 try
137- iterate_fun_in_tables (Name , Value , Fun )
149+ iterate_fun_in_tables (SegmentRecord , Value , Fun )
138150 catch
139151 Class :Reason ->
140152 Metadata = #{
141153 name => Name , delete_type => Type , value => Value , class => Class , reason => Reason
142154 },
143- telemetry :execute ([ segmented_cache , Name , delete_error ], #{}, Metadata )
155+ telemetry :execute (Prefix ++ [ delete_error ], #{}, Metadata )
144156 end .
145157
146158% %====================================================================
147159% % Internals
148160% %====================================================================
149161
150- -spec iterate_fun_in_tables (segmented_cache : name (), Key , IterativeFun ) -> Value when
162+ -spec iterate_fun_in_tables (config (), Key , IterativeFun ) -> Value when
151163 IterativeFun :: iterative_fun (Key , Value ).
152- iterate_fun_in_tables (Name , Key , IterativeFun ) ->
153- SegmentRecord = get_cache_config (Name ),
164+ iterate_fun_in_tables (SegmentRecord , Key , IterativeFun ) ->
154165 Segments = SegmentRecord # segmented_cache .segments ,
155166 Size = tuple_size (Segments ),
156167 CurrentIndex = atomics :get (SegmentRecord # segmented_cache .index , 1 ),
@@ -318,8 +329,8 @@ purge_last_segment_and_rotate(Name) ->
318329 atomics :put (SegmentRecord # segmented_cache .index , 1 , NewIndex ),
319330 NewIndex .
320331
321- -spec assert_parameters (segmented_cache :opts ()) -> segmented_cache :opts ().
322- assert_parameters (Opts0 ) when is_map (Opts0 ) ->
332+ -spec assert_parameters (segmented_cache :name (), segmented_cache : opts ()) -> segmented_cache :opts ().
333+ assert_parameters (Name , Opts0 ) when is_map (Opts0 ) ->
323334 #{
324335 scope := Scope ,
325336 strategy := Strategy ,
@@ -328,6 +339,8 @@ assert_parameters(Opts0) when is_map(Opts0) ->
328339 ttl := TTL0 ,
329340 merger_fun := MergerFun
330341 } = Opts = maps :merge (defaults (), Opts0 ),
342+ TelemetryEventName = maps :get (prefix , Opts0 , [segmented_cache , Name , request ]),
343+ true = is_list (TelemetryEventName ),
331344 TTL =
332345 case TTL0 of
333346 infinity -> infinity ;
@@ -343,7 +356,7 @@ assert_parameters(Opts0) when is_map(Opts0) ->
343356 true = (Strategy =:= fifo ) orelse (Strategy =:= lru ),
344357 true = is_function (MergerFun , 2 ),
345358 true = (undefined =/= whereis (Scope )),
346- Opts #{ttl := TTL }.
359+ Opts #{ttl := TTL , prefix => TelemetryEventName }.
347360
348361is_pos_int_or_infinity (Value ) ->
349362 (Value =:= infinity ) orelse (is_integer (Value ) andalso 0 < Value ).
0 commit comments