mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-09-14 13:45:06 +00:00
Add more parameters to Watch
* Add labels selector (same as List) * Add fields selector * Plan to let you select pods by Host and/or Status * Add resourceVersion to let you resume a watch where you left off.
This commit is contained in:
@@ -296,18 +296,19 @@ func Everything(interface{}) bool {
|
||||
|
||||
// WatchList begins watching the specified key's items. Items are decoded into
|
||||
// API objects, and any items passing 'filter' are sent down the returned
|
||||
// watch.Interface.
|
||||
func (h *EtcdHelper) WatchList(key string, filter FilterFunc) (watch.Interface, error) {
|
||||
// watch.Interface. resourceVersion may be used to specify what version to begin
|
||||
// watching (e.g., for reconnecting without missing any updateds).
|
||||
func (h *EtcdHelper) WatchList(key string, resourceVersion uint64, filter FilterFunc) (watch.Interface, error) {
|
||||
w := newEtcdWatcher(true, filter, h.Codec)
|
||||
go w.etcdWatch(h.Client, key)
|
||||
go w.etcdWatch(h.Client, key, resourceVersion)
|
||||
return w, nil
|
||||
}
|
||||
|
||||
// Watch begins watching the specified key. Events are decoded into
|
||||
// API objects and sent down the returned watch.Interface.
|
||||
func (h *EtcdHelper) Watch(key string) (watch.Interface, error) {
|
||||
func (h *EtcdHelper) Watch(key string, resourceVersion uint64) (watch.Interface, error) {
|
||||
w := newEtcdWatcher(false, nil, h.Codec)
|
||||
go w.etcdWatch(h.Client, key)
|
||||
go w.etcdWatch(h.Client, key, resourceVersion)
|
||||
return w, nil
|
||||
}
|
||||
|
||||
@@ -350,10 +351,10 @@ func newEtcdWatcher(list bool, filter FilterFunc, encoding Codec) *etcdWatcher {
|
||||
|
||||
// etcdWatch calls etcd's Watch function, and handles any errors. Meant to be called
|
||||
// as a goroutine.
|
||||
func (w *etcdWatcher) etcdWatch(client EtcdGetSet, key string) {
|
||||
func (w *etcdWatcher) etcdWatch(client EtcdGetSet, key string, resourceVersion uint64) {
|
||||
defer util.HandleCrash()
|
||||
defer close(w.etcdCallEnded)
|
||||
_, err := client.Watch(key, 0, w.list, w.etcdIncoming, w.etcdStop)
|
||||
_, err := client.Watch(key, resourceVersion, w.list, w.etcdIncoming, w.etcdStop)
|
||||
if err != etcd.ErrWatchStoppedByUser {
|
||||
glog.Errorf("etcd.Watch stopped unexpectedly: %v (%#v)", err, err)
|
||||
}
|
||||
@@ -385,18 +386,20 @@ func (w *etcdWatcher) sendResult(res *etcd.Response) {
|
||||
var action watch.EventType
|
||||
var data []byte
|
||||
switch res.Action {
|
||||
case "create", "set":
|
||||
case "create":
|
||||
if res.Node == nil {
|
||||
glog.Errorf("unexpected nil node: %#v", res)
|
||||
return
|
||||
}
|
||||
data = []byte(res.Node.Value)
|
||||
// TODO: Is this conditional correct?
|
||||
if res.EtcdIndex > 0 {
|
||||
action = watch.Modified
|
||||
} else {
|
||||
action = watch.Added
|
||||
action = watch.Added
|
||||
case "set":
|
||||
if res.Node == nil {
|
||||
glog.Errorf("unexpected nil node: %#v", res)
|
||||
return
|
||||
}
|
||||
data = []byte(res.Node.Value)
|
||||
action = watch.Modified
|
||||
case "delete":
|
||||
if res.PrevNode == nil {
|
||||
glog.Errorf("unexpected nil prev node: %#v", res)
|
||||
|
@@ -325,6 +325,30 @@ func TestAtomicUpdate_CreateCollision(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestWatchInterpretation_ListCreate(t *testing.T) {
|
||||
w := newEtcdWatcher(true, func(interface{}) bool {
|
||||
t.Errorf("unexpected filter call")
|
||||
return true
|
||||
}, encoding)
|
||||
pod := &api.Pod{JSONBase: api.JSONBase{ID: "foo"}}
|
||||
podBytes, _ := encoding.Encode(pod)
|
||||
|
||||
go w.sendResult(&etcd.Response{
|
||||
Action: "create",
|
||||
Node: &etcd.Node{
|
||||
Value: string(podBytes),
|
||||
},
|
||||
})
|
||||
|
||||
got := <-w.outgoing
|
||||
if e, a := watch.Added, got.Type; e != a {
|
||||
t.Errorf("Expected %v, got %v", e, a)
|
||||
}
|
||||
if e, a := pod, got.Object; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("Expected %v, got %v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWatchInterpretation_ListAdd(t *testing.T) {
|
||||
w := newEtcdWatcher(true, func(interface{}) bool {
|
||||
t.Errorf("unexpected filter call")
|
||||
@@ -341,7 +365,7 @@ func TestWatchInterpretation_ListAdd(t *testing.T) {
|
||||
})
|
||||
|
||||
got := <-w.outgoing
|
||||
if e, a := watch.Added, got.Type; e != a {
|
||||
if e, a := watch.Modified, got.Type; e != a {
|
||||
t.Errorf("Expected %v, got %v", e, a)
|
||||
}
|
||||
if e, a := pod, got.Object; !reflect.DeepEqual(e, a) {
|
||||
@@ -420,7 +444,7 @@ func TestWatch(t *testing.T) {
|
||||
fakeClient := MakeFakeEtcdClient(t)
|
||||
h := EtcdHelper{fakeClient, codec, versioner}
|
||||
|
||||
watching, err := h.Watch("/some/key")
|
||||
watching, err := h.Watch("/some/key", 0)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
@@ -438,7 +462,7 @@ func TestWatch(t *testing.T) {
|
||||
}
|
||||
|
||||
event := <-watching.ResultChan()
|
||||
if e, a := watch.Added, event.Type; e != a {
|
||||
if e, a := watch.Modified, event.Type; e != a {
|
||||
t.Errorf("Expected %v, got %v", e, a)
|
||||
}
|
||||
if e, a := pod, event.Object; !reflect.DeepEqual(e, a) {
|
||||
@@ -462,7 +486,7 @@ func TestWatchPurposefulShutdown(t *testing.T) {
|
||||
h := EtcdHelper{fakeClient, codec, versioner}
|
||||
|
||||
// Test purposeful shutdown
|
||||
watching, err := h.Watch("/some/key")
|
||||
watching, err := h.Watch("/some/key", 0)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
|
Reference in New Issue
Block a user