blob: 4aabb4df4c9c224cce9d9ae8298132411fcadf38 [file]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#![allow(clippy::future_not_send)]
mod args;
use args::Args;
use clap::Parser;
use server_ng::bootstrap::{bootstrap, load_config};
use server_ng::server_error::ServerNgError;
use tracing::{error, info};
fn main() -> Result<(), ServerNgError> {
let bootstrap_runtime = match server_common::create_shard_executor() {
Ok(rt) => rt,
Err(e) => {
match e.kind() {
std::io::ErrorKind::InvalidInput => {
server_common::diagnostics::print_invalid_io_uring_args_info();
}
std::io::ErrorKind::OutOfMemory => {
server_common::diagnostics::print_locked_memory_limit_info();
}
std::io::ErrorKind::PermissionDenied => {
server_common::diagnostics::print_io_uring_permission_info();
}
_ => {}
}
panic!("Cannot create server-ng bootstrap executor: {e}");
}
};
// Bootstrap on a temporary runtime: parse args, init logging, load
// config, init the memory pool. Then drop the runtime and spawn the
// per-shard runtimes - each shard thread builds its OWN
// `compio::runtime::Runtime` via `create_shard_executor`, pinned to
// its CPU.
let bootstrap_result: Result<
(
configs::server_ng::ServerNgConfig,
Option<u8>,
server_common::log::Logging,
),
ServerNgError,
> = bootstrap_runtime.block_on(async {
let args = Args::parse();
if let Ok(env_path) = std::env::var("IGGY_ENV_PATH") {
let _ = dotenvy::from_path(&env_path);
} else {
let _ = dotenvy::dotenv();
}
let mut logging = server_common::log::Logging::new(server_ng::VERSION);
logging.early_init();
server_common::print_build_info!(server_ng::VERSION);
let config = load_config(&mut logging).await?;
server_common::MemoryPool::init_pool(&config.system.memory_pool.into_other());
Ok((config, args.replica_id, logging))
});
// `_logging` owns the tracing appender worker guards; it must outlive the
// shard threads or every log line after bootstrap is silently dropped.
let (config, replica_id, _logging) = bootstrap_result?;
drop(bootstrap_runtime);
let shards = bootstrap(config, replica_id)?;
if let Err(error) = shards.install_ctrlc_handler() {
// Without a working SIGINT handler the server has no way to
// observe an operator Ctrl-C and the shutdown flag would never
// flip, leaving shard threads parked indefinitely. Fail fast
// rather than boot into an un-killable state.
error!(error = %error, "failed to install Ctrl-C handler; aborting boot");
std::process::exit(1);
}
info!("server-ng running; waiting on shard threads");
shards.join_all()?;
info!("server-ng shutdown complete");
Ok(())
}