#[macro_use]
extern crate sozu_lib as sozu;
#[macro_use]
extern crate sozu_command_lib;
#[cfg(target_os = "linux")]
extern crate num_cpus;
#[cfg(feature = "jemallocator")]
#[global_allocator]
static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;
mod cli;
mod command;
mod ctl;
mod upgrade;
pub mod util;
mod worker;
use std::panic;
use cli::Args;
use command::{StartError, begin_main_process};
use ctl::CtlError;
use sozu::metrics::METRICS;
use upgrade::UpgradeError;
use worker::WorkerError;
#[derive(thiserror::Error, Debug)]
enum MainError {
#[error("failed to start Sōzu: {0}")]
StartMain(StartError),
#[error("failed to start new worker: {0}")]
BeginWorker(WorkerError),
#[error("failed to start new main process: {0}")]
BeginNewMain(UpgradeError),
#[error("{0}")]
Cli(CtlError),
#[error("paw io error: {0}")]
Io(std::io::Error),
}
impl From<std::io::Error> for MainError {
fn from(value: std::io::Error) -> Self {
Self::Io(value)
}
}
#[paw::main]
fn main(args: Args) -> Result<(), MainError> {
register_panic_hook();
let result = match args.cmd {
cli::SubCmd::Start => begin_main_process(&args).map_err(MainError::StartMain),
cli::SubCmd::Worker {
fd: worker_to_main_channel_fd,
scm: worker_to_main_scm_fd,
configuration_state_fd,
id,
command_buffer_size,
max_command_buffer_size,
} => {
let max_command_buffer_size =
max_command_buffer_size.unwrap_or(command_buffer_size * 2);
worker::begin_worker_process(
worker_to_main_channel_fd,
worker_to_main_scm_fd,
configuration_state_fd,
id,
command_buffer_size,
max_command_buffer_size,
)
.map_err(MainError::BeginWorker)
}
cli::SubCmd::Main {
fd,
upgrade_fd,
command_buffer_size,
max_command_buffer_size,
} => {
let max_command_buffer_size =
max_command_buffer_size.unwrap_or(command_buffer_size * 2);
upgrade::begin_new_main_process(
fd,
upgrade_fd,
command_buffer_size,
max_command_buffer_size,
)
.map_err(MainError::BeginNewMain)
}
_ => ctl::ctl(args).map_err(MainError::Cli),
};
if let Err(main_error) = &result {
eprintln!("\n{main_error}\n");
}
result
}
fn register_panic_hook() {
let original_panic_hook = panic::take_hook();
panic::set_hook(Box::new(move |panic_info| {
incr!("panic");
METRICS.with(|metrics| {
(*metrics.borrow_mut()).send_data();
});
(*original_panic_hook)(panic_info)
}));
}