@@ -54,14 +54,10 @@ use crate::HTTP_CLIENT;
54
54
use super :: base_path_without_preceding_slash;
55
55
use super :: ingest:: PostError ;
56
56
use super :: logstream:: error:: StreamError ;
57
- use super :: modal:: { IndexerMetadata , IngestorMetadata , Metadata } ;
57
+ use super :: modal:: { IndexerMetadata , IngestorMetadata , Metadata , NodeMetadata , QuerierMetadata } ;
58
58
use super :: rbac:: RBACError ;
59
59
use super :: role:: RoleError ;
60
60
61
- type IngestorMetadataArr = Vec < IngestorMetadata > ;
62
-
63
- type IndexerMetadataArr = Vec < IndexerMetadata > ;
64
-
65
61
pub const INTERNAL_STREAM_NAME : & str = "pmeta" ;
66
62
67
63
const CLUSTER_METRICS_INTERVAL_SECONDS : Interval = clokwerk:: Interval :: Minutes ( 1 ) ;
@@ -77,7 +73,7 @@ pub async fn sync_streams_with_ingestors(
77
73
for ( key, value) in headers. iter ( ) {
78
74
reqwest_headers. insert ( key. clone ( ) , value. clone ( ) ) ;
79
75
}
80
- let ingestor_infos = get_ingestor_info ( ) . await . map_err ( |err| {
76
+ let ingestor_infos: Vec < NodeMetadata > = get_node_info ( "ingestor" ) . await . map_err ( |err| {
81
77
error ! ( "Fatal: failed to get ingestor info: {:?}" , err) ;
82
78
StreamError :: Anyhow ( err)
83
79
} ) ?;
@@ -125,7 +121,7 @@ pub async fn sync_users_with_roles_with_ingestors(
125
121
username : & String ,
126
122
role : & HashSet < String > ,
127
123
) -> Result < ( ) , RBACError > {
128
- let ingestor_infos = get_ingestor_info ( ) . await . map_err ( |err| {
124
+ let ingestor_infos: Vec < NodeMetadata > = get_node_info ( "ingestor" ) . await . map_err ( |err| {
129
125
error ! ( "Fatal: failed to get ingestor info: {:?}" , err) ;
130
126
RBACError :: Anyhow ( err)
131
127
} ) ?;
@@ -175,7 +171,7 @@ pub async fn sync_users_with_roles_with_ingestors(
175
171
176
172
// forward the delete user request to all ingestors to keep them in sync
177
173
pub async fn sync_user_deletion_with_ingestors ( username : & String ) -> Result < ( ) , RBACError > {
178
- let ingestor_infos = get_ingestor_info ( ) . await . map_err ( |err| {
174
+ let ingestor_infos: Vec < NodeMetadata > = get_node_info ( "ingestor" ) . await . map_err ( |err| {
179
175
error ! ( "Fatal: failed to get ingestor info: {:?}" , err) ;
180
176
RBACError :: Anyhow ( err)
181
177
} ) ?;
@@ -222,7 +218,7 @@ pub async fn sync_user_creation_with_ingestors(
222
218
user : User ,
223
219
role : & Option < HashSet < String > > ,
224
220
) -> Result < ( ) , RBACError > {
225
- let ingestor_infos = get_ingestor_info ( ) . await . map_err ( |err| {
221
+ let ingestor_infos: Vec < NodeMetadata > = get_node_info ( "ingestor" ) . await . map_err ( |err| {
226
222
error ! ( "Fatal: failed to get ingestor info: {:?}" , err) ;
227
223
RBACError :: Anyhow ( err)
228
224
} ) ?;
@@ -280,7 +276,7 @@ pub async fn sync_user_creation_with_ingestors(
280
276
281
277
// forward the password reset request to all ingestors to keep them in sync
282
278
pub async fn sync_password_reset_with_ingestors ( username : & String ) -> Result < ( ) , RBACError > {
283
- let ingestor_infos = get_ingestor_info ( ) . await . map_err ( |err| {
279
+ let ingestor_infos: Vec < NodeMetadata > = get_node_info ( "ingestor" ) . await . map_err ( |err| {
284
280
error ! ( "Fatal: failed to get ingestor info: {:?}" , err) ;
285
281
RBACError :: Anyhow ( err)
286
282
} ) ?;
@@ -328,7 +324,7 @@ pub async fn sync_role_update_with_ingestors(
328
324
name : String ,
329
325
privileges : Vec < DefaultPrivilege > ,
330
326
) -> Result < ( ) , RoleError > {
331
- let ingestor_infos = get_ingestor_info ( ) . await . map_err ( |err| {
327
+ let ingestor_infos: Vec < NodeMetadata > = get_node_info ( "ingestor" ) . await . map_err ( |err| {
332
328
error ! ( "Fatal: failed to get ingestor info: {:?}" , err) ;
333
329
RoleError :: Anyhow ( err)
334
330
} ) ?;
@@ -545,34 +541,48 @@ pub async fn send_retention_cleanup_request(
545
541
546
542
pub async fn get_cluster_info ( ) -> Result < impl Responder , StreamError > {
547
543
// Get ingestor and indexer metadata concurrently
548
- let ( ingestor_result, indexer_result) =
549
- future:: join ( get_ingestor_info ( ) , get_indexer_info ( ) ) . await ;
544
+ let ( querier_result, ingestor_result, indexer_result) = future:: join3 (
545
+ get_node_info ( "querier" ) ,
546
+ get_node_info ( "ingestor" ) ,
547
+ get_node_info ( "indexer" ) ,
548
+ )
549
+ . await ;
550
+
551
+ // Handle querier metadata result
552
+ let querier_metadata: Vec < NodeMetadata > = querier_result
553
+ . map_err ( |err| {
554
+ error ! ( "Fatal: failed to get querier info: {:?}" , err) ;
555
+ PostError :: Invalid ( err)
556
+ } )
557
+ . map_err ( |err| StreamError :: Anyhow ( err. into ( ) ) ) ?;
550
558
551
559
// Handle ingestor metadata result
552
- let ingestor_metadata = ingestor_result
560
+ let ingestor_metadata: Vec < NodeMetadata > = ingestor_result
553
561
. map_err ( |err| {
554
562
error ! ( "Fatal: failed to get ingestor info: {:?}" , err) ;
555
563
PostError :: Invalid ( err)
556
564
} )
557
565
. map_err ( |err| StreamError :: Anyhow ( err. into ( ) ) ) ?;
558
566
559
567
// Handle indexer metadata result
560
- let indexer_metadata = indexer_result
568
+ let indexer_metadata: Vec < NodeMetadata > = indexer_result
561
569
. map_err ( |err| {
562
570
error ! ( "Fatal: failed to get indexer info: {:?}" , err) ;
563
571
PostError :: Invalid ( err)
564
572
} )
565
573
. map_err ( |err| StreamError :: Anyhow ( err. into ( ) ) ) ?;
566
574
567
575
// Fetch info for both node types concurrently
568
- let ( ingestor_infos, indexer_infos) = future:: join (
576
+ let ( querier_infos, ingestor_infos, indexer_infos) = future:: join3 (
577
+ fetch_nodes_info ( querier_metadata) ,
569
578
fetch_nodes_info ( ingestor_metadata) ,
570
579
fetch_nodes_info ( indexer_metadata) ,
571
580
)
572
581
. await ;
573
582
574
583
// Combine results from both node types
575
584
let mut infos = Vec :: new ( ) ;
585
+ infos. extend ( querier_infos?) ;
576
586
infos. extend ( ingestor_infos?) ;
577
587
infos. extend ( indexer_infos?) ;
578
588
@@ -671,40 +681,22 @@ pub async fn get_cluster_metrics() -> Result<impl Responder, PostError> {
671
681
Ok ( actix_web:: HttpResponse :: Ok ( ) . json ( dresses) )
672
682
}
673
683
674
- pub async fn get_ingestor_info ( ) -> anyhow:: Result < IngestorMetadataArr > {
684
+ pub async fn get_node_info < T : Metadata + DeserializeOwned > ( prefix : & str ) -> anyhow:: Result < Vec < T > > {
675
685
let store = PARSEABLE . storage . get_object_store ( ) ;
676
-
677
686
let root_path = RelativePathBuf :: from ( PARSEABLE_ROOT_DIRECTORY ) ;
678
- let arr = store
679
- . get_objects (
680
- Some ( & root_path) ,
681
- Box :: new ( |file_name| file_name. starts_with ( "ingestor" ) ) ,
682
- )
683
- . await ?
684
- . iter ( )
685
- // this unwrap will most definateley shoot me in the foot later
686
- . map ( |x| serde_json:: from_slice :: < IngestorMetadata > ( x) . unwrap_or_default ( ) )
687
- . collect_vec ( ) ;
688
-
689
- Ok ( arr)
690
- }
687
+ let prefix_owned = prefix. to_string ( ) ; // Create an owned copy of the prefix
691
688
692
- pub async fn get_indexer_info ( ) -> anyhow:: Result < IndexerMetadataArr > {
693
- let store = PARSEABLE . storage . get_object_store ( ) ;
694
-
695
- let root_path = RelativePathBuf :: from ( PARSEABLE_ROOT_DIRECTORY ) ;
696
- let arr = store
689
+ let metadata = store
697
690
. get_objects (
698
691
Some ( & root_path) ,
699
- Box :: new ( |file_name| file_name. starts_with ( "indexer" ) ) ,
692
+ Box :: new ( move |file_name| file_name. starts_with ( & prefix_owned ) ) , // Use the owned copy
700
693
)
701
694
. await ?
702
695
. iter ( )
703
- // this unwrap will most definateley shoot me in the foot later
704
- . map ( |x| serde_json:: from_slice :: < IndexerMetadata > ( x) . unwrap_or_default ( ) )
705
- . collect_vec ( ) ;
696
+ . filter_map ( |x| serde_json:: from_slice :: < T > ( x) . ok ( ) )
697
+ . collect ( ) ;
706
698
707
- Ok ( arr )
699
+ Ok ( metadata )
708
700
}
709
701
710
702
pub async fn remove_node ( node_url : Path < String > ) -> Result < impl Responder , PostError > {
@@ -725,7 +717,11 @@ pub async fn remove_node(node_url: Path<String>) -> Result<impl Responder, PostE
725
717
let removed_indexer =
726
718
remove_node_metadata :: < IndexerMetadata > ( & object_store, & domain_name) . await ?;
727
719
728
- let msg = if removed_ingestor || removed_indexer {
720
+ // Delete querier metadata
721
+ let removed_querier =
722
+ remove_node_metadata :: < QuerierMetadata > ( & object_store, & domain_name) . await ?;
723
+
724
+ let msg = if removed_ingestor || removed_indexer || removed_querier {
729
725
format ! ( "node {} removed successfully" , domain_name)
730
726
} else {
731
727
format ! ( "node {} is not found" , domain_name)
@@ -836,6 +832,9 @@ where
836
832
T : Metadata + Send + Sync + ' static ,
837
833
{
838
834
let nodes_len = nodes. len ( ) ;
835
+ if nodes_len == 0 {
836
+ return Ok ( vec ! [ ] ) ;
837
+ }
839
838
let results = stream:: iter ( nodes)
840
839
. map ( |node| async move { fetch_node_metrics ( & node) . await } )
841
840
. buffer_unordered ( nodes_len) // No concurrency limit
@@ -858,23 +857,31 @@ where
858
857
/// Main function to fetch all cluster metrics, parallelized and refactored
859
858
async fn fetch_cluster_metrics ( ) -> Result < Vec < Metrics > , PostError > {
860
859
// Get ingestor and indexer metadata concurrently
861
- let ( ingestor_result, indexer_result) =
862
- future:: join ( get_ingestor_info ( ) , get_indexer_info ( ) ) . await ;
860
+ let ( querier_result, ingestor_result, indexer_result) = future:: join3 (
861
+ get_node_info ( "querier" ) ,
862
+ get_node_info ( "ingestor" ) ,
863
+ get_node_info ( "indexer" ) ,
864
+ )
865
+ . await ;
863
866
867
+ // Handle querier metadata result
868
+ let querier_metadata: Vec < NodeMetadata > = querier_result. map_err ( |err| {
869
+ error ! ( "Fatal: failed to get querier info: {:?}" , err) ;
870
+ PostError :: Invalid ( err)
871
+ } ) ?;
864
872
// Handle ingestor metadata result
865
- let ingestor_metadata = ingestor_result. map_err ( |err| {
873
+ let ingestor_metadata: Vec < NodeMetadata > = ingestor_result. map_err ( |err| {
866
874
error ! ( "Fatal: failed to get ingestor info: {:?}" , err) ;
867
875
PostError :: Invalid ( err)
868
876
} ) ?;
869
-
870
877
// Handle indexer metadata result
871
- let indexer_metadata = indexer_result. map_err ( |err| {
878
+ let indexer_metadata: Vec < NodeMetadata > = indexer_result. map_err ( |err| {
872
879
error ! ( "Fatal: failed to get indexer info: {:?}" , err) ;
873
880
PostError :: Invalid ( err)
874
881
} ) ?;
875
-
876
882
// Fetch metrics from ingestors and indexers concurrently
877
- let ( ingestor_metrics, indexer_metrics) = future:: join (
883
+ let ( querier_metrics, ingestor_metrics, indexer_metrics) = future:: join3 (
884
+ fetch_nodes_metrics ( querier_metadata) ,
878
885
fetch_nodes_metrics ( ingestor_metadata) ,
879
886
fetch_nodes_metrics ( indexer_metadata) ,
880
887
)
@@ -883,6 +890,12 @@ async fn fetch_cluster_metrics() -> Result<Vec<Metrics>, PostError> {
883
890
// Combine all metrics
884
891
let mut all_metrics = Vec :: new ( ) ;
885
892
893
+ // Add querier metrics
894
+ match querier_metrics {
895
+ Ok ( metrics) => all_metrics. extend ( metrics) ,
896
+ Err ( err) => return Err ( err) ,
897
+ }
898
+
886
899
// Add ingestor metrics
887
900
match ingestor_metrics {
888
901
Ok ( metrics) => all_metrics. extend ( metrics) ,
0 commit comments