bubbles 4.1.0

Bubble integration server for powder diffraction
#[macro_use]
extern crate clap;
#[macro_use]
extern crate log;
use crate::dispatcher::Dispatcher;
use crate::params::Params;
use crate::server::{Server, TcpConnect};
use actix::{Actor, Addr, AsyncContext, SyncArbiter, System};
use std::str::FromStr;
use std::sync::Arc;
use std::{fmt, net};
use tokio::net::TcpListener;

pub mod dispatcher;
pub mod notifier;
pub mod session;
pub mod utils;
#[macro_use]
pub mod macros;
pub mod averager;
pub mod codec;
pub mod integrator;
pub mod logger;
pub mod params;
pub mod results;
pub mod server;
pub mod walker;

#[actix::main]
async fn main() {
    let params = Params::from_command_line();
    info!("{} thread(s) will be used for integration", params.threads);
    let params = Arc::new(params);
    let address = params.address();
    let addr = net::SocketAddr::from_str(&address).unwrap();
    let listener = match TcpListener::bind(&addr).await {
        Ok(listener) => listener,
        Err(err) => die!(
            "Failed to start TCP/IP listener at port {}: {}",
            params.port,
            err
        ),
    };
    let waxs_dispatcher = start_dispatcher(params.clone(), IType::WAXS);
    let saxs_dispatcher = start_dispatcher(params.clone(), IType::SAXS);
    let stream = async_stream::stream! {
        while let Ok((st, addr)) = listener.accept().await {
            yield TcpConnect(st, addr);
        }
    };
    Server::create(move |ctx| {
        ctx.add_message_stream(stream);
        Server {
            params,
            waxs_dispatcher,
            saxs_dispatcher,
        }
    });
    info!("Awaiting requests from clients at {}", &address);
    tokio::signal::ctrl_c().await.unwrap();
    info!("Ctrl-C received, shutting down");
    System::current().stop();
}

fn start_dispatcher(params: Arc<Params>, itype: IType) -> Addr<Dispatcher> {
    SyncArbiter::start(1, move || Dispatcher::new(itype, params.clone()))
}

#[derive(PartialEq, Copy, Clone)]
pub enum IType {
    SAXS,
    WAXS,
}

impl fmt::Display for IType {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            IType::SAXS => write!(f, "SAXS"),
            IType::WAXS => write!(f, "WAXS"),
        }
    }
}