@@ -47,6 +47,7 @@ use crate::{
47
47
pub struct MemoryEntry {
48
48
value : String ,
49
49
update_time : CopyValue < Instant > ,
50
+ ttl : u64 ,
50
51
}
51
52
52
53
impl ByteSizeOf for MemoryEntry {
@@ -56,13 +57,10 @@ impl ByteSizeOf for MemoryEntry {
56
57
}
57
58
58
59
impl MemoryEntry {
59
- pub ( super ) fn as_object_map (
60
- & self ,
61
- now : Instant ,
62
- total_ttl : u64 ,
63
- key : & str ,
64
- ) -> Result < ObjectMap , String > {
65
- let ttl = total_ttl. saturating_sub ( now. duration_since ( * self . update_time ) . as_secs ( ) ) ;
60
+ pub ( super ) fn as_object_map ( & self , now : Instant , key : & str ) -> Result < ObjectMap , String > {
61
+ let ttl = self
62
+ . ttl
63
+ . saturating_sub ( now. duration_since ( * self . update_time ) . as_secs ( ) ) ;
66
64
Ok ( ObjectMap :: from ( [
67
65
(
68
66
KeyString :: from ( "key" ) ,
@@ -80,8 +78,8 @@ impl MemoryEntry {
80
78
] ) )
81
79
}
82
80
83
- fn expired ( & self , now : Instant , ttl : u64 ) -> bool {
84
- now. duration_since ( * self . update_time ) . as_secs ( ) > ttl
81
+ fn expired ( & self , now : Instant ) -> bool {
82
+ now. duration_since ( * self . update_time ) . as_secs ( ) > self . ttl
85
83
}
86
84
}
87
85
@@ -128,9 +126,9 @@ impl Memory {
128
126
let mut writer = self . write_handle . lock ( ) . expect ( "mutex poisoned" ) ;
129
127
let now = Instant :: now ( ) ;
130
128
131
- for ( k, v ) in value. into_iter ( ) {
129
+ for ( k, value ) in value. into_iter ( ) {
132
130
let new_entry_key = String :: from ( k) ;
133
- let Ok ( v) = serde_json:: to_string ( & v ) else {
131
+ let Ok ( v) = serde_json:: to_string ( & value ) else {
134
132
emit ! ( MemoryEnrichmentTableInsertFailed {
135
133
key: & new_entry_key,
136
134
include_key_metric_tag: self . config. internal_metrics. include_key_tag
@@ -140,6 +138,15 @@ impl Memory {
140
138
let new_entry = MemoryEntry {
141
139
value : v,
142
140
update_time : now. into ( ) ,
141
+ ttl : self
142
+ . config
143
+ . ttl_field
144
+ . path
145
+ . as_ref ( )
146
+ . and_then ( |p| value. get ( p) )
147
+ . and_then ( |v| v. as_integer ( ) )
148
+ . map ( |v| v as u64 )
149
+ . unwrap_or ( self . config . ttl ) ,
143
150
} ;
144
151
let new_entry_size = new_entry_key. size_of ( ) + new_entry. size_of ( ) ;
145
152
if let Some ( max_byte_size) = self . config . max_byte_size
@@ -182,7 +189,7 @@ impl Memory {
182
189
if let Some ( reader) = self . get_read_handle ( ) . read ( ) {
183
190
for ( k, v) in reader. iter ( ) {
184
191
if let Some ( entry) = v. get_one ( )
185
- && entry. expired ( now, self . config . ttl )
192
+ && entry. expired ( now)
186
193
{
187
194
// Byte size is not reduced at this point, because the actual deletion
188
195
// will only happen at refresh time
@@ -283,8 +290,7 @@ impl Table for Memory {
283
290
key: & key,
284
291
include_key_metric_tag: self . config. internal_metrics. include_key_tag
285
292
} ) ;
286
- row. as_object_map ( Instant :: now ( ) , self . config . ttl , & key)
287
- . map ( |r| vec ! [ r] )
293
+ row. as_object_map ( Instant :: now ( ) , & key) . map ( |r| vec ! [ r] )
288
294
}
289
295
None => {
290
296
emit ! ( MemoryEnrichmentTableReadFailed {
@@ -386,8 +392,10 @@ mod tests {
386
392
use futures:: { StreamExt , future:: ready} ;
387
393
use futures_util:: stream;
388
394
use tokio:: time;
395
+
389
396
use vector_lib:: {
390
397
event:: { EventContainer , MetricValue } ,
398
+ lookup:: lookup_v2:: OptionalValuePath ,
391
399
metrics:: Controller ,
392
400
sink:: VectorSink ,
393
401
} ;
@@ -442,6 +450,7 @@ mod tests {
442
450
MemoryEntry {
443
451
value : "5" . to_string ( ) ,
444
452
update_time : ( Instant :: now ( ) - Duration :: from_secs ( secs_to_subtract) ) . into ( ) ,
453
+ ttl,
445
454
} ,
446
455
) ;
447
456
handle. write_handle . refresh ( ) ;
@@ -462,6 +471,64 @@ mod tests {
462
471
) ;
463
472
}
464
473
474
+ #[ test]
475
+ fn calculates_ttl_override ( ) {
476
+ let global_ttl = 100 ;
477
+ let ttl_override = 10 ;
478
+ let memory = Memory :: new ( build_memory_config ( |c| {
479
+ c. ttl = global_ttl;
480
+ c. ttl_field = OptionalValuePath :: new ( "ttl" ) ;
481
+ } ) ) ;
482
+ memory. handle_value ( ObjectMap :: from ( [
483
+ (
484
+ "ttl_override" . into ( ) ,
485
+ Value :: from ( ObjectMap :: from ( [
486
+ ( "val" . into ( ) , Value :: from ( 5 ) ) ,
487
+ ( "ttl" . into ( ) , Value :: from ( ttl_override) ) ,
488
+ ] ) ) ,
489
+ ) ,
490
+ (
491
+ "default_ttl" . into ( ) ,
492
+ Value :: from ( ObjectMap :: from ( [ ( "val" . into ( ) , Value :: from ( 5 ) ) ] ) ) ,
493
+ ) ,
494
+ ] ) ) ;
495
+
496
+ let default_condition = Condition :: Equals {
497
+ field : "key" ,
498
+ value : Value :: from ( "default_ttl" ) ,
499
+ } ;
500
+ let override_condition = Condition :: Equals {
501
+ field : "key" ,
502
+ value : Value :: from ( "ttl_override" ) ,
503
+ } ;
504
+
505
+ assert_eq ! (
506
+ Ok ( ObjectMap :: from( [
507
+ ( "key" . into( ) , Value :: from( "default_ttl" ) ) ,
508
+ ( "ttl" . into( ) , Value :: from( global_ttl) ) ,
509
+ (
510
+ "value" . into( ) ,
511
+ Value :: from( ObjectMap :: from( [ ( "val" . into( ) , Value :: from( 5 ) ) ] ) )
512
+ ) ,
513
+ ] ) ) ,
514
+ memory. find_table_row( Case :: Sensitive , & [ default_condition] , None , None , None )
515
+ ) ;
516
+ assert_eq ! (
517
+ Ok ( ObjectMap :: from( [
518
+ ( "key" . into( ) , Value :: from( "ttl_override" ) ) ,
519
+ ( "ttl" . into( ) , Value :: from( ttl_override) ) ,
520
+ (
521
+ "value" . into( ) ,
522
+ Value :: from( ObjectMap :: from( [
523
+ ( "val" . into( ) , Value :: from( 5 ) ) ,
524
+ ( "ttl" . into( ) , Value :: from( ttl_override) )
525
+ ] ) )
526
+ ) ,
527
+ ] ) ) ,
528
+ memory. find_table_row( Case :: Sensitive , & [ override_condition] , None , None , None )
529
+ ) ;
530
+ }
531
+
465
532
#[ test]
466
533
fn removes_expired_records_on_scan_interval ( ) {
467
534
let ttl = 100 ;
@@ -475,6 +542,7 @@ mod tests {
475
542
MemoryEntry {
476
543
value : "5" . to_string ( ) ,
477
544
update_time : ( Instant :: now ( ) - Duration :: from_secs ( ttl + 10 ) ) . into ( ) ,
545
+ ttl,
478
546
} ,
479
547
) ;
480
548
handle. write_handle . refresh ( ) ;
@@ -542,6 +610,7 @@ mod tests {
542
610
MemoryEntry {
543
611
value : "5" . to_string ( ) ,
544
612
update_time : ( Instant :: now ( ) - Duration :: from_secs ( ttl / 2 ) ) . into ( ) ,
613
+ ttl,
545
614
} ,
546
615
) ;
547
616
handle. write_handle . refresh ( ) ;
0 commit comments