@@ -20,14 +20,14 @@ use chrono::{TimeDelta, Timelike};
2020use std:: future:: Future ;
2121use std:: panic:: AssertUnwindSafe ;
2222use tokio:: sync:: oneshot;
23+ use tokio:: task:: JoinSet ;
2324use tokio:: time:: { interval_at, sleep, Duration , Instant } ;
2425use tokio:: { select, task} ;
2526use tracing:: { error, info, trace, warn} ;
2627
2728use crate :: alerts:: { alerts_utils, AlertConfig , AlertError } ;
2829use crate :: parseable:: PARSEABLE ;
29- use crate :: storage:: LOCAL_SYNC_INTERVAL ;
30- use crate :: { STORAGE_CONVERSION_INTERVAL , STORAGE_UPLOAD_INTERVAL } ;
30+ use crate :: { LOCAL_SYNC_INTERVAL , STORAGE_UPLOAD_INTERVAL } ;
3131
3232// Calculates the instant that is the start of the next minute
3333fn next_minute ( ) -> Instant {
6363 if warned_once {
6464 warn!(
6565 "Task '{task_name}' took longer than expected: {:?} (threshold: {threshold:?})" ,
66- start_time. elapsed( ) - threshold
66+ start_time. elapsed( )
6767 ) ;
6868 }
6969 break res. expect( "Task handle shouldn't error" ) ;
@@ -74,28 +74,22 @@ where
7474
7575/// Flushes arrows onto disk every `LOCAL_SYNC_INTERVAL` seconds, packs arrows into parquet every
7676/// `STORAGE_CONVERSION_INTERVAL` secondsand uploads them every `STORAGE_UPLOAD_INTERVAL` seconds.
77- #[ tokio:: main( flavor = "current_thread" ) ]
77+ #[ tokio:: main( flavor = "multi_thread" , worker_threads = 2 ) ]
7878pub async fn handler ( mut cancel_rx : oneshot:: Receiver < ( ) > ) -> anyhow:: Result < ( ) > {
79- let ( localsync_handler, mut localsync_outbox, localsync_inbox) = run_local_sync ( ) ;
79+ let ( localsync_handler, mut localsync_outbox, localsync_inbox) = local_sync ( ) ;
8080 let ( mut remote_sync_handler, mut remote_sync_outbox, mut remote_sync_inbox) =
8181 object_store_sync ( ) ;
82- let ( mut remote_conversion_handler, mut remote_conversion_outbox, mut remote_conversion_inbox) =
83- arrow_conversion ( ) ;
8482 loop {
8583 select ! {
8684 _ = & mut cancel_rx => {
8785 // actix server finished .. stop other threads and stop the server
8886 remote_sync_inbox. send( ( ) ) . unwrap_or( ( ) ) ;
8987 localsync_inbox. send( ( ) ) . unwrap_or( ( ) ) ;
90- remote_conversion_inbox. send( ( ) ) . unwrap_or( ( ) ) ;
9188 if let Err ( e) = localsync_handler. await {
92- error!( "Error joining remote_sync_handler : {:?}" , e ) ;
89+ error!( "Error joining localsync_handler : {e :?}" ) ;
9390 }
9491 if let Err ( e) = remote_sync_handler. await {
95- error!( "Error joining remote_sync_handler: {:?}" , e) ;
96- }
97- if let Err ( e) = remote_conversion_handler. await {
98- error!( "Error joining remote_conversion_handler: {:?}" , e) ;
92+ error!( "Error joining remote_sync_handler: {e:?}" ) ;
9993 }
10094 return Ok ( ( ) ) ;
10195 } ,
@@ -107,17 +101,10 @@ pub async fn handler(mut cancel_rx: oneshot::Receiver<()>) -> anyhow::Result<()>
107101 _ = & mut remote_sync_outbox => {
108102 // remote_sync failed, this is recoverable by just starting remote_sync thread again
109103 if let Err ( e) = remote_sync_handler. await {
110- error!( "Error joining remote_sync_handler: {:?}" , e ) ;
104+ error!( "Error joining remote_sync_handler: {e :?}" ) ;
111105 }
112106 ( remote_sync_handler, remote_sync_outbox, remote_sync_inbox) = object_store_sync( ) ;
113107 } ,
114- _ = & mut remote_conversion_outbox => {
115- // remote_conversion failed, this is recoverable by just starting remote_conversion thread again
116- if let Err ( e) = remote_conversion_handler. await {
117- error!( "Error joining remote_conversion_handler: {:?}" , e) ;
118- }
119- ( remote_conversion_handler, remote_conversion_outbox, remote_conversion_inbox) = arrow_conversion( ) ;
120- } ,
121108 }
122109 }
123110}
@@ -132,8 +119,7 @@ pub fn object_store_sync() -> (
132119
133120 let handle = task:: spawn ( async move {
134121 let result = std:: panic:: catch_unwind ( AssertUnwindSafe ( || async move {
135- let mut sync_interval =
136- interval_at ( next_minute ( ) , Duration :: from_secs ( STORAGE_UPLOAD_INTERVAL ) ) ;
122+ let mut sync_interval = interval_at ( next_minute ( ) , STORAGE_UPLOAD_INTERVAL ) ;
137123
138124 let mut inbox_rx = AssertUnwindSafe ( inbox_rx) ;
139125
@@ -183,64 +169,8 @@ pub fn object_store_sync() -> (
183169 ( handle, outbox_rx, inbox_tx)
184170}
185171
186- pub fn arrow_conversion ( ) -> (
187- task:: JoinHandle < ( ) > ,
188- oneshot:: Receiver < ( ) > ,
189- oneshot:: Sender < ( ) > ,
190- ) {
191- let ( outbox_tx, outbox_rx) = oneshot:: channel :: < ( ) > ( ) ;
192- let ( inbox_tx, inbox_rx) = oneshot:: channel :: < ( ) > ( ) ;
193-
194- let handle = task:: spawn ( async move {
195- let result = std:: panic:: catch_unwind ( AssertUnwindSafe ( || async move {
196- let mut sync_interval = interval_at (
197- next_minute ( ) + Duration :: from_secs ( 5 ) , // 5 second delay
198- Duration :: from_secs ( STORAGE_CONVERSION_INTERVAL ) ,
199- ) ;
200-
201- let mut inbox_rx = AssertUnwindSafe ( inbox_rx) ;
202-
203- loop {
204- select ! {
205- _ = sync_interval. tick( ) => {
206- trace!( "Converting Arrow to Parquet... " ) ;
207- if let Err ( e) = monitor_task_duration(
208- "arrow_conversion" ,
209- Duration :: from_secs( 30 ) ,
210- || async { PARSEABLE . streams. prepare_parquet( false ) } ,
211- ) . await
212- {
213- warn!( "failed to convert local arrow data to parquet. {e:?}" ) ;
214- }
215- } ,
216- res = & mut inbox_rx => { match res{
217- Ok ( _) => break ,
218- Err ( _) => {
219- warn!( "Inbox channel closed unexpectedly" ) ;
220- break ;
221- } }
222- }
223- }
224- }
225- } ) ) ;
226-
227- match result {
228- Ok ( future) => {
229- future. await ;
230- }
231- Err ( panic_error) => {
232- error ! ( "Panic in object store sync task: {panic_error:?}" ) ;
233- let _ = outbox_tx. send ( ( ) ) ;
234- }
235- }
236-
237- info ! ( "Object store sync task ended" ) ;
238- } ) ;
239-
240- ( handle, outbox_rx, inbox_tx)
241- }
242-
243- pub fn run_local_sync ( ) -> (
172+ /// Flush arrows onto disk and convert them into parquet files
173+ pub fn local_sync ( ) -> (
244174 task:: JoinHandle < ( ) > ,
245175 oneshot:: Receiver < ( ) > ,
246176 oneshot:: Sender < ( ) > ,
@@ -253,15 +183,23 @@ pub fn run_local_sync() -> (
253183 let mut inbox_rx = inbox_rx;
254184
255185 let result = std:: panic:: catch_unwind ( AssertUnwindSafe ( || async move {
256- let mut sync_interval =
257- interval_at ( next_minute ( ) , Duration :: from_secs ( LOCAL_SYNC_INTERVAL ) ) ;
186+ let mut sync_interval = interval_at ( next_minute ( ) , LOCAL_SYNC_INTERVAL ) ;
187+ let mut joinset = JoinSet :: new ( ) ;
258188
259189 loop {
260190 select ! {
191+ // Spawns a flush+conversion task every `LOCAL_SYNC_INTERVAL` seconds
261192 _ = sync_interval. tick( ) => {
262- trace!( "Flushing Arrows to disk..." ) ;
263- PARSEABLE . flush_all_streams( ) ;
193+ PARSEABLE . streams. flush_and_convert( & mut joinset, false )
264194 } ,
195+ // Joins and logs errors in spawned tasks
196+ Some ( res) = joinset. join_next( ) , if !joinset. is_empty( ) => {
197+ match res {
198+ Ok ( Ok ( _) ) => info!( "Successfully converted arrow files to parquet." ) ,
199+ Ok ( Err ( err) ) => warn!( "Failed to convert arrow files to parquet. {err:?}" ) ,
200+ Err ( err) => error!( "Issue joining flush+conversion task: {err}" ) ,
201+ }
202+ }
265203 res = & mut inbox_rx => { match res{
266204 Ok ( _) => break ,
267205 Err ( _) => {
@@ -278,7 +216,7 @@ pub fn run_local_sync() -> (
278216 future. await ;
279217 }
280218 Err ( panic_error) => {
281- error ! ( "Panic in local sync task: {:?}" , panic_error ) ;
219+ error ! ( "Panic in local sync task: {panic_error :?}" ) ;
282220 }
283221 }
284222
0 commit comments