timeout actually works like its meant to

This commit is contained in:
Alex Janka 2024-03-23 08:32:00 +11:00
parent 7fdbb13ca4
commit c3eaf6ead6
5 changed files with 28 additions and 19 deletions

2
Cargo.lock generated
View file

@ -1143,7 +1143,7 @@ dependencies = [
[[package]]
name = "homekit-exporter"
version = "0.5.1"
version = "0.5.2"
dependencies = [
"clap",
"env_logger",

View file

@ -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<HashMap<String, PythonPairingData>, 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)]

View file

@ -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"

View file

@ -1,7 +1,7 @@
# Maintainer: Alex Janka <alex@alexjanka.com>
pkgname=homekit-logger
pkgver=0.5.1
pkgver=0.5.2
pkgrel=1
pkgdesc="Prometheus exporter for HomeKit sensors"
arch=('x86_64' 'aarch64')

View file

@ -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<Mutex<HashMap<String, DeviceConnection>>>) -> Option<String> {
let mut state = state.lock().await;
@ -27,11 +25,7 @@ pub async fn metrics(state: &State<Mutex<HashMap<String, DeviceConnection>>>) ->
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<Mutex<HashMap<String, DeviceConnection>>>) ->
);
}
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}"))
}