Add load, remove unwraps, fix high CPU

This commit is contained in:
Artemis Tosini 2020-05-31 02:48:45 +00:00
parent 49c82ade0b
commit 224739a7ec
Signed by: artemist
GPG key ID: EE5227935FE3FF18
5 changed files with 81 additions and 14 deletions

View file

@ -5,7 +5,6 @@ pub mod tiles;
use dbus_tokio::connection::new_session_sync; use dbus_tokio::connection::new_session_sync;
use std::sync::Arc; use std::sync::Arc;
use tile::Tile; use tile::Tile;
use tokio;
use tokio::sync::mpsc::channel; use tokio::sync::mpsc::channel;
use uuid::Uuid; use uuid::Uuid;
@ -22,17 +21,25 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
let (sender, receiver) = channel(1024); let (sender, receiver) = channel(1024);
let instance = Uuid::new_v4().to_string().into_boxed_str(); let tiles: Vec<Arc<dyn Tile>> = vec![
let tiles: Vec<Arc<dyn Tile>> = vec![Arc::new(tiles::Time::new(0, sender, instance))]; 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 { for tile in &tiles {
tile.clone().spawn(); tile.clone().spawn();
} }
let num_tiles = tiles.len(); let num_tiles = tiles.len();
tokio::spawn(async move { output::launch(num_tiles, receiver).await?;
output::launch(num_tiles, receiver).await.unwrap();
});
loop {} Ok(())
} }

View file

@ -71,5 +71,5 @@ pub struct TileData {
} }
pub trait Tile: Send { pub trait Tile: Send {
fn spawn(self: Arc<Self>) -> JoinHandle<()>; fn spawn(self: Arc<Self>) -> JoinHandle<Result<(), Box<dyn std::error::Error + Send + Sync>>>;
} }

60
src/tiles/load.rs Normal file
View file

@ -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<Sender<TileData>>,
instance: Box<str>,
}
impl Load {
pub fn new(sender_id: usize, sender: Sender<TileData>, instance: Box<str>) -> Load {
Load {
sender_id,
sender: RwLock::new(sender),
instance,
}
}
async fn send(&self, data: TileData) -> Result<(), SendError<TileData>> {
let mut sender = self.sender.write().await;
sender.send(data).await
}
async fn run(&self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
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<Self>) -> JoinHandle<Result<(), Box<dyn std::error::Error + Send + Sync>>> {
tokio::spawn(async move {
let instance = self;
instance.run().await
})
}
}

View file

@ -1,2 +1,4 @@
pub mod load;
pub mod time; pub mod time;
pub use load::Load;
pub use time::Time; pub use time::Time;

View file

@ -47,10 +47,10 @@ impl Time {
self.send(data).await self.send(data).await
} }
async fn run(&self) { async fn run(&self) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let mut time = Local::now(); let mut time = Local::now();
loop { loop {
self.send_time(time).await.unwrap(); self.send_time(time).await?;
time = Local::now(); time = Local::now();
let millis_part = time.naive_local().timestamp_subsec_millis() as u64; 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 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 { impl Tile for Time {
fn spawn(self: Arc<Self>) -> JoinHandle<()> { fn spawn(self: Arc<Self>) -> JoinHandle<Result<(), Box<dyn std::error::Error + Send + Sync>>> {
tokio::spawn(async move { tokio::spawn(async move {
let instance = self; let instance = self;
loop {
instance.run().await instance.run().await
}
}) })
} }
} }