@@ -72,8 +72,8 @@ async fn dashboard(
7272 query : web:: Query < HashMap < String , String > > ,
7373) -> impl Responder {
7474 let uptime = Utc :: now ( ) . signed_duration_since ( app_info. start_time ) . num_seconds ( ) as f64 ;
75- let http_requests = 0.0 ;
76- let queue_size = queue. get_ref ( ) . len ( ) . await . unwrap_or ( 0 ) ;
75+ let http_requests = 0.0 ; // Placeholder; update if metrics_middleware tracks this
76+ let queue_size = queue. len ( ) . unwrap_or ( 0 ) ;
7777 let db_status = match db. query ( "SELECT 1 AS test" ) . await {
7878 Ok ( _) => "success" ,
7979 Err ( _) => "error" ,
@@ -238,19 +238,14 @@ async fn main() -> anyhow::Result<()> {
238238
239239 info ! ( "Starting TimeFusion application" ) ;
240240
241- // Read AWS configuration from environment variables.
242- // AWS_S3_BUCKET should be your bucket name, e.g. "my-aws-bucket"
243- // AWS_S3_ENDPOINT should be your AWS S3 endpoint, e.g. "https://s3.amazonaws.com"
241+ // Read AWS configuration from environment variables
244242 let bucket = env:: var ( "AWS_S3_BUCKET" ) . expect ( "AWS_S3_BUCKET environment variable not set" ) ;
245243 let aws_endpoint = env:: var ( "AWS_S3_ENDPOINT" ) . unwrap_or_else ( |_| "https://s3.amazonaws.com" . to_string ( ) ) ;
246- // Build the storage URI for AWS S3.
247244 let storage_uri = format ! ( "s3://{}/?endpoint={}" , bucket, aws_endpoint) ;
248245 info ! ( "Storage URI configured: {}" , storage_uri) ;
249- // Set AWS_ENDPOINT so that the underlying S3 client uses the specified endpoint.
250246 unsafe {
251247 env:: set_var ( "AWS_ENDPOINT" , & aws_endpoint) ;
252248 }
253- // Parse the AWS endpoint URL and register it.
254249 let aws_url = Url :: parse ( & aws_endpoint) . expect ( "AWS endpoint must be a valid URL" ) ;
255250 deltalake:: aws:: register_handlers ( Some ( aws_url) ) ;
256251 info ! ( "AWS handlers registered" ) ;
@@ -266,7 +261,6 @@ async fn main() -> anyhow::Result<()> {
266261 return Err ( e) ;
267262 }
268263 } ;
269- // Use the fixed table name "telemetry_events".
270264 if let Err ( e) = db. add_project ( "telemetry_events" , & storage_uri) . await {
271265 error ! ( "Failed to add table 'telemetry_events': {:?}" , e) ;
272266 return Err ( e) ;
@@ -287,7 +281,7 @@ async fn main() -> anyhow::Result<()> {
287281 let queue_db_path = env:: var ( "QUEUE_DB_PATH" ) . unwrap_or_else ( |_| "/app/queue_db" . to_string ( ) ) ;
288282 info ! ( "Using queue DB path: {}" , queue_db_path) ;
289283
290- let queue = match PersistentQueue :: new ( & queue_db_path) {
284+ let queue = match PersistentQueue :: new ( & queue_db_path, db . clone ( ) ) {
291285 Ok ( q) => {
292286 info ! ( "PersistentQueue initialized successfully" ) ;
293287 Arc :: new ( q)
@@ -387,20 +381,18 @@ async fn main() -> anyhow::Result<()> {
387381 }
388382 _ = sleep( Duration :: from_secs( 5 ) ) => {
389383 debug!( "Checking queue for records to flush" ) ;
390- let records = match queue_clone. dequeue_all( ) . await {
391- Ok ( r) => {
392- debug!( "Dequeued {} records" , r. len( ) ) ;
393- r
394- } ,
384+ match queue_clone. dequeue_all( ) . await {
385+ Ok ( records) => {
386+ debug!( "Dequeued {} records" , records. len( ) ) ;
387+ if !records. is_empty( ) {
388+ info!( "Flushing {} enqueued records" , records. len( ) ) ;
389+ for ( key, record) in records {
390+ process_record( & db_clone, & queue_clone, & status_store_clone, key, record) . await ;
391+ }
392+ }
393+ }
395394 Err ( e) => {
396395 error!( "Error during dequeue_all: {:?}" , e) ;
397- Vec :: new( )
398- }
399- } ;
400- if !records. is_empty( ) {
401- info!( "Flushing {} enqueued records" , records. len( ) ) ;
402- for ( key, record) in records {
403- process_record( & db_clone, & queue_clone, & status_store_clone, key, record) . await ;
404396 }
405397 }
406398 }
@@ -485,18 +477,34 @@ async fn main() -> anyhow::Result<()> {
485477 Ok ( ( ) )
486478}
487479
488- async fn process_record ( db : & Arc < Database > , queue : & Arc < PersistentQueue > , status_store : & IngestStatusStore , key : sled:: IVec , record : IngestRecord ) {
489- use std:: str;
490- let id = str:: from_utf8 ( & key) . unwrap_or ( "unknown" ) . to_string ( ) ;
491- status_store. set_status ( id. clone ( ) , "Processing" . to_string ( ) ) ;
492- if chrono:: DateTime :: parse_from_rfc3339 ( & record. timestamp ) . is_ok ( ) {
480+ async fn process_record (
481+ db : & Arc < Database > ,
482+ queue : & Arc < PersistentQueue > ,
483+ status_store : & Arc < IngestStatusStore > ,
484+ key : String ,
485+ record : IngestRecord ,
486+ ) {
487+ status_store. set_status ( key. clone ( ) , "Processing" . to_string ( ) ) ;
488+ let timestamp = chrono:: DateTime :: from_timestamp (
489+ record. start_time_unix_nano / 1_000_000_000 ,
490+ ( record. start_time_unix_nano % 1_000_000_000 ) as u32 ,
491+ )
492+ . unwrap_or ( Utc :: now ( ) )
493+ . to_rfc3339 ( ) ;
494+
495+ if chrono:: DateTime :: parse_from_rfc3339 ( & timestamp) . is_ok ( ) {
493496 match db. write ( & record) . await {
494497 Ok ( ( ) ) => {
495498 INGESTION_COUNTER . inc ( ) ;
496- status_store. set_status ( id . clone ( ) , "Ingested" . to_string ( ) ) ;
499+ status_store. set_status ( key . clone ( ) , "Ingested" . to_string ( ) ) ;
497500 if let Err ( e) = spawn_blocking ( {
498501 let queue = queue. clone ( ) ;
499- move || queue. remove_sync ( key)
502+ let key = key. clone ( ) ;
503+ move || {
504+ if let Err ( e) = queue. db . remove ( key. as_bytes ( ) ) {
505+ error ! ( "Failed to remove record from queue: {:?}" , e) ;
506+ }
507+ }
500508 } )
501509 . await
502510 {
@@ -506,16 +514,20 @@ async fn process_record(db: &Arc<Database>, queue: &Arc<PersistentQueue>, status
506514 Err ( e) => {
507515 ERROR_COUNTER . inc ( ) ;
508516 error ! ( "Error writing record: {:?}" , e) ;
509- status_store. set_status ( id , format ! ( "Failed: {:?}" , e) ) ;
517+ status_store. set_status ( key , format ! ( "Failed: {:?}" , e) ) ;
510518 }
511519 }
512520 } else {
513521 ERROR_COUNTER . inc ( ) ;
514- error ! ( "Invalid timestamp in record: {}" , record . timestamp) ;
515- status_store. set_status ( id , "Invalid timestamp" . to_string ( ) ) ;
522+ error ! ( "Invalid timestamp in record: {}" , timestamp) ;
523+ status_store. set_status ( key . clone ( ) , "Invalid timestamp" . to_string ( ) ) ;
516524 let _ = spawn_blocking ( {
517525 let queue = queue. clone ( ) ;
518- move || queue. remove_sync ( key)
526+ move || {
527+ if let Err ( e) = queue. db . remove ( key. as_bytes ( ) ) {
528+ error ! ( "Failed to remove record from queue: {:?}" , e) ;
529+ }
530+ }
519531 } )
520532 . await ;
521533 }
0 commit comments