func watch(client *etcd.Client, idx uint64, etcdchan chan *etcd.Response, key string, stop chan bool) { for true { select { case <-stop: log.V(1).Infof("Gracefully closing etcd watch loop: key=%s", key) return default: log.V(1).Infof("Creating etcd watcher: key=%s, index=%d, machines=%s", key, idx, strings.Join(client.GetCluster(), ",")) resp, err := client.Watch(key, idx, true, nil, nil) if err == nil { idx = resp.Node.ModifiedIndex + 1 etcdchan <- resp continue } log.Errorf("etcd watcher returned error: key=%s, err=\"%s\"", key, err.Error()) etcdError, ok := err.(*etcd.EtcdError) 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 etcdErr.EcodeEventIndexCleared: // 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) } } } }
func watch(client *etcd.Client, etcdchan chan *etcd.Response, key string, closechan chan bool) { idx := uint64(0) for true { select { case <-closechan: log.V(2).Infof("Gracefully closing etcd watch loop: key=%s", key) return default: log.V(2).Infof("Creating etcd watcher: key=%s, index=%d, machines=%s", key, idx, strings.Join(client.GetCluster(), ",")) resp, err := client.Watch(key, idx, true, nil, nil) if err == nil { idx = resp.Node.ModifiedIndex + 1 etcdchan <- resp } else { log.V(2).Infof("etcd watcher returned error: key=%s, err=\"%s\"", key, err.Error()) // Let's not slam the etcd server in the event that we know // an unexpected error occurred. time.Sleep(time.Second) } } } }