1
- use std:: {
2
- num:: NonZeroU64 ,
3
- time:: { Duration , Instant } ,
4
- } ;
1
+ use std:: time:: { Duration , Instant } ;
5
2
6
3
use chrono:: Utc ;
7
4
use futures:: StreamExt ;
@@ -10,40 +7,22 @@ use tokio_stream::wrappers::IntervalStream;
10
7
use vector_lib:: {
11
8
ByteSizeOf , EstimatedJsonEncodedSizeOf ,
12
9
config:: LogNamespace ,
13
- configurable:: configurable_component,
14
10
event:: { Event , EventMetadata , LogEvent } ,
15
11
internal_event:: {
16
- ByteSize , BytesReceived , CountByteSize , EventsReceived , InternalEventHandle , Protocol ,
12
+ ByteSize , BytesReceived , BytesReceivedHandle , CountByteSize , EventsReceived ,
13
+ EventsReceivedHandle , InternalEventHandle , Protocol ,
17
14
} ,
18
15
shutdown:: ShutdownSignal ,
19
16
} ;
20
17
21
18
use super :: { Memory , MemoryConfig } ;
22
- use crate :: { SourceSender , internal_events:: StreamClosedError } ;
19
+ use crate :: {
20
+ SourceSender ,
21
+ enrichment_tables:: memory:: { MemoryEntryPair , MemorySourceConfig } ,
22
+ internal_events:: StreamClosedError ,
23
+ } ;
23
24
24
- /// Configuration for memory enrichment table source functionality.
25
- #[ configurable_component]
26
- #[ derive( Clone , Debug , PartialEq , Eq ) ]
27
- #[ serde( deny_unknown_fields) ]
28
- pub struct MemorySourceConfig {
29
- /// Interval for exporting all data from the table when used as a source.
30
- pub export_interval : NonZeroU64 ,
31
- /// Batch size for data exporting. Used to prevent exporting entire table at
32
- /// once and blocking the system.
33
- ///
34
- /// By default, batches are not used and entire table is exported.
35
- #[ serde( skip_serializing_if = "vector_lib::serde::is_default" ) ]
36
- pub export_batch_size : Option < u64 > ,
37
- /// If set to true, all data will be removed from cache after exporting.
38
- /// Only valid if used as a source and export_interval > 0
39
- ///
40
- /// By default, export will not remove data from cache
41
- #[ serde( default = "crate::serde::default_false" ) ]
42
- pub remove_after_export : bool ,
43
- /// Key to use for this component when used as a source. This must be different from the
44
- /// component key.
45
- pub source_key : String ,
46
- }
25
+ pub ( crate ) const EXPIRED_ROUTE : & str = "expired" ;
47
26
48
27
/// A struct that represents Memory when used as a source.
49
28
pub ( crate ) struct MemorySource {
@@ -61,78 +40,145 @@ impl MemorySource {
61
40
. memory
62
41
. config
63
42
. source_config
64
- . as_ref ( )
43
+ . clone ( )
65
44
. expect ( "Unexpected missing source config in memory table used as a source." ) ;
66
45
let mut interval = IntervalStream :: new ( interval ( Duration :: from_secs (
67
- source_config. export_interval . into ( ) ,
46
+ source_config
47
+ . export_interval
48
+ . map ( Into :: into)
49
+ . unwrap_or ( u64:: MAX ) ,
68
50
) ) )
69
- . take_until ( self . shutdown ) ;
51
+ . take_until ( self . shutdown . clone ( ) ) ;
52
+ let mut expired_receiver = self . memory . subscribe_to_expired_items ( ) ;
70
53
71
- while interval. next ( ) . await . is_some ( ) {
72
- let mut sent = 0_usize ;
73
- loop {
74
- let mut events = Vec :: new ( ) ;
75
- {
76
- let mut writer = self . memory . write_handle . lock ( ) . unwrap ( ) ;
77
- if let Some ( reader) = self . memory . get_read_handle ( ) . read ( ) {
78
- let now = Instant :: now ( ) ;
79
- let utc_now = Utc :: now ( ) ;
80
- events = reader
81
- . iter ( )
82
- . skip ( if source_config. remove_after_export {
83
- 0
84
- } else {
85
- sent
86
- } )
87
- . take ( if let Some ( batch_size) = source_config. export_batch_size {
88
- batch_size as usize
89
- } else {
90
- usize:: MAX
91
- } )
92
- . filter_map ( |( k, v) | {
93
- if source_config. remove_after_export {
94
- writer. write_handle . empty ( k. clone ( ) ) ;
95
- }
96
- v. get_one ( ) . map ( |v| ( k, v) )
97
- } )
98
- . filter_map ( |( k, v) | {
99
- let mut event = Event :: Log ( LogEvent :: from_map (
100
- v. as_object_map ( now, k) . ok ( ) ?,
101
- EventMetadata :: default ( ) ,
102
- ) ) ;
103
- let log = event. as_mut_log ( ) ;
104
- self . log_namespace . insert_standard_vector_source_metadata (
105
- log,
106
- MemoryConfig :: NAME ,
107
- utc_now,
108
- ) ;
109
-
110
- Some ( event)
111
- } )
112
- . collect :: < Vec < _ > > ( ) ;
113
- if source_config. remove_after_export {
114
- writer. write_handle . refresh ( ) ;
115
- }
54
+ loop {
55
+ tokio:: select! {
56
+ interval_time = interval. next( ) => {
57
+ if interval_time. is_none( ) {
58
+ break ;
116
59
}
117
- }
118
- let count = events. len ( ) ;
119
- let byte_size = events. size_of ( ) ;
120
- let json_size = events. estimated_json_encoded_size_of ( ) ;
121
- bytes_received. emit ( ByteSize ( byte_size) ) ;
122
- events_received. emit ( CountByteSize ( count, json_size) ) ;
123
- if self . out . send_batch ( events) . await . is_err ( ) {
124
- emit ! ( StreamClosedError { count } ) ;
125
- }
60
+ self . export_table_items( & source_config, & events_received, & bytes_received) . await ;
61
+ } ,
126
62
127
- sent += count;
128
- match source_config. export_batch_size {
129
- None => break ,
130
- Some ( export_batch_size) if count < export_batch_size as usize => break ,
131
- _ => { }
63
+ Ok ( expired) = expired_receiver. recv( ) => {
64
+ self . export_expired_entries( expired, & events_received, & bytes_received) . await ;
132
65
}
133
66
}
134
67
}
135
68
136
69
Ok ( ( ) )
137
70
}
71
+
72
+ async fn export_table_items (
73
+ & mut self ,
74
+ source_config : & MemorySourceConfig ,
75
+ events_received : & EventsReceivedHandle ,
76
+ bytes_received : & BytesReceivedHandle ,
77
+ ) {
78
+ let mut sent = 0_usize ;
79
+ loop {
80
+ let mut events = Vec :: new ( ) ;
81
+ {
82
+ let mut writer = self . memory . write_handle . lock ( ) . unwrap ( ) ;
83
+ if let Some ( reader) = self . memory . get_read_handle ( ) . read ( ) {
84
+ let now = Instant :: now ( ) ;
85
+ let utc_now = Utc :: now ( ) ;
86
+ events = reader
87
+ . iter ( )
88
+ . skip ( if source_config. remove_after_export {
89
+ 0
90
+ } else {
91
+ sent
92
+ } )
93
+ . take ( if let Some ( batch_size) = source_config. export_batch_size {
94
+ batch_size as usize
95
+ } else {
96
+ usize:: MAX
97
+ } )
98
+ . filter_map ( |( k, v) | {
99
+ if source_config. remove_after_export {
100
+ writer. write_handle . empty ( k. clone ( ) ) ;
101
+ }
102
+ v. get_one ( ) . map ( |v| ( k, v) )
103
+ } )
104
+ . filter_map ( |( k, v) | {
105
+ let mut event = Event :: Log ( LogEvent :: from_map (
106
+ v. as_object_map ( now, k) . ok ( ) ?,
107
+ EventMetadata :: default ( ) ,
108
+ ) ) ;
109
+ let log = event. as_mut_log ( ) ;
110
+ self . log_namespace . insert_standard_vector_source_metadata (
111
+ log,
112
+ MemoryConfig :: NAME ,
113
+ utc_now,
114
+ ) ;
115
+
116
+ Some ( event)
117
+ } )
118
+ . collect :: < Vec < _ > > ( ) ;
119
+ if source_config. remove_after_export {
120
+ writer. write_handle . refresh ( ) ;
121
+ }
122
+ }
123
+ }
124
+ let count = events. len ( ) ;
125
+ let byte_size = events. size_of ( ) ;
126
+ let json_size = events. estimated_json_encoded_size_of ( ) ;
127
+ bytes_received. emit ( ByteSize ( byte_size) ) ;
128
+ events_received. emit ( CountByteSize ( count, json_size) ) ;
129
+ if self . out . send_batch ( events) . await . is_err ( ) {
130
+ emit ! ( StreamClosedError { count } ) ;
131
+ }
132
+
133
+ sent += count;
134
+ match source_config. export_batch_size {
135
+ None => break ,
136
+ Some ( export_batch_size) if count < export_batch_size as usize => break ,
137
+ _ => { }
138
+ }
139
+ }
140
+ }
141
+
142
+ async fn export_expired_entries (
143
+ & mut self ,
144
+ entries : Vec < MemoryEntryPair > ,
145
+ events_received : & EventsReceivedHandle ,
146
+ bytes_received : & BytesReceivedHandle ,
147
+ ) {
148
+ let now = Instant :: now ( ) ;
149
+ let events = entries
150
+ . into_iter ( )
151
+ . filter_map (
152
+ |MemoryEntryPair {
153
+ key,
154
+ entry : expired_event,
155
+ } | {
156
+ let mut event = Event :: Log ( LogEvent :: from_map (
157
+ expired_event. as_object_map ( now, & key) . ok ( ) ?,
158
+ EventMetadata :: default ( ) ,
159
+ ) ) ;
160
+ let log = event. as_mut_log ( ) ;
161
+ self . log_namespace . insert_standard_vector_source_metadata (
162
+ log,
163
+ MemoryConfig :: NAME ,
164
+ Utc :: now ( ) ,
165
+ ) ;
166
+ Some ( event)
167
+ } ,
168
+ )
169
+ . collect :: < Vec < _ > > ( ) ;
170
+ let count = events. len ( ) ;
171
+ let byte_size = events. size_of ( ) ;
172
+ let json_size = events. estimated_json_encoded_size_of ( ) ;
173
+ bytes_received. emit ( ByteSize ( byte_size) ) ;
174
+ events_received. emit ( CountByteSize ( count, json_size) ) ;
175
+ if self
176
+ . out
177
+ . send_batch_named ( EXPIRED_ROUTE , events)
178
+ . await
179
+ . is_err ( )
180
+ {
181
+ emit ! ( StreamClosedError { count } ) ;
182
+ }
183
+ }
138
184
}
0 commit comments