From d11b5d78a27d89c2b8d647d02fc2f631aaa95c9d Mon Sep 17 00:00:00 2001 From: Lyon <88232613+pikasTech@users.noreply.github.com> Date: Fri, 26 Jun 2026 14:10:18 +0800 Subject: [PATCH] fix: relax v03 external postgres startup timeouts (#2190) --- deploy/deploy.yaml | 39 ++++++++++++++++++++++++++++++--- internal/userbilling/service.go | 19 ++++++++++++++-- 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/deploy/deploy.yaml b/deploy/deploy.yaml index 1cb90363..9866de38 100644 --- a/deploy/deploy.yaml +++ b/deploy/deploy.yaml @@ -353,7 +353,7 @@ lanes: timeoutMs: 3000 sessionsSummary: maxAttempts: 1 - attemptTimeoutMs: 2500 + attemptTimeoutMs: 10000 backoffMs: 0 factsQuery: maxAttempts: 1 @@ -361,8 +361,8 @@ lanes: backoffMaxMs: 1 postgres: poolMax: 16 - queryTimeoutMs: 3000 - readyTimeoutMs: 2000 + queryTimeoutMs: 10000 + readyTimeoutMs: 10000 cache: redis: enabled: true @@ -473,6 +473,16 @@ lanes: artifactKind: go-service healthPath: /health/ready healthPort: 6671 + healthProbe: + readiness: + timeoutSeconds: 10 + failureThreshold: 5 + liveness: + timeoutSeconds: 5 + failureThreshold: 6 + startup: + timeoutSeconds: 10 + failureThreshold: 30 componentPaths: - go.mod - go.sum @@ -488,6 +498,16 @@ lanes: artifactKind: go-service healthPath: /health/ready healthPort: 6670 + healthProbe: + readiness: + timeoutSeconds: 10 + failureThreshold: 5 + liveness: + timeoutSeconds: 5 + failureThreshold: 6 + startup: + timeoutSeconds: 10 + failureThreshold: 30 componentPaths: - go.mod - go.sum @@ -503,6 +523,16 @@ lanes: artifactKind: bun-command healthPath: /health/ready healthPort: 6672 + healthProbe: + readiness: + timeoutSeconds: 10 + failureThreshold: 5 + liveness: + timeoutSeconds: 5 + failureThreshold: 6 + startup: + timeoutSeconds: 10 + failureThreshold: 30 componentPaths: - cmd/hwlab-project-management/ - internal/project-management/ @@ -751,6 +781,8 @@ lanes: env: HWLAB_USER_BILLING_DB_URL: secretRef:hwlab-cloud-api-v03-db/database-url HWLAB_USER_BILLING_DB_POOL_MAX: "2" + HWLAB_USER_BILLING_MIGRATION_TIMEOUT_SECONDS: "180" + HWLAB_USER_BILLING_BOOTSTRAP_TIMEOUT_SECONDS: "60" HWLAB_BOOTSTRAP_ADMIN_ID: usr_v03_admin HWLAB_BOOTSTRAP_ADMIN_USERNAME: admin HWLAB_BOOTSTRAP_ADMIN_DISPLAY_NAME: HWLAB v0.3 Admin @@ -769,6 +801,7 @@ lanes: replicas: 1 env: HWLAB_PROJECT_MANAGEMENT_DB_URL: secretRef:hwlab-cloud-api-v03-db/database-url + HWLAB_PROJECT_MANAGEMENT_DB_CONNECT_TIMEOUT_MS: "5000" HWLAB_PROJECT_MANAGEMENT_PORT: "6672" HWLAB_PROJECT_MANAGEMENT_SOURCE_ROOT: /workspace/hwlab-boot/repo HWLAB_PROJECT_MANAGEMENT_SOURCE_ID: hwlab-v03-mdtodo diff --git a/internal/userbilling/service.go b/internal/userbilling/service.go index a3b730cd..691e638d 100644 --- a/internal/userbilling/service.go +++ b/internal/userbilling/service.go @@ -46,6 +46,8 @@ type Config struct { InternalToken string RequireInternalToken bool MigrateOnStart bool + MigrationTimeout time.Duration + BootstrapTimeout time.Duration StateAuthority string RuntimeNamespace string ExternalDatabaseLabel string @@ -332,6 +334,8 @@ func LoadConfig(env []string) Config { InternalToken: values["HWLAB_USER_BILLING_INTERNAL_TOKEN"], RequireInternalToken: values["HWLAB_USER_BILLING_REQUIRE_INTERNAL_TOKEN"] == "1", MigrateOnStart: values["HWLAB_USER_BILLING_MIGRATE_ON_START"] != "0", + MigrationTimeout: parseDurationSeconds(values["HWLAB_USER_BILLING_MIGRATION_TIMEOUT_SECONDS"], 20), + BootstrapTimeout: parseDurationSeconds(values["HWLAB_USER_BILLING_BOOTSTRAP_TIMEOUT_SECONDS"], 10), StateAuthority: first(values["HWLAB_USER_BILLING_STATE_AUTHORITY"], "pk01-postgres"), RuntimeNamespace: first(values["POD_NAMESPACE"], values["HWLAB_NAMESPACE"], "hwlab-v03"), ExternalDatabaseLabel: first(values["HWLAB_USER_BILLING_EXTERNAL_DB_LABEL"], "pk01-external-postgres"), @@ -357,13 +361,13 @@ func NewServer(ctx context.Context, cfg Config) (*Server, error) { db.SetConnMaxLifetime(30 * time.Minute) server.db = db if cfg.MigrateOnStart { - migrateCtx, cancel := context.WithTimeout(ctx, 20*time.Second) + migrateCtx, cancel := context.WithTimeout(ctx, durationOrDefault(cfg.MigrationTimeout, 20*time.Second)) defer cancel() if err := server.migrate(migrateCtx); err != nil { return nil, fmt.Errorf("migrate user billing schema: %w", err) } } - bootstrapCtx, cancel := context.WithTimeout(ctx, 10*time.Second) + bootstrapCtx, cancel := context.WithTimeout(ctx, durationOrDefault(cfg.BootstrapTimeout, 10*time.Second)) defer cancel() if err := server.ensureBootstrapAdmin(bootstrapCtx); err != nil { return nil, fmt.Errorf("ensure bootstrap admin: %w", err) @@ -2941,6 +2945,17 @@ func parseDurationMinutes(value string, fallbackMinutes int64) time.Duration { return time.Duration(parseInt64(value, fallbackMinutes)) * time.Minute } +func parseDurationSeconds(value string, fallbackSeconds int64) time.Duration { + return time.Duration(parseInt64(value, fallbackSeconds)) * time.Second +} + +func durationOrDefault(value time.Duration, fallback time.Duration) time.Duration { + if value <= 0 { + return fallback + } + return value +} + func first(values ...string) string { for _, value := range values { if strings.TrimSpace(value) != "" {