Change:
Currently, Watch request with resourceVersion=0 results in: returning a single "watch event" for every object existing "now" starts watching from that point This is pretty misleading (e.g. it's different that what we have in etcd, where there is no first step from above). In the v2 api, we should probably eliminate the first stop (or even disallow watch requests with resourceVersion = 0).
/cc
Issues go stale after 30d of inactivity. Mark the issue as fresh with . Stale issues rot after an additional 30d of inactivity and eventually close. Prevent issues from auto-closing with an comment. If this issue is safe to close now please do so with . Send feedback to sig-testing, kubernetes/test-infra and/or . /lifecycle stale
Stale issues rot after 30d of inactivity. Mark the issue as fresh with . Rotten issues close after an additional 30d of inactivity. If this issue is safe to close now please do so with . Send feedback to sig-testing, kubernetes/test-infra and/or . /lifecycle rotten /remove-lifecycle stale
Rotten issues close after 30d of inactivity. Reopen the issue with . Mark the issue as fresh with . Send feedback to sig-testing, kubernetes/test-infra and/or . /close
/remove-lifecycle rotten /lifecycle frozen
What do you mean by v2 API? Are we ever going to have a v2 of the machiery and semantics?
In 2015 I thought it's not ridiculous. I'm not sure I believe in it now. Moreover, with we will actually be taking benefits of semantic like this, so we should close this.

Discussion:
return } action := watch.Added <del> if res.Node.ModifiedIndex != res.Node.CreatedIndex { action = watch.Modified } </del> w.emit(watch.Event{ Type:   action, Object: obj,

func (w *etcdWatcher) sendResult(res *etcd.Response) { switch res.Action { case EtcdCreate, EtcdGet: <ins> // "Get" will only happen in watch 0 case, where we explicitly want ADDED event // for initial state. </ins> w.sendAdd(res) case EtcdSet, EtcdCAS: w.sendModify(res)

} pod.ResourceVersion = "" <ins> watching, err := h.Watch(context.TODO(), key, "0", storage.Everything) if err != nil { t.Fatalf("Unexpected error: %v", err) } // The create trigger ADDED event when watching from 0 event := <-watching.ResultChan() watching.Stop() if event.Type != watch.Added { t.Errorf("Unexpected event %#v", event) } </ins> // check for concatenation on watch event with CAS updateFn := func(input runtime.Object, res storage.ResponseMeta) (runtime.Object, *uint64, error) { pod := input.(*api.Pod)

t.Fatalf("Unexpected error: %v", err) } <del> watching, err := h.Watch(context.TODO(), key, "0", storage.Everything) </del> <ins> watching, err = h.Watch(context.TODO(), key, "0", storage.Everything) </ins> if err != nil { t.Fatalf("Unexpected error: %v", err) } defer watching.Stop() <del> // marked as modified b/c of concatenation event := <-watching.ResultChan() if event.Type != watch.Modified { </del> <ins> // because we watch from 0, first event that we receive will always be ADDED event = <-watching.ResultChan() if event.Type != watch.Added { </ins> t.Errorf("Unexpected event %#v", event) }

t.Errorf("Unexpected event %#v", event) } <del> if e, a := pod, event.Object; !api.Semantic.DeepDerivative(e, a) { </del> <ins> if e, a := pod, event.Object; a == nil || !api.Semantic.DeepDerivative(e, a) { </ins> t.Errorf("Unexpected error: expected %#v, got %#v", e, a) } }

// resourceVersion may be used to specify what version to begin watching, // which should be the current resourceVersion, and no longer rv+1 // (e.g. reconnecting without missing any updates). <ins> // If resource version is "0", this interface will get current object at given key // and send it in an "ADDED" event, before watch starts. </ins> Watch(ctx context.Context, key string, resourceVersion string, p SelectionPredicate) (watch.Interface, error) // WatchList begins watching the specified key's items. Items are decoded into API

// resourceVersion may be used to specify what version to begin watching, // which should be the current resourceVersion, and no longer rv+1 // (e.g. reconnecting without missing any updates). <ins> // If resource version is "0", this interface will list current objects directory defined by key // and send them in "ADDED" events, before watch starts. </ins> WatchList(ctx context.Context, key string, resourceVersion string, p SelectionPredicate) (watch.Interface, error) // Get unmarshals json found at key into objPtr. On a not found error, will either