@@ -42,6 +42,43 @@ impl MessageProcessor {
42
42
} )
43
43
}
44
44
45
+ pub async fn try_new_single_pipeline (
46
+ config_dir : impl AsRef < Path > ,
47
+ pipeline : impl AsRef < Path > ,
48
+ ) -> Result < Self , LoadError > {
49
+ let config_dir = config_dir. as_ref ( ) . to_owned ( ) ;
50
+ let pipeline = pipeline. as_ref ( ) . to_owned ( ) ;
51
+ let mut js_runtime = JsRuntime :: try_new ( ) . await ?;
52
+ let mut pipeline_specs = PipelineSpecs :: default ( ) ;
53
+ pipeline_specs
54
+ . load_single_pipeline ( & mut js_runtime, & config_dir, & pipeline)
55
+ . await ;
56
+ let pipelines = pipeline_specs. compile ( & js_runtime, & config_dir) ;
57
+ Ok ( MessageProcessor {
58
+ config_dir,
59
+ pipelines,
60
+ js_runtime,
61
+ } )
62
+ }
63
+
64
+ pub async fn try_new_single_filter (
65
+ config_dir : impl AsRef < Path > ,
66
+ filter : impl AsRef < Path > ,
67
+ ) -> Result < Self , LoadError > {
68
+ let config_dir = config_dir. as_ref ( ) . to_owned ( ) ;
69
+ let mut js_runtime = JsRuntime :: try_new ( ) . await ?;
70
+ let mut pipeline_specs = PipelineSpecs :: default ( ) ;
71
+ pipeline_specs
72
+ . load_single_filter ( & mut js_runtime, & filter)
73
+ . await ;
74
+ let pipelines = pipeline_specs. compile ( & js_runtime, & config_dir) ;
75
+ Ok ( MessageProcessor {
76
+ config_dir,
77
+ pipelines,
78
+ js_runtime,
79
+ } )
80
+ }
81
+
45
82
pub fn subscriptions ( & self ) -> TopicFilter {
46
83
let mut topics = TopicFilter :: empty ( ) ;
47
84
for pipeline in self . pipelines . values ( ) {
@@ -63,19 +100,6 @@ impl MessageProcessor {
63
100
out_messages
64
101
}
65
102
66
- pub async fn process_with_pipeline (
67
- & mut self ,
68
- pipeline_id : & String ,
69
- timestamp : & DateTime ,
70
- message : & Message ,
71
- ) -> Result < Vec < Message > , FilterError > {
72
- let pipeline = self
73
- . pipelines
74
- . get_mut ( pipeline_id)
75
- . ok_or_else ( || anyhow:: anyhow!( "No such pipeline: {pipeline_id}" ) ) ?;
76
- pipeline. process ( & self . js_runtime , timestamp, message) . await
77
- }
78
-
79
103
pub async fn tick (
80
104
& mut self ,
81
105
timestamp : & DateTime ,
@@ -88,18 +112,6 @@ impl MessageProcessor {
88
112
out_messages
89
113
}
90
114
91
- pub async fn tick_with_pipeline (
92
- & mut self ,
93
- pipeline_id : & String ,
94
- timestamp : & DateTime ,
95
- ) -> Result < Vec < Message > , FilterError > {
96
- let pipeline = self
97
- . pipelines
98
- . get_mut ( pipeline_id)
99
- . ok_or_else ( || anyhow:: anyhow!( "No such pipeline: {pipeline_id}" ) ) ?;
100
- pipeline. tick ( & self . js_runtime , timestamp) . await
101
- }
102
-
103
115
pub async fn dump_memory_stats ( & self ) {
104
116
self . js_runtime . dump_memory_stats ( ) . await ;
105
117
}
@@ -235,10 +247,71 @@ impl PipelineSpecs {
235
247
}
236
248
}
237
249
250
+ pub async fn load_single_pipeline (
251
+ & mut self ,
252
+ js_runtime : & mut JsRuntime ,
253
+ config_dir : & PathBuf ,
254
+ pipeline : & Path ,
255
+ ) {
256
+ let Some ( path) = Utf8Path :: from_path ( pipeline) . map ( |p| p. to_path_buf ( ) ) else {
257
+ error ! ( target: "MAPPING" , "Skipping non UTF8 path: {}" , pipeline. display( ) ) ;
258
+ return ;
259
+ } ;
260
+ if let Err ( err) = self . load_pipeline ( & path) . await {
261
+ error ! ( target: "MAPPING" , "Failed to load pipeline {path}: {err}" ) ;
262
+ return ;
263
+ }
264
+
265
+ let Ok ( mut entries) = read_dir ( config_dir) . await . map_err ( |err|
266
+ error ! ( target: "MAPPING" , "Failed to read filters from {}: {err}" , config_dir. display( ) )
267
+ ) else {
268
+ return ;
269
+ } ;
270
+
271
+ while let Ok ( Some ( entry) ) = entries. next_entry ( ) . await {
272
+ let Some ( path) = Utf8Path :: from_path ( & entry. path ( ) ) . map ( |p| p. to_path_buf ( ) ) else {
273
+ error ! ( target: "MAPPING" , "Skipping non UTF8 path: {}" , entry. path( ) . display( ) ) ;
274
+ continue ;
275
+ } ;
276
+ if let Ok ( file_type) = entry. file_type ( ) . await {
277
+ if file_type. is_file ( ) {
278
+ match path. extension ( ) {
279
+ Some ( "js" ) | Some ( "ts" ) => {
280
+ info ! ( target: "MAPPING" , "Loading filter: {path}" ) ;
281
+ if let Err ( err) = self . load_filter ( js_runtime, path) . await {
282
+ error ! ( target: "MAPPING" , "Failed to load filter: {err}" ) ;
283
+ }
284
+ }
285
+ _ => { }
286
+ }
287
+ }
288
+ }
289
+ }
290
+ }
291
+
292
+ pub async fn load_single_filter (
293
+ & mut self ,
294
+ js_runtime : & mut JsRuntime ,
295
+ filter : impl AsRef < Path > ,
296
+ ) {
297
+ let filter = filter. as_ref ( ) ;
298
+ let Some ( path) = Utf8Path :: from_path ( filter) . map ( |p| p. to_path_buf ( ) ) else {
299
+ error ! ( target: "MAPPING" , "Skipping non UTF8 path: {}" , filter. display( ) ) ;
300
+ return ;
301
+ } ;
302
+ if let Err ( err) = js_runtime. load_file ( & path) . await {
303
+ error ! ( target: "MAPPING" , "Failed to load filter {path}: {err}" ) ;
304
+ }
305
+ let pipeline_id = MessageProcessor :: pipeline_id ( & path) ;
306
+ let pipeline = PipelineConfig :: from_filter ( path. to_owned ( ) ) ;
307
+ self . pipeline_specs
308
+ . insert ( pipeline_id, ( path. to_owned ( ) , pipeline) ) ;
309
+ }
310
+
238
311
async fn load_pipeline ( & mut self , file : impl AsRef < Utf8Path > ) -> Result < ( ) , LoadError > {
239
312
let path = file. as_ref ( ) ;
240
313
let pipeline_id = MessageProcessor :: pipeline_id ( path) ;
241
- let specs = read_to_string ( file . as_ref ( ) ) . await ?;
314
+ let specs = read_to_string ( path ) . await ?;
242
315
let pipeline: PipelineConfig = toml:: from_str ( & specs) ?;
243
316
self . pipeline_specs
244
317
. insert ( pipeline_id, ( path. to_owned ( ) , pipeline) ) ;
@@ -249,9 +322,9 @@ impl PipelineSpecs {
249
322
async fn load_filter (
250
323
& mut self ,
251
324
js_runtime : & mut JsRuntime ,
252
- file : impl AsRef < Utf8Path > ,
325
+ file : impl AsRef < Path > ,
253
326
) -> Result < ( ) , LoadError > {
254
- js_runtime. load_file ( file. as_ref ( ) ) . await ?;
327
+ js_runtime. load_file ( file) . await ?;
255
328
Ok ( ( ) )
256
329
}
257
330
0 commit comments