server: supervise uvc helper
This commit is contained in:
parent
f1aaa1743d
commit
3c1f647b04
@ -7,8 +7,8 @@ use futures_util::{Stream, StreamExt};
|
||||
use gstreamer as gst;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
||||
use std::{backtrace::Backtrace, panic, pin::Pin, process::Command, sync::Arc};
|
||||
use tokio::{fs::OpenOptions, io::AsyncWriteExt, sync::Mutex};
|
||||
use std::{backtrace::Backtrace, panic, pin::Pin, sync::Arc};
|
||||
use tokio::{fs::OpenOptions, io::AsyncWriteExt, process::Command, sync::Mutex};
|
||||
use tokio_stream::wrappers::ReceiverStream;
|
||||
use tonic::transport::Server;
|
||||
use tonic::{Request, Response, Status};
|
||||
@ -164,9 +164,12 @@ fn pick_uvc_device() -> anyhow::Result<String> {
|
||||
))
|
||||
}
|
||||
|
||||
fn spawn_uvc_control(uvc_dev: &str) -> anyhow::Result<std::process::Child> {
|
||||
let bin = std::env::var("LESAVKA_UVC_CTRL_BIN")
|
||||
.unwrap_or_else(|_| "/usr/local/bin/lesavka-uvc".to_string());
|
||||
fn uvc_ctrl_bin() -> String {
|
||||
std::env::var("LESAVKA_UVC_CTRL_BIN")
|
||||
.unwrap_or_else(|_| "/usr/local/bin/lesavka-uvc".to_string())
|
||||
}
|
||||
|
||||
fn spawn_uvc_control(bin: &str, uvc_dev: &str) -> anyhow::Result<tokio::process::Child> {
|
||||
Command::new(bin)
|
||||
.arg("--device")
|
||||
.arg(uvc_dev)
|
||||
@ -174,6 +177,48 @@ fn spawn_uvc_control(uvc_dev: &str) -> anyhow::Result<std::process::Child> {
|
||||
.context("spawning lesavka-uvc")
|
||||
}
|
||||
|
||||
async fn supervise_uvc_control(bin: String) {
|
||||
let mut waiting_logged = false;
|
||||
loop {
|
||||
let uvc_dev = match pick_uvc_device() {
|
||||
Ok(dev) => {
|
||||
if waiting_logged {
|
||||
info!(%dev, "📷 UVC device discovered");
|
||||
waiting_logged = false;
|
||||
}
|
||||
dev
|
||||
}
|
||||
Err(e) => {
|
||||
if !waiting_logged {
|
||||
warn!("⚠️ UVC device not ready: {e:#}");
|
||||
waiting_logged = true;
|
||||
}
|
||||
tokio::time::sleep(Duration::from_secs(2)).await;
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
match spawn_uvc_control(&bin, &uvc_dev) {
|
||||
Ok(mut child) => {
|
||||
info!(%uvc_dev, "📷 UVC control helper started");
|
||||
match child.wait().await {
|
||||
Ok(status) => {
|
||||
warn!(%uvc_dev, "⚠️ lesavka-uvc exited: {status}");
|
||||
}
|
||||
Err(e) => {
|
||||
warn!(%uvc_dev, "⚠️ lesavka-uvc wait failed: {e:#}");
|
||||
}
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
warn!(%uvc_dev, "⚠️ failed to start lesavka-uvc: {e:#}");
|
||||
}
|
||||
}
|
||||
|
||||
tokio::time::sleep(Duration::from_secs(2)).await;
|
||||
}
|
||||
}
|
||||
|
||||
/*──────────────── Handler ───────────────────*/
|
||||
struct Handler {
|
||||
kb: Arc<Mutex<tokio::fs::File>>,
|
||||
@ -401,27 +446,12 @@ async fn main() -> anyhow::Result<()> {
|
||||
}));
|
||||
|
||||
let gadget = UsbGadget::new("lesavka");
|
||||
let _uvc_ctrl = if std::env::var("LESAVKA_DISABLE_UVC").is_err() {
|
||||
match pick_uvc_device() {
|
||||
Ok(uvc_dev) => match spawn_uvc_control(&uvc_dev) {
|
||||
Ok(child) => {
|
||||
info!(%uvc_dev, "📷 UVC control helper started");
|
||||
Some(child)
|
||||
}
|
||||
Err(e) => {
|
||||
warn!("⚠️ failed to start lesavka-uvc: {e:#}");
|
||||
None
|
||||
}
|
||||
},
|
||||
Err(e) => {
|
||||
warn!("⚠️ UVC device not ready: {e:#}");
|
||||
None
|
||||
}
|
||||
}
|
||||
if std::env::var("LESAVKA_DISABLE_UVC").is_err() {
|
||||
let bin = uvc_ctrl_bin();
|
||||
tokio::spawn(supervise_uvc_control(bin));
|
||||
} else {
|
||||
info!("📷 UVC disabled (LESAVKA_DISABLE_UVC set)");
|
||||
None
|
||||
};
|
||||
}
|
||||
let handler = Handler::new(gadget.clone()).await?;
|
||||
|
||||
info!("🌐 lesavka-server listening on 0.0.0.0:50051");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user