72 lines
2 KiB
Rust
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()
|
|
}
|