Skip to content

Commit

Permalink
perf: ⚡ parallelize server initialization
Browse files Browse the repository at this point in the history
  • Loading branch information
Eason0729 committed Dec 8, 2023
1 parent 2581dc0 commit d5c22c3
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 35 deletions.
6 changes: 3 additions & 3 deletions backend/src/controller/judger/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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<Self, Error> {
let router = Router::new(config.judger.clone(), span).await?;
pub async fn new(config: Vec<config::Judger>, span: &Span) -> Result<Self, Error> {
let router = Router::new(config, span).await?;
Ok(JudgerController {
router,
pubsub: Arc::new(PubSub::default()),
Expand Down
6 changes: 3 additions & 3 deletions backend/src/init/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand Down
13 changes: 7 additions & 6 deletions backend/src/init/db.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::path::PathBuf;
use std::sync::Arc;

use ring::digest;
use sea_orm::{
Expand All @@ -8,31 +9,31 @@ 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<DatabaseConnection> = 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
.expect("fail connecting to database");
init_user(config, &db).await;
DB.set(db).ok();
}
fn hash(config: &GlobalConfig, src: &str) -> Vec<u8> {
fn hash(config: &config::Database, src: &str) -> Vec<u8> {
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;
}
Expand Down
2 changes: 1 addition & 1 deletion backend/src/init/logger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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!(
Expand Down
2 changes: 1 addition & 1 deletion backend/src/init/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
49 changes: 28 additions & 21 deletions backend/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*,
Expand Down Expand Up @@ -34,34 +34,41 @@ pub struct Server {
impl Server {
pub async fn new() -> Arc<Self> {
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,
Expand Down

0 comments on commit d5c22c3

Please sign in to comment.