feat(backend): add age condition for state versions retention
All checks were successful
main / main (push) Successful in 2m47s
main / deploy (push) Has been skipped
main / publish (push) Has been skipped

Closes #59
This commit is contained in:
Julien Dessaux 2025-05-01 14:27:49 +02:00
parent 5d7b540718
commit 0a63e1f593
Signed by: adyxax
GPG key ID: F92E51B86E07177E
3 changed files with 32 additions and 20 deletions

View file

@ -36,6 +36,8 @@ func TestMain(m *testing.M) {
return "a528D1m9q3IZxLinSmHmeKxrx3Pmm7GQ3nBzIDxjr0A="
case "TFSTATED_VERSIONS_HISTORY_LIMIT":
return "3"
case "TFSTATED_VERSIONS_HISTORY_MINIMUM_DAYS":
return "0"
default:
return ""
}

View file

@ -28,12 +28,13 @@ func initDB(ctx context.Context, url string) (*sql.DB, error) {
}
type DB struct {
ctx context.Context
dataEncryptionKey scrypto.AES256Key
readDB *sql.DB
sessionsSalt scrypto.AES256Key
versionsHistoryLimit int
writeDB *sql.DB
ctx context.Context
dataEncryptionKey scrypto.AES256Key
readDB *sql.DB
sessionsSalt scrypto.AES256Key
versionsHistoryLimit int
versionsHistoryMinimumDays int
writeDB *sql.DB
}
func NewDB(ctx context.Context, url string, getenv func(string) string) (*DB, error) {
@ -60,10 +61,11 @@ func NewDB(ctx context.Context, url string, getenv func(string) string) (*DB, er
writeDB.SetMaxOpenConns(1)
db := DB{
ctx: ctx,
readDB: readDB,
versionsHistoryLimit: 64,
writeDB: writeDB,
ctx: ctx,
readDB: readDB,
versionsHistoryLimit: 128,
versionsHistoryMinimumDays: 28,
writeDB: writeDB,
}
pragmas := []struct {
key string
@ -103,6 +105,12 @@ func NewDB(ctx context.Context, url string, getenv func(string) string) (*DB, er
return nil, fmt.Errorf("failed to parse the TFSTATED_VERSIONS_HISTORY_LIMIT environment variable, expected an integer: %w", err)
}
}
versionsHistoryMinimumDays := getenv("TFSTATED_VERSIONS_HISTORY_MINIMUM_DAYS")
if versionsHistoryMinimumDays != "" {
if db.versionsHistoryMinimumDays, err = strconv.Atoi(versionsHistoryMinimumDays); err != nil {
return nil, fmt.Errorf("failed to parse the TFSTATED_VERSIONS_HISTORY_MINIMUM_DAYS environment variable, expected an integer: %w", err)
}
}
return &db, nil
}

View file

@ -244,19 +244,21 @@ func (db *DB) SetState(path string, accountId uuid.UUID, data []byte, lock strin
if err != nil {
return fmt.Errorf("failed to touch updated for state: %w", err)
}
min := time.Now().Add(time.Duration(db.versionsHistoryMinimumDays) * -24 * time.Hour)
_, err = tx.ExecContext(db.ctx,
`DELETE FROM versions
WHERE state_id = (SELECT id
FROM states
WHERE path = :path)
AND id < (SELECT MIN(id)
FROM(SELECT versions.id
FROM versions
JOIN states ON states.id = versions.state_id
WHERE states.path = :path
ORDER BY versions.id DESC
LIMIT :limit));`,
WHERE state_id = (SELECT id
FROM states
WHERE path = :path)
AND id < (SELECT MIN(id)
FROM(SELECT versions.id
FROM versions
JOIN states ON states.id = versions.state_id
WHERE states.path = :path AND versions.created < :min
ORDER BY versions.id DESC
LIMIT :limit));`,
sql.Named("limit", db.versionsHistoryLimit),
sql.Named("min", min),
sql.Named("path", path),
)
return err