tracing and changes

This commit is contained in:
2026-09-13 16:25:47 +01:00
parent 74f59be3f8
commit 57201bc0ff
17 changed files with 306 additions and 47 deletions
+3
View File
@@ -39,12 +39,15 @@ impl ClockTicker {
iced::stream::channel(0, move |mut sender: mpsc::Sender<Wire>| async move {
let mut clock = ClockTicker::new();
let mut interval = tokio::time::interval(std::time::Duration::from_secs(1));
tracing::info!(key, "clock service started");
loop {
tokio::select! {
_ = interval.tick() => {
if let Some(payload) = clock.tick() {
tracing::debug!(key, kind = ?payload.kind, "publishing clock");
let wire = Wire::topic(Endpoint::service(key), key, payload);
if sender.send(wire).await.is_err() {
tracing::warn!(key, "clock send failed; stopping service");
return;
}
}
+8 -4
View File
@@ -20,10 +20,14 @@ pub trait IntoSubscription {
impl IntoSubscription for Service {
fn into_subscription(self, inbox: Inbox) -> Subscription<Wire> {
match self.0 {
key if key.starts_with(datetime::NAMESPACE) => datetime::ClockTicker::run(inbox),
key if key.starts_with(weather::NAMESPACE) => weather::WeatherService::run(inbox),
_ => Subscription::none(),
let key = self.0;
match key {
k if k.starts_with(datetime::NAMESPACE) => datetime::ClockTicker::run(inbox),
k if k.starts_with(weather::NAMESPACE) => weather::WeatherService::run(inbox),
_ => {
tracing::warn!(service = key, "no service impl for route key");
Subscription::none()
}
}
}
}
+37 -16
View File
@@ -1,7 +1,10 @@
use std::time::Duration;
use std::{sync::Arc, time::Duration};
use common::{Inbox, WeatherResponse, Wire};
use iced::{futures::channel::mpsc, Subscription};
use common::{Endpoint, Inbox, WeatherMsg, WeatherPayload, WeatherResponse, Wire};
use iced::{
futures::{channel::mpsc, SinkExt},
Subscription,
};
use tokio::time::interval;
pub const NAMESPACE: &str = "weather.";
@@ -12,28 +15,37 @@ const FORECAST_URL: &str = "https://api.open-meteo.com/v1/forecast\
pub struct WeatherService {
client: reqwest::Client,
latest: Option<WeatherResponse>,
}
impl WeatherService {
fn new() -> Self {
Self {
client: reqwest::Client::default(),
latest: None,
}
}
pub fn run(inbox: Inbox) -> Subscription<Wire> {
Subscription::run_with(inbox, |inbox| {
let _key = inbox.key();
let key = inbox.key();
let mut _rx = inbox.take().expect("cant take");
iced::stream::channel(0, move |mut _sender: mpsc::Sender<Wire>| async move {
iced::stream::channel(0, move |mut sender: mpsc::Sender<Wire>| async move {
let mut weather = WeatherService::new();
let mut interval = interval(Duration::from_mins(30));
tracing::info!(key = key, "weather service started");
loop {
tokio::select! {
_ = interval.tick() => {
weather.latest = weather.get_weather().await;
if let Some(resp) = weather.get_weather().await {
let env = WeatherPayload {
kind: WeatherMsg::State,
payload: Arc::new(resp),
};
let wire = Wire::topic(Endpoint::service(key), key, env);
if sender.send(wire).await.is_err() {
tracing::warn!(key, "weather send failed; stopping service");
return;
}
}
}
}
}
@@ -41,13 +53,22 @@ impl WeatherService {
})
}
async fn get_weather(&self) -> Option<WeatherResponse> {
self.client
.get(FORECAST_URL)
.send()
.await
.ok()?
.json::<WeatherResponse>()
.await
.ok()
tracing::debug!(url = FORECAST_URL, "fetching weather");
match self.client.get(FORECAST_URL).send().await {
Ok(resp) => match resp.json::<WeatherResponse>().await {
Ok(parsed) => {
tracing::debug!("weather fetched");
Some(parsed)
}
Err(e) => {
tracing::warn!(error = %e, "weather response decode failed");
None
}
},
Err(e) => {
tracing::warn!(error = %e, "weather request failed");
None
}
}
}
}