Example #1
0
func (md *MasterDetector) detect(f detector.MasterChanged) {
	log.V(3).Infoln("detecting children at", currentPath)
detectLoop:
	for {
		select {
		case <-md.Done():
			return
		default:
		}
		log.V(3).Infoln("watching children at", currentPath)
		path, childrenCh, errCh := md.client.watchChildren(currentPath)
		rewatch := false
		for {
			started := time.Now()
			select {
			case children := <-childrenCh:
				md.childrenChanged(path, children, f)
			case err, ok := <-errCh:
				// check for a tie first (required for predictability (tests)); the downside of
				// doing this is that a listener might get two callbacks back-to-back ("new leader",
				// followed by "no leader").
				select {
				case children := <-childrenCh:
					md.childrenChanged(path, children, f)
				default:
				}
				if ok {
					log.V(1).Infoln("child watch ended with error, master lost; error was:", err.Error())
				} else {
					// detector shutdown likely...
					log.V(1).Infoln("child watch ended, master lost")
				}
				select {
				case <-md.Done():
					return
				default:
					if md.leaderNode != "" {
						log.V(2).Infof("changing leader node from %q -> \"\"", md.leaderNode)
						md.leaderNode = ""
						f.OnMasterChanged(nil)
					}
				}
				rewatch = true
			}
			// rate-limit master changes
			if elapsed := time.Now().Sub(started); elapsed > 0 {
				log.V(2).Infoln("resting before next detection cycle")
				select {
				case <-md.Done():
					return
				case <-time.After(md.minDetectorCyclePeriod - elapsed): // noop
				}
			}
			if rewatch {
				continue detectLoop
			}
		}
	}
}
Example #2
0
func (md *MasterDetector) notifyMasterChanged(path string, list []string, obs detector.MasterChanged) {
	// mesos v0.24 writes JSON only, v0.23 writes json and protobuf, v0.22 and prior only write protobuf
	topNode, codec := md.selectTopNode(list)
	if md.leaderNode == topNode {
		log.V(2).Infof("ignoring children-changed event, leader has not changed: %v", path)
		return
	}

	log.V(2).Infof("changing leader node from %q -> %q", md.leaderNode, topNode)
	md.leaderNode = topNode

	var masterInfo *mesos.MasterInfo
	if md.leaderNode != "" {
		var err error
		if masterInfo, err = codec(path, topNode); err != nil {
			log.Errorln(err.Error())
		}
	}
	log.V(2).Infof("detected master info: %+v", masterInfo)
	logPanic(func() { obs.OnMasterChanged(masterInfo) })
}