Fail closed when SpacetimeDB auth restore is unavailable

This commit is contained in:
kdletters
2026-05-27 20:58:37 +08:00
parent 948d5a698c
commit 418fcb0548
24 changed files with 595 additions and 601 deletions

View File

@@ -107,9 +107,13 @@ use std::{
use tokio::net::TcpListener;
use tokio::runtime::Builder as TokioRuntimeBuilder;
use tokio::time::timeout;
use tracing::{info, warn};
use tracing::{error, info};
use crate::{app::build_router, config::AppConfig, state::AppState};
use crate::{
app::{build_router, build_spacetime_unavailable_router},
config::AppConfig,
state::{AppState, AppStateInitError},
};
const API_SERVER_STARTUP_STACK_SIZE_BYTES: usize = 32 * 1024 * 1024;
const AUTH_STORE_STARTUP_RESTORE_TIMEOUT: Duration = Duration::from_secs(8);
@@ -156,14 +160,21 @@ async fn run_server(config: AppConfig) -> Result<(), io::Error> {
let otel_enabled = config.otel_enabled;
let listener = build_tcp_listener(bind_address, listen_backlog)?;
let state = restore_app_state_for_startup(config)
.await
.map_err(|error| std::io::Error::other(format!("初始化应用状态失败:{error}")))?;
state.puzzle_gallery_cache().spawn_cleanup_task();
if let Some(outbox) = state.tracking_outbox() {
outbox.spawn_worker();
}
let router = build_router(state);
let router = match restore_app_state_for_startup(config).await {
Ok(state) => {
state.puzzle_gallery_cache().spawn_cleanup_task();
if let Some(outbox) = state.tracking_outbox() {
outbox.spawn_worker();
}
build_router(state)
}
Err(AppStateInitError::DependencyUnavailable(message)) => {
build_spacetime_unavailable_router(message)
}
Err(error) => {
return Err(std::io::Error::other(format!("初始化应用状态失败:{error}")));
}
};
info!(
%bind_address,
@@ -192,7 +203,6 @@ fn build_tcp_listener(
async fn restore_app_state_for_startup(
config: AppConfig,
) -> Result<AppState, state::AppStateInitError> {
let fallback_config = config.clone();
match timeout(
AUTH_STORE_STARTUP_RESTORE_TIMEOUT,
AppState::try_restore_auth_store_from_spacetime(config),
@@ -201,11 +211,13 @@ async fn restore_app_state_for_startup(
{
Ok(result) => result,
Err(_) => {
warn!(
error!(
timeout_seconds = AUTH_STORE_STARTUP_RESTORE_TIMEOUT.as_secs(),
"启动恢复认证快照超时,跳过远端恢复并继续启动 api-server"
"启动等待 SpacetimeDB 恢复认证快照超时api-server 将进入依赖不可用模式"
);
AppState::new(fallback_config)
Err(state::AppStateInitError::DependencyUnavailable(
"SpacetimeDB 启动恢复认证快照超时".to_string(),
))
}
}
}