Golang / GoLang System Architecture and Testing Interview Questions
How do you implement configuration hot-reloading in a Go service without restart?
Some configuration changes — feature flags, rate limits, log levels — should not require a pod restart. Hot-reloading reads new config from a file or config service and atomically swaps the configuration pointer.
// Atomic configuration pointer â reads and writes are goroutine-safe type DynamicConfig struct { current atomic.Pointer[Config] } func NewDynamicConfig(initial *Config) *DynamicConfig { dc := &DynamicConfig{} dc.current.Store(initial) return dc } // Get returns the current config â zero allocation, lock-free func (dc *DynamicConfig) Get() *Config { return dc.current.Load() } // Reload atomically swaps to a new config func (dc *DynamicConfig) Reload(path string) error { data, err := os.ReadFile(path) if err != nil { return err } var cfg Config if err := yaml.Unmarshal(data, &cfg); err != nil { return err } if err := cfg.Validate(); err != nil { return err } dc.current.Store(&cfg) // atomic swap slog.Info("config reloaded", "path", path) return nil } // SIGHUP-triggered reload func watchConfigSignal(dc *DynamicConfig, path string) { sighup := make(chan os.Signal, 1) signal.Notify(sighup, syscall.SIGHUP) for range sighup { if err := dc.Reload(path); err != nil { slog.Error("config reload failed", "err", err) // Keep running with old config } } } // File watcher approach func watchConfigFile(dc *DynamicConfig, path string, ctx context.Context) { watcher, _ := fsnotify.NewWatcher() watcher.Add(path) defer watcher.Close() for { select { case <-ctx.Done(): return case event := <-watcher.Events: if event.Has(fsnotify.Write) { time.Sleep(100 * time.Millisecond) // wait for write to complete dc.Reload(path) } } } }
More Related questions...