feat: support server port reuse
This commit is contained in:
@@ -40,13 +40,13 @@ pub struct AppContext {
|
||||
cache: CacheService,
|
||||
mikan: MikanClient,
|
||||
auth: AuthService,
|
||||
graphql: GraphQLService,
|
||||
storage: StorageService,
|
||||
crypto: CryptoService,
|
||||
working_dir: String,
|
||||
environment: Environment,
|
||||
message: MessageService,
|
||||
task: OnceCell<TaskService>,
|
||||
graphql: OnceCell<GraphQLService>,
|
||||
}
|
||||
|
||||
impl AppContext {
|
||||
@@ -65,7 +65,6 @@ impl AppContext {
|
||||
let auth = AuthService::from_conf(config.auth).await?;
|
||||
let mikan = MikanClient::from_config(config.mikan).await?;
|
||||
let crypto = CryptoService::from_config(config.crypto).await?;
|
||||
let graphql = GraphQLService::from_config_and_database(config.graphql, db.clone()).await?;
|
||||
|
||||
let ctx = Arc::new(AppContext {
|
||||
config: config_cloned,
|
||||
@@ -77,10 +76,10 @@ impl AppContext {
|
||||
storage,
|
||||
mikan,
|
||||
working_dir: working_dir.to_string(),
|
||||
graphql,
|
||||
crypto,
|
||||
message,
|
||||
task: OnceCell::new(),
|
||||
graphql: OnceCell::new(),
|
||||
});
|
||||
|
||||
ctx.task
|
||||
@@ -89,6 +88,12 @@ impl AppContext {
|
||||
})
|
||||
.await?;
|
||||
|
||||
ctx.graphql
|
||||
.get_or_try_init(async || {
|
||||
GraphQLService::from_config_and_ctx(config.graphql, ctx.clone()).await
|
||||
})
|
||||
.await?;
|
||||
|
||||
Ok(ctx)
|
||||
}
|
||||
}
|
||||
@@ -119,7 +124,7 @@ impl AppContextTrait for AppContext {
|
||||
&self.auth
|
||||
}
|
||||
fn graphql(&self) -> &GraphQLService {
|
||||
&self.graphql
|
||||
self.graphql.get().expect("graphql should be set")
|
||||
}
|
||||
fn storage(&self) -> &dyn StorageServiceTrait {
|
||||
&self.storage
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
use std::{net::SocketAddr, sync::Arc};
|
||||
|
||||
use axum::Router;
|
||||
use tokio::signal;
|
||||
use tokio::{net::TcpSocket, signal};
|
||||
use tracing::instrument;
|
||||
|
||||
use super::{builder::AppBuilder, context::AppContextTrait};
|
||||
use crate::{
|
||||
@@ -22,14 +23,31 @@ impl App {
|
||||
AppBuilder::default()
|
||||
}
|
||||
|
||||
#[instrument(err, skip(self))]
|
||||
pub async fn serve(&self) -> RecorderResult<()> {
|
||||
let context = &self.context;
|
||||
let config = context.config();
|
||||
let listener = tokio::net::TcpListener::bind(&format!(
|
||||
"{}:{}",
|
||||
config.server.binding, config.server.port
|
||||
))
|
||||
.await?;
|
||||
|
||||
let listener = {
|
||||
let addr: SocketAddr =
|
||||
format!("{}:{}", config.server.binding, config.server.port).parse()?;
|
||||
|
||||
let socket = if addr.is_ipv4() {
|
||||
TcpSocket::new_v4()
|
||||
} else {
|
||||
TcpSocket::new_v6()
|
||||
}?;
|
||||
|
||||
socket.set_reuseaddr(true)?;
|
||||
|
||||
#[cfg(all(unix, not(target_os = "solaris")))]
|
||||
if let Err(e) = socket.set_reuseport(true) {
|
||||
tracing::warn!("Failed to set SO_REUSEPORT: {}", e);
|
||||
}
|
||||
|
||||
socket.bind(addr)?;
|
||||
socket.listen(1024)
|
||||
}?;
|
||||
|
||||
let mut router = Router::<Arc<dyn AppContextTrait>>::new();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user