From 224739a7ec9c430972b7d7f760e605fda084f28f Mon Sep 17 00:00:00 2001 From: Artemis Tosini Date: Sun, 31 May 2020 02:48:45 +0000 Subject: [PATCH] Add load, remove unwraps, fix high CPU --- src/main.rs | 21 +++++++++++------ src/tile.rs | 2 +- src/tiles/load.rs | 60 +++++++++++++++++++++++++++++++++++++++++++++++ src/tiles/mod.rs | 2 ++ src/tiles/time.rs | 10 ++++---- 5 files changed, 81 insertions(+), 14 deletions(-) create mode 100644 src/tiles/load.rs diff --git a/src/main.rs b/src/main.rs index 8a817d9..ae29dc4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,7 +5,6 @@ pub mod tiles; use dbus_tokio::connection::new_session_sync; use std::sync::Arc; use tile::Tile; -use tokio; use tokio::sync::mpsc::channel; use uuid::Uuid; @@ -22,17 +21,25 @@ async fn main() -> Result<(), Box> { let (sender, receiver) = channel(1024); - let instance = Uuid::new_v4().to_string().into_boxed_str(); - let tiles: Vec> = vec![Arc::new(tiles::Time::new(0, sender, instance))]; + let tiles: Vec> = vec![ + Arc::new(tiles::Load::new( + 0, + sender.clone(), + Uuid::new_v4().to_string().into_boxed_str(), + )), + Arc::new(tiles::Time::new( + 1, + sender, + Uuid::new_v4().to_string().into_boxed_str(), + )), + ]; for tile in &tiles { tile.clone().spawn(); } let num_tiles = tiles.len(); - tokio::spawn(async move { - output::launch(num_tiles, receiver).await.unwrap(); - }); + output::launch(num_tiles, receiver).await?; - loop {} + Ok(()) } diff --git a/src/tile.rs b/src/tile.rs index 18d2ad0..e604365 100644 --- a/src/tile.rs +++ b/src/tile.rs @@ -71,5 +71,5 @@ pub struct TileData { } pub trait Tile: Send { - fn spawn(self: Arc) -> JoinHandle<()>; + fn spawn(self: Arc) -> JoinHandle>>; } diff --git a/src/tiles/load.rs b/src/tiles/load.rs new file mode 100644 index 0000000..b972b60 --- /dev/null +++ b/src/tiles/load.rs @@ -0,0 +1,60 @@ +use crate::tile::{Block, Tile, TileData}; +use async_std::sync::RwLock; +use std::fs::File; +use std::io::Read; +use std::sync::Arc; +use std::time::Duration; +use tokio::sync::mpsc::{error::SendError, Sender}; +use tokio::task::JoinHandle; +use tokio::time::interval; + +pub struct Load { + sender_id: usize, + sender: RwLock>, + instance: Box, +} + +impl Load { + pub fn new(sender_id: usize, sender: Sender, instance: Box) -> Load { + Load { + sender_id, + sender: RwLock::new(sender), + instance, + } + } + + async fn send(&self, data: TileData) -> Result<(), SendError> { + let mut sender = self.sender.write().await; + sender.send(data).await + } + + async fn run(&self) -> Result<(), Box> { + let mut timer = interval(Duration::from_secs(5)); + let mut raw = String::new(); + loop { + timer.tick().await; + File::open("/proc/loadavg")?.read_to_string(&mut raw)?; + let (load, _rest) = raw.split_at(raw.find(' ').unwrap_or(0)); + let block = Block { + full_text: load.into(), + instance: self.instance.clone(), + name: "load".into(), + ..Default::default() + }; + let data = TileData { + block, + sender_id: self.sender_id, + }; + self.send(data).await?; + } + } +} + +impl Tile for Load { + fn spawn(self: Arc) -> JoinHandle>> { + tokio::spawn(async move { + let instance = self; + instance.run().await + }) + } +} diff --git a/src/tiles/mod.rs b/src/tiles/mod.rs index 1ae628f..acafe19 100644 --- a/src/tiles/mod.rs +++ b/src/tiles/mod.rs @@ -1,2 +1,4 @@ +pub mod load; pub mod time; +pub use load::Load; pub use time::Time; diff --git a/src/tiles/time.rs b/src/tiles/time.rs index 53f9a4b..3d12a24 100644 --- a/src/tiles/time.rs +++ b/src/tiles/time.rs @@ -47,10 +47,10 @@ impl Time { self.send(data).await } - async fn run(&self) { + async fn run(&self) -> Result<(), Box> { let mut time = Local::now(); loop { - self.send_time(time).await.unwrap(); + self.send_time(time).await?; time = Local::now(); let millis_part = time.naive_local().timestamp_subsec_millis() as u64; let delay_ms = 1000u64 - millis_part % 1000; // Don't crash if we hit a leap second @@ -60,12 +60,10 @@ impl Time { } impl Tile for Time { - fn spawn(self: Arc) -> JoinHandle<()> { + fn spawn(self: Arc) -> JoinHandle>> { tokio::spawn(async move { let instance = self; - loop { - instance.run().await - } + instance.run().await }) } }