rubot/src/main.rs
reverse 7846f91afe
All checks were successful
ci / check (push) Successful in 44s
Format with rustfmt
2026-07-29 19:17:16 +00:00

72 lines
2 KiB
Rust

use std::thread;
use std::time::Duration;
use rustbot::bot::Bot;
use rustbot::config::{self, Config};
use rustbot::irc::Connection;
use rustbot::log;
fn main() {
let configs = config::load();
if configs.is_empty() {
log("no networks configured; nothing to do");
std::process::exit(1);
}
let names: Vec<&str> = configs.iter().map(|c| c.name.as_str()).collect();
log(&format!(
"starting rustbot across {} network(s): {}",
configs.len(),
names.join(", ")
));
let labelled = configs.len() > 1;
let mut handles = Vec::new();
for config in configs {
let name = config.name.clone();
let handle = thread::Builder::new()
.name(name.clone())
.spawn(move || supervise(config, labelled))
.unwrap_or_else(|e| panic!("failed to spawn thread for {name}: {e}"));
handles.push(handle);
}
for handle in handles {
let _ = handle.join();
}
}
fn supervise(config: Config, labelled: bool) {
let tag = if labelled {
format!("[{}] ", config.name)
} else {
String::new()
};
log(&format!(
"{tag}connecting as {} -> {}:{} (tls={})",
config.nick, config.server, config.port, config.tls
));
let mut backoff = 1u64;
loop {
match run_once(&config, labelled) {
Ok(()) => {
log(&format!(
"{tag}server closed the connection; reconnecting shortly"
));
backoff = 1;
}
Err(e) => log(&format!("{tag}session error: {e}; retrying in {backoff}s")),
}
thread::sleep(Duration::from_secs(backoff));
backoff = (backoff * 2).min(60);
}
}
fn run_once(config: &Config, labelled: bool) -> std::io::Result<()> {
let mut conn = Connection::connect(&config.server, config.port, config.tls, config.verbose)?;
if labelled {
conn.set_label(&config.name);
}
let mut bot = Bot::new(config.clone(), conn);
bot.run()
}