Move startup camera test to background thread

Server starts accepting requests immediately instead of blocking on
the camera test. If the camera lock is held by a previous process,
the server is still reachable and will attempt live camera access
on each request independently.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Leopere 2026-02-15 11:49:37 -05:00
parent de34516fed
commit 2026bf5305
Signed by: colin
SSH Key Fingerprint: SHA256:nRPCQTeMFLdGytxRQmPVK9VXY3/ePKQ5lGRyJhT5DY8
1 changed files with 34 additions and 30 deletions

View File

@ -53,39 +53,43 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
.unwrap_or(DEFAULT_PORT); .unwrap_or(DEFAULT_PORT);
let config = CameraConfig::from_env(); let config = CameraConfig::from_env();
// Test camera access at startup (informational only). // Test camera access at startup (informational only, non-blocking).
println!("Testing camera access..."); // Server starts immediately; the camera test runs in the background.
match test_camera(&config) { let startup_config = config.clone();
Ok((actual_w, actual_h, frame_size)) => { std::thread::spawn(move || {
let conditioned_per_frame = (frame_size / CHUNK_SIZE) * 32; println!("Testing camera access...");
let throughput_30fps = conditioned_per_frame * 30; match test_camera(&startup_config) {
let raw_mbps = (frame_size as f64 * 30.0 * 8.0) / 1_000_000.0; Ok((actual_w, actual_h, frame_size)) => {
let conditioned_kbs = throughput_30fps / 1_000; let conditioned_per_frame = (frame_size / CHUNK_SIZE) * 32;
println!( let throughput_30fps = conditioned_per_frame * 30;
"Camera OK: {}x{}, {} KB/frame ({} bytes)", let raw_mbps = (frame_size as f64 * 30.0 * 8.0) / 1_000_000.0;
actual_w, actual_h, frame_size / 1024, frame_size let conditioned_kbs = throughput_30fps / 1_000;
); println!(
if raw_mbps >= 1000.0 { "Camera OK: {}x{}, {} KB/frame ({} bytes)",
println!("Throughput: {:.1} Gbps raw, ~{} MB/s conditioned @ 30fps", actual_w, actual_h, frame_size / 1024, frame_size
raw_mbps / 1000.0, throughput_30fps / 1_000_000);
} else {
println!("Throughput: {:.0} Mbps raw, ~{} KB/s conditioned @ 30fps",
raw_mbps, conditioned_kbs);
}
println!("Ensure lens is covered for optimal quantum noise capture");
}
Err(e) => {
eprintln!(
"Camera error: {}. Requests will fail until camera is available.",
e
);
if e.contains("Lock Rejected") || e.contains("lock") {
eprintln!(
" → To release camera: ./scripts/release-camera.sh then restart."
); );
if raw_mbps >= 1000.0 {
println!("Throughput: {:.1} Gbps raw, ~{} MB/s conditioned @ 30fps",
raw_mbps / 1000.0, throughput_30fps / 1_000_000);
} else {
println!("Throughput: {:.0} Mbps raw, ~{} KB/s conditioned @ 30fps",
raw_mbps, conditioned_kbs);
}
println!("Ensure lens is covered for optimal quantum noise capture");
}
Err(e) => {
eprintln!(
"Camera warning: {}. Requests will fail until camera is available.",
e
);
if e.contains("Lock Rejected") || e.contains("lock") {
eprintln!(
" → To release camera: ./scripts/release-camera.sh then restart."
);
}
} }
} }
} });
let app = Router::new() let app = Router::new()
.route("/", get(index)) .route("/", get(index))