123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- //#![allow(unused)]
- #![allow(incomplete_features)]
- #![feature(impl_trait_in_bindings)]
- #![feature(async_closure)]
-
- use std::collections::*;
- use std::path::PathBuf;
-
- use clap::Clap;
-
- use tokio::runtime;
- use tokio::sync::mpsc;
-
- mod config;
- mod sender;
- mod spool;
-
- use crate::config::*;
-
- #[derive(Clap)]
- #[clap(version = "0.1")]
- struct Opts {
- #[clap(
- name = "config",
- short = "c",
- help = "Read this config file by itself, parsed before -C"
- )]
- conf: Option<PathBuf>,
-
- #[clap(
- name = "configdir",
- short = "C",
- help = "Read all config files in this directory"
- )]
- conf_dir: Option<PathBuf>,
-
- #[clap(
- name = "triggerpath",
- short = "r",
- help = "Delete this file to trigger a config reload [NYI]"
- )]
- reload_trigger: Option<PathBuf>,
- }
-
- fn main() {
- let opts = Opts::parse();
- if opts.reload_trigger.is_some() {
- eprintln!("[init] warning: reload trigger file specified, but this option is not supported yet, ignoring...");
- }
-
- let mut rt = make_runtime();
-
- // Figure out which files we want to configure.
- let mut confs = Vec::new();
- if let Some(main) = opts.conf {
- confs.push(main.clone());
- }
- if let Some(dir) = opts.conf_dir {
- match rt.block_on(find_configs(&dir)) {
- Ok(paths) => confs.extend(paths),
- Err(e) => {
- eprintln!("[init] error reading configuration: {:?}", e);
- return;
- }
- }
- }
-
- // Sanity check.
- if confs.len() == 0 {
- println!("[init] no configuration declared, exiting...");
- return;
- }
-
- // Process configuration.
- // TODO Remove all these cases of `block_on` except for a final toplevel task.
- let config = match rt.block_on(parse_configs(&confs)) {
- Ok(c) => c,
- Err(e) => {
- eprintln!("[init] error parsing configuration: {:?}", e);
- return; // maybe
- }
- };
-
- let mut clients = HashMap::new();
- let mut sender_futs = Vec::new();
-
- // Init each account and put outgoing channels into a table for later reference.
- for cc in config.accounts.iter() {
- match rt.block_on(sender::create_and_auth_client(cc.1.clone())) {
- Ok(c) => {
- let (send, recv) = mpsc::channel(2); // FIXME configurable
- clients.insert(cc.0.clone(), send);
- sender_futs.push(sender::submit_messages(c, recv));
- }
- Err(e) => {
- eprintln!("[init] error: client setup failed: {:?}", e);
- return; // maybe
- }
- }
- }
-
- // This is where the real stuff actually happens.
- match rt.block_on(spool::start_spoolers(config, clients)) {
- Ok(_) => {}
- Err(e) => println!("fatal error: {:?}", e),
- }
-
- // just wait I guess?
- rt.block_on(futures::future::join_all(sender_futs.into_iter()));
- }
-
- fn make_runtime() -> runtime::Runtime {
- runtime::Builder::new()
- .max_threads(1)
- .enable_all()
- .basic_scheduler()
- .build()
- .expect("init runtime")
- }
|