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();
|
||||
|
||||
|
||||
@@ -10,10 +10,6 @@ use sea_orm_migration::MigratorTrait;
|
||||
use super::DatabaseConfig;
|
||||
use crate::{errors::RecorderResult, migrations::Migrator};
|
||||
|
||||
pub trait DatabaseServiceConnectionTrait {
|
||||
fn get_database_connection(&self) -> &DatabaseConnection;
|
||||
}
|
||||
|
||||
pub struct DatabaseService {
|
||||
connection: DatabaseConnection,
|
||||
#[cfg(all(any(test, feature = "playground"), feature = "testcontainers"))]
|
||||
|
||||
@@ -25,6 +25,8 @@ pub enum RecorderError {
|
||||
source: Box<fancy_regex::Error>,
|
||||
},
|
||||
#[snafu(transparent)]
|
||||
NetAddrParseError { source: std::net::AddrParseError },
|
||||
#[snafu(transparent)]
|
||||
RegexError { source: regex::Error },
|
||||
#[snafu(transparent)]
|
||||
InvalidMethodError { source: http::method::InvalidMethod },
|
||||
|
||||
@@ -139,7 +139,7 @@ fn add_crypto_column_output_conversion<T>(
|
||||
);
|
||||
}
|
||||
|
||||
pub fn crypto_transformer(context: &mut BuilderContext, ctx: Arc<dyn AppContextTrait>) {
|
||||
pub fn add_crypto_transformers(context: &mut BuilderContext, ctx: Arc<dyn AppContextTrait>) {
|
||||
add_crypto_column_input_conversion::<credential_3rd::Entity>(
|
||||
context,
|
||||
ctx.clone(),
|
||||
@@ -150,7 +150,7 @@ pub fn crypto_transformer(context: &mut BuilderContext, ctx: Arc<dyn AppContextT
|
||||
ctx.clone(),
|
||||
&credential_3rd::Column::Username,
|
||||
);
|
||||
add_crypto_column_output_conversion::<credential_3rd::Entity>(
|
||||
add_crypto_column_input_conversion::<credential_3rd::Entity>(
|
||||
context,
|
||||
ctx.clone(),
|
||||
&credential_3rd::Column::Password,
|
||||
|
||||
@@ -1,21 +1,27 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use async_graphql::dynamic::*;
|
||||
use once_cell::sync::OnceCell;
|
||||
use sea_orm::{DatabaseConnection, EntityTrait, Iterable};
|
||||
use sea_orm::{EntityTrait, Iterable};
|
||||
use seaography::{Builder, BuilderContext, FilterType, FilterTypesMapHelper};
|
||||
|
||||
use crate::graphql::{
|
||||
infra::{
|
||||
filter::{
|
||||
JSONB_FILTER_NAME, SUBSCRIBER_ID_FILTER_INFO, init_custom_filter_info,
|
||||
register_jsonb_input_filter_to_dynamic_schema, subscriber_id_condition_function,
|
||||
use crate::{
|
||||
app::AppContextTrait,
|
||||
graphql::{
|
||||
infra::{
|
||||
filter::{
|
||||
JSONB_FILTER_NAME, SUBSCRIBER_ID_FILTER_INFO, init_custom_filter_info,
|
||||
register_jsonb_input_filter_to_dynamic_schema, subscriber_id_condition_function,
|
||||
},
|
||||
guard::{guard_entity_with_subscriber_id, guard_field_with_subscriber_id},
|
||||
transformer::{
|
||||
add_crypto_transformers, build_filter_condition_transformer,
|
||||
build_mutation_input_object_transformer,
|
||||
},
|
||||
util::{get_entity_column_key, get_entity_key},
|
||||
},
|
||||
guard::{guard_entity_with_subscriber_id, guard_field_with_subscriber_id},
|
||||
transformer::{
|
||||
build_filter_condition_transformer, build_mutation_input_object_transformer,
|
||||
},
|
||||
util::{get_entity_column_key, get_entity_key},
|
||||
views::register_subscriptions_to_schema,
|
||||
},
|
||||
views::register_subscriptions_to_schema,
|
||||
};
|
||||
|
||||
pub static CONTEXT: OnceCell<BuilderContext> = OnceCell::new();
|
||||
@@ -88,11 +94,13 @@ where
|
||||
}
|
||||
|
||||
pub fn build_schema(
|
||||
database: DatabaseConnection,
|
||||
app_ctx: Arc<dyn AppContextTrait>,
|
||||
depth: Option<usize>,
|
||||
complexity: Option<usize>,
|
||||
) -> Result<Schema, SchemaError> {
|
||||
use crate::models::*;
|
||||
let database = app_ctx.db().as_ref().clone();
|
||||
|
||||
init_custom_filter_info();
|
||||
let context = CONTEXT.get_or_init(|| {
|
||||
let mut context = BuilderContext::default();
|
||||
@@ -148,6 +156,7 @@ pub fn build_schema(
|
||||
&mut context,
|
||||
&subscriber_tasks::Column::Job,
|
||||
);
|
||||
add_crypto_transformers(&mut context, app_ctx);
|
||||
for column in subscribers::Column::iter() {
|
||||
if !matches!(column, subscribers::Column::Id) {
|
||||
restrict_filter_input_for_entity::<subscribers::Entity>(
|
||||
@@ -159,6 +168,7 @@ pub fn build_schema(
|
||||
}
|
||||
context
|
||||
});
|
||||
|
||||
let mut builder = Builder::new(context, database.clone());
|
||||
|
||||
{
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use async_graphql::dynamic::Schema;
|
||||
use sea_orm::DatabaseConnection;
|
||||
|
||||
use super::{build_schema, config::GraphQLConfig};
|
||||
use crate::errors::RecorderResult;
|
||||
use crate::{app::AppContextTrait, errors::RecorderResult};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct GraphQLService {
|
||||
@@ -10,12 +11,12 @@ pub struct GraphQLService {
|
||||
}
|
||||
|
||||
impl GraphQLService {
|
||||
pub async fn from_config_and_database(
|
||||
pub async fn from_config_and_ctx(
|
||||
config: GraphQLConfig,
|
||||
db: DatabaseConnection,
|
||||
ctx: Arc<dyn AppContextTrait>,
|
||||
) -> RecorderResult<Self> {
|
||||
let schema = build_schema(
|
||||
db,
|
||||
ctx,
|
||||
config.depth_limit.and_then(|l| l.into()),
|
||||
config.complexity_limit.and_then(|l| l.into()),
|
||||
)?;
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
source: apps/recorder/src/web/middleware/request_id.rs
|
||||
assertion_line: 126
|
||||
expression: id
|
||||
---
|
||||
"foo-barbaz"
|
||||
Reference in New Issue
Block a user