mirror of https://github.com/Xhofe/alist
				
				
				
			perf: Speed of database initialization (#7694)
* perf: 优化非sqlite3数据库时初始化慢的问题 * refactorpull/7673/head
							parent
							
								
									b8bd14f99b
								
							
						
					
					
						commit
						db99224126
					
				| 
						 | 
				
			
			@ -3,6 +3,7 @@ package data
 | 
			
		|||
import (
 | 
			
		||||
	"github.com/alist-org/alist/v3/cmd/flags"
 | 
			
		||||
	"github.com/alist-org/alist/v3/internal/conf"
 | 
			
		||||
	"github.com/alist-org/alist/v3/internal/db"
 | 
			
		||||
	"github.com/alist-org/alist/v3/internal/model"
 | 
			
		||||
	"github.com/alist-org/alist/v3/internal/offline_download/tool"
 | 
			
		||||
	"github.com/alist-org/alist/v3/internal/op"
 | 
			
		||||
| 
						 | 
				
			
			@ -21,17 +22,19 @@ func initSettings() {
 | 
			
		|||
	if err != nil {
 | 
			
		||||
		utils.Log.Fatalf("failed get settings: %+v", err)
 | 
			
		||||
	}
 | 
			
		||||
	for i := range settings {
 | 
			
		||||
		if !isActive(settings[i].Key) && settings[i].Flag != model.DEPRECATED {
 | 
			
		||||
			settings[i].Flag = model.DEPRECATED
 | 
			
		||||
			err = op.SaveSettingItem(&settings[i])
 | 
			
		||||
	settingMap := map[string]*model.SettingItem{}
 | 
			
		||||
	for _, v := range settings {
 | 
			
		||||
		if !isActive(v.Key) && v.Flag != model.DEPRECATED {
 | 
			
		||||
			v.Flag = model.DEPRECATED
 | 
			
		||||
			err = op.SaveSettingItem(&v)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				utils.Log.Fatalf("failed save setting: %+v", err)
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		settingMap[v.Key] = &v
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// create or save setting
 | 
			
		||||
	save := false
 | 
			
		||||
	for i := range initialSettingItems {
 | 
			
		||||
		item := &initialSettingItems[i]
 | 
			
		||||
		item.Index = uint(i)
 | 
			
		||||
| 
						 | 
				
			
			@ -39,26 +42,33 @@ func initSettings() {
 | 
			
		|||
			item.PreDefault = item.Value
 | 
			
		||||
		}
 | 
			
		||||
		// err
 | 
			
		||||
		stored, err := op.GetSettingItemByKey(item.Key)
 | 
			
		||||
		stored, ok := settingMap[item.Key]
 | 
			
		||||
		if !ok {
 | 
			
		||||
			stored, err = op.GetSettingItemByKey(item.Key)
 | 
			
		||||
			if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
 | 
			
		||||
				utils.Log.Fatalf("failed get setting: %+v", err)
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
		// save
 | 
			
		||||
		}
 | 
			
		||||
		if stored != nil && item.Key != conf.VERSION && stored.Value != item.PreDefault {
 | 
			
		||||
			item.Value = stored.Value
 | 
			
		||||
		}
 | 
			
		||||
		if stored == nil || *item != *stored {
 | 
			
		||||
			err = op.SaveSettingItem(item)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				utils.Log.Fatalf("failed save setting: %+v", err)
 | 
			
		||||
			}
 | 
			
		||||
		} else {
 | 
			
		||||
			// Not save so needs to execute hook
 | 
			
		||||
		_, err = op.HandleSettingItemHook(item)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			utils.Log.Errorf("failed to execute hook on %s: %+v", item.Key, err)
 | 
			
		||||
			continue
 | 
			
		||||
		}
 | 
			
		||||
		// save
 | 
			
		||||
		if stored == nil || *item != *stored {
 | 
			
		||||
			save = true
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if save {
 | 
			
		||||
		err = db.SaveSettingItems(initialSettingItems)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			utils.Log.Fatalf("failed save setting: %+v", err)
 | 
			
		||||
		} else {
 | 
			
		||||
			op.SettingCacheUpdate()
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -56,20 +56,20 @@ func InitDB() {
 | 
			
		|||
			}
 | 
			
		||||
		case "mysql":
 | 
			
		||||
			{
 | 
			
		||||
				dsn := database.DSN
 | 
			
		||||
				if dsn == "" {
 | 
			
		||||
					//[username[:password]@][protocol[(address)]]/dbname[?param1=value1&...¶mN=valueN]
 | 
			
		||||
				dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Local&tls=%s",
 | 
			
		||||
					dsn = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Local&tls=%s",
 | 
			
		||||
						database.User, database.Password, database.Host, database.Port, database.Name, database.SSLMode)
 | 
			
		||||
				if database.DSN != "" {
 | 
			
		||||
					dsn = database.DSN
 | 
			
		||||
				}
 | 
			
		||||
				dB, err = gorm.Open(mysql.Open(dsn), gormConfig)
 | 
			
		||||
			}
 | 
			
		||||
		case "postgres":
 | 
			
		||||
			{
 | 
			
		||||
				dsn := fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%d sslmode=%s TimeZone=Asia/Shanghai",
 | 
			
		||||
				dsn := database.DSN
 | 
			
		||||
				if dsn == "" {
 | 
			
		||||
					dsn = fmt.Sprintf("host=%s user=%s password=%s dbname=%s port=%d sslmode=%s TimeZone=Asia/Shanghai",
 | 
			
		||||
						database.Host, database.User, database.Password, database.Name, database.Port, database.SSLMode)
 | 
			
		||||
				if database.DSN != "" {
 | 
			
		||||
					dsn = database.DSN
 | 
			
		||||
				}
 | 
			
		||||
				dB, err = gorm.Open(postgres.Open(dsn), gormConfig)
 | 
			
		||||
			}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,7 +26,7 @@ var settingGroupCacheF = func(key string, item []model.SettingItem) {
 | 
			
		|||
	settingGroupCache.Set(key, item, cache.WithEx[[]model.SettingItem](time.Hour))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func settingCacheUpdate() {
 | 
			
		||||
func SettingCacheUpdate() {
 | 
			
		||||
	settingCache.Clear()
 | 
			
		||||
	settingGroupCache.Clear()
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -167,7 +167,7 @@ func SaveSettingItems(items []model.SettingItem) error {
 | 
			
		|||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if len(errs) < len(items)-len(noHookItems)+1 {
 | 
			
		||||
		settingCacheUpdate()
 | 
			
		||||
		SettingCacheUpdate()
 | 
			
		||||
	}
 | 
			
		||||
	return utils.MergeErrors(errs...)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -181,7 +181,7 @@ func SaveSettingItem(item *model.SettingItem) (err error) {
 | 
			
		|||
	if err = db.SaveSettingItem(item); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	settingCacheUpdate()
 | 
			
		||||
	SettingCacheUpdate()
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -193,6 +193,6 @@ func DeleteSettingItemByKey(key string) error {
 | 
			
		|||
	if !old.IsDeprecated() {
 | 
			
		||||
		return errors.Errorf("setting [%s] is not deprecated", key)
 | 
			
		||||
	}
 | 
			
		||||
	settingCacheUpdate()
 | 
			
		||||
	SettingCacheUpdate()
 | 
			
		||||
	return db.DeleteSettingItemByKey(key)
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,16 +12,16 @@ import (
 | 
			
		|||
func GetApiUrl(r *http.Request) string {
 | 
			
		||||
	api := conf.Conf.SiteURL
 | 
			
		||||
	if strings.HasPrefix(api, "http") {
 | 
			
		||||
		return api
 | 
			
		||||
		return strings.TrimSuffix(api, "/")
 | 
			
		||||
	}
 | 
			
		||||
	if r != nil {
 | 
			
		||||
		protocol := "http"
 | 
			
		||||
		if r.TLS != nil || r.Header.Get("X-Forwarded-Proto") == "https" {
 | 
			
		||||
			protocol = "https"
 | 
			
		||||
		}
 | 
			
		||||
		host := r.Host
 | 
			
		||||
		if r.Header.Get("X-Forwarded-Host") != "" {
 | 
			
		||||
			host = r.Header.Get("X-Forwarded-Host")
 | 
			
		||||
		host := r.Header.Get("X-Forwarded-Host")
 | 
			
		||||
		if host == "" {
 | 
			
		||||
			host = r.Host
 | 
			
		||||
		}
 | 
			
		||||
		api = fmt.Sprintf("%s://%s", protocol, stdpath.Join(host, api))
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue