Maison >développement back-end >Golang >Comment concevoir un cache de configuration qui gère efficacement les mises à jour et les erreurs ?
Charger la configuration à partir de fichiers et actualiser avec de nouvelles mises à jour
Énoncé du problème :
Un code la conception implique de charger une configuration à partir de fichiers au démarrage et de l'actualiser périodiquement avec des versions plus récentes. L'objectif est d'avoir un mécanisme qui gère les exigences suivantes :
La conception initiale utilise une carte concurrente pour stocker la configuration , mais est confronté à un problème où des erreurs lors de la mise à jour peuvent conduire à une carte vide.
Solution :
Une conception simplifiée est proposée qui répond à toutes les exigences :
CustomerConfig Structure :
Définit la configuration à mettre en cache :
type CustomerConfig struct { Data map[string]bool LoadedAt time.Time }
loadConfig Fonction :
Charge la configuration à partir des fichiers :
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 }
Structure ConfigCache :
Gère la mise en cache de la configuration :
type ConfigCache struct { configMu sync.RWMutex config *CustomerConfig closeCh chan struct{} }
Fonction NewConfigCache :
Crée un nouveau cache de configuration :
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 }
Fonction de rafraîchissement :
Vérifie périodiquement les modifications de configuration et met à jour le 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 } } }
Fonction d'arrêt :
Arrête la goroutine de rafraîchissement :
func (cc *ConfigCache) Stop() { close(cc.closeCh) }
Fonction GetConfig :
Accès à la configuration actuelle :
func (cc *ConfigCache) GetConfig() *CustomerConfig { cc.configMu.RLock() defer cc.configMu.RUnlock() return cc.config }
Utilisation :
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()
Cette solution assure :
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!