fix(region): auto clean invalid cached images (#20804)

This commit is contained in:
屈轩
2024-08-09 09:41:46 +08:00
committed by GitHub
parent 0e5d5c6366
commit 48fb20150a
2 changed files with 82 additions and 43 deletions
+58
View File
@@ -19,6 +19,8 @@ import (
"database/sql"
"fmt"
"reflect"
"strings"
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
@@ -602,3 +604,59 @@ func FetchDistinctField(modelManager IModelManager, field string) ([]string, err
return q.Distinct()
})
}
func Purge(modelManager IModelManager, field string, ids []string, forceDelete bool) error {
if len(ids) == 0 {
return nil
}
var splitByLen = func(data []string, splitLen int) [][]string {
var result [][]string
for i := 0; i < len(data); i += splitLen {
end := i + splitLen
if end > len(data) {
end = len(data)
}
result = append(result, data[i:end])
}
return result
}
var purge = func(ids []string) error {
vars := []interface{}{}
placeholders := make([]string, len(ids))
for i := range placeholders {
placeholders[i] = "?"
vars = append(vars, ids[i])
}
placeholder := strings.Join(placeholders, ",")
sql := fmt.Sprintf(
"delete from %s where %s in (%s)",
modelManager.TableSpec().Name(), field, placeholder,
)
if !forceDelete {
sql = fmt.Sprintf(
"update %s set deleted=1, deleted_at= ? where %s in (%s)",
modelManager.TableSpec().Name(), field, placeholder,
)
vars = append([]interface{}{time.Now()}, vars...)
}
_, err := sqlchemy.GetDB().Exec(
sql, vars...,
)
if err != nil {
return errors.Wrapf(err, strings.ReplaceAll(sql, "?", "%s"), vars...)
}
return nil
}
idsArr := splitByLen(ids, 100)
for i := range idsArr {
err := purge(idsArr[i])
if err != nil {
return errors.Wrapf(err, "purge")
}
}
return nil
}
+24 -43
View File
@@ -945,6 +945,10 @@ func (manager *SCachedimageManager) AutoCleanImageCaches(ctx context.Context, us
if err != nil {
log.Errorf("cleanExternalImages error: %v", err)
}
err = manager.cleanStoragecachedimages()
if err != nil {
log.Errorf("cleanStoragecachedimages error: %v", err)
}
}()
lastSync := time.Now().Add(time.Duration(-1*api.CACHED_IMAGE_REFERENCE_SESSION_EXPIRE_SECONDS) * time.Second)
q := manager.Query()
@@ -1020,55 +1024,32 @@ func (manager *SCachedimageManager) cleanExternalImages() error {
return errors.Wrapf(err, "getExpireExternalImageIds")
}
if len(ids) == 0 {
return nil
}
var splitByLen = func(data []string, splitLen int) [][]string {
var result [][]string
for i := 0; i < len(data); i += splitLen {
end := i + splitLen
if end > len(data) {
end = len(data)
}
result = append(result, data[i:end])
}
return result
}
var purge = func(ids []string) error {
vars := []interface{}{}
placeholders := make([]string, len(ids))
for i := range placeholders {
placeholders[i] = "?"
vars = append(vars, ids[i])
}
placeholder := strings.Join(placeholders, ",")
sql := fmt.Sprintf(
"delete from %s where id in (%s)",
manager.TableSpec().Name(), placeholder,
)
_, err = sqlchemy.GetDB().Exec(
sql, vars...,
)
if err != nil {
return errors.Wrapf(err, strings.ReplaceAll(sql, "?", "%s"), vars...)
}
return nil
}
idsArr := splitByLen(ids, 100)
for i := range idsArr {
err = purge(idsArr[i])
if err != nil {
return errors.Wrapf(err, "purge")
}
err = db.Purge(manager, "id", ids, true)
if err != nil {
return errors.Wrapf(err, "purge")
}
log.Debugf("clean %d expired external images", len(ids))
return nil
}
func (manager *SCachedimageManager) cleanStoragecachedimages() error {
ids, err := db.FetchField(StoragecachedimageManager, "row_id", func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
sq := manager.Query("id").Distinct().SubQuery()
return q.NotIn("cachedimage_id", sq)
})
if err != nil {
return errors.Wrapf(err, "getExpireExternalImageIds")
}
err = db.Purge(StoragecachedimageManager, "row_id", ids, true)
if err != nil {
return errors.Wrapf(err, "purge")
}
log.Debugf("clean %d invalid storagecachedimages", len(ids))
return nil
}
func (image *SCachedimage) GetAllClassMetadata() (map[string]string, error) {
meta, err := image.SSharableVirtualResourceBase.GetAllClassMetadata()
if err != nil {