mirror of
https://github.com/fawney19/Aether.git
synced 2026-10-09 02:47:45 +08:00
refactor(workspace): enforce layered crate boundaries
This commit is contained in:
@@ -138,6 +138,10 @@ impl NodeRoleArg {
|
||||
const fn spawns_background_tasks(self) -> bool {
|
||||
matches!(self, Self::All | Self::Background)
|
||||
}
|
||||
|
||||
const fn isolates_background_database(self) -> bool {
|
||||
matches!(self, Self::All)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, ValueEnum)]
|
||||
@@ -358,6 +362,18 @@ fn usage_queue_workers_for_request_concurrency(request_concurrency: usize) -> us
|
||||
workers.clamp(AUTO_USAGE_QUEUE_WORKERS_MIN, MAX_USAGE_QUEUE_WORKERS)
|
||||
}
|
||||
|
||||
fn usage_database_config_for_role<'a>(
|
||||
node_role: NodeRoleArg,
|
||||
database: Option<&'a SqlDatabaseConfig>,
|
||||
isolated_background_database: Option<&'a SqlDatabaseConfig>,
|
||||
) -> Option<&'a SqlDatabaseConfig> {
|
||||
if node_role.isolates_background_database() {
|
||||
isolated_background_database.or(database)
|
||||
} else {
|
||||
database
|
||||
}
|
||||
}
|
||||
|
||||
fn usage_queue_worker_database_cap(
|
||||
node_role: NodeRoleArg,
|
||||
database: Option<&SqlDatabaseConfig>,
|
||||
@@ -1279,7 +1295,7 @@ struct Args {
|
||||
#[arg(
|
||||
long,
|
||||
env = "AETHER_RUNTIME_COMMAND_TIMEOUT_MS",
|
||||
default_value_t = 1_000
|
||||
default_value_t = 2_000
|
||||
)]
|
||||
runtime_command_timeout_ms: u64,
|
||||
|
||||
@@ -1710,6 +1726,18 @@ async fn run() -> Result<(), Box<dyn std::error::Error>> {
|
||||
runtime_redis_url.as_deref(),
|
||||
runtime_backend,
|
||||
)?;
|
||||
let data_config = args.data.to_config();
|
||||
let isolate_background_database = args.node_role.isolates_background_database();
|
||||
let background_database_config = if isolate_background_database {
|
||||
data_config.background_database_config()
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let usage_database_config = usage_database_config_for_role(
|
||||
args.node_role,
|
||||
data_config.database(),
|
||||
background_database_config.as_ref(),
|
||||
);
|
||||
let request_concurrency_limit = args
|
||||
.max_in_flight_requests
|
||||
.filter(|limit| *limit > 0)
|
||||
@@ -1728,16 +1756,16 @@ async fn run() -> Result<(), Box<dyn std::error::Error>> {
|
||||
args.node_role,
|
||||
Some(request_concurrency_limit),
|
||||
args.distributed_request_limit,
|
||||
sql_database_config.as_ref(),
|
||||
usage_database_config,
|
||||
);
|
||||
let usage_queue_worker_max_count = args.usage.effective_queue_worker_max_count(
|
||||
args.node_role,
|
||||
sql_database_config.as_ref(),
|
||||
usage_database_config,
|
||||
usage_queue_workers,
|
||||
);
|
||||
let usage_worker_record_concurrency_limit = args
|
||||
.usage
|
||||
.effective_worker_record_concurrency_limit(args.node_role, sql_database_config.as_ref());
|
||||
.effective_worker_record_concurrency_limit(args.node_role, usage_database_config);
|
||||
let usage_config = args.usage.to_config(
|
||||
usage_queue_workers,
|
||||
usage_queue_worker_max_count,
|
||||
@@ -1745,7 +1773,7 @@ async fn run() -> Result<(), Box<dyn std::error::Error>> {
|
||||
);
|
||||
let usage_blocking_stream_lanes = args.usage.runtime_state_blocking_stream_lanes(
|
||||
args.node_role,
|
||||
sql_database_config.as_ref(),
|
||||
usage_database_config,
|
||||
usage_config.worker_max_count,
|
||||
);
|
||||
let runtime_state = Arc::new(
|
||||
@@ -1757,7 +1785,6 @@ async fn run() -> Result<(), Box<dyn std::error::Error>> {
|
||||
.await
|
||||
.map_err(|err| std::io::Error::new(std::io::ErrorKind::InvalidInput, err.to_string()))?,
|
||||
);
|
||||
let data_config = args.data.to_config();
|
||||
let rate_limit_config = if matches!(args.deployment_topology, DeploymentTopologyArg::MultiNode)
|
||||
{
|
||||
args.rate_limit.config().with_local_fallback(false)
|
||||
@@ -1859,7 +1886,7 @@ async fn run() -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
||||
let mut state = AppState::new()?
|
||||
.with_runtime_state(runtime_state)
|
||||
.with_data_config(data_config)?
|
||||
.with_data_config_and_background_isolation(data_config, isolate_background_database)?
|
||||
.with_usage_runtime_config(usage_config)?
|
||||
.with_video_task_truth_source_mode(args.video_task_truth_source_mode.into());
|
||||
if let Some(cors_config) = args.frontdoor.cors_config() {
|
||||
@@ -1927,6 +1954,7 @@ async fn run() -> Result<(), Box<dyn std::error::Error>> {
|
||||
"aether-gateway data layer configured"
|
||||
);
|
||||
prepare_database_startup_requirements(&state, args.auto_prepare_database).await?;
|
||||
state.warm_database_pools().await?;
|
||||
let reset_stale_proxy_nodes = state.reset_stale_proxy_node_tunnel_statuses().await?;
|
||||
if reset_stale_proxy_nodes > 0 {
|
||||
info!(
|
||||
@@ -1986,6 +2014,13 @@ async fn run() -> Result<(), Box<dyn std::error::Error>> {
|
||||
);
|
||||
None
|
||||
};
|
||||
if state.prewarm_metric_snapshot().await {
|
||||
info!("gateway metric snapshot prewarmed");
|
||||
} else {
|
||||
warn!(
|
||||
"gateway metric snapshot prewarm did not complete; continuing with fail-open metrics"
|
||||
);
|
||||
}
|
||||
let listen_backlog = gateway_listen_backlog(args.listen_backlog);
|
||||
let listener_shards = gateway_listener_shards(args.listener_shards);
|
||||
let listeners = gateway_listeners(bind_addr, listen_backlog, listener_shards)?;
|
||||
@@ -2378,15 +2413,15 @@ mod tests {
|
||||
automatic_gateway_request_concurrency_for_parallelism, automatic_sql_pool_config,
|
||||
automatic_sql_pool_config_for_parallelism, automatic_usage_queue_workers_for_parallelism,
|
||||
ensure_database_backfills_are_current, ensure_database_schema_is_current,
|
||||
pending_backfills_error, pending_schema_error, resolve_healthcheck_url, Args,
|
||||
DatabaseDriverArg, DeploymentTopologyArg, GatewayDataArgs, GatewayFrontdoorArgs,
|
||||
GatewayLogDestinationArg, GatewayLogFormatArg, GatewayLogRotationArg, GatewayLoggingArgs,
|
||||
GatewayRateLimitArgs, GatewayUsageArgs, NodeRoleArg, RuntimeBackendArg,
|
||||
VideoTaskTruthSourceArg, DEFAULT_GATEWAY_HTTP2_MAX_CONCURRENT_STREAMS,
|
||||
DEFAULT_GATEWAY_LISTENER_SHARDS, DEFAULT_GATEWAY_LISTEN_BACKLOG,
|
||||
MAX_GATEWAY_HTTP2_MAX_CONCURRENT_STREAMS, MAX_GATEWAY_LISTENER_SHARDS,
|
||||
MAX_GATEWAY_LISTEN_BACKLOG, MIN_GATEWAY_HTTP2_MAX_CONCURRENT_STREAMS,
|
||||
MIN_GATEWAY_LISTEN_BACKLOG,
|
||||
pending_backfills_error, pending_schema_error, resolve_healthcheck_url,
|
||||
usage_database_config_for_role, Args, DatabaseDriverArg, DeploymentTopologyArg,
|
||||
GatewayDataArgs, GatewayFrontdoorArgs, GatewayLogDestinationArg, GatewayLogFormatArg,
|
||||
GatewayLogRotationArg, GatewayLoggingArgs, GatewayRateLimitArgs, GatewayUsageArgs,
|
||||
NodeRoleArg, RuntimeBackendArg, VideoTaskTruthSourceArg,
|
||||
DEFAULT_GATEWAY_HTTP2_MAX_CONCURRENT_STREAMS, DEFAULT_GATEWAY_LISTENER_SHARDS,
|
||||
DEFAULT_GATEWAY_LISTEN_BACKLOG, MAX_GATEWAY_HTTP2_MAX_CONCURRENT_STREAMS,
|
||||
MAX_GATEWAY_LISTENER_SHARDS, MAX_GATEWAY_LISTEN_BACKLOG,
|
||||
MIN_GATEWAY_HTTP2_MAX_CONCURRENT_STREAMS, MIN_GATEWAY_LISTEN_BACKLOG,
|
||||
};
|
||||
use aether_data::{DatabaseDriver, SqlDatabaseConfig, SqlPoolConfig};
|
||||
use aether_gateway::AppState;
|
||||
@@ -2695,6 +2730,36 @@ mod tests {
|
||||
assert_eq!(many_cpu.max_connections, 100);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gateway_database_pool_isolation_and_usage_capacity_follow_role() {
|
||||
assert!(NodeRoleArg::All.isolates_background_database());
|
||||
assert!(!NodeRoleArg::Frontdoor.isolates_background_database());
|
||||
assert!(!NodeRoleArg::Background.isolates_background_database());
|
||||
|
||||
let database = test_database(DatabaseDriver::Postgres, 20);
|
||||
let isolated_background = test_database(DatabaseDriver::Postgres, 4);
|
||||
assert_eq!(
|
||||
usage_database_config_for_role(
|
||||
NodeRoleArg::All,
|
||||
Some(&database),
|
||||
Some(&isolated_background),
|
||||
)
|
||||
.expect("all-role usage database")
|
||||
.pool
|
||||
.max_connections,
|
||||
4
|
||||
);
|
||||
for role in [NodeRoleArg::Frontdoor, NodeRoleArg::Background] {
|
||||
assert_eq!(
|
||||
usage_database_config_for_role(role, Some(&database), Some(&isolated_background),)
|
||||
.expect("single-pool role usage database")
|
||||
.pool
|
||||
.max_connections,
|
||||
20
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn gateway_usage_queue_workers_manual_override_wins_and_is_capped() {
|
||||
let mut args = test_args();
|
||||
|
||||
Reference in New Issue
Block a user