65 lines
2.3 KiB
Rust
65 lines
2.3 KiB
Rust
mod query;
|
|
mod runner;
|
|
mod types;
|
|
|
|
use anyhow::Result;
|
|
use std::collections::HashSet;
|
|
use std::env;
|
|
use std::sync::Arc;
|
|
use rustls;
|
|
use tokio::sync::Mutex;
|
|
use tokio::time::{sleep, Duration};
|
|
use tracing::{error, info};
|
|
|
|
#[tokio::main]
|
|
async fn main() -> Result<()> {
|
|
rustls::crypto::ring::default_provider().install_default().ok();
|
|
|
|
tracing_subscriber::fmt()
|
|
.with_env_filter(env::var("RUST_LOG").unwrap_or_else(|_| "info".into()))
|
|
.init();
|
|
|
|
let coordinator_url = env::var("COORDINATOR_URL")
|
|
.unwrap_or_else(|_| "http://localhost:3000".into());
|
|
let monitor_token = env::var("MONITOR_TOKEN")
|
|
.expect("MONITOR_TOKEN must be set");
|
|
// Region label this runner reports on every ping. "default" means the operator
|
|
// didn't pin this runner to a named region — it's still a meaningful label so
|
|
// alerts say where they came from instead of being blank.
|
|
let region = env::var("REGION").ok().filter(|s| !s.is_empty()).unwrap_or_else(|| "default".to_string());
|
|
|
|
info!("PingQL monitor starting, coordinator: {coordinator_url}, region: {region}");
|
|
|
|
let client = reqwest::Client::builder()
|
|
.user_agent("PingQL-Monitor/0.1")
|
|
.connect_timeout(std::time::Duration::from_secs(10))
|
|
.build()?;
|
|
|
|
let in_flight: Arc<Mutex<HashSet<String>>> = Arc::new(Mutex::new(HashSet::new()));
|
|
|
|
let shutdown = tokio::signal::ctrl_c();
|
|
tokio::pin!(shutdown);
|
|
|
|
loop {
|
|
tokio::select! {
|
|
_ = &mut shutdown => {
|
|
info!("Shutdown signal received, waiting for in-flight checks...");
|
|
let deadline = tokio::time::Instant::now() + Duration::from_secs(35);
|
|
while !in_flight.lock().await.is_empty() && tokio::time::Instant::now() < deadline {
|
|
sleep(Duration::from_millis(500)).await;
|
|
}
|
|
info!("Shutdown complete");
|
|
break;
|
|
}
|
|
_ = sleep(Duration::from_millis(500)) => {
|
|
match runner::fetch_and_run(&client, &coordinator_url, &monitor_token, ®ion, &in_flight).await {
|
|
Ok(n) => { if n > 0 { info!("Spawned {n} checks"); } },
|
|
Err(e) => error!("Check cycle failed: {e}"),
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|