diff --git a/backend/src/controller/judger/mod.rs b/backend/src/controller/judger/mod.rs index b56bbf63..4f8f8dde 100644 --- a/backend/src/controller/judger/mod.rs +++ b/backend/src/controller/judger/mod.rs @@ -2,7 +2,7 @@ mod pubsub; mod route; use std::sync::Arc; -use crate::{grpc::TonicStream, ofl, report_internal}; +use crate::{grpc::TonicStream, init::config, ofl, report_internal}; use futures::Future; use leaky_bucket::RateLimiter; use sea_orm::{ActiveModelTrait, ActiveValue, EntityTrait, QueryOrder}; @@ -122,8 +122,8 @@ pub struct JudgerController { impl JudgerController { #[tracing::instrument(parent=span, name="judger_construct",level = "info",skip_all)] - pub async fn new(config: &GlobalConfig, span: &Span) -> Result { - let router = Router::new(config.judger.clone(), span).await?; + pub async fn new(config: Vec, span: &Span) -> Result { + let router = Router::new(config, span).await?; Ok(JudgerController { router, pubsub: Arc::new(PubSub::default()), diff --git a/backend/src/init/config.rs b/backend/src/init/config.rs index dd28166b..a0db4a4c 100644 --- a/backend/src/init/config.rs +++ b/backend/src/init/config.rs @@ -5,7 +5,7 @@ use tokio::{fs, io::AsyncReadExt}; static CONFIG_PATH: &str = "config/config.toml"; -#[derive(Serialize, Deserialize, Debug)] +#[derive(Serialize, Deserialize, Debug, Clone)] pub struct GlobalConfig { #[serde(default = "default_bind_address")] pub bind_address: String, @@ -49,7 +49,7 @@ pub struct Judger { pub judger_type: JudgerType, } -#[derive(Serialize, Deserialize, Debug)] +#[derive(Serialize, Deserialize, Debug, Clone)] pub struct GrpcOption { pub trust_x_forwarded_for: bool, pub public_pem: PathBuf, @@ -66,7 +66,7 @@ impl Default for GrpcOption { } } -#[derive(Serialize, Deserialize, Debug)] +#[derive(Serialize, Deserialize, Debug, Clone)] pub struct Database { pub path: String, pub salt: String, diff --git a/backend/src/init/db.rs b/backend/src/init/db.rs index 1b2f6db9..b360c6d1 100644 --- a/backend/src/init/db.rs +++ b/backend/src/init/db.rs @@ -1,4 +1,5 @@ use std::path::PathBuf; +use std::sync::Arc; use ring::digest; use sea_orm::{ @@ -8,14 +9,14 @@ use sea_orm::{ use tokio::fs; use tokio::sync::OnceCell; -use super::config::GlobalConfig; +use super::config::{self, GlobalConfig}; use crate::controller::token::UserPermBytes; pub static DB: OnceCell = OnceCell::const_new(); -pub async fn init(config: &GlobalConfig) { +pub async fn init(config: &config::Database) { // sqlite://database/backend.sqlite?mode=rwc - let uri = format!("sqlite://{}", config.database.path.clone()); + let uri = format!("sqlite://{}", config.path.clone()); let db = Database::connect(&uri) .await @@ -23,16 +24,16 @@ pub async fn init(config: &GlobalConfig) { init_user(config, &db).await; DB.set(db).ok(); } -fn hash(config: &GlobalConfig, src: &str) -> Vec { +fn hash(config: &config::Database, src: &str) -> Vec { digest::digest( &digest::SHA256, - &[src.as_bytes(), config.database.salt.as_bytes()].concat(), + &[src.as_bytes(), config.salt.as_bytes()].concat(), ) .as_ref() .to_vec() } -pub async fn init_user(config: &GlobalConfig, db: &DatabaseConnection) { +pub async fn init_user(config: &config::Database, db: &DatabaseConnection) { if entity::user::Entity::find().count(db).await.unwrap() != 0 { return; } diff --git a/backend/src/init/logger.rs b/backend/src/init/logger.rs index ef8203e7..3defba40 100644 --- a/backend/src/init/logger.rs +++ b/backend/src/init/logger.rs @@ -107,7 +107,7 @@ fn init_tracing_subscriber(level: Level) -> OtelGuard { .with(MetricsLayer::new(meter_provider.clone())) .with(OpenTelemetryLayer::new(init_tracer())) .init(); - + std::panic::set_hook(Box::new(|panic| { if let Some(location) = panic.location() { tracing::error!( diff --git a/backend/src/init/mod.rs b/backend/src/init/mod.rs index 198accc2..9a7d4fb8 100644 --- a/backend/src/init/mod.rs +++ b/backend/src/init/mod.rs @@ -7,6 +7,6 @@ pub mod logger; pub async fn new() -> (GlobalConfig, OtelGuard) { let config = config::init().await; let olp_guard = logger::init(&config); - db::init(&config).await; + db::init(&config.database).await; (config, olp_guard) } diff --git a/backend/src/server.rs b/backend/src/server.rs index 83115921..c51789b5 100644 --- a/backend/src/server.rs +++ b/backend/src/server.rs @@ -2,7 +2,7 @@ use std::sync::Arc; use tokio::fs; use tonic::transport; -use tracing::{instrument, span, Instrument, Level}; +use tracing::{span, Instrument, Level}; use crate::{ controller::*, @@ -34,34 +34,41 @@ pub struct Server { impl Server { pub async fn new() -> Arc { let config = config::init().await; - let otp_guard = logger::init(&config); - let span = span!(Level::INFO, "construct_server"); - - init::db::init(&config) - .instrument(span!(parent:span.clone(),Level::INFO,"construct_database")) - .await; - - tracing::info!("Loading TLS certificate..."); - let cert = fs::read_to_string(&config.grpc.public_pem) - .instrument(span!(parent:span.clone(),Level::INFO,"load_tls")) - .await - .expect("public key.pem not found"); - let key = fs::read_to_string(&config.grpc.private_pem) - .instrument(span!(parent:span.clone(),Level::INFO,"load_tls")) - .await - .expect("privite key.pem not found"); + let config1 = config.database.clone(); + let config2 = config.grpc.public_pem.clone(); + let config3 = config.grpc.private_pem.clone(); + let config4 = config.judger.clone(); - let identity = transport::Identity::from_pem(cert, key); + let span = span!(Level::INFO, "server_construct"); + let span1 = span.clone(); - tracing::info!("Constructing server..."); + let (_, cert, key, submit) = tokio::try_join!( + tokio::spawn( + async move { init::db::init(&config1).await } + .instrument(span!(parent:span.clone(),Level::INFO,"construct_database")) + ), + tokio::spawn( + async move { fs::read_to_string(&config2).await } + .instrument(span!(parent:span.clone(),Level::INFO,"load_tls")) + ), + tokio::spawn( + async move { fs::read_to_string(&config3).await } + .instrument(span!(parent:span.clone(),Level::INFO,"load_tls")) + ), + tokio::spawn(async move { judger::JudgerController::new(config4, &span1).await }) + ) + .unwrap(); - let submit = judger::JudgerController::new(&config, &span).await.unwrap(); + let identity = transport::Identity::from_pem( + cert.expect("public key.pem not found"), + key.expect("privite key.pem not found"), + ); Arc::new(Server { token: token::TokenController::new(&span), - submit: submit, + submit: submit.unwrap(), dup: duplicate::DupController::new(&span), crypto: crypto::CryptoController::new(&config, &span), config,