caveman/hunter/src/main.rs

110 lines
3.6 KiB
Rust
Raw Normal View History

2022-11-02 21:12:16 +01:00
use std::time::Duration;
2022-11-03 16:50:08 +01:00
use std::{panic, process};
2022-11-02 22:06:43 +01:00
use tokio::time::timeout;
2022-11-02 21:12:16 +01:00
2022-11-02 22:06:43 +01:00
mod config;
2022-11-03 15:40:20 +01:00
mod scheduler;
2022-11-02 21:12:16 +01:00
mod feed;
mod worker;
2022-11-03 16:17:04 +01:00
mod redis_store;
2022-11-02 21:12:16 +01:00
use worker::Message;
2022-11-03 17:34:29 +01:00
fn systemd_status(status: &str) {
systemd::daemon::notify(false, [(systemd::daemon::STATE_STATUS, status)].iter())
.unwrap();
}
2022-11-02 21:12:16 +01:00
#[tokio::main]
async fn main() {
2022-11-03 16:50:08 +01:00
let orig_hook = panic::take_hook();
panic::set_hook(Box::new(move |panic_info| {
// invoke the default handler and exit the process
orig_hook(panic_info);
process::exit(1);
}));
2022-11-03 17:22:21 +01:00
env_logger::init();
2022-11-03 17:34:29 +01:00
let config_file = std::env::args()
.skip(1)
.next()
.expect("Call with config.yaml");
systemd_status(&format!("Loading config file {}", config_file));
let config = config::Config::load_file(&config_file);
2022-11-02 21:12:16 +01:00
2022-11-03 17:34:29 +01:00
systemd_status("Starting redis client");
2022-11-03 16:17:04 +01:00
let redis_client = redis::Client::open(config.redis)
.expect("redis::Client");
2022-11-03 18:58:37 +01:00
let mut redis_man = redis::aio::ConnectionManager::new(redis_client).await
2022-11-03 16:17:04 +01:00
.expect("redis::aio::ConnectionManager");
2022-11-03 17:34:29 +01:00
systemd_status("Starting scheduler");
2022-11-03 15:40:20 +01:00
let mut scheduler = scheduler::Scheduler::new();
2022-11-02 22:06:43 +01:00
for host in config.hosts.into_iter() {
scheduler.introduce(host).await;
2022-11-03 18:58:37 +01:00
}
for host in crate::redis_store::get_hosts(&mut redis_man).await.into_iter() {
scheduler.introduce(host).await;
2022-11-02 22:06:43 +01:00
}
2022-11-03 16:50:40 +01:00
2022-11-03 17:34:29 +01:00
systemd_status("Starting HTTP client");
2022-11-02 21:12:16 +01:00
let client = reqwest::Client::builder()
2022-11-03 02:54:28 +01:00
.timeout(Duration::from_secs(30))
2022-11-03 20:48:36 +01:00
.pool_max_idle_per_host(0)
2022-11-02 21:12:16 +01:00
.user_agent(concat!(
env!("CARGO_PKG_NAME"),
"/",
env!("CARGO_PKG_VERSION"),
))
.deflate(true)
.gzip(true)
.build()
.expect("reqwest::Client");
2022-11-03 17:34:29 +01:00
systemd_status("Ready");
systemd::daemon::notify(false, [(systemd::daemon::STATE_READY, "1")].iter())
.unwrap();
2022-11-02 22:06:43 +01:00
let mut workers_active = 0usize;
2022-11-03 01:21:53 +01:00
let (message_tx, mut message_rx) = tokio::sync::mpsc::unbounded_channel();
2022-11-02 21:12:16 +01:00
loop {
2022-11-03 17:22:21 +01:00
log::trace!("{} workers active, queued {} of {}", workers_active, scheduler.queue_len(), scheduler.size());
2022-11-03 17:34:29 +01:00
systemd_status(&format!("{} workers active, queued {} of {}", workers_active, scheduler.queue_len(), scheduler.size()));
2022-11-02 22:06:43 +01:00
let next_task = if workers_active < config.max_workers {
2022-11-03 15:40:20 +01:00
scheduler.dequeue()
2022-11-02 22:06:43 +01:00
} else {
2022-11-03 00:27:16 +01:00
Err(Duration::from_secs(5))
2022-11-02 22:06:43 +01:00
};
match next_task {
Err(duration) => {
2022-11-02 21:49:37 +01:00
let _ = timeout(duration, async {
2022-11-03 01:21:53 +01:00
let message = message_rx.recv().await.unwrap();
2022-11-02 21:49:37 +01:00
match message {
2022-11-03 16:17:04 +01:00
Message::Fetched { host, next_interval, new_posts } => {
2022-11-02 22:06:43 +01:00
workers_active -= 1;
2022-11-03 16:17:04 +01:00
scheduler.enqueue(host, new_posts > 0, next_interval);
2022-11-02 22:06:43 +01:00
}
2022-11-02 21:49:37 +01:00
Message::IntroduceHosts { hosts } => {
for host in hosts.into_iter() {
scheduler.introduce(host).await;
2022-11-02 21:12:16 +01:00
}
}
}
}).await;
}
Ok(host) => {
2022-11-02 22:06:43 +01:00
workers_active += 1;
2022-11-03 01:21:53 +01:00
worker::fetch_and_process(
message_tx.clone(),
2022-11-03 16:17:04 +01:00
redis_man.clone(),
2022-11-03 01:21:53 +01:00
client.clone(),
host
);
2022-11-03 17:34:29 +01:00
systemd::daemon::notify(false, [(systemd::daemon::STATE_WATCHDOG, "1")].iter())
.unwrap();
2022-11-02 21:12:16 +01:00
}
}
}
}