New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix resourcVersion = 0 in cacher #13910
Fix resourcVersion = 0 in cacher #13910
Conversation
|
GCE e2e build/test passed for commit c7b7f55baed2d02217289aacf39e03e3bbcd360c. |
|
Does this restore the previous behavior where you get modified events for all objects that exist when the watch was started? That was what made watch from 0 useful |
|
cc @stefwalter |
@lavalamp But yeah... I will try to fix that. |
|
I spent more time debugging this to make sure I was not mistaken. if I do the following direct to etcd on a running Kubernetes system: It waits until there was a node change event from Kubernetes, and only then returns the action for a Node update. I do not get any other data in the system. Meaning I do not get all the existing data. I think the change proposed here actually is consistent with the behavior that we used to have. |
|
@derekwaynecarr - I agree it's what etcd does (and I agree it's the most intuitive solution). |
|
@wojtek-t - I am testing what we actually had in 1.0 right now, will comment on original issue. |
|
We need to restore to the previous behavior - we can deprecate and remove On Mon, Sep 14, 2015 at 10:33 AM, Wojciech Tyczynski <
Clayton Coleman | Lead Engineer, OpenShift |
|
I tested on all the stuff in question as I was confused myself tracking etcd and kube versions. see #13809 (comment) I think we need to special case resourceVersion=0 to internally kube does LIST and then WATCH from the last observed watch state to maintain consistency with 1.0 release. |
|
Yeah, this is not the old behavior. IMO this behavior makes more sense, but since the point of this is to maintain compatibility, we should stick to the old behavior, which was list, send each item individually, then watch. With no way for user to tell where one ended and the other began. |
|
Labelling this PR as size/M |
|
I agree - will fix that PR tomorrow. |
c7b7f55
to
0007794
Compare
|
I've updated the PR to be compatible with what we have in v1.0. PTAL |
|
GCE e2e build/test passed for commit 0007794f68239f54b8803baeb08dba16f9e2f607. |
|
I can see items like this showing up from the watch while smoke testing this: I don't think |
0007794
to
fa1a4a5
Compare
|
Yes - I initially thought that it was the case before. Should be fixed now. |
|
Works well now. A tiny nit ... the previous behavior was to list the initial set of items with |
|
GCE e2e build/test passed for commit fa1a4a5eca364a918b549ab80b14334b8ca14915. |
| // However, to keep backward compatibility, we additionally need to return the | ||
| // current state and only then start watching from that point. | ||
| // | ||
| // TODO: In v2 api, we should stop returning the current state |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Open an issue to track change of WATCH behavior and and link to it here.
Reference the issue on the umbrella after #8190
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
fa1a4a5
to
12eaf67
Compare
|
@derekwaynecarr - PTAL |
|
GCE e2e build/test failed for commit 12eaf67. |
|
@k8s-bot test this |
| // current state and only then start watching from that point. | ||
| // | ||
| // TODO: In v2 api, we should stop returning the current state - #13969. | ||
| allItems := w.store.List() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this list go out to hit etcd? I guess it doesn't matter since this feature can't be used safely anyway, but if it doesn't go out to hit etcd there's no guarantee the combined state returned by the list would be a complete/correct one as of any particular resource version.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe that the List() will work against the current state in the backing cache.Store and not hit etcd.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wait, why is this feature not safe? The original implementation was safe -
we called etcd to do a list, then watched from the list timestamp. How is
the new version less able to deliver safety?
On Tue, Sep 15, 2015 at 1:30 PM, Daniel Smith notifications@github.com
wrote:
In pkg/storage/watch_cache.go
#13910 (comment)
:@@ -250,6 +250,20 @@ func (w *watchCache) GetAllEventsSinceThreadUnsafe(resourceVersion uint64) ([]wa
if size > 0 {
oldest = w.cache[w.startIndex%w.capacity].resourceVersion
}
- if resourceVersion == 0 {
// resourceVersion = 0 means that we don't require any specific starting point// and we would like to start watching from ~now.// However, to keep backward compatibility, we additionally need to return the// current state and only then start watching from that point.//// TODO: In v2 api, we should stop returning the current state - #13969.allItems := w.store.List()Does this list go out to hit etcd? I guess it doesn't matter since this
feature can't be used safely anyway, but if it doesn't go out to hit etcd
there's no guarantee the combined state returned by the list would be a
complete/correct one as of any particular resource version.—
Reply to this email directly or view it on GitHub
https://github.com/kubernetes/kubernetes/pull/13910/files#r39539558.
Clayton Coleman | Lead Engineer, OpenShift
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, I have the same question. I can tell @lavalamp doesn't like this method, but I haven't heard a concrete reason an internal list followed by watch of the list's resourceVersion is unsafe
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suspect he is referring to a potential race between the backing cache.Store and the watch cache. So if the current items are enumerated from the cache.store, and a watch is initiated, its possible that in the time between that a change in etcd was missed. I think to fix that you would need to know the resource version of the most recent item for when w.store.List() returned its value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I say it's not "safe" because at no point in time can the client be certain it has a complete or correct list. I get that for many uses this safety isn't important.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is safe (due to how it is implemented).
Basically, the backing store contains a correct state at some point in time. The way it is implemented is that the cacher is locking watchCache, gets the state from that point in time (using list on the backing store) and starts watch from exactly that point. Every new watch event delivered to the backing store will be propagated to that watcher,
So there is no risk that some event will not be delivered.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I say it's not "safe" because at no point in time can the client be certain it has a complete or correct list. I get that for many uses this safety isn't important.
I don't understand it btw. It is guaranteed that this list is a correct list from some point in time (as long as we don't have multi-object transactions, which is true for now).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@wojtek-t thank you for the clarification.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I see! Yes, this sounds correct. In theory, etcd would provide the same
list at some resourceVersion. Thanks for explaining.
On Tue, Sep 15, 2015 at 11:32 PM, Wojciech Tyczynski <
notifications@github.com> wrote:
In pkg/storage/watch_cache.go
#13910 (comment)
:@@ -250,6 +250,20 @@ func (w *watchCache) GetAllEventsSinceThreadUnsafe(resourceVersion uint64) ([]wa
if size > 0 {
oldest = w.cache[w.startIndex%w.capacity].resourceVersion
}
- if resourceVersion == 0 {
// resourceVersion = 0 means that we don't require any specific starting point// and we would like to start watching from ~now.// However, to keep backward compatibility, we additionally need to return the// current state and only then start watching from that point.//// TODO: In v2 api, we should stop returning the current state - #13969.allItems := w.store.List()It is safe (due to how it is implemented).
Basically, the backing store contains a correct state at some point in
time. The way it is implemented is that the cacher is locking watchCache,
gets the state from that point in time (using list on the backing store)
and starts watch from exactly that point. Every new watch event delivered
to the backing store will be propagated to that watcher,
So there is no risk that some event will not be delivered.—
Reply to this email directly or view it on GitHub
https://github.com/kubernetes/kubernetes/pull/13910/files#r39597444.
|
GCE e2e build/test passed for commit 12eaf67. |
|
LGTM |
|
@k8s-bot test this [submit-queue is verifying that this PR is safe to merge] |
|
GCE e2e build/test failed for commit 12eaf67. |
|
@k8s-bot test this please |
|
GCE e2e build/test passed for commit 12eaf67. |
|
@k8s-bot test this [submit-queue is verifying that this PR is safe to merge] |
|
GCE e2e build/test passed for commit 12eaf67. |
|
Automatic merge from SubmitQueue |
Auto commit by PR queue bot
Fix #13809
cc @lavalamp @derekwaynecarr @smarterclayton @StefWalker