stream_non_blocking/
stream_non_blocking.rs

1//! Example: Non-blocking stream reading
2//!
3//! This example demonstrates how to do non-blocking reads from the process stream,
4//! allowing your application to continue doing other work while checking for output.
5
6use sandbox_rs::{SandboxBuilder, StreamChunk};
7use std::time::Duration;
8use tempfile::tempdir;
9
10fn main() -> sandbox_rs::Result<()> {
11    let tmp = tempdir().expect("Failed to create temp dir");
12
13    let mut sandbox = SandboxBuilder::new("non-blocking-example")
14        .memory_limit_str("256M")?
15        .cpu_limit_percent(50)
16        .root(tmp.path())
17        .build()?;
18
19    println!("Running process with non-blocking stream reads...\n");
20
21    // Run a process that outputs slowly
22    let (result, stream) = sandbox.run_with_stream(
23        "/bin/bash",
24        &[
25            "-c",
26            "for i in {1..3}; do echo \"Message $i\"; sleep 0.1; done",
27        ],
28    )?;
29
30    println!("Non-blocking polling:");
31
32    let mut received_chunks = 0;
33    let mut polling_attempts = 0;
34
35    loop {
36        polling_attempts += 1;
37
38        // Try to read without blocking
39        match stream.try_recv()? {
40            Some(chunk) => match chunk {
41                StreamChunk::Stdout(line) => {
42                    println!("[STDOUT] {}", line);
43                    received_chunks += 1;
44                }
45                StreamChunk::Stderr(line) => {
46                    eprintln!("[STDERR] {}", line);
47                    received_chunks += 1;
48                }
49                StreamChunk::Exit {
50                    exit_code,
51                    signal: _,
52                } => {
53                    println!("Process exited with code: {}", exit_code);
54                    break;
55                }
56            },
57            None => {
58                // No data available right now, we could do other work here
59                std::thread::sleep(Duration::from_millis(10));
60            }
61        }
62
63        // Safety limit to prevent infinite loop in case of issues
64        if polling_attempts > 10000 {
65            println!("Safety timeout reached");
66            break;
67        }
68    }
69
70    println!("\nStatistics:");
71    println!("  Chunks received: {}", received_chunks);
72    println!("  Polling attempts: {}", polling_attempts);
73    println!("  Exit code: {}", result.exit_code);
74    println!("  Wall time: {} ms", result.wall_time_ms);
75
76    Ok(())
77}