Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
049e63d2
Commit
049e63d2
authored
Apr 13, 2016
by
Andy Goldstein
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Honor starting resourceVersion in watch cache
Compare the requested resourceVersion to each event's resourceVersion to ensure events that occurred in the past are not sent to the client.
parent
1186f4bf
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
61 additions
and
9 deletions
+61
-9
cacher.go
pkg/storage/cacher.go
+8
-5
cacher_test.go
pkg/storage/cacher_test.go
+48
-0
watch_cache.go
pkg/storage/watch_cache.go
+5
-4
No files found.
pkg/storage/cacher.go
View file @
049e63d2
...
...
@@ -264,7 +264,7 @@ func (c *Cacher) Watch(ctx context.Context, key string, resourceVersion string,
c
.
Lock
()
defer
c
.
Unlock
()
watcher
:=
newCacheWatcher
(
initEvents
,
filterFunction
(
key
,
c
.
keyFunc
,
filter
),
forgetWatcher
(
c
,
c
.
watcherIdx
))
watcher
:=
newCacheWatcher
(
watchRV
,
initEvents
,
filterFunction
(
key
,
c
.
keyFunc
,
filter
),
forgetWatcher
(
c
,
c
.
watcherIdx
))
c
.
watchers
[
c
.
watcherIdx
]
=
watcher
c
.
watcherIdx
++
return
watcher
,
nil
...
...
@@ -465,7 +465,7 @@ type cacheWatcher struct {
forget
func
(
bool
)
}
func
newCacheWatcher
(
initEvents
[]
watchCacheEvent
,
filter
FilterFunc
,
forget
func
(
bool
))
*
cacheWatcher
{
func
newCacheWatcher
(
resourceVersion
uint64
,
initEvents
[]
watchCacheEvent
,
filter
FilterFunc
,
forget
func
(
bool
))
*
cacheWatcher
{
watcher
:=
&
cacheWatcher
{
input
:
make
(
chan
watchCacheEvent
,
10
),
result
:
make
(
chan
watch
.
Event
,
10
),
...
...
@@ -473,7 +473,7 @@ func newCacheWatcher(initEvents []watchCacheEvent, filter FilterFunc, forget fun
stopped
:
false
,
forget
:
forget
,
}
go
watcher
.
process
(
initEvents
)
go
watcher
.
process
(
initEvents
,
resourceVersion
)
return
watcher
}
...
...
@@ -537,7 +537,7 @@ func (c *cacheWatcher) sendWatchCacheEvent(event watchCacheEvent) {
}
}
func
(
c
*
cacheWatcher
)
process
(
initEvents
[]
watchCacheEvent
)
{
func
(
c
*
cacheWatcher
)
process
(
initEvents
[]
watchCacheEvent
,
resourceVersion
uint64
)
{
defer
utilruntime
.
HandleCrash
()
for
_
,
event
:=
range
initEvents
{
...
...
@@ -550,6 +550,9 @@ func (c *cacheWatcher) process(initEvents []watchCacheEvent) {
if
!
ok
{
return
}
c
.
sendWatchCacheEvent
(
event
)
// only send events newer than resourceVersion
if
event
.
ResourceVersion
>
resourceVersion
{
c
.
sendWatchCacheEvent
(
event
)
}
}
}
pkg/storage/cacher_test.go
View file @
049e63d2
...
...
@@ -346,3 +346,51 @@ func TestFiltering(t *testing.T) {
verifyWatchEvent
(
t
,
watcher
,
watch
.
Modified
,
podFooPrime
)
verifyWatchEvent
(
t
,
watcher
,
watch
.
Deleted
,
podFooPrime
)
}
func
TestStartingResourceVersion
(
t
*
testing
.
T
)
{
server
,
etcdStorage
:=
newEtcdTestStorage
(
t
,
testapi
.
Default
.
Codec
(),
etcdtest
.
PathPrefix
())
defer
server
.
Terminate
(
t
)
cacher
:=
newTestCacher
(
etcdStorage
)
defer
cacher
.
Stop
()
// add 1 object
podFoo
:=
makeTestPod
(
"foo"
)
fooCreated
:=
updatePod
(
t
,
etcdStorage
,
podFoo
,
nil
)
// Set up Watch starting at fooCreated.ResourceVersion + 10
rv
,
err
:=
storage
.
ParseWatchResourceVersion
(
fooCreated
.
ResourceVersion
)
if
err
!=
nil
{
t
.
Fatalf
(
"Unexpected error: %v"
,
err
)
}
rv
+=
10
startVersion
:=
strconv
.
Itoa
(
int
(
rv
))
watcher
,
err
:=
cacher
.
Watch
(
context
.
TODO
(),
"pods/ns/foo"
,
startVersion
,
storage
.
Everything
)
if
err
!=
nil
{
t
.
Fatalf
(
"Unexpected error: %v"
,
err
)
}
defer
watcher
.
Stop
()
lastFoo
:=
fooCreated
for
i
:=
0
;
i
<
11
;
i
++
{
podFooForUpdate
:=
makeTestPod
(
"foo"
)
podFooForUpdate
.
Labels
=
map
[
string
]
string
{
"foo"
:
strconv
.
Itoa
(
i
)}
lastFoo
=
updatePod
(
t
,
etcdStorage
,
podFooForUpdate
,
lastFoo
)
}
select
{
case
e
:=
<-
watcher
.
ResultChan
()
:
pod
:=
e
.
Object
.
(
*
api
.
Pod
)
podRV
,
err
:=
storage
.
ParseWatchResourceVersion
(
pod
.
ResourceVersion
)
if
err
!=
nil
{
t
.
Fatalf
(
"unexpected error: %v"
,
err
)
}
// event should have at least rv + 1, since we're starting the watch at rv
if
podRV
<=
rv
{
t
.
Errorf
(
"expected event with resourceVersion of at least %d, got %d"
,
rv
+
1
,
podRV
)
}
case
<-
time
.
After
(
wait
.
ForeverTestTimeout
)
:
t
.
Errorf
(
"timed out waiting for event"
)
}
}
pkg/storage/watch_cache.go
View file @
049e63d2
...
...
@@ -42,9 +42,10 @@ const (
// the previous value of the object to enable proper filtering in the
// upper layers.
type
watchCacheEvent
struct
{
Type
watch
.
EventType
Object
runtime
.
Object
PrevObject
runtime
.
Object
Type
watch
.
EventType
Object
runtime
.
Object
PrevObject
runtime
.
Object
ResourceVersion
uint64
}
// watchCacheElement is a single "watch event" stored in a cache.
...
...
@@ -179,7 +180,7 @@ func (w *watchCache) processEvent(event watch.Event, resourceVersion uint64, upd
if
exists
{
prevObject
=
previous
.
(
runtime
.
Object
)
}
watchCacheEvent
:=
watchCacheEvent
{
event
.
Type
,
event
.
Object
,
prevObject
}
watchCacheEvent
:=
watchCacheEvent
{
event
.
Type
,
event
.
Object
,
prevObject
,
resourceVersion
}
if
w
.
onEvent
!=
nil
{
w
.
onEvent
(
watchCacheEvent
)
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment