package storage import ( "strings" "time" ) const configHotReloadMinInterval = 2 * time.Second // MaybeSyncRuntimeConfigFromDB 在「管理后台在其它节点保存了配置」时,用 MySQL 中的最新行覆盖本进程内存缓存,避免多副本部署必须重启才生效。 // 带最短间隔节流,减少读库频率。 func (s *Store) MaybeSyncRuntimeConfigFromDB() { s.hotReloadMu.Lock() elapsed := time.Since(s.lastHotReload) should := s.lastHotReload.IsZero() || elapsed >= configHotReloadMinInterval if should { s.lastHotReload = time.Now() } s.hotReloadMu.Unlock() if !should { return } _ = s.syncRuntimeConfigFromDB() } func (s *Store) syncRuntimeConfigFromDB() error { if err := s.reloadOAuthConfigFromDB(); err != nil { return err } if err := s.reloadTurnstileConfigFromDB(); err != nil { return err } // 含邀请码列表等 return s.loadOrCreateRegistrationConfig() } func (s *Store) reloadOAuthConfigFromDB() error { var cfg OAuthConfig found, err := s.getConfig("oauth", &cfg) if err != nil || !found { return err } if strings.TrimSpace(cfg.GiteaBaseURL) == "" { cfg.GiteaBaseURL = defaultGiteaBaseURL } cfg.GiteaBaseURL = strings.TrimRight(strings.TrimSpace(cfg.GiteaBaseURL), "/") if strings.TrimSpace(cfg.LinuxdoConnectBaseURL) == "" { cfg.LinuxdoConnectBaseURL = defaultLinuxdoConnectBaseURL } cfg.LinuxdoConnectBaseURL = strings.TrimRight(strings.TrimSpace(cfg.LinuxdoConnectBaseURL), "/") if strings.TrimSpace(cfg.MicrosoftTenant) == "" { cfg.MicrosoftTenant = defaultMicrosoftTenant } else { cfg.MicrosoftTenant = strings.TrimSpace(cfg.MicrosoftTenant) } s.mu.Lock() s.oauthConfig = cfg s.mu.Unlock() return nil } func (s *Store) reloadTurnstileConfigFromDB() error { var cfg TurnstileConfig _, err := s.getConfig("turnstile", &cfg) if err != nil { return err } s.mu.Lock() s.turnstileConfig = cfg s.mu.Unlock() return nil }