chore: sync local updates
This commit is contained in:
161
mengyaping-backend/storage/app_config.go
Normal file
161
mengyaping-backend/storage/app_config.go
Normal file
@@ -0,0 +1,161 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"mengyaping-backend/config"
|
||||
)
|
||||
|
||||
const (
|
||||
kvKeyServer = "cfg_server"
|
||||
kvKeyMonitor = "cfg_monitor"
|
||||
kvKeyDataPath = "cfg_data_path"
|
||||
kvKeyDatabase = "cfg_database"
|
||||
)
|
||||
|
||||
type monitorKVPayload struct {
|
||||
IntervalMinutes int `json:"interval_minutes"`
|
||||
TimeoutSeconds int `json:"timeout_seconds"`
|
||||
RetryCount int `json:"retry_count"`
|
||||
HistoryDays int `json:"history_days"`
|
||||
}
|
||||
|
||||
func (s *Storage) getKVRaw(key string) string {
|
||||
var row MonitorKV
|
||||
s.db.Where("cfg_key = ?", key).Limit(1).Find(&row)
|
||||
if row.CfgKey == "" {
|
||||
return ""
|
||||
}
|
||||
return row.CfgValue
|
||||
}
|
||||
|
||||
func (s *Storage) setKVRaw(key, val string) error {
|
||||
var row MonitorKV
|
||||
s.db.Where("cfg_key = ?", key).Limit(1).Find(&row)
|
||||
if row.CfgKey == "" {
|
||||
return s.db.Create(&MonitorKV{CfgKey: key, CfgValue: val}).Error
|
||||
}
|
||||
row.CfgValue = val
|
||||
return s.db.Save(&row).Error
|
||||
}
|
||||
|
||||
// loadAndSyncAppConfig 从 monitor_kv 覆盖内存配置,再写回全量(补全缺省键、统一格式)
|
||||
func (s *Storage) loadAndSyncAppConfig() {
|
||||
cfg := config.GetConfig()
|
||||
|
||||
if v := s.getKVRaw(kvKeyServer); v != "" {
|
||||
var sc config.ServerConfig
|
||||
if err := json.Unmarshal([]byte(v), &sc); err != nil {
|
||||
log.Printf("解析 %s: %v", kvKeyServer, err)
|
||||
} else {
|
||||
if sc.Port != "" {
|
||||
cfg.Server.Port = sc.Port
|
||||
}
|
||||
if sc.Host != "" {
|
||||
cfg.Server.Host = sc.Host
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if v := s.getKVRaw(kvKeyMonitor); v != "" {
|
||||
var m monitorKVPayload
|
||||
if err := json.Unmarshal([]byte(v), &m); err != nil {
|
||||
log.Printf("解析 %s: %v", kvKeyMonitor, err)
|
||||
} else {
|
||||
if m.IntervalMinutes > 0 {
|
||||
snapped := config.SnapMonitorIntervalMinutes(m.IntervalMinutes)
|
||||
cfg.Monitor.Interval = time.Duration(snapped) * time.Minute
|
||||
}
|
||||
if m.TimeoutSeconds > 0 {
|
||||
cfg.Monitor.Timeout = time.Duration(m.TimeoutSeconds) * time.Second
|
||||
}
|
||||
if m.RetryCount > 0 {
|
||||
cfg.Monitor.RetryCount = m.RetryCount
|
||||
}
|
||||
if m.HistoryDays > 0 {
|
||||
cfg.Monitor.HistoryDays = m.HistoryDays
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if v := s.getKVRaw(kvKeyDataPath); v != "" {
|
||||
cfg.DataPath = v
|
||||
}
|
||||
|
||||
if v := s.getKVRaw(kvKeyDatabase); v != "" {
|
||||
var dc config.DatabaseConfig
|
||||
if err := json.Unmarshal([]byte(v), &dc); err != nil {
|
||||
log.Printf("解析 %s: %v", kvKeyDatabase, err)
|
||||
} else {
|
||||
if dc.Host != "" {
|
||||
cfg.Database.Host = dc.Host
|
||||
}
|
||||
if dc.Port != "" {
|
||||
cfg.Database.Port = dc.Port
|
||||
}
|
||||
if dc.User != "" {
|
||||
cfg.Database.User = dc.User
|
||||
}
|
||||
if dc.Password != "" {
|
||||
cfg.Database.Password = dc.Password
|
||||
}
|
||||
if dc.Database != "" {
|
||||
cfg.Database.Database = dc.Database
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err := s.PersistAppConfig(); err != nil {
|
||||
log.Printf("同步应用配置到 monitor_kv: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// PersistAppConfig 将当前内存中的 server/monitor/data_path/database 写入 monitor_kv
|
||||
func (s *Storage) PersistAppConfig() error {
|
||||
cfg := config.GetConfig()
|
||||
|
||||
b, err := json.Marshal(cfg.Server)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.setKVRaw(kvKeyServer, string(b)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
m := monitorKVPayload{
|
||||
IntervalMinutes: config.SnapMonitorIntervalMinutes(int(cfg.Monitor.Interval / time.Minute)),
|
||||
TimeoutSeconds: int(cfg.Monitor.Timeout.Seconds()),
|
||||
RetryCount: cfg.Monitor.RetryCount,
|
||||
HistoryDays: cfg.Monitor.HistoryDays,
|
||||
}
|
||||
b, err = json.Marshal(m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.setKVRaw(kvKeyMonitor, string(b)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := s.setKVRaw(kvKeyDataPath, cfg.DataPath); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b, err = json.Marshal(cfg.Database)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return s.setKVRaw(kvKeyDatabase, string(b))
|
||||
}
|
||||
|
||||
// SetMonitorIntervalMinutes 更新检测周期并写入 monitor_kv
|
||||
func (s *Storage) SetMonitorIntervalMinutes(minutes int) error {
|
||||
if !config.IsAllowedMonitorInterval(minutes) {
|
||||
return fmt.Errorf("interval_minutes 必须是预设值之一: %v", config.AllowedMonitorIntervalMinutes)
|
||||
}
|
||||
cfg := config.GetConfig()
|
||||
cfg.Monitor.Interval = time.Duration(minutes) * time.Minute
|
||||
return s.PersistAppConfig()
|
||||
}
|
||||
Reference in New Issue
Block a user