func watch(client etcd.Client, key string, stop chan struct{}) (res *etcd.Result) { for res == nil { select { case <-stop: log.V(1).Infof("Gracefully closing etcd watch loop: key=%s", key) return default: req := &etcd.Watch{ Key: key, WaitIndex: 0, Recursive: true, } log.V(1).Infof("Creating etcd watcher: %v", req) var err error res, err = client.Wait(req, stop) if err != nil { log.Errorf("etcd watcher %v returned error: %v", req, err) } } // Let's not slam the etcd server in the event that we know // an unexpected error occurred. time.Sleep(time.Second) } return }
func watch(client etcd.Client, idx uint64, etcdchan chan *etcd.Result, key string, stop chan bool) { for { select { case <-stop: log.V(1).Infof("Gracefully closing etcd watch loop: key=%s", key) return default: req := &etcd.Watch{ Key: key, WaitIndex: idx, Recursive: true, } log.V(1).Infof("Creating etcd watcher: %v", req) resp, err := client.Wait(req, stop) if err == nil { if resp.Node != nil { idx = resp.Node.ModifiedIndex + 1 } etcdchan <- resp continue } log.Errorf("etcd watcher %v returned error: %v", req, err) etcdError, ok := err.(etcd.Error) if !ok { // Let's not slam the etcd server in the event that we know // an unexpected error occurred. time.Sleep(time.Second) continue } switch etcdError.ErrorCode { case etcd.ErrorEventIndexCleared: // This is racy, but adding one to the last known index // will help get this watcher back into the range of // etcd's internal event history idx = idx + 1 default: // Let's not slam the etcd server in the event that we know // an unexpected error occurred. time.Sleep(time.Second) } } } }