diff --git a/Cargo.lock b/Cargo.lock index abbfaf3..440fb50 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1143,7 +1143,7 @@ dependencies = [ [[package]] name = "homekit-exporter" -version = "0.5.1" +version = "0.5.2" dependencies = [ "clap", "env_logger", diff --git a/homekit-controller/src/lib.rs b/homekit-controller/src/lib.rs index 9fe209f..70cffea 100644 --- a/homekit-controller/src/lib.rs +++ b/homekit-controller/src/lib.rs @@ -6,7 +6,7 @@ use ed25519_dalek::{Signer, Verifier}; use hkdf::Hkdf; use sha2::Sha512; -use std::{collections::HashMap, path::PathBuf}; +use std::{collections::HashMap, path::PathBuf, time::Duration}; use thiserror::Error; use x25519_dalek::{EphemeralSecret, PublicKey}; @@ -24,6 +24,8 @@ mod homekit_http; mod pairing_data; mod tlv8; +const METRIC_GATHER_TIMEOUT_SECS: u64 = 3; + pub fn load(pairing_data: PathBuf) -> Result, HomekitError> { Ok(serde_json::from_str(&std::fs::read_to_string( pairing_data, @@ -294,7 +296,19 @@ impl DeviceConnection { } pub async fn update_characteristics(&mut self) -> Result<(), HomekitError> { - self.characteristics_request(true).await + match tokio::time::timeout( + Duration::from_secs(METRIC_GATHER_TIMEOUT_SECS), + self.characteristics_request(true), + ) + .await + { + Ok(r) => r, + Err(_) => { + log::warn!("failed to update characteristics"); + self.socket = None; + Err(HomekitError::Timeout) + } + } } async fn characteristics_request(&mut self, additional_data: bool) -> Result<(), HomekitError> { @@ -385,10 +399,10 @@ pub enum HomekitError { Utf8(#[from] std::string::FromUtf8Error), #[error("device not found")] DeviceNotFound, - #[error("timeout")] - Timeout(#[from] tokio::time::error::Elapsed), #[error("discovery")] Discovery(#[from] DiscoveryError), + #[error("timeout")] + Timeout, } #[derive(Debug, Error)] diff --git a/homekit-exporter/Cargo.toml b/homekit-exporter/Cargo.toml index b2b7bbe..12505f4 100644 --- a/homekit-exporter/Cargo.toml +++ b/homekit-exporter/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "homekit-exporter" -version = "0.5.1" +version = "0.5.2" edition = "2021" license = "Apache-2.0" description = "Prometheus exporter for HomeKit sensors" diff --git a/homekit-exporter/packaging/PKGBUILD b/homekit-exporter/packaging/PKGBUILD index 0928231..d651d7f 100644 --- a/homekit-exporter/packaging/PKGBUILD +++ b/homekit-exporter/packaging/PKGBUILD @@ -1,7 +1,7 @@ # Maintainer: Alex Janka pkgname=homekit-logger -pkgver=0.5.1 +pkgver=0.5.2 pkgrel=1 pkgdesc="Prometheus exporter for HomeKit sensors" arch=('x86_64' 'aarch64') diff --git a/homekit-exporter/src/server.rs b/homekit-exporter/src/server.rs index 3f62cda..99d45b1 100644 --- a/homekit-exporter/src/server.rs +++ b/homekit-exporter/src/server.rs @@ -1,6 +1,6 @@ use homekit_controller::{Data, DeviceConnection}; use rocket::State; -use std::{collections::HashMap, time::Duration}; +use std::collections::HashMap; use tokio::{sync::Mutex, task::JoinSet}; use crate::MONITORED_CHARACTERISTICS; @@ -15,8 +15,6 @@ pub fn launch( .mount("/", routes![metrics]) } -const METRIC_GATHER_TIMEOUT_SECS: u64 = 3; - #[get("/metrics")] pub async fn metrics(state: &State>>) -> Option { let mut state = state.lock().await; @@ -27,11 +25,7 @@ pub async fn metrics(state: &State>>) -> let mut return_string = String::new(); let mut types_seen = Vec::new(); - match tokio::time::timeout(Duration::from_secs(METRIC_GATHER_TIMEOUT_SECS), connected.update_characteristics()).await{ - Ok(r) => r.ok()?, - Err(_) => log::warn!("failed to update characteristics for {name}"), - } - + connected.update_characteristics().await.ok()?; for (aid, accessory) in &connected.accessories { for service in accessory.services.values() { @@ -78,18 +72,19 @@ pub async fn metrics(state: &State>>) -> ); } - let mut s = String::new(); + let mut types_string = String::new(); + let mut values_string = String::new(); let mut shown_types = Vec::new(); while let Some(Ok(Some((k, v, metrics, types)))) = set.join_next().await { state.insert(k, v); for c in types { if !shown_types.contains(&c) { - s.push_str(format!("# TYPE {} gauge\n", c).as_str()); + types_string.push_str(format!("# TYPE {} gauge\n", c).as_str()); shown_types.push(c); } } - s.push_str(&metrics); + values_string.push_str(&metrics); } - Some(s) + Some(format!("{types_string}{values_string}")) }