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
6f80ec91
Commit
6f80ec91
authored
Oct 26, 2016
by
Kubernetes Submit Queue
Committed by
GitHub
Oct 26, 2016
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #35415 from wojtek-t/avoid_get
Automatic merge from submit-queue Try to avoid Get to etcd in GuaranteedUpdate in Cacher
parents
e09fc6d5
a1090151
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
74 additions
and
11 deletions
+74
-11
cacher.go
pkg/storage/cacher.go
+15
-1
etcd_helper.go
pkg/storage/etcd/etcd_helper.go
+4
-1
store.go
pkg/storage/etcd3/store.go
+49
-8
interfaces.go
pkg/storage/interfaces.go
+6
-1
No files found.
pkg/storage/cacher.go
View file @
6f80ec91
...
...
@@ -462,7 +462,21 @@ func (c *Cacher) List(ctx context.Context, key string, resourceVersion string, p
}
// Implements storage.Interface.
func
(
c
*
Cacher
)
GuaranteedUpdate
(
ctx
context
.
Context
,
key
string
,
ptrToType
runtime
.
Object
,
ignoreNotFound
bool
,
preconditions
*
Preconditions
,
tryUpdate
UpdateFunc
)
error
{
func
(
c
*
Cacher
)
GuaranteedUpdate
(
ctx
context
.
Context
,
key
string
,
ptrToType
runtime
.
Object
,
ignoreNotFound
bool
,
preconditions
*
Preconditions
,
tryUpdate
UpdateFunc
,
_
...
runtime
.
Object
)
error
{
// Ignore the suggestion and try to pass down the current version of the object
// read from cache.
if
elem
,
exists
,
err
:=
c
.
watchCache
.
GetByKey
(
key
);
err
!=
nil
{
glog
.
Errorf
(
"GetByKey returned error: %v"
,
err
)
}
else
if
exists
{
currObj
,
copyErr
:=
api
.
Scheme
.
Copy
(
elem
.
(
*
storeElement
)
.
Object
)
if
copyErr
==
nil
{
return
c
.
storage
.
GuaranteedUpdate
(
ctx
,
key
,
ptrToType
,
ignoreNotFound
,
preconditions
,
tryUpdate
,
currObj
)
}
glog
.
Errorf
(
"couldn't copy object: %v"
,
copyErr
)
}
// If we couldn't get the object, fallback to no-suggestion.
return
c
.
storage
.
GuaranteedUpdate
(
ctx
,
key
,
ptrToType
,
ignoreNotFound
,
preconditions
,
tryUpdate
)
}
...
...
pkg/storage/etcd/etcd_helper.go
View file @
6f80ec91
...
...
@@ -434,7 +434,10 @@ func (h *etcdHelper) listEtcdNode(ctx context.Context, key string) ([]*etcd.Node
}
// Implements storage.Interface.
func
(
h
*
etcdHelper
)
GuaranteedUpdate
(
ctx
context
.
Context
,
key
string
,
ptrToType
runtime
.
Object
,
ignoreNotFound
bool
,
preconditions
*
storage
.
Preconditions
,
tryUpdate
storage
.
UpdateFunc
)
error
{
func
(
h
*
etcdHelper
)
GuaranteedUpdate
(
ctx
context
.
Context
,
key
string
,
ptrToType
runtime
.
Object
,
ignoreNotFound
bool
,
preconditions
*
storage
.
Preconditions
,
tryUpdate
storage
.
UpdateFunc
,
_
...
runtime
.
Object
)
error
{
// Ignore the suggestion about current object.
if
ctx
==
nil
{
glog
.
Errorf
(
"Context is nil"
)
}
...
...
pkg/storage/etcd3/store.go
View file @
6f80ec91
...
...
@@ -211,22 +211,33 @@ func (s *store) conditionalDelete(ctx context.Context, key string, out runtime.O
}
// GuaranteedUpdate implements storage.Interface.GuaranteedUpdate.
func
(
s
*
store
)
GuaranteedUpdate
(
ctx
context
.
Context
,
key
string
,
out
runtime
.
Object
,
ignoreNotFound
bool
,
precondtions
*
storage
.
Preconditions
,
tryUpdate
storage
.
UpdateFunc
)
error
{
func
(
s
*
store
)
GuaranteedUpdate
(
ctx
context
.
Context
,
key
string
,
out
runtime
.
Object
,
ignoreNotFound
bool
,
precondtions
*
storage
.
Preconditions
,
tryUpdate
storage
.
UpdateFunc
,
suggestion
...
runtime
.
Object
)
error
{
v
,
err
:=
conversion
.
EnforcePtr
(
out
)
if
err
!=
nil
{
panic
(
"unable to convert output object to pointer"
)
}
key
=
keyWithPrefix
(
s
.
pathPrefix
,
key
)
getResp
,
err
:=
s
.
client
.
KV
.
Get
(
ctx
,
key
,
s
.
getOps
...
)
if
err
!=
nil
{
return
err
}
for
{
origState
,
err
:=
s
.
getState
(
getResp
,
key
,
v
,
ignoreNotFound
)
var
origState
*
objState
if
len
(
suggestion
)
==
1
&&
suggestion
[
0
]
!=
nil
{
origState
,
err
=
s
.
getStateFromObject
(
suggestion
[
0
])
if
err
!=
nil
{
return
err
}
}
else
{
getResp
,
err
:=
s
.
client
.
KV
.
Get
(
ctx
,
key
,
s
.
getOps
...
)
if
err
!=
nil
{
return
err
}
origState
,
err
=
s
.
getState
(
getResp
,
key
,
v
,
ignoreNotFound
)
if
err
!=
nil
{
return
err
}
}
for
{
if
err
:=
checkPreconditions
(
key
,
precondtions
,
origState
.
obj
);
err
!=
nil
{
return
err
}
...
...
@@ -260,8 +271,12 @@ func (s *store) GuaranteedUpdate(ctx context.Context, key string, out runtime.Ob
return
err
}
if
!
txnResp
.
Succeeded
{
getResp
=
(
*
clientv3
.
GetResponse
)(
txnResp
.
Responses
[
0
]
.
GetResponseRange
())
getResp
:
=
(
*
clientv3
.
GetResponse
)(
txnResp
.
Responses
[
0
]
.
GetResponseRange
())
glog
.
V
(
4
)
.
Infof
(
"GuaranteedUpdate of %s failed because of a conflict, going to retry"
,
key
)
origState
,
err
=
s
.
getState
(
getResp
,
key
,
v
,
ignoreNotFound
)
if
err
!=
nil
{
return
err
}
continue
}
putResp
:=
txnResp
.
Responses
[
0
]
.
GetResponsePut
()
...
...
@@ -369,6 +384,32 @@ func (s *store) getState(getResp *clientv3.GetResponse, key string, v reflect.Va
return
state
,
nil
}
func
(
s
*
store
)
getStateFromObject
(
obj
runtime
.
Object
)
(
*
objState
,
error
)
{
state
:=
&
objState
{
obj
:
obj
,
meta
:
&
storage
.
ResponseMeta
{},
}
rv
,
err
:=
s
.
versioner
.
ObjectResourceVersion
(
obj
)
if
err
!=
nil
{
return
nil
,
fmt
.
Errorf
(
"couldn't get resource version: %v"
,
err
)
}
state
.
rev
=
int64
(
rv
)
state
.
meta
.
ResourceVersion
=
uint64
(
state
.
rev
)
// Compute the serialized form - for that we need to temporarily clean
// its resource version field (those are not stored in etcd).
if
err
:=
s
.
versioner
.
UpdateObject
(
obj
,
0
);
err
!=
nil
{
return
nil
,
errors
.
New
(
"resourceVersion cannot be set on objects store in etcd"
)
}
state
.
data
,
err
=
runtime
.
Encode
(
s
.
codec
,
obj
)
if
err
!=
nil
{
return
nil
,
err
}
s
.
versioner
.
UpdateObject
(
state
.
obj
,
uint64
(
rv
))
return
state
,
nil
}
func
(
s
*
store
)
updateState
(
st
*
objState
,
userUpdate
storage
.
UpdateFunc
)
(
runtime
.
Object
,
uint64
,
error
)
{
ret
,
ttlPtr
,
err
:=
userUpdate
(
st
.
obj
,
*
st
.
meta
)
if
err
!=
nil
{
...
...
pkg/storage/interfaces.go
View file @
6f80ec91
...
...
@@ -147,6 +147,9 @@ type Interface interface {
// or zero value in 'ptrToType' parameter otherwise.
// If the object to update has the same value as previous, it won't do any update
// but will return the object in 'ptrToType' parameter.
// If 'suggestion' can contain zero or one element - in such case this can be used as
// a suggestion about the current version of the object to avoid read operation from
// storage to get it.
//
// Example:
//
...
...
@@ -166,5 +169,7 @@ type Interface interface {
// return cur, nil, nil
// }
// })
GuaranteedUpdate
(
ctx
context
.
Context
,
key
string
,
ptrToType
runtime
.
Object
,
ignoreNotFound
bool
,
precondtions
*
Preconditions
,
tryUpdate
UpdateFunc
)
error
GuaranteedUpdate
(
ctx
context
.
Context
,
key
string
,
ptrToType
runtime
.
Object
,
ignoreNotFound
bool
,
precondtions
*
Preconditions
,
tryUpdate
UpdateFunc
,
suggestion
...
runtime
.
Object
)
error
}
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