// Reload triggers a new state load from the configured mesos masters. // This method is not goroutine-safe. func (res *Resolver) Reload() { t := records.RecordGenerator{} err := t.ParseState(res.config, res.masters...) if err != nil { logging.VeryVerbose.Println("Warning: master not found; serving only static entries") } timestamp := uint32(time.Now().Unix()) // may need to refactor for fairness res.rsLock.Lock() defer res.rsLock.Unlock() res.config.SOASerial = timestamp res.rs = &t logging.PrintCurLog() }
// Reload triggers a new state load from the configured mesos masters. // This method is not goroutine-safe. func (res *Resolver) Reload() { t := records.NewRecordGenerator(res.generatorOptions...) err := t.ParseState(res.config, res.masters...) if err == nil { timestamp := uint32(time.Now().Unix()) // may need to refactor for fairness res.rsLock.Lock() defer res.rsLock.Unlock() atomic.StoreUint32(&res.config.SOASerial, timestamp) res.rs = t } else { logging.Error.Printf("Warning: Error generating records: %v; keeping old DNS state", err) } logging.PrintCurLog() }
func main() { util.PanicHandlers = append(util.PanicHandlers, func(_ interface{}) { // by default the handler already logs the panic os.Exit(1) }) var versionFlag bool // parse flags cjson := flag.String("config", "config.json", "path to config file (json)") flag.BoolVar(&versionFlag, "version", false, "output the version") flag.Parse() // -version if versionFlag { fmt.Println(version) os.Exit(0) } // initialize logging logging.SetupLogs() // initialize resolver config := records.SetConfig(*cjson) resolver := resolver.New(version, config) var dnsErr, httpErr, zkErr <-chan error var newLeader <-chan struct{} // launch DNS server if config.DNSOn { dnsErr = resolver.LaunchDNS() } // launch HTTP server if config.HTTPOn { httpErr = resolver.LaunchHTTP() } // launch Zookeeper listener if config.Zk != "" { newLeader, zkErr = resolver.LaunchZK(zkInitialDetectionTimeout) } else { // uniform behavior when new leader from masters field leader := make(chan struct{}, 1) leader <- struct{}{} newLeader = leader } // print error and terminate handleServerErr := func(name string, err error) { if err != nil { logging.Error.Fatalf("%s failed: %v", name, err) } else { logging.Error.Fatalf("%s stopped unexpectedly", name) } } // generate reload signal; up to 1 reload pending at any time reloadSignal := make(chan struct{}, 1) tryReload := func() { // non-blocking, attempt to queue a reload select { case reloadSignal <- struct{}{}: default: } } // periodic loading of DNS state (pull from Master) go func() { defer util.HandleCrash() reloadTimeout := time.Second * time.Duration(config.RefreshSeconds) reloadTimer := time.AfterFunc(reloadTimeout, tryReload) for _ = range reloadSignal { resolver.Reload() logging.PrintCurLog() reloadTimer.Reset(reloadTimeout) } }() // infinite loop until there is fatal error for { select { case <-newLeader: tryReload() case err := <-dnsErr: handleServerErr("DNS server", err) case err := <-httpErr: handleServerErr("HTTP server", err) case err := <-zkErr: handleServerErr("ZK watcher", err) } } }