mirror of
https://github.com/MHSanaei/3x-ui.git
synced 2026-06-28 00:24:19 +00:00
perf(settings): save all settings in one transaction
UpdateAllSetting issued a separate SELECT plus Save per field in its own autocommit transaction, so each panel-settings save triggered 100+ SQLite write transactions (one fsync each). Wrap the whole update in a single transaction, read existing rows once, and skip unchanged values.
This commit is contained in:
@@ -23,6 +23,8 @@ import (
|
||||
"github.com/mhsanaei/3x-ui/v3/internal/util/reflect_util"
|
||||
"github.com/mhsanaei/3x-ui/v3/internal/web/entity"
|
||||
"github.com/mhsanaei/3x-ui/v3/internal/xray"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
//go:embed config.json
|
||||
@@ -1049,17 +1051,37 @@ func (s *SettingService) UpdateAllSetting(allSetting *entity.AllSetting) error {
|
||||
v := reflect.ValueOf(allSetting).Elem()
|
||||
t := reflect.TypeFor[entity.AllSetting]()
|
||||
fields := reflect_util.GetFields(t)
|
||||
errs := make([]error, 0)
|
||||
for _, field := range fields {
|
||||
key := field.Tag.Get("json")
|
||||
fieldV := v.FieldByName(field.Name)
|
||||
value := fmt.Sprint(fieldV.Interface())
|
||||
err := s.saveSetting(key, value)
|
||||
if err != nil {
|
||||
errs = append(errs, err)
|
||||
|
||||
db := database.GetDB()
|
||||
return db.Transaction(func(tx *gorm.DB) error {
|
||||
var existing []*model.Setting
|
||||
if err := tx.Find(&existing).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return common.Combine(errs...)
|
||||
byKey := make(map[string]*model.Setting, len(existing))
|
||||
for _, st := range existing {
|
||||
byKey[st.Key] = st
|
||||
}
|
||||
for _, field := range fields {
|
||||
key := field.Tag.Get("json")
|
||||
fieldV := v.FieldByName(field.Name)
|
||||
value := fmt.Sprint(fieldV.Interface())
|
||||
if st, ok := byKey[key]; ok {
|
||||
if st.Value == value {
|
||||
continue
|
||||
}
|
||||
st.Value = value
|
||||
if err := tx.Save(st).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
if err := tx.Create(&model.Setting{Key: key, Value: value}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (s *SettingService) preserveRedactedSecrets(allSetting *entity.AllSetting) error {
|
||||
|
||||
Reference in New Issue
Block a user