Beispiel #1
0
func (back *zkConfig) reregisterWatch(path string, logger log.Logger) error {
	logger = log.NewContext(logger).With(logkey.ZkPath, path)
	logger.Log("Reregistering watch")
	_, _, _, err := back.conn.ExistsW(path)
	if err != nil {
		logger.Log(log.Err, err, "Unable to reregistering watch")
		return errors.Annotatef(err, "unable to reregister watch for node %s", path)
	}
	return nil
}
Beispiel #2
0
// Duration returns a duration object that calls ParseDuration() on the given key
func (c *Distconf) Duration(key string, defaultVal time.Duration) *Duration {
	s := &durationConf{
		defaultVal: defaultVal,
		Duration: Duration{
			currentVal: defaultVal.Nanoseconds(),
		},
		logger: log.NewContext(c.Logger).With(logkey.DistconfKey, key),
	}
	// Note: in race conditions 's' may not be the thing actually returned
	ret, okCast := c.register(key, s).(*durationConf)
	if !okCast {
		c.Logger.Log(logkey.DistconfKey, key, "Registering key with multiple types!  FIX ME!!!!")
		return nil
	}
	return &ret.Duration
}
Beispiel #3
0
func (back *zkConfig) refreshWatches(functionLogger log.Logger) {
	for path, callbacks := range back.callbacks.copy() {
		pathLogger := log.NewContext(functionLogger).With(logkey.ZkPath, path)
		for _, c := range callbacks {
			c(path)
		}
		for {
			err := back.reregisterWatch(path, pathLogger)
			if err == nil {
				break
			}
			pathLogger.Log(log.Err, err, "Error reregistering watch")
			time.Sleep(back.refreshDelay.get())
		}
	}
}
Beispiel #4
0
// Zk creates a zookeeper readable backing
func Zk(zkConnector ZkConnector, conf *ZkConfig) (ReaderWriter, error) {
	conf = pointer.FillDefaultFrom(conf, DefaultZkConfig).(*ZkConfig)
	ret := &zkConfig{
		rootLogger: log.NewContext(conf.Logger).With(logkey.DistconfBacking, "zk"),
		shouldQuit: make(chan struct{}),
		callbacks: callbackMap{
			callbacks: make(map[string][]backingCallbackFunction),
		},
		refreshDelay: atomicDuration{
			refreshRetryDelay: time.Millisecond * 500,
		},
	}
	var err error
	ret.conn, ret.eventChan, err = zkConnector.Connect()
	if err != nil {
		return nil, errors.Annotate(err, "cannot create zk connection")
	}
	go ret.drainEventChan(conf.Logger)
	return ret, nil
}
Beispiel #5
0
func (back *zkConfig) drainEventChan(functionLogger log.Logger) {
	drainContext := log.NewContext(functionLogger).With(logkey.Func, "drainEventChan")
	defer drainContext.Log("Draining done")
	for {
		drainContext.Log("Blocking with event")
		select {
		case e := <-back.eventChan:
			eventContext := drainContext.With(logkey.ZkEvent, e)
			eventContext.Log("event seen")
			back.logInfoState(eventContext, e)
			if e.State == zk.StateHasSession {
				eventContext.Log("Server now has a session.")
				back.refreshWatches(eventContext)
				continue
			}
			if e.Path == "" {
				continue
			}
			if len(e.Path) > 0 && e.Path[0] == '/' {
				e.Path = e.Path[1:]
			}
			{
				eventContext.Log(logkey.ArrLen, back.callbacks.len(), "change state")
				for _, c := range back.callbacks.get(e.Path) {
					c(e.Path)
				}
			}
			eventContext.Log("reregistering watch")

			// Note: return value currently ignored.  Not sure what to do about it
			back.reregisterWatch(e.Path, eventContext)
			eventContext.Log("reregistering watch finished")
		case <-back.shouldQuit:
			drainContext.Log("quit message seen")
			return
		}
	}
}