// etcdWatch calls etcd's Watch function, and handles any errors. Meant to be called // as a goroutine. func (w *etcdWatcher) etcdWatch(client tools.EtcdClient, key string, resourceVersion uint64) { // glog.Infof("Watching") defer util.HandleCrash() defer close(w.etcdError) if resourceVersion == 0 { latest, err := etcdGetInitialWatchState(client, key, w.list, w.etcdIncoming) if err != nil { if etcdError, ok := err.(*etcd.EtcdError); ok && etcdError != nil && etcdError.ErrorCode == tools.EtcdErrorCodeNotFound { // glog.Errorf("Error getting initial watch, key not found: %v", err) return } glog.Errorf("Error getting initial watch: %v", err) w.etcdError <- err return } resourceVersion = latest + 1 } response, err := client.Watch(key, resourceVersion, w.list, w.etcdIncoming, w.etcdStop) glog.Infof("response is %v", response) if err != nil && err != etcd.ErrWatchStoppedByUser { glog.Errorf("Error watch: %v", err) w.etcdError <- err } }
// TestEtcdClient verifies a client is functional. It will attempt to // connect to the etcd server and block until the server responds at least once, or return an // error if the server never responded. func testEtcdClient(etcdClient tools.EtcdClient) error { for i := 0; ; i++ { _, err := etcdClient.Get("/", false, false) if err == nil { break } if i > 100 { return fmt.Errorf("Could not reach etcd: %v", err) } time.Sleep(50 * time.Millisecond) } glog.V(3).Infof("Etcd client test passed") return nil }
// etcdGetInitialWatchState turns an etcd Get request into a watch equivalent func etcdGetInitialWatchState(client tools.EtcdClient, key string, recursive bool, incoming chan<- *etcd.Response) (resourceVersion uint64, err error) { resp, err := client.Get(key, false, recursive) if err != nil { if !IsEtcdNotFound(err) { glog.Errorf("watch was unable to retrieve the current index for the provided key (%q): %v", key, err) return resourceVersion, err } if index, ok := etcdErrorIndex(err); ok { resourceVersion = index } return resourceVersion, nil } resourceVersion = resp.EtcdIndex convertRecursiveResponse(resp.Node, resp, incoming) return }
// etcdWatch calls etcd's Watch function, and handles any errors. Meant to be called // as a goroutine. func (w *etcdWatcher) etcdWatch(client tools.EtcdClient, key string, resourceVersion uint64) { defer util.HandleCrash() defer close(w.etcdError) if resourceVersion == 0 { latest, err := etcdGetInitialWatchState(client, key, w.list, w.etcdIncoming) if err != nil { w.etcdError <- err return } resourceVersion = latest + 1 } _, err := client.Watch(key, resourceVersion, w.list, w.etcdIncoming, w.etcdStop) if err != nil && err != etcd.ErrWatchStoppedByUser { w.etcdError <- err } }
func storeToEtcd(client tools.EtcdClient, path, name string, obj interface{}) error { data, err := encodeToThirdParty(name, obj) if err != nil { return err } _, err = client.Set(etcdtest.PathPrefix()+path, string(data), 0) return err }
func (s *SchedulerServer) fetchFrameworkID(client tools.EtcdClient) (*mesos.FrameworkID, error) { if s.FailoverTimeout > 0 { if response, err := client.Get(meta.FrameworkIDKey, false, false); err != nil { if !etcdstorage.IsEtcdNotFound(err) { return nil, fmt.Errorf("unexpected failure attempting to load framework ID from etcd: %v", err) } log.V(1).Infof("did not find framework ID in etcd") } else if response.Node.Value != "" { log.Infof("configuring FrameworkInfo with Id found in etcd: '%s'", response.Node.Value) return mutil.NewFrameworkID(response.Node.Value), nil } } else { //TODO(jdef) this seems like a totally hackish way to clean up the framework ID if _, err := client.Delete(meta.FrameworkIDKey, true); err != nil { if !etcdstorage.IsEtcdNotFound(err) { return nil, fmt.Errorf("failed to delete framework ID from etcd: %v", err) } log.V(1).Infof("nothing to delete: did not find framework ID in etcd") } } return nil, nil }