now lazy fetches statuses

This commit is contained in:
Edward Shen 2019-04-30 03:53:13 -04:00
parent adb0c9d41c
commit b1d73e075b
Signed by: edward
GPG key ID: F350507060ED6C90
3 changed files with 63 additions and 17 deletions

1
Cargo.lock generated
View file

@ -427,6 +427,7 @@ dependencies = [
name = "endstat" name = "endstat"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"actix 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)",
"actix-web 0.7.19 (registry+https://github.com/rust-lang/crates.io-index)", "actix-web 0.7.19 (registry+https://github.com/rust-lang/crates.io-index)",
"reqwest 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)", "reqwest 0.9.15 (registry+https://github.com/rust-lang/crates.io-index)",
"ron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "ron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",

View file

@ -10,3 +10,4 @@ serde = { version = "1.0.90", features = ["derive"] }
ron = "0.5" ron = "0.5"
actix-web = "0.7" actix-web = "0.7"
tokio = "0.1" tokio = "0.1"
actix = "0.7"

View file

@ -1,11 +1,23 @@
extern crate actix;
extern crate actix_web;
extern crate reqwest;
extern crate ron;
extern crate serde;
use actix::System;
use actix_web::{
http::{Method, StatusCode},
server, App, HttpResponse, State,
};
use reqwest::{Client, Url, UrlError}; use reqwest::{Client, Url, UrlError};
use ron::de::from_str; use ron::de::from_str;
use serde::Deserialize; use serde::Deserialize;
use std::error::Error; use std::{
use std::fs::read_to_string; error::Error,
use std::time::{Duration, Instant}; fs::read_to_string,
use tokio::prelude::*; sync::{Arc, Mutex},
use tokio::timer::Interval; time::{Duration, Instant},
};
#[derive(Deserialize, Debug, Clone)] #[derive(Deserialize, Debug, Clone)]
struct EndpointConf { struct EndpointConf {
@ -38,29 +50,61 @@ struct Status {
error: Option<String>, error: Option<String>,
} }
struct FetchResults {
last_update: Instant,
refresh_time: u64,
config: Config,
statuses: Vec<Status>,
}
type StatusState = Arc<Mutex<FetchResults>>;
fn index(state: State<StatusState>) -> HttpResponse {
let mut state = state.lock().unwrap();
let mut result = String::new();
if Instant::now().duration_since(state.last_update) > Duration::from_secs(state.refresh_time) {
result = format!(
"it has been {:} seconds since last update, updating",
Instant::now().duration_since(state.last_update).as_secs()
);
state.last_update = Instant::now();
state.statuses = update_status(&state.config);
}
let result = format!("{}\n{:?}", result, state.statuses);
HttpResponse::with_body(StatusCode::OK, result)
}
fn main() -> Result<(), Box<Error>> { fn main() -> Result<(), Box<Error>> {
let config = from_str::<Config>(&read_to_string("./endstat_conf.ron")?)?; let config = from_str::<Config>(&read_to_string("./endstat_conf.ron")?)?;
let mut statuses = update_status(config.clone());
let update_loop = Interval::new(Instant::now(), Duration::from_secs(config.refresh_time)) println!("running server");
.for_each(move |_instant| { let sys = System::new("status");
statuses = update_status(config.clone());
Ok(()) let a: Arc<Mutex<FetchResults>> = Arc::from(Mutex::from(FetchResults {
last_update: Instant::now(),
refresh_time: config.refresh_time,
config: config.clone(),
statuses: update_status(&config),
}));
server::new(move || {
App::with_state(a.clone()).resource("/", |r| r.method(Method::GET).with(index))
}) })
.map_err(|e| panic!("interval errored; err={:?}", e)); .bind("0.0.0.0:8080")?
.start();
tokio::run(update_loop);
sys.run();
Ok(()) Ok(())
} }
fn update_status(config: Config) -> Vec<Status> { fn update_status(config: &Config) -> Vec<Status> {
let client = Client::new(); let client = Client::new();
let mut results: Vec<Status> = vec![]; let mut results: Vec<Status> = vec![];
for website_conf in config.websites { for website_conf in &config.websites {
for endpoint in website_conf.endpoints { for endpoint in &website_conf.endpoints {
let (label, path, port, code, body) = get_endpoint_info(endpoint); let (label, path, port, code, body) = get_endpoint_info(endpoint.clone());
let url = get_url(&website_conf.base, &path, port).expect("reading config"); let url = get_url(&website_conf.base, &path, port).expect("reading config");
if let Ok(mut res) = client.get(&url).send() { if let Ok(mut res) = client.get(&url).send() {
let res_body = res.text().expect("could not get body of request"); let res_body = res.text().expect("could not get body of request");