2020-04-24 10:10:01 +00:00
|
|
|
use std::path::PathBuf;
|
|
|
|
use std::sync::Arc;
|
|
|
|
|
|
|
|
use futures_util::future::*;
|
|
|
|
use tokio::sync::watch;
|
|
|
|
|
|
|
|
use garage_util::background::*;
|
|
|
|
use garage_util::config::*;
|
|
|
|
use garage_util::error::Error;
|
|
|
|
|
|
|
|
use garage_api::api_server;
|
2020-07-07 11:59:22 +00:00
|
|
|
use garage_model::garage::Garage;
|
2020-04-24 10:10:01 +00:00
|
|
|
use garage_rpc::rpc_server::RpcServer;
|
2020-11-10 08:59:52 +00:00
|
|
|
use garage_web::web_server;
|
2020-04-24 10:10:01 +00:00
|
|
|
|
|
|
|
use crate::admin_rpc::*;
|
|
|
|
|
|
|
|
async fn shutdown_signal(send_cancel: watch::Sender<bool>) -> Result<(), Error> {
|
|
|
|
// Wait for the CTRL+C signal
|
|
|
|
tokio::signal::ctrl_c()
|
|
|
|
.await
|
|
|
|
.expect("failed to install CTRL+C signal handler");
|
|
|
|
info!("Received CTRL+C, shutting down.");
|
2021-03-15 21:36:41 +00:00
|
|
|
send_cancel.send(true)?;
|
2020-04-24 10:10:01 +00:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn wait_from(mut chan: watch::Receiver<bool>) -> () {
|
2021-03-15 21:36:41 +00:00
|
|
|
while !*chan.borrow() {
|
|
|
|
if chan.changed().await.is_err() {
|
2020-04-24 10:10:01 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn run_server(config_file: PathBuf) -> Result<(), Error> {
|
|
|
|
info!("Loading configuration...");
|
|
|
|
let config = read_config(config_file).expect("Unable to read config file");
|
|
|
|
|
|
|
|
info!("Opening database...");
|
|
|
|
let mut db_path = config.metadata_dir.clone();
|
|
|
|
db_path.push("db");
|
2021-03-10 15:38:31 +00:00
|
|
|
let db = sled::open(&db_path).expect("Unable to open sled DB");
|
2020-04-24 10:10:01 +00:00
|
|
|
|
|
|
|
info!("Initialize RPC server...");
|
|
|
|
let mut rpc_server = RpcServer::new(config.rpc_bind_addr.clone(), config.rpc_tls.clone());
|
|
|
|
|
|
|
|
info!("Initializing background runner...");
|
|
|
|
let (send_cancel, watch_cancel) = watch::channel(false);
|
2021-03-15 22:14:12 +00:00
|
|
|
let (background, await_background_done) = BackgroundRunner::new(16, watch_cancel.clone());
|
2020-04-24 10:10:01 +00:00
|
|
|
|
2021-03-12 17:12:31 +00:00
|
|
|
info!("Initializing Garage main data store...");
|
2021-03-15 22:14:12 +00:00
|
|
|
let garage = Garage::new(config.clone(), db, background, &mut rpc_server);
|
|
|
|
let bootstrap = garage.system.clone().bootstrap(
|
|
|
|
&config.bootstrap_peers[..],
|
|
|
|
config.consul_host,
|
|
|
|
config.consul_service_name,
|
|
|
|
);
|
2020-04-24 10:10:01 +00:00
|
|
|
|
|
|
|
info!("Crate admin RPC handler...");
|
|
|
|
AdminRpcHandler::new(garage.clone()).register_handler(&mut rpc_server);
|
|
|
|
|
|
|
|
info!("Initializing RPC and API servers...");
|
|
|
|
let run_rpc_server = Arc::new(rpc_server).run(wait_from(watch_cancel.clone()));
|
|
|
|
let api_server = api_server::run_api_server(garage.clone(), wait_from(watch_cancel.clone()));
|
2021-03-15 22:14:12 +00:00
|
|
|
let web_server = web_server::run_web_server(garage, wait_from(watch_cancel.clone()));
|
2020-04-24 10:10:01 +00:00
|
|
|
|
|
|
|
futures::try_join!(
|
2021-03-15 22:14:12 +00:00
|
|
|
bootstrap.map(|rv| {
|
|
|
|
info!("Bootstrap done");
|
|
|
|
Ok(rv)
|
|
|
|
}),
|
2020-04-24 10:10:01 +00:00
|
|
|
run_rpc_server.map(|rv| {
|
|
|
|
info!("RPC server exited");
|
|
|
|
rv
|
|
|
|
}),
|
|
|
|
api_server.map(|rv| {
|
|
|
|
info!("API server exited");
|
|
|
|
rv
|
|
|
|
}),
|
2020-11-02 14:48:39 +00:00
|
|
|
web_server.map(|rv| {
|
|
|
|
info!("Web server exited");
|
|
|
|
rv
|
|
|
|
}),
|
2021-03-15 22:14:12 +00:00
|
|
|
await_background_done.map(|rv| {
|
|
|
|
info!("Background runner exited: {:?}", rv);
|
|
|
|
Ok(())
|
2020-04-24 10:10:01 +00:00
|
|
|
}),
|
|
|
|
shutdown_signal(send_cancel),
|
|
|
|
)?;
|
|
|
|
|
|
|
|
info!("Cleaning up...");
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|