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 gstreamer as gst;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
||||||
use std::{backtrace::Backtrace, panic, pin::Pin, process::Command, sync::Arc};
|
use std::{backtrace::Backtrace, panic, pin::Pin, sync::Arc};
|
||||||
use tokio::{fs::OpenOptions, io::AsyncWriteExt, sync::Mutex};
|
use tokio::{fs::OpenOptions, io::AsyncWriteExt, process::Command, sync::Mutex};
|
||||||
use tokio_stream::wrappers::ReceiverStream;
|
use tokio_stream::wrappers::ReceiverStream;
|
||||||
use tonic::transport::Server;
|
use tonic::transport::Server;
|
||||||
use tonic::{Request, Response, Status};
|
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> {
|
fn uvc_ctrl_bin() -> String {
|
||||||
let bin = std::env::var("LESAVKA_UVC_CTRL_BIN")
|
std::env::var("LESAVKA_UVC_CTRL_BIN")
|
||||||
.unwrap_or_else(|_| "/usr/local/bin/lesavka-uvc".to_string());
|
.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)
|
Command::new(bin)
|
||||||
.arg("--device")
|
.arg("--device")
|
||||||
.arg(uvc_dev)
|
.arg(uvc_dev)
|
||||||
@ -174,6 +177,48 @@ fn spawn_uvc_control(uvc_dev: &str) -> anyhow::Result<std::process::Child> {
|
|||||||
.context("spawning lesavka-uvc")
|
.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 ───────────────────*/
|
/*──────────────── Handler ───────────────────*/
|
||||||
struct Handler {
|
struct Handler {
|
||||||
kb: Arc<Mutex<tokio::fs::File>>,
|
kb: Arc<Mutex<tokio::fs::File>>,
|
||||||
@ -401,27 +446,12 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
let gadget = UsbGadget::new("lesavka");
|
let gadget = UsbGadget::new("lesavka");
|
||||||
let _uvc_ctrl = if std::env::var("LESAVKA_DISABLE_UVC").is_err() {
|
if std::env::var("LESAVKA_DISABLE_UVC").is_err() {
|
||||||
match pick_uvc_device() {
|
let bin = uvc_ctrl_bin();
|
||||||
Ok(uvc_dev) => match spawn_uvc_control(&uvc_dev) {
|
tokio::spawn(supervise_uvc_control(bin));
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
info!("📷 UVC disabled (LESAVKA_DISABLE_UVC set)");
|
info!("📷 UVC disabled (LESAVKA_DISABLE_UVC set)");
|
||||||
None
|
}
|
||||||
};
|
|
||||||
let handler = Handler::new(gadget.clone()).await?;
|
let handler = Handler::new(gadget.clone()).await?;
|
||||||
|
|
||||||
info!("🌐 lesavka-server listening on 0.0.0.0:50051");
|
info!("🌐 lesavka-server listening on 0.0.0.0:50051");
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user