Beispiel #1
0
// 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()
}
Beispiel #2
0
// 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()
}
Beispiel #3
0
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)
		}
	}
}