refactor(workspace): enforce layered crate boundaries

This commit is contained in:
elky
2026-07-15 23:47:19 +08:00
parent a728c090a9
commit 8616fe6ee2
969 changed files with 40187 additions and 27240 deletions
@@ -761,33 +761,38 @@ pub(crate) fn spawn_account_self_check_worker(
}
let config = AccountSelfCheckWorkerConfig::from_env();
Some(tokio::spawn(async move {
let mut interval = tokio::time::interval(config.scan_interval);
interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Delay);
interval.tick().await;
let mut deferred_since = None;
loop {
Some(crate::task_runtime::spawn_singleton_worker(
state,
crate::task_runtime::TASK_KEY_ACCOUNT_SELF_CHECK,
move |state| async move {
let mut interval = tokio::time::interval(config.scan_interval);
interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Delay);
interval.tick().await;
if state
.data
.should_defer_maintenance_for_database_pool_pressure(&mut deferred_since)
{
debug!(
event_name = "maintenance_worker_deferred",
log_type = "ops",
worker = "account_self_check",
"gateway account self-check deferred because database pool has no idle reserve"
);
continue;
let mut deferred_since = None;
loop {
interval.tick().await;
if state
.data
.should_defer_maintenance_for_database_pool_pressure(&mut deferred_since)
{
debug!(
event_name = "maintenance_worker_deferred",
log_type = "ops",
worker = "account_self_check",
"gateway account self-check deferred because database pool has no idle reserve"
);
continue;
}
if let Err(err) = perform_account_self_check_once_with_config(&state, config).await
{
warn!(
error = ?err,
"gateway account self-check worker tick failed"
);
}
}
if let Err(err) = perform_account_self_check_once_with_config(&state, config).await {
warn!(
error = ?err,
"gateway account self-check worker tick failed"
);
}
}
}))
},
))
}
#[cfg(test)]
@@ -1701,20 +1701,24 @@ pub(crate) fn spawn_pool_quota_probe_worker(
}
let config = PoolQuotaProbeWorkerConfig::from_env();
Some(tokio::spawn(async move {
let mut interval = tokio::time::interval(config.scan_interval);
interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Delay);
interval.tick().await;
loop {
Some(crate::task_runtime::spawn_singleton_worker(
state,
crate::task_runtime::TASK_KEY_POOL_QUOTA_PROBE,
move |state| async move {
let mut interval = tokio::time::interval(config.scan_interval);
interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Delay);
interval.tick().await;
if let Err(err) = perform_pool_quota_probe_once_with_config(&state, config).await {
warn!(
error = ?err,
"gateway pool quota probe worker tick failed"
);
loop {
interval.tick().await;
if let Err(err) = perform_pool_quota_probe_once_with_config(&state, config).await {
warn!(
error = ?err,
"gateway pool quota probe worker tick failed"
);
}
}
}
}))
},
))
}
#[cfg(test)]
@@ -401,50 +401,54 @@ pub(crate) fn spawn_pool_score_rebuild_worker(
}
let config = PoolScoreRebuildWorkerConfig::from_env();
Some(tokio::spawn(async move {
if let Err(err) = perform_pool_score_rebuild_once_with_config(&state, config).await {
warn!(
error = ?err,
"gateway pool score rebuild initial tick failed"
);
}
let mut interval = tokio::time::interval(config.interval);
interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Delay);
let mut deferred_since = None;
loop {
interval.tick().await;
if state
.data
.should_defer_maintenance_for_database_pool_pressure(&mut deferred_since)
{
debug!(
event_name = "maintenance_worker_deferred",
log_type = "ops",
worker = "pool_score_rebuild",
"gateway pool score rebuild deferred because database pool has no idle reserve"
Some(crate::task_runtime::spawn_singleton_worker(
state,
crate::task_runtime::TASK_KEY_POOL_SCORE_REBUILD,
move |state| async move {
if let Err(err) = perform_pool_score_rebuild_once_with_config(&state, config).await {
warn!(
error = ?err,
"gateway pool score rebuild initial tick failed"
);
continue;
}
match perform_pool_score_rebuild_once_with_config(&state, config).await {
Ok(summary) if summary.scores_upserted > 0 => {
info!(
providers_checked = summary.providers_checked,
providers_scored = summary.providers_scored,
keys_seen = summary.keys_seen,
scores_upserted = summary.scores_upserted,
"gateway pool score rebuild completed"
let mut interval = tokio::time::interval(config.interval);
interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Delay);
let mut deferred_since = None;
loop {
interval.tick().await;
if state
.data
.should_defer_maintenance_for_database_pool_pressure(&mut deferred_since)
{
debug!(
event_name = "maintenance_worker_deferred",
log_type = "ops",
worker = "pool_score_rebuild",
"gateway pool score rebuild deferred because database pool has no idle reserve"
);
continue;
}
Ok(_) => {}
Err(err) => {
warn!(
error = ?err,
"gateway pool score rebuild worker tick failed"
);
match perform_pool_score_rebuild_once_with_config(&state, config).await {
Ok(summary) if summary.scores_upserted > 0 => {
info!(
providers_checked = summary.providers_checked,
providers_scored = summary.providers_scored,
keys_seen = summary.keys_seen,
scores_upserted = summary.scores_upserted,
"gateway pool score rebuild completed"
);
}
Ok(_) => {}
Err(err) => {
warn!(
error = ?err,
"gateway pool score rebuild worker tick failed"
);
}
}
}
}
}))
},
))
}
#[cfg(test)]
@@ -116,7 +116,7 @@ pub(super) async fn run_proxy_upgrade_rollout_once(state: &AppState) -> Result<(
for probe in probes {
match state
.tunnel
.probe_node_url(&probe.node_id, &probe.url, probe.timeout_secs)
.probe_node_url_routed(state, &probe.node_id, &probe.url, probe.timeout_secs)
.await
{
Ok(status) if (200..300).contains(&status) => {
@@ -39,24 +39,34 @@ use super::{
#[tokio::test]
async fn spawn_audit_cleanup_worker_skips_when_postgres_unavailable() {
assert!(spawn_audit_cleanup_worker(Arc::new(GatewayDataState::disabled())).is_none());
let state = AppState::new()
.expect("gateway state should build")
.with_data_state_for_tests(GatewayDataState::disabled());
assert!(spawn_audit_cleanup_worker(state).is_none());
}
#[tokio::test]
async fn spawn_db_maintenance_worker_skips_when_database_maintenance_unavailable() {
assert!(spawn_db_maintenance_worker(Arc::new(GatewayDataState::disabled())).is_none());
let state = AppState::new()
.expect("gateway state should build")
.with_data_state_for_tests(GatewayDataState::disabled());
assert!(spawn_db_maintenance_worker(state).is_none());
}
#[tokio::test]
async fn spawn_pending_cleanup_worker_skips_when_usage_writer_unavailable() {
assert!(spawn_pending_cleanup_worker(Arc::new(GatewayDataState::disabled())).is_none());
let state = AppState::new()
.expect("gateway state should build")
.with_data_state_for_tests(GatewayDataState::disabled());
assert!(spawn_pending_cleanup_worker(state).is_none());
}
#[tokio::test]
async fn spawn_proxy_node_stale_cleanup_worker_skips_when_proxy_nodes_unavailable() {
assert!(
spawn_proxy_node_stale_cleanup_worker(Arc::new(GatewayDataState::disabled())).is_none()
);
let state = AppState::new()
.expect("gateway state should build")
.with_data_state_for_tests(GatewayDataState::disabled());
assert!(spawn_proxy_node_stale_cleanup_worker(state).is_none());
}
#[tokio::test]
@@ -95,7 +105,10 @@ async fn spawn_proxy_upgrade_rollout_worker_skips_when_system_config_unavailable
#[tokio::test]
async fn spawn_pool_monitor_worker_skips_when_postgres_unavailable() {
assert!(spawn_pool_monitor_worker(Arc::new(GatewayDataState::disabled())).is_none());
let state = AppState::new()
.expect("gateway state should build")
.with_data_state_for_tests(GatewayDataState::disabled());
assert!(spawn_pool_monitor_worker(state).is_none());
}
#[tokio::test]
@@ -559,28 +572,35 @@ async fn proxy_upgrade_rollout_active_probe_advances_next_wave_after_version_con
#[tokio::test]
async fn spawn_stats_aggregation_worker_skips_when_stats_daily_backend_unavailable() {
assert!(spawn_stats_aggregation_worker(Arc::new(GatewayDataState::disabled())).is_none());
let state = AppState::new()
.expect("gateway state should build")
.with_data_state_for_tests(GatewayDataState::disabled());
assert!(spawn_stats_aggregation_worker(state).is_none());
}
#[tokio::test]
async fn spawn_stats_hourly_aggregation_worker_skips_when_stats_hourly_backend_unavailable() {
assert!(
spawn_stats_hourly_aggregation_worker(Arc::new(GatewayDataState::disabled())).is_none()
);
let state = AppState::new()
.expect("gateway state should build")
.with_data_state_for_tests(GatewayDataState::disabled());
assert!(spawn_stats_hourly_aggregation_worker(state).is_none());
}
#[tokio::test]
async fn spawn_usage_cleanup_worker_skips_when_usage_writer_unavailable() {
assert!(spawn_usage_cleanup_worker(Arc::new(GatewayDataState::disabled())).is_none());
let state = AppState::new()
.expect("gateway state should build")
.with_data_state_for_tests(GatewayDataState::disabled());
assert!(spawn_usage_cleanup_worker(state).is_none());
}
#[tokio::test]
async fn spawn_wallet_daily_usage_aggregation_worker_skips_when_wallet_daily_usage_backend_unavailable(
) {
assert!(
spawn_wallet_daily_usage_aggregation_worker(Arc::new(GatewayDataState::disabled()))
.is_none()
);
let state = AppState::new()
.expect("gateway state should build")
.with_data_state_for_tests(GatewayDataState::disabled());
assert!(spawn_wallet_daily_usage_aggregation_worker(state).is_none());
}
#[tokio::test]
File diff suppressed because it is too large Load Diff