Created
March 24, 2020 08:16
-
-
Save MarinPostma/955ef5c0a30a4e989c3fa17c05940524 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use std::collections::VecDeque; | |
use std::time::Instant; | |
use std::time::{SystemTime, UNIX_EPOCH}; | |
use tokio::select; | |
use tokio::stream::StreamExt; | |
use tokio::time::{self, Duration}; | |
#[derive(Debug)] | |
struct Website { | |
pub url: String, | |
pub interval: Duration, | |
last_active: Option<Duration>, | |
up: Option<bool>, | |
logs: VecDeque<Log>, | |
} | |
impl PartialEq for Website { | |
fn eq(&self, other: &Self) -> bool { | |
self.url == other.url | |
} | |
} | |
impl Eq for Website {} | |
impl std::hash::Hash for Website { | |
fn hash<H: std::hash::Hasher>(&self, state: &mut H) { | |
self.url.hash(state); | |
} | |
} | |
#[derive(Debug)] | |
struct Log { | |
pub status: reqwest::StatusCode, | |
pub timestamp: Duration, | |
pub request_time: Duration, | |
} | |
async fn make_req(url: &str) -> Log { | |
let begin_time = Instant::now(); | |
let resp = reqwest::get(url).await.unwrap(); | |
Log { | |
status: resp.status(), | |
request_time: begin_time.elapsed(), | |
timestamp: SystemTime::now() | |
.duration_since(UNIX_EPOCH) | |
.expect("error computing time"), | |
} | |
} | |
#[tokio::main] | |
async fn main() -> Result<(), Box<dyn std::error::Error>> { | |
let matches = clap::App::new("monitron") | |
.author("mposmta, postma.marin@protonmail.com") | |
.version("0.1") | |
.about("Monitors website metrics, with user defined specs") | |
.arg( | |
clap::Arg::with_name("add_monitor") | |
.short('a') | |
.long("add") | |
.required(true) | |
.multiple(true) | |
.number_of_values(2) | |
.help("add a website to monitor, with an interval in millis") | |
.value_names(&["url", "interval"]), | |
) | |
.get_matches(); | |
let mut logs = tokio::stream::StreamMap::new(); | |
for pair in matches | |
.values_of("add_monitor") | |
.unwrap() | |
.collect::<Vec<&str>>() | |
.chunks(2) | |
{ | |
let url = pair[0].to_string(); | |
let interval = Duration::from_millis(pair[1].parse()?); | |
let site = Website { | |
url, | |
interval, | |
up: None, | |
last_active: None, | |
logs: VecDeque::new(), | |
}; | |
logs.insert( | |
site, | |
time::interval(site.interval).map(move |_| make_req(&site.url)), | |
); | |
} | |
loop { | |
select! { | |
Some(event) = logs.next() => { | |
println!("here"); | |
}, | |
else => break, | |
}; | |
} | |
Ok(()) | |
} | |
/* | |
error[E0599]: no method named `next` found for struct `tokio::stream::stream_map::StreamMap<Website, tokio::stream::map::Map<tokio::time::interval::Interval, [closure@src/main.rs:86:47: 86:75 site:_]>>` in the current scope | |
--> src/main.rs:91:32 | |
| | |
91 | Some(event) = logs.next() => { | |
| ^^^^ method not found in `tokio::stream::stream_map::StreamMap<Website, tokio::stream::map::Map<tokio::time::interval::Interval, [closure@src/main.rs:86:47: 86:75 site:_]>>` | |
| | |
= note: the method `next` exists but the following trait bounds were not satisfied: | |
`tokio::stream::stream_map::StreamMap<Website, tokio::stream::map::Map<tokio::time::interval::Interval, [closure@src/main.rs:86:47: 86:75 site:_]>> : tokio::stream::StreamExt` | |
error[E0599]: no method named `poll` found for struct `std::pin::Pin<&mut _>` in the current scope | |
--> src/main.rs:90:9 | |
| | |
90 | / select! { | |
91 | | Some(event) = logs.next() => { | |
92 | | println!("here"); | |
93 | | }, | |
94 | | else => break, | |
95 | | }; | |
| |__________^ method not found in `std::pin::Pin<&mut _>` | |
| | |
= note: `fut` is a function, perhaps you wish to call it | |
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment