@@ -23,7 +23,7 @@ use arrow_schema::{Field, Fields, Schema};
2323use chrono:: { NaiveDateTime , Timelike , Utc } ;
2424use derive_more:: derive:: { Deref , DerefMut } ;
2525use itertools:: Itertools ;
26- use once_cell:: sync:: Lazy ;
26+ use once_cell:: sync:: { Lazy , OnceCell } ;
2727use parquet:: {
2828 arrow:: ArrowWriter ,
2929 basic:: Encoding ,
@@ -33,6 +33,7 @@ use parquet::{
3333 } ,
3434 schema:: types:: ColumnPath ,
3535} ;
36+ use rayon:: iter:: { IntoParallelIterator , ParallelIterator } ;
3637use relative_path:: RelativePathBuf ;
3738use std:: sync:: PoisonError ;
3839use std:: {
@@ -62,6 +63,7 @@ use crate::{
6263 option:: Mode ,
6364 parseable:: { DEFAULT_TENANT , PARSEABLE } ,
6465 storage:: { StreamType , object_storage:: to_bytes, retention:: Retention } ,
66+ sync:: FLUSH_AND_CONVERT_RUNTIME ,
6567 utils:: time:: { Minute , TimeRange } ,
6668} ;
6769
@@ -70,6 +72,8 @@ use super::{
7072 staging:: { StagingError , reader:: MergedReverseRecordReader , writer:: Writer } ,
7173} ;
7274
75+ static HOSTNAME : OnceCell < String > = OnceCell :: new ( ) ;
76+
7377const DISK_WRITE_BATCH_ROWS_VAR : & str = "DISK_WRITE_BATCH_ROWS" ;
7478static DISK_WRITE_BATCH_ROWS : Lazy < usize > = Lazy :: new ( || {
7579 if let Ok ( var) = std:: env:: var ( DISK_WRITE_BATCH_ROWS_VAR )
@@ -209,12 +213,16 @@ impl Stream {
209213 parsed_timestamp : NaiveDateTime ,
210214 custom_partition_values : & HashMap < String , String > ,
211215 ) -> String {
212- let mut hostname = hostname:: get ( )
213- . unwrap_or_else ( |_| std:: ffi:: OsString :: from ( & Ulid :: new ( ) . to_string ( ) ) )
214- . into_string ( )
215- . unwrap_or_else ( |_| Ulid :: new ( ) . to_string ( ) )
216- . matches ( |c : char | c. is_alphanumeric ( ) || c == '-' || c == '_' )
217- . collect :: < String > ( ) ;
216+ let mut hostname = HOSTNAME
217+ . get_or_init ( || {
218+ hostname:: get ( )
219+ . unwrap_or_else ( |_| std:: ffi:: OsString :: from ( & Ulid :: new ( ) . to_string ( ) ) )
220+ . into_string ( )
221+ . unwrap_or_else ( |_| Ulid :: new ( ) . to_string ( ) )
222+ . matches ( |c : char | c. is_alphanumeric ( ) || c == '-' || c == '_' )
223+ . collect :: < String > ( )
224+ } )
225+ . clone ( ) ;
218226
219227 if let Some ( id) = & self . ingestor_id {
220228 hostname. push_str ( id) ;
@@ -257,7 +265,7 @@ impl Stream {
257265 return vec ! [ ] ;
258266 } ;
259267
260- //iterate through all the inprocess_ directories and collect all arrow files
268+ // iterate through all the inprocess_ directories and collect all arrow files
261269 dir. filter_map ( |entry| {
262270 let path = entry. ok ( ) ?. path ( ) ;
263271 if path. is_dir ( )
@@ -587,6 +595,7 @@ impl Stream {
587595 self . stream_name, poisoned
588596 ) ) )
589597 } ) ?;
598+ // why clean Writer.MemWriter?
590599 writer. mem . clear ( ) ;
591600 writer. take_flushable_disk ( forced)
592601 } ;
@@ -825,32 +834,52 @@ impl Stream {
825834 }
826835
827836 self . update_staging_metrics ( & staging_files, tenant_id) ;
828- for ( parquet_path, arrow_files) in staging_files {
829- let record_reader = MergedReverseRecordReader :: try_new ( & arrow_files) ;
830- if record_reader. readers . is_empty ( ) {
831- continue ;
832- }
833- let merged_schema = record_reader. merged_schema ( ) ;
834- let props = self . parquet_writer_props ( & merged_schema, time_partition, custom_partition) ;
835- schemas. push ( merged_schema. clone ( ) ) ;
836- let schema = Arc :: new ( merged_schema) ;
837-
838- let part_path = parquet_path. with_extension ( "part" ) ;
839-
840- if !self . write_parquet_part_file (
841- & part_path,
842- record_reader,
843- & schema,
844- & props,
845- time_partition,
846- ) ? {
847- continue ;
848- }
849837
850- if let Err ( e) = std:: fs:: rename ( & part_path, & parquet_path) {
851- error ! ( "Couldn't rename part file: {part_path:?} -> {parquet_path:?}, error = {e}" ) ;
852- } else {
853- self . cleanup_arrow_files_and_dir ( & arrow_files, tenant_id) ;
838+ let _schemas: Vec < Result < Option < Schema > , StagingError > > = staging_files. into_par_iter ( ) . map (
839+ |( parquet_path, arrow_files) | -> Result < Option < Schema > , StagingError > {
840+ let record_reader = MergedReverseRecordReader :: try_new ( & arrow_files) ;
841+ if record_reader. readers . is_empty ( ) {
842+ Ok ( None )
843+ } else {
844+ let merged_schema = record_reader. merged_schema ( ) ;
845+ let props =
846+ self . parquet_writer_props ( & merged_schema, time_partition, custom_partition) ;
847+ // schemas.push(merged_schema.clone());
848+ let schema = Arc :: new ( merged_schema. clone ( ) ) ;
849+
850+ let part_path = parquet_path. with_extension ( "part" ) ;
851+
852+ if !self . write_parquet_part_file (
853+ & part_path,
854+ record_reader,
855+ & schema,
856+ & props,
857+ time_partition,
858+ ) ? {
859+ return Ok ( None )
860+ }
861+
862+ if let Err ( e) = std:: fs:: rename ( & part_path, & parquet_path) {
863+ error ! (
864+ "Couldn't rename part file: {part_path:?} -> {parquet_path:?}, error = {e}"
865+ ) ;
866+ } else {
867+ self . cleanup_arrow_files_and_dir ( & arrow_files, tenant_id) ;
868+ }
869+ Ok ( Some ( merged_schema) )
870+ }
871+ } ,
872+ )
873+ . collect ( ) ;
874+
875+ for res in _schemas {
876+ match res {
877+ Ok ( s) => {
878+ if let Some ( s) = s {
879+ schemas. push ( s)
880+ }
881+ }
882+ Err ( e) => return Err ( e) ,
854883 }
855884 }
856885 if schemas. is_empty ( ) {
@@ -880,6 +909,8 @@ impl Stream {
880909 . open ( part_path)
881910 . map_err ( |_| StagingError :: Create ) ?;
882911 let mut writer = ArrowWriter :: try_new ( & mut part_file, schema. clone ( ) , Some ( props. clone ( ) ) ) ?;
912+
913+ // does pruning help with query?
883914 let sort_for_metric_pruning = self . is_otel_metrics ( ) ;
884915 let time_partition_field = time_partition. map_or_else (
885916 || DEFAULT_TIMESTAMP_KEY . to_string ( ) ,
@@ -1409,20 +1440,24 @@ impl Stream {
14091440 // For regular cycles, use false to only flush non-current writers
14101441 let forced = init_signal || shutdown_signal;
14111442 self . flush ( forced) ?;
1412- info ! (
1413- "Flushing stream ({}) took: {}s" ,
1414- self . stream_name,
1415- start_flush. elapsed( ) . as_secs_f64( )
1416- ) ;
1443+ if self . get_stream_type ( ) . eq ( & StreamType :: UserDefined ) {
1444+ info ! (
1445+ "Flushing stream ({}) took: {}s" ,
1446+ self . stream_name,
1447+ start_flush. elapsed( ) . as_secs_f64( )
1448+ ) ;
1449+ }
14171450
14181451 let start_convert = Instant :: now ( ) ;
14191452
14201453 self . prepare_parquet ( init_signal, shutdown_signal, tenant_id) ?;
1421- info ! (
1422- "Converting arrows to parquet on stream ({}) took: {}s" ,
1423- self . stream_name,
1424- start_convert. elapsed( ) . as_secs_f64( )
1425- ) ;
1454+ if self . get_stream_type ( ) . eq ( & StreamType :: UserDefined ) {
1455+ info ! (
1456+ "Converting arrows to parquet on stream ({}) took: {}s" ,
1457+ self . stream_name,
1458+ start_convert. elapsed( ) . as_secs_f64( )
1459+ ) ;
1460+ }
14261461
14271462 Ok ( ( ) )
14281463 }
@@ -1512,15 +1547,6 @@ impl Streams {
15121547 } else {
15131548 vec ! [ ]
15141549 }
1515-
1516- // self.read()
1517- // .expect(LOCK_EXPECT)
1518- // .get(&tenant_id)
1519- // .and_then(|v|v.keys())
1520- // .map(f)
1521- // .keys()
1522- // .map(String::clone)
1523- // .collect()
15241550 }
15251551
15261552 pub fn list_internal_streams ( & self , tenant_id : & Option < String > ) -> Vec < String > {
@@ -1553,6 +1579,7 @@ impl Streams {
15531579 vec ! [ DEFAULT_TENANT . to_owned( ) ]
15541580 } ;
15551581
1582+ let handle = FLUSH_AND_CONVERT_RUNTIME . handle ( ) ;
15561583 for tenant_id in tenants {
15571584 let guard = self . read ( ) . expect ( LOCK_EXPECT ) ;
15581585 let streams: Vec < Arc < Stream > > = if let Some ( tenant_streams) = guard. get ( & tenant_id) {
@@ -1563,10 +1590,13 @@ impl Streams {
15631590 for stream in streams {
15641591 let tenant = tenant_id. clone ( ) ;
15651592 let span = info_span ! ( "stream_sync" , stream_name = %stream. stream_name) ;
1566- joinset. spawn_blocking ( move || {
1567- let _guard = span. enter ( ) ;
1568- stream. flush_and_convert ( init_signal, shutdown_signal, & Some ( tenant) )
1569- } ) ;
1593+ joinset. spawn_blocking_on (
1594+ move || {
1595+ let _guard = span. enter ( ) ;
1596+ stream. flush_and_convert ( init_signal, shutdown_signal, & Some ( tenant) )
1597+ } ,
1598+ handle,
1599+ ) ;
15701600 }
15711601 }
15721602 }
0 commit comments