Merge pull request #10503 from spzala/v3argorder10431

clientV3: fix behavior of WithPrefix and WithFromKey functions
This commit is contained in:
Xiang Li 2019-03-08 11:59:17 -08:00 committed by GitHub
commit 4dc9d8b058
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 0 deletions

View File

@ -218,6 +218,10 @@ func (op Op) isWrite() bool {
// OpGet returns "get" operation based on given key and operation options.
func OpGet(key string, opts ...OpOption) Op {
// WithPrefix and WithFromKey are not supported together
if isWithPrefix(opts) && isWithFromKey(opts) {
panic("`WithPrefix` and `WithFromKey` cannot be set at the same time, choose one")
}
ret := Op{t: tRange, key: []byte(key)}
ret.applyOpts(opts)
return ret
@ -225,6 +229,10 @@ func OpGet(key string, opts ...OpOption) Op {
// OpDelete returns "delete" operation based on given key and operation options.
func OpDelete(key string, opts ...OpOption) Op {
// WithPrefix and WithFromKey are not supported together
if isWithPrefix(opts) && isWithFromKey(opts) {
panic("`WithPrefix` and `WithFromKey` cannot be set at the same time, choose one")
}
ret := Op{t: tDeleteRange, key: []byte(key)}
ret.applyOpts(opts)
switch {
@ -544,3 +552,9 @@ func toLeaseTimeToLiveRequest(id LeaseID, opts ...LeaseOption) *pb.LeaseTimeToLi
ret.applyOpts(opts)
return &pb.LeaseTimeToLiveRequest{ID: int64(id), Keys: ret.attachedKeys}
}
// isWithPrefix returns true if WithPrefix is being called in the op
func isWithPrefix(opts []OpOption) bool { return isOpFuncCalled("WithPrefix", opts) }
// isWithFromKey returns true if WithFromKey is being called in the op
func isWithFromKey(opts []OpOption) bool { return isOpFuncCalled("WithFromKey", opts) }

View File

@ -16,6 +16,9 @@ package clientv3
import (
"math/rand"
"reflect"
"runtime"
"strings"
"time"
)
@ -29,3 +32,18 @@ func jitterUp(duration time.Duration, jitter float64) time.Duration {
multiplier := jitter * (rand.Float64()*2 - 1)
return time.Duration(float64(duration) * (1 + multiplier))
}
// Check if the provided function is being called in the op options.
func isOpFuncCalled(op string, opts []OpOption) bool {
for _, opt := range opts {
v := reflect.ValueOf(opt)
if v.Kind() == reflect.Func {
if opFunc := runtime.FuncForPC(v.Pointer()); opFunc != nil {
if strings.Contains(opFunc.Name(), op) {
return true
}
}
}
}
return false
}