1use crate::serial_actor::SerialEvent;
7
8pub async fn run_debug_output(mut rx: tokio::sync::broadcast::Receiver<SerialEvent>) {
19 use std::io::{BufWriter, Write};
20 use std::path::Path;
21
22 let (write_tx, write_rx) = std::sync::mpsc::channel::<Vec<u8>>();
23 let write_handle = tokio::task::spawn_blocking(move || {
24 let path = Path::new("./debug.txt");
25 let file = match std::fs::File::create(path) {
26 Ok(f) => f,
27 Err(e) => {
28 eprintln!("Failed to create file: {e}");
29 return;
30 }
31 };
32 let mut writer = BufWriter::with_capacity(48 * 1024, file);
33 let mut last_flush = std::time::Instant::now();
34
35 writeln!(writer, "Session started at: {}", chrono::Utc::now()).ok();
36 while let Ok(data) = write_rx.recv() {
37 writeln!(
38 writer,
39 "[{}] RX {} bytes: {:02X?}{} UTF8: {}",
40 chrono::Utc::now().format("%H:%M:%S%.3f"),
41 data.len(),
42 &data[..std::cmp::min(8, data.len())],
43 if data.len() > 8 { "..." } else { "" },
44 String::from_utf8_lossy(&data)
45 )
46 .ok();
47
48 let now = std::time::Instant::now();
49 if now.duration_since(last_flush) > std::time::Duration::from_millis(100)
50 || writer.buffer().len() > 32 * 1024
51 {
52 let _ = writer.flush();
53 last_flush = now;
54 }
55 }
56 let _ = writer.flush();
57 });
58
59 let data_streamer = tokio::spawn(async move {
60 let mut write_buf = Vec::with_capacity(4096);
61 let mut batch_timer = tokio::time::interval(tokio::time::Duration::from_millis(200));
62
63 loop {
64 tokio::select! {
65 event = rx.recv() => {
66 match event {
67 Ok(SerialEvent::Data(data)) => {
68 write_buf.extend_from_slice(&data);
69 if write_buf.len() >= 4096 && write_tx.send(std::mem::take(&mut write_buf)).is_err() {
70 break;
71 }
72 }
73 Err(tokio::sync::broadcast::error::RecvError::Lagged(skipped)) => {
74 eprintln!("File writer lagged, skipped {skipped} messages");
75 continue; }
77 _ => break,
78 }
79 }
80 _ = batch_timer.tick() => {
81 if !write_buf.is_empty() && write_tx.send(std::mem::take(&mut write_buf)).is_err() {
82 break;
83 }
84 }
85 }
86 }
87 if !write_buf.is_empty() {
88 let _ = write_tx.send(std::mem::take(&mut write_buf));
89 }
90 drop(write_tx);
91 });
92
93 let _ = data_streamer.await;
94 let _ = write_handle.await;
95}