Manual cherry-pick of (37969b1) #34155 into release 10.11. (#34334)

Automatic Merge
Этот коммит содержится в:
Ibrahim Serdar Acikgoz
2025-10-30 16:29:11 +01:00
коммит произвёл GitHub
родитель b922174f48
Коммит 75132b7a91
3 изменённых файлов: 84 добавлений и 30 удалений

Просмотреть файл

@@ -418,9 +418,24 @@ func (ds *DatabaseStore) Close() error {
return ds.db.Close() return ds.db.Close()
} }
// removes configurations from database if they are older than threshold. // removes configurations from database if they are older than threshold,
func (ds *DatabaseStore) cleanUp(thresholdCreatAt int) error { // keeping the active configuration and the last 5 most recent ones.
if _, err := ds.db.NamedExec("DELETE FROM Configurations Where CreateAt < :timestamp", map[string]any{"timestamp": thresholdCreatAt}); err != nil { func (ds *DatabaseStore) cleanUp(thresholdCreateAt int64) error {
query := `
DELETE FROM Configurations
WHERE CreateAt < :timestamp
AND (Active IS NULL OR Active = false)
AND ID NOT IN (
SELECT ID FROM (
SELECT ID
FROM Configurations
ORDER BY CreateAt DESC
LIMIT 5
) AS recent
);
`
if _, err := ds.db.NamedExec(query, map[string]any{"timestamp": thresholdCreateAt}); err != nil {
return errors.Wrap(err, "unable to clean Configurations table") return errors.Wrap(err, "unable to clean Configurations table")
} }

Просмотреть файл

@@ -1122,6 +1122,7 @@ func TestCleanUp(t *testing.T) {
require.NotNil(t, ds) require.NotNil(t, ds)
defer ds.Close() defer ds.Close()
t.Run("should keep last 5 configurations regardless", func(t *testing.T) {
dbs, ok := ds.backingStore.(*DatabaseStore) dbs, ok := ds.backingStore.(*DatabaseStore)
require.True(t, ok, "should be a DatabaseStore instance") require.True(t, ok, "should be a DatabaseStore instance")
@@ -1130,12 +1131,17 @@ func TestCleanUp(t *testing.T) {
ds.config.JobSettings.CleanupConfigThresholdDays = model.NewPointer(30) // we set 30 days as threshold ds.config.JobSettings.CleanupConfigThresholdDays = model.NewPointer(30) // we set 30 days as threshold
var initialCount int
row := dbs.db.QueryRow("SELECT COUNT(*) FROM Configurations")
err = row.Scan(&initialCount)
require.NoError(t, err)
require.Less(t, initialCount, 5, "should have less than 5 configurations before test")
now := time.Now() now := time.Now()
for i := 0; i < 5; i++ { for i := range 10 {
// 20 days, we expect to remove at least 3 configuration values from the store // we are simulating that each config was created 40 days apart
// first 2 (0 and 1) will be within a month constraint, others will be older than // so all but last 5 should be deleted
// a month hence we expect 3 configurations to be removed from the database. m := -1 * i * 24 * 40
m := -1 * i * 24 * 20
params := map[string]any{ params := map[string]any{
"id": model.NewId(), "id": model.NewId(),
"value": string(b), "value": string(b),
@@ -1145,10 +1151,11 @@ func TestCleanUp(t *testing.T) {
_, err = dbs.db.NamedExec("INSERT INTO Configurations (Id, Value, CreateAt) VALUES (:id, :value, :create_at)", params) _, err = dbs.db.NamedExec("INSERT INTO Configurations (Id, Value, CreateAt) VALUES (:id, :value, :create_at)", params)
require.NoError(t, err) require.NoError(t, err)
} }
var initialCount int var beforeCleanup int
row := dbs.db.QueryRow("SELECT COUNT(*) FROM Configurations") row = dbs.db.QueryRow("SELECT COUNT(*) FROM Configurations")
err = row.Scan(&initialCount) err = row.Scan(&beforeCleanup)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, 10+initialCount, beforeCleanup, "should have more than 10 configurations before cleanup")
err = ds.CleanUp() err = ds.CleanUp()
require.NoError(t, err) require.NoError(t, err)
@@ -1157,5 +1164,37 @@ func TestCleanUp(t *testing.T) {
row = dbs.db.QueryRow("SELECT COUNT(*) FROM Configurations") row = dbs.db.QueryRow("SELECT COUNT(*) FROM Configurations")
err = row.Scan(&count) err = row.Scan(&count)
require.NoError(t, err) require.NoError(t, err)
require.True(t, count+3 == initialCount) require.Equal(t, 5, count, "should have only 5 configurations left")
})
t.Run("should keep the active configuration regardless", func(t *testing.T) {
b, err := marshalConfig(ds.config)
require.NoError(t, err)
dbs, ok := ds.backingStore.(*DatabaseStore)
require.True(t, ok, "should be a DatabaseStore instance")
// remove all other configurations
_, err = dbs.db.Exec("DELETE FROM Configurations")
require.NoError(t, err)
params := map[string]any{
"id": model.NewId(),
"value": string(b),
// we set the create_at to 100 days ago so it wouldn't be deleted if it is active
"create_at": model.GetMillisForTime(time.Now().Add(time.Duration(-1*100*24) * time.Hour)),
}
_, err = dbs.db.NamedExec("INSERT INTO Configurations (Id, Value, CreateAt) VALUES (:id, :value, :create_at)", params)
require.NoError(t, err)
err = ds.CleanUp()
require.NoError(t, err)
var count int
row := dbs.db.QueryRow("SELECT COUNT(*) FROM Configurations")
err = row.Scan(&count)
require.NoError(t, err)
require.Equal(t, 1, count, "should have only 1 configuration left")
})
} }

Просмотреть файл

@@ -406,7 +406,7 @@ func (s *Store) CleanUp() error {
case *DatabaseStore: case *DatabaseStore:
dur := time.Duration(*s.config.JobSettings.CleanupConfigThresholdDays) * time.Hour * 24 dur := time.Duration(*s.config.JobSettings.CleanupConfigThresholdDays) * time.Hour * 24
expiry := model.GetMillisForTime(time.Now().Add(-dur)) expiry := model.GetMillisForTime(time.Now().Add(-dur))
return bs.cleanUp(int(expiry)) return bs.cleanUp(expiry)
default: default:
return nil return nil
} }