diff --git a/backend/internal/repository/ent.go b/backend/internal/repository/ent.go index 6094b9ec61..165fea4baf 100644 --- a/backend/internal/repository/ent.go +++ b/backend/internal/repository/ent.go @@ -22,9 +22,9 @@ import ( ) const ( - maxDatabaseInitializationAttempts = 8 - databaseInitializationRetryBase = time.Second - databaseInitializationRetryMax = 30 * time.Second + maxDatabaseInitializationRetries = 8 + databaseInitializationRetryBase = time.Second + databaseInitializationRetryMax = 30 * time.Second ) // initializeDatabaseWithRetry retries only errors that indicate PostgreSQL is @@ -39,32 +39,29 @@ func initializeDatabaseWithRetryWithWait( initialize func(context.Context) error, wait func(context.Context, time.Duration) error, ) error { - var lastErr error - for attempt := 1; attempt <= maxDatabaseInitializationAttempts; attempt++ { + for attempt := 1; ; attempt++ { if err := initialize(ctx); err == nil { return nil } else { - lastErr = err - if !isTransientDatabaseInitializationError(err) || attempt == maxDatabaseInitializationAttempts { + if !isTransientDatabaseInitializationError(err) || attempt > maxDatabaseInitializationRetries { + return err + } + + delay := databaseInitializationRetryBase * time.Duration(1<<(attempt-1)) + if delay > databaseInitializationRetryMax { + delay = databaseInitializationRetryMax + } + slog.Warn("database initialization temporarily unavailable; retrying", + "retry", attempt, + "max_retries", maxDatabaseInitializationRetries, + "retry_in", delay, + "error", err, + ) + if err := wait(ctx, delay); err != nil { return err } } - - delay := databaseInitializationRetryBase * time.Duration(1<<(attempt-1)) - if delay > databaseInitializationRetryMax { - delay = databaseInitializationRetryMax - } - slog.Warn("database initialization temporarily unavailable; retrying", - "attempt", attempt, - "max_attempts", maxDatabaseInitializationAttempts, - "retry_in", delay, - "error", lastErr, - ) - if err := wait(ctx, delay); err != nil { - return err - } } - return lastErr } func waitForDatabaseInitializationRetry(ctx context.Context, delay time.Duration) error { diff --git a/backend/internal/repository/ent_init_retry_test.go b/backend/internal/repository/ent_init_retry_test.go index e0c6d4d116..e3bde3d24d 100644 --- a/backend/internal/repository/ent_init_retry_test.go +++ b/backend/internal/repository/ent_init_retry_test.go @@ -99,8 +99,8 @@ func TestInitializeDatabaseWithRetryReturnsLastErrorAfterLimit(t *testing.T) { }) require.ErrorIs(t, err, lastErr) - require.Equal(t, maxDatabaseInitializationAttempts, attempts) - require.Len(t, delays, maxDatabaseInitializationAttempts-1) + require.Equal(t, maxDatabaseInitializationRetries+1, attempts) + require.Len(t, delays, maxDatabaseInitializationRetries) require.Equal(t, databaseInitializationRetryMax, delays[len(delays)-1]) }