refactor(server): extract shared runtime and implement service install/run in arbiter-server.exe #44

Open
CleverWild wants to merge 6 commits from win-service into main
4 changed files with 73 additions and 82 deletions
Showing only changes of commit e3050bc5ff - Show all commits

View File

@@ -1,12 +1,19 @@
#![forbid(unsafe_code)]
use crate::context::ServerContext;
use std::{net::SocketAddr, path::PathBuf};
use arbiter_proto::{proto::arbiter_service_server::ArbiterServiceServer, url::ArbiterUrl};
use miette::miette;
use tonic::transport::{Identity, ServerTlsConfig};
use tracing::info;
use crate::{actors::bootstrap::GetToken, context::ServerContext};
pub mod actors;
pub mod context;
pub mod db;
pub mod evm;
pub mod grpc;
pub mod runtime;
pub mod safe_cell;
pub mod utils;
@@ -19,3 +26,64 @@ impl Server {
Self { context }
}
}
#[derive(Debug, Clone)]
pub struct RunConfig {
pub addr: SocketAddr,
pub data_dir: Option<PathBuf>,
pub log_arbiter_url: bool,
}
impl RunConfig {
pub fn new(addr: SocketAddr, data_dir: Option<PathBuf>) -> Self {
Self {
addr,
data_dir,
log_arbiter_url: true,
}
}
}
pub async fn run_server_until_shutdown<F>(config: RunConfig, shutdown: F) -> miette::Result<()>
where
F: Future<Output = ()> + Send + 'static,
{
arbiter_proto::set_home_path_override(config.data_dir.clone())
.map_err(|err| miette!("failed to set home path override: {err}"))?;
let db = db::create_pool(None).await?;
info!(addr = %config.addr, "Database ready");
let context = ServerContext::new(db).await?;
info!(addr = %config.addr, "Server context ready");
if config.log_arbiter_url {
let url = ArbiterUrl {
host: config.addr.ip().to_string(),
port: config.addr.port(),
ca_cert: context.tls.ca_cert().clone().into_owned(),
bootstrap_token: context
.actors
.bootstrapper
.ask(GetToken)
.await
.map_err(|err| miette!("failed to get bootstrap token from actor: {err}"))?,
};
info!(%url, "Server URL");
}
let tls = ServerTlsConfig::new().identity(Identity::from_pem(
context.tls.cert_pem(),
context.tls.key_pem(),
));
tonic::transport::Server::builder()
.tls_config(tls)
.map_err(|err| miette!("Failed to setup TLS: {err}"))?
.add_service(ArbiterServiceServer::new(Server::new(context)))
.serve_with_shutdown(config.addr, shutdown)
.await
.map_err(|e| miette!("gRPC server error: {e}"))?;
Ok(())
}

View File

@@ -25,8 +25,8 @@ async fn main() -> miette::Result<()> {
async fn run_foreground(args: RunArgs) -> miette::Result<()> {
info!(addr = %args.listen_addr, "Starting arbiter server");
arbiter_server::runtime::run_server_until_shutdown(
arbiter_server::runtime::RunConfig::new(args.listen_addr, args.data_dir),
arbiter_server::run_server_until_shutdown(
arbiter_server::RunConfig::new(args.listen_addr, args.data_dir),
std::future::pending::<()>(),
)
.await

View File

@@ -1,77 +0,0 @@
use std::{future::Future, net::SocketAddr, path::PathBuf};
use arbiter_proto::{proto::arbiter_service_server::ArbiterServiceServer, url::ArbiterUrl};
use kameo::actor::ActorRef;
use miette::miette;
use tonic::transport::{Identity, ServerTlsConfig};
use tracing::info;
use crate::{Server, actors::bootstrap::GetToken, context::ServerContext, db};
#[derive(Debug, Clone)]
pub struct RunConfig {
pub addr: SocketAddr,
pub data_dir: Option<PathBuf>,
pub log_arbiter_url: bool,
}
impl RunConfig {
pub fn new(addr: SocketAddr, data_dir: Option<PathBuf>) -> Self {
Self {
addr,
data_dir,
log_arbiter_url: true,
}
}
}
pub async fn run_server_until_shutdown<F>(config: RunConfig, shutdown: F) -> miette::Result<()>
where
F: Future<Output = ()> + Send + 'static,
{
arbiter_proto::set_home_path_override(config.data_dir.clone())
.map_err(|err| miette!("failed to set home path override: {err}"))?;
let db = db::create_pool(None).await?;
info!(addr = %config.addr, "Database ready");
let context = ServerContext::new(db).await?;
info!(addr = %config.addr, "Server context ready");
if config.log_arbiter_url {
let url =
build_arbiter_url(config.addr, &context.actors.bootstrapper, &context.tls).await?;
info!(%url, "Server URL");
}
let tls = ServerTlsConfig::new().identity(Identity::from_pem(
context.tls.cert_pem(),
context.tls.key_pem(),
));
tonic::transport::Server::builder()
.tls_config(tls)
.map_err(|err| miette!("Failed to setup TLS: {err}"))?
.add_service(ArbiterServiceServer::new(Server::new(context)))
.serve_with_shutdown(config.addr, shutdown)
.await
.map_err(|e| miette!("gRPC server error: {e}"))?;
Ok(())
}
async fn build_arbiter_url(
addr: SocketAddr,
bootstrapper: &ActorRef<crate::actors::bootstrap::Bootstrapper>,
tls: &crate::context::tls::TlsManager,
) -> miette::Result<ArbiterUrl> {
Ok(ArbiterUrl {
host: addr.ip().to_string(),
port: addr.port(),
ca_cert: tls.ca_cert().clone().into_owned(),
bootstrap_token: bootstrapper
.ask(GetToken)
.await
.map_err(|err| miette!("failed to get bootstrap token from actor: {err}"))?,
})
}

View File

@@ -19,7 +19,7 @@ use windows_service::{
};
use crate::cli::{ServiceInstallArgs, ServiceRunArgs};
use arbiter_server::runtime::{RunConfig, run_server_until_shutdown};
use arbiter_server::{RunConfig, run_server_until_shutdown};
const SERVICE_NAME: &str = "ArbiterServer";
const SERVICE_DISPLAY_NAME: &str = "Arbiter Server";