Konfiguration aus Dateien laden und mit neuen Updates aktualisieren
Problembeschreibung:
Ein Code Beim Design wird beim Start eine Konfiguration aus Dateien geladen und regelmäßig mit neueren Versionen aktualisiert. Ziel ist es, über einen Mechanismus zu verfügen, der die folgenden Anforderungen erfüllt:
Das ursprüngliche Design verwendet eine gleichzeitige Karte zum Speichern der Konfiguration , steht aber vor einem Problem, bei dem Fehler während der Aktualisierung zu einer leeren Karte führen können.
Lösung:
Es wird ein vereinfachtes Design vorgeschlagen, das alle Anforderungen erfüllt:
CustomerConfig-Struktur:
Definiert die zwischenzuspeichernde Konfiguration:
type CustomerConfig struct { Data map[string]bool LoadedAt time.Time }
loadConfig-Funktion:
Ladet die Konfiguration aus Dateien:
func loadConfig() (*CustomerConfig, error) { cfg := &CustomerConfig{ Data: map[string]bool{}, LoadedAt: time.Now(), } // Logic to load files and populate cfg.Data // If an error occurs, return it // If loading succeeds, return the config return cfg, nil }
ConfigCache-Struktur:
Verwaltet das Konfigurations-Caching:
type ConfigCache struct { configMu sync.RWMutex config *CustomerConfig closeCh chan struct{} }
NeueConfigCache-Funktion:
Erstellt einen neuen Konfigurationscache:
func NewConfigCache() (*ConfigCache, error) { cfg, err := loadConfig() if err != nil { return nil, fmt.Errorf("loading initial config failed: %w", err) } cc := &ConfigCache{ config: cfg, closeCh: make(chan struct{}), } // Launch a goroutine to periodically check for changes and load new configs go cc.refresher() return cc, nil }
Auffrischungsfunktion:
Prüft regelmäßig auf Konfigurationsänderungen und aktualisiert den Cache:
func (cc *ConfigCache) refresher() { ticker := time.NewTicker(1 * time.Minute) // Every minute defer ticker.Stop() for { select { case <-ticker.C: // Check for changes changes := false // Logic to detect changes if !changes { continue // No changes, continue } // Changes! Load new config: cfg, err := loadConfig() if err != nil { log.Printf("Failed to load config: %v", err) continue // Keep the previous config } // Apply / store new config cc.configMu.Lock() cc.config = cfg cc.configMu.Unlock() case <-cc.closeCh: return } } }
Stopp-Funktion:
Stoppt die Refresh-Goroutine:
func (cc *ConfigCache) Stop() { close(cc.closeCh) }
GetConfig-Funktion:
Zugriff auf die aktuelle Konfiguration:
func (cc *ConfigCache) GetConfig() *CustomerConfig { cc.configMu.RLock() defer cc.configMu.RUnlock() return cc.config }
Verwendung:
cc, err := NewConfigCache() if err != nil { // Handle the error appropriately } // Access the configuration whenever needed: cfg := cc.GetConfig() // Use the configuration here // Stop the cache refreshing when necessary: cc.Stop()
Diese Lösung gewährleistet:
Das obige ist der detaillierte Inhalt vonWie entwerfe ich einen Konfigurationscache, der Aktualisierungen und Fehler ordnungsgemäß verarbeitet?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!