diff --git a/client/src/app.rs b/client/src/app.rs index 2aa7fb3..a845969 100644 --- a/client/src/app.rs +++ b/client/src/app.rs @@ -41,36 +41,46 @@ impl NavkaClientApp { // 3) Start reading from all keyboards in a background task let mut aggregator = KeyboardAggregator::new(tx.clone()); aggregator.init_devices()?; // discover & grab - let input_task = tokio::spawn(async move { + let kb_handle = tokio::spawn(async move { if let Err(e) = aggregator.run().await { tracing::error!("KeyboardAggregator failed: {e}"); } }); // 4) Add 30 second suicide for dev mode - if self.dev_mode { - // dev mode: we do a 30-second kill - info!("NAVKA_DEV_MODE: aggregator will time out in 30 seconds"); - match timeout(Duration::from_secs(30), input_task).await { - Ok(_) => { - info!("aggregator finished within 30s"); - } - Err(_) => { - tracing::warn!("dev mode: aggregator didn’t finish in 30s -> kill navka-client"); - } + let suicide_fut = async { + if std::env::var_os("NAVKA_DEV_MODE").is_some() { + tracing::info!("DEV-mode: will exit in 30 s"); + tokio::time::sleep(Duration::from_secs(30)).await; + Err::<(), _>(anyhow::anyhow!("dev-mode timer expired")) // cause select! branch to win + } else { + futures::future::pending().await } - std::process::exit(0); - } else { - // normal mode: read aggregator forever - } + }; // 5) Inbound loop: we do something with reports from the server, e.g. logging: - while let Some(report) = inbound.message().await? { - tracing::info!(?report.data, "echo from server"); + let inbound_fut = async { + while let Some(report) = inbound.message().await? { + tracing::debug!(?report.data, "msg from server"); + } + Err::<(), _>(anyhow::anyhow!("server closed stream")) + }; + + // 6) Race the futures + tokio::select! { + res = inbound_fut => { + tracing::warn!("Inbound stream ended: {res:?}"); + }, + res = kb_handle => { + tracing::warn!("Keyboard task finished: {res:?}"); + }, + res = suicide_fut => { + tracing::warn!("Dev-mode shutdown: {res:?}"); + }, } - // 6) If inbound stream ends, stop the input task - input_task.abort(); + // 7) If inbound stream ends, stop the input task + kb_handle.abort(); Ok(()) } } diff --git a/scripts/install-client.sh b/scripts/install-client.sh index e9e4f78..59323c7 100755 --- a/scripts/install-client.sh +++ b/scripts/install-client.sh @@ -28,16 +28,18 @@ install -Dm755 "$SRC/client/target/release/navka-client" "$HOME/.local/bin/navka mkdir -p "$HOME/.config/systemd/user" cat >"$HOME/.config/systemd/user/navka-client.service" <<'EOF' [Unit] -Description=Navka Client (keyboard/mouse → navka-server) +Description=Navka Client (keyboard/mouse -> navka-server) After=network-online.target Wants=network-online.target [Service] +Type=simple +ExecStart=/usr/local/bin/navka-client Environment=RUST_LOG=debug Environment=NAVKA_DEV_MODE=1 Environment=NAVKA_SERVER_ADDR=http://64.25.10.31:50051 ExecStart=%h/.local/bin/navka-client -Restart=on-failure +Restart=no [Install] WantedBy=default.target