feat: make setup migration timeout configurable

This commit is contained in:
weiness
2026-07-03 10:29:33 +08:00
parent 0b8e5eec32
commit 36d5f4e4ca
7 changed files with 58 additions and 8 deletions
+18 -8
View File
@@ -28,6 +28,7 @@ const (
InstallLockFile = ".installed"
defaultUserConcurrency = 5
simpleModeAdminConcurrency = 30
defaultMigrationTimeout = 60 * time.Second
)
func setupDefaultAdminConcurrency() int {
@@ -73,12 +74,13 @@ func GetInstallLockPath() string {
// SetupConfig holds the setup configuration
type SetupConfig struct {
Database DatabaseConfig `json:"database" yaml:"database"`
Redis RedisConfig `json:"redis" yaml:"redis"`
Admin AdminConfig `json:"admin" yaml:"-"` // Not stored in config file
Server ServerConfig `json:"server" yaml:"server"`
JWT JWTConfig `json:"jwt" yaml:"jwt"`
Timezone string `json:"timezone" yaml:"timezone"` // e.g. "Asia/Shanghai", "UTC"
Database DatabaseConfig `json:"database" yaml:"database"`
Redis RedisConfig `json:"redis" yaml:"redis"`
Admin AdminConfig `json:"admin" yaml:"-"` // Not stored in config file
Server ServerConfig `json:"server" yaml:"server"`
JWT JWTConfig `json:"jwt" yaml:"jwt"`
Timezone string `json:"timezone" yaml:"timezone"` // e.g. "Asia/Shanghai", "UTC"
MigrationTimeoutSeconds int `json:"migration_timeout_seconds" yaml:"migration_timeout_seconds,omitempty"`
}
type DatabaseConfig struct {
@@ -350,11 +352,18 @@ func initializeDatabase(cfg *SetupConfig) error {
}
}()
migrationCtx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
migrationCtx, cancel := context.WithTimeout(context.Background(), cfg.migrationTimeout())
defer cancel()
return repository.ApplyMigrations(migrationCtx, db)
}
func (cfg *SetupConfig) migrationTimeout() time.Duration {
if cfg != nil && cfg.MigrationTimeoutSeconds > 0 {
return time.Duration(cfg.MigrationTimeoutSeconds) * time.Second
}
return defaultMigrationTimeout
}
func createAdminUser(cfg *SetupConfig) (bool, string, error) {
dsn := fmt.Sprintf(
"host=%s port=%d user=%s password=%s dbname=%s sslmode=%s",
@@ -578,7 +587,8 @@ func AutoSetupFromEnv() error {
Secret: getEnvOrDefault("JWT_SECRET", ""),
ExpireHour: getEnvIntOrDefault("JWT_EXPIRE_HOUR", 24),
},
Timezone: tz,
Timezone: tz,
MigrationTimeoutSeconds: getEnvIntOrDefault("SETUP_MIGRATION_TIMEOUT_SECONDS", 0),
}
// Generate JWT secret if not provided
+17
View File
@@ -4,6 +4,7 @@ import (
"os"
"strings"
"testing"
"time"
)
func TestDecideAdminBootstrap(t *testing.T) {
@@ -70,6 +71,22 @@ func TestSetupDefaultAdminConcurrency(t *testing.T) {
})
}
func TestSetupMigrationTimeout(t *testing.T) {
t.Run("uses default timeout when unset", func(t *testing.T) {
cfg := &SetupConfig{}
if got := cfg.migrationTimeout(); got != 60*time.Second {
t.Fatalf("migrationTimeout()=%s, want 60s", got)
}
})
t.Run("uses configured timeout", func(t *testing.T) {
cfg := &SetupConfig{MigrationTimeoutSeconds: 300}
if got := cfg.migrationTimeout(); got != 300*time.Second {
t.Fatalf("migrationTimeout()=%s, want 300s", got)
}
})
}
func TestWriteConfigFileKeepsDefaultUserConcurrency(t *testing.T) {
t.Setenv("RUN_MODE", "simple")
t.Setenv("DATA_DIR", t.TempDir())
+7
View File
@@ -196,6 +196,13 @@ JWT_EXPIRE_HOUR=24
# - =0: 回退使用 JWT_EXPIRE_HOUR
JWT_ACCESS_TOKEN_EXPIRE_MINUTES=0
# -----------------------------------------------------------------------------
# Setup Configuration
# -----------------------------------------------------------------------------
# Database migration timeout during initial setup, in seconds.
# Leave 0 to use the built-in default of 60 seconds.
SETUP_MIGRATION_TIMEOUT_SECONDS=0
# -----------------------------------------------------------------------------
# TOTP (2FA) Configuration
# TOTP(双因素认证)配置
+1
View File
@@ -38,6 +38,7 @@ services:
- ADMIN_EMAIL=${ADMIN_EMAIL:-admin@sub2api.local}
- ADMIN_PASSWORD=${ADMIN_PASSWORD:-}
- JWT_SECRET=${JWT_SECRET:-}
- SETUP_MIGRATION_TIMEOUT_SECONDS=${SETUP_MIGRATION_TIMEOUT_SECONDS:-0}
- TOTP_ENCRYPTION_KEY=${TOTP_ENCRYPTION_KEY:-}
- TZ=${TZ:-Asia/Shanghai}
# OpenAI HTTP upstream protocol/timeout
+5
View File
@@ -94,6 +94,11 @@ services:
- JWT_SECRET=${JWT_SECRET:-}
- JWT_EXPIRE_HOUR=${JWT_EXPIRE_HOUR:-24}
# =======================================================================
# Setup Configuration
# =======================================================================
- SETUP_MIGRATION_TIMEOUT_SECONDS=${SETUP_MIGRATION_TIMEOUT_SECONDS:-0}
# =======================================================================
# TOTP (2FA) Configuration
# =======================================================================
+5
View File
@@ -76,6 +76,11 @@ services:
- JWT_SECRET=${JWT_SECRET:-}
- JWT_EXPIRE_HOUR=${JWT_EXPIRE_HOUR:-24}
# =======================================================================
# Setup Configuration
# =======================================================================
- SETUP_MIGRATION_TIMEOUT_SECONDS=${SETUP_MIGRATION_TIMEOUT_SECONDS:-0}
# =======================================================================
# Timezone Configuration
# =======================================================================
+5
View File
@@ -90,6 +90,11 @@ services:
- JWT_SECRET=${JWT_SECRET:-}
- JWT_EXPIRE_HOUR=${JWT_EXPIRE_HOUR:-24}
# =======================================================================
# Setup Configuration
# =======================================================================
- SETUP_MIGRATION_TIMEOUT_SECONDS=${SETUP_MIGRATION_TIMEOUT_SECONDS:-0}
# =======================================================================
# TOTP (2FA) Configuration
# =======================================================================