use std::{net::SocketAddr, path::PathBuf, sync::Arc};
use bayard::{
client::Client,
cluster::{membership::Membership, metadata::Metadata},
index::{metastore::Metastore, INDICES_DIR},
node::Node,
server::{handle_grpc_server, handle_http_server},
signal::handle_signals,
};
use clap::{AppSettings, Parser};
use tokio::{
sync::{watch, RwLock},
time::{sleep, Duration},
};
#[derive(Parser, Debug)]
#[clap(version, about, long_about = None, setting = AppSettings::DeriveDisplayOrder)]
struct Args {
#[clap(
short = 'b',
long = "bind-address",
default_value = "0.0.0.0:2000",
value_name = "BIND_ADDRESS"
)]
bind_address: String,
#[clap(
short = 'a',
long = "advertise-address",
value_name = "ADVERTISE_ADDRESS"
)]
advertise_address: Option<String>,
#[clap(short = 's', long = "seed-address", value_name = "SEED_ADDRESS")]
seed_address: Option<String>,
#[clap(
short = 'g',
long = "grpc-address",
default_value = "0.0.0.0:5000",
value_name = "GRPC_ADDRESS"
)]
grpc_address: String,
#[clap(
short = 'H',
long = "http-address",
default_value = "0.0.0.0:8000",
value_name = "HTTP_ADDRESS"
)]
http_address: String,
#[clap(
short = 'd',
long = "data-directory",
default_value = "/tmp/bayard",
value_name = "DATA_DIRECTORY"
)]
data_directory: PathBuf,
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
tracing_subscriber::fmt::init();
let args = Args::parse();
let bind_address = args.bind_address.parse::<SocketAddr>()?;
let advertise_address = args
.advertise_address
.unwrap_or_else(|| args.bind_address.clone())
.parse::<SocketAddr>()?;
let seed_address = if let Some(a) = args.seed_address {
Some(a.parse::<SocketAddr>()?)
} else {
None
};
let grpc_address = args.grpc_address.parse::<SocketAddr>()?;
let http_address = args.http_address.parse::<SocketAddr>()?;
let (tx_signal, rx_signal) = watch::channel(());
let signal_handler = tokio::spawn(async move {
handle_signals(tx_signal);
});
let metadata = Metadata {
grpc_address: Some(grpc_address),
http_address: Some(http_address),
};
let membership = Arc::new(
Membership::new(
bind_address,
advertise_address,
metadata,
args.data_directory.clone(),
seed_address,
)
.await?,
);
let metastore = Arc::new(Metastore::new(args.data_directory.join(INDICES_DIR)).await?);
let client = Arc::new(Client::new(Arc::clone(&membership), Arc::clone(&metastore)).await);
let node = Arc::new(RwLock::new(
Node::new(membership, metastore, args.data_directory.join(INDICES_DIR)).await?,
));
let rx_grpc_signal = rx_signal.clone();
let grpc_server_handler = tokio::spawn(async move {
handle_grpc_server(grpc_address, node, client, rx_grpc_signal).await;
});
sleep(Duration::from_secs(1)).await;
let http_server_handler = tokio::spawn(async move {
handle_http_server(http_address, grpc_address, rx_signal).await;
});
grpc_server_handler.await?;
http_server_handler.await?;
signal_handler.await?;
Ok(())
}