Fnlb/k8s grouper (#563)

* WIP: add k8s grouper

- This shares a great deal of behaviour with allGrouper. Once it's
tested, refactor that to share as much as possible

- Glide hell. Checked in the yaml and lock files but a glide i -v
will be required to bring vendor/ up-to-date. Will address once this
is ready.

* Update README. Make the watch tracking work.

(To follow: add the junk that was pulled in via the glide update.)

* Vendor updates.

* go fmt

* Use the allGrouper with a k8s-backed DBStore instead.

This is much tidier :-)

* Fix up go vet
This commit is contained in:
jan grant
2017-12-06 18:45:27 +00:00
committed by Reed Allman
parent 53a2b2702a
commit 8fc4bdcf97
2626 changed files with 626646 additions and 89487 deletions

View File

@@ -133,11 +133,11 @@ const (
// Note that this will always cause rpc tests to fail, since they need io.EOF sent via panic.
recoverPanicToErr = true
// resetSliceElemToZeroValue: on decoding a slice, reset the element to a zero value first.
// concern: if the slice already contained some garbage, we will decode into that garbage.
// if resetSliceElemToZeroValue, then on decoding a slice, reset the element to a zero value first.
// Only concern is that, if the slice already contained some garbage, we will decode into that garbage.
// The chances of this are slim, so leave this "optimization".
// TODO: should this be true, to ensure that we always decode into a "zero" "empty" value?
resetSliceElemToZeroValue = false
resetSliceElemToZeroValue bool = false
)
var (
@@ -250,8 +250,6 @@ type jsonUnmarshaler interface {
UnmarshalJSON([]byte) error
}
// type byteAccepter func(byte) bool
var (
bigen = binary.BigEndian
structInfoFieldName = "_struct"
@@ -280,17 +278,17 @@ var (
selferTyp = reflect.TypeOf((*Selfer)(nil)).Elem()
uint8SliceTypId = rt2id(uint8SliceTyp)
rawExtTypId = rt2id(rawExtTyp)
rawTypId = rt2id(rawTyp)
intfTypId = rt2id(intfTyp)
timeTypId = rt2id(timeTyp)
stringTypId = rt2id(stringTyp)
uint8SliceTypId = reflect.ValueOf(uint8SliceTyp).Pointer()
rawExtTypId = reflect.ValueOf(rawExtTyp).Pointer()
rawTypId = reflect.ValueOf(rawTyp).Pointer()
intfTypId = reflect.ValueOf(intfTyp).Pointer()
timeTypId = reflect.ValueOf(timeTyp).Pointer()
stringTypId = reflect.ValueOf(stringTyp).Pointer()
mapStrIntfTypId = rt2id(mapStrIntfTyp)
mapIntfIntfTypId = rt2id(mapIntfIntfTyp)
intfSliceTypId = rt2id(intfSliceTyp)
// mapBySliceTypId = rt2id(mapBySliceTyp)
mapStrIntfTypId = reflect.ValueOf(mapStrIntfTyp).Pointer()
mapIntfIntfTypId = reflect.ValueOf(mapIntfIntfTyp).Pointer()
intfSliceTypId = reflect.ValueOf(intfSliceTyp).Pointer()
// mapBySliceTypId = reflect.ValueOf(mapBySliceTyp).Pointer()
intBitsize uint8 = uint8(reflect.TypeOf(int(0)).Bits())
uintBitsize uint8 = uint8(reflect.TypeOf(uint(0)).Bits())
@@ -305,24 +303,6 @@ var (
var defTypeInfos = NewTypeInfos([]string{"codec", "json"})
var immutableKindsSet = [32]bool{
reflect.Int: true,
reflect.Int8: true,
reflect.Int16: true,
reflect.Int32: true,
reflect.Int64: true,
reflect.Uint: true,
reflect.Uint8: true,
reflect.Uint16: true,
reflect.Uint32: true,
reflect.Uint64: true,
reflect.Uintptr: true,
reflect.Float32: true,
reflect.Float64: true,
reflect.Bool: true,
reflect.String: true,
}
// Selfer defines methods by which a value can encode or decode itself.
//
// Any type which implements Selfer will be able to encode or decode itself.
@@ -363,10 +343,10 @@ func (x *BasicHandle) getBasicHandle() *BasicHandle {
}
func (x *BasicHandle) getTypeInfo(rtid uintptr, rt reflect.Type) (pti *typeInfo) {
if x.TypeInfos == nil {
return defTypeInfos.get(rtid, rt)
if x.TypeInfos != nil {
return x.TypeInfos.get(rtid, rt)
}
return x.TypeInfos.get(rtid, rt)
return defTypeInfos.get(rtid, rt)
}
// Handle is the interface for a specific encoding format.
@@ -496,6 +476,9 @@ func (x *setExtWrapper) UpdateExt(dest interface{}, v interface{}) {
x.i.UpdateExt(dest, v)
}
// type errorString string
// func (x errorString) Error() string { return string(x) }
type binaryEncodingType struct{}
func (_ binaryEncodingType) isBinary() bool { return true }
@@ -576,7 +559,7 @@ func (o *extHandle) SetExt(rt reflect.Type, tag uint64, ext Ext) (err error) {
return
}
rtid := rt2id(rt)
rtid := reflect.ValueOf(rt).Pointer()
for _, v := range *o {
if v.rtid == rtid {
v.tag, v.ext = tag, ext
@@ -728,7 +711,6 @@ type typeInfo struct {
rt reflect.Type
rtid uintptr
// rv0 reflect.Value // saved zero value, used if immutableKind
numMeth uint16 // number of methods
@@ -761,49 +743,42 @@ type typeInfo struct {
toArray bool // whether this (struct) type should be encoded as an array
}
// linear search. faster than binary search in my testing up to 16-field structs.
const binarySearchThreshold = 8 // similar to what python does for hashtables
func (ti *typeInfo) indexForEncName(name string) int {
// NOTE: name may be a stringView, so don't pass it to another function.
//tisfi := ti.sfi
sfilen := len(ti.sfi)
if sfilen < binarySearchThreshold {
const binarySearchThreshold = 16
if sfilen := len(ti.sfi); sfilen < binarySearchThreshold {
// linear search. faster than binary search in my testing up to 16-field structs.
for i, si := range ti.sfi {
if si.encName == name {
return i
}
}
return -1
}
// binary search. adapted from sort/search.go.
h, i, j := 0, 0, sfilen
for i < j {
h = i + (j-i)/2
if ti.sfi[h].encName < name {
i = h + 1
} else {
j = h
} else {
// binary search. adapted from sort/search.go.
h, i, j := 0, 0, sfilen
for i < j {
h = i + (j-i)/2
if ti.sfi[h].encName < name {
i = h + 1
} else {
j = h
}
}
if i < sfilen && ti.sfi[i].encName == name {
return i
}
}
if i < sfilen && ti.sfi[i].encName == name {
return i
}
return -1
}
type rtid2ti struct {
rtid uintptr
ti *typeInfo
}
// TypeInfos caches typeInfo for each type on first inspection.
//
// It is configured with a set of tag keys, which are used to get
// configuration for the type.
type TypeInfos struct {
infos atomicTypeInfoSlice // formerly map[uintptr]*typeInfo, now *[]rtid2ti
mu sync.Mutex
infos map[uintptr]*typeInfo
mu sync.RWMutex
tags []string
}
@@ -812,7 +787,7 @@ type TypeInfos struct {
// This allows users customize the struct tag keys which contain configuration
// of their types.
func NewTypeInfos(tags []string) *TypeInfos {
return &TypeInfos{tags: tags}
return &TypeInfos{tags: tags, infos: make(map[uintptr]*typeInfo, 64)}
}
func (x *TypeInfos) structTag(t reflect.StructTag) (s string) {
@@ -827,46 +802,20 @@ func (x *TypeInfos) structTag(t reflect.StructTag) (s string) {
return
}
func (x *TypeInfos) find(sp *[]rtid2ti, rtid uintptr) (idx int, ti *typeInfo) {
// binary search. adapted from sort/search.go.
// fmt.Printf(">>>> calling typeinfos.find ... \n")
// if sp == nil {
// return -1, nil
// }
s := *sp
h, i, j := 0, 0, len(s)
for i < j {
h = i + (j-i)/2
if s[h].rtid < rtid {
i = h + 1
} else {
j = h
}
}
if i < len(s) && s[i].rtid == rtid {
return i, s[i].ti
}
return i, nil
}
func (x *TypeInfos) get(rtid uintptr, rt reflect.Type) (pti *typeInfo) {
// fmt.Printf(">>>> calling typeinfos.get ... \n")
sp := x.infos.load()
var idx int
if sp != nil {
idx, pti = x.find(sp, rtid)
if pti != nil {
return
}
var ok bool
x.mu.RLock()
pti, ok = x.infos[rtid]
x.mu.RUnlock()
if ok {
return
}
// do not hold lock while computing this.
// it may lead to duplication, but that's ok.
ti := typeInfo{rt: rt, rtid: rtid}
// ti.rv0 = reflect.Zero(rt)
ti.numMeth = uint16(rt.NumMethod())
var ok bool
var indir int8
if ok, indir = implementsIntf(rt, binaryMarshalerTyp); ok {
ti.bm, ti.bmIndir = true, indir
@@ -905,7 +854,7 @@ func (x *TypeInfos) get(rtid uintptr, rt reflect.Type) (pti *typeInfo) {
ti.baseId = rtid
} else {
ti.base = pt
ti.baseId = rt2id(pt)
ti.baseId = reflect.ValueOf(pt).Pointer()
ti.baseIndir = ptIndir
}
@@ -926,28 +875,12 @@ func (x *TypeInfos) get(rtid uintptr, rt reflect.Type) (pti *typeInfo) {
}
// sfi = sfip
var vs []rtid2ti
x.mu.Lock()
sp = x.infos.load()
if sp == nil {
// fmt.Printf(">>>> in typeinfos.get: sp == nil\n")
if pti, ok = x.infos[rtid]; !ok {
pti = &ti
vs = []rtid2ti{{rtid, pti}}
x.infos.store(&vs)
} else {
idx, pti = x.find(sp, rtid)
if pti == nil {
s := *sp
pti = &ti
vs = make([]rtid2ti, len(s)+1)
copy(vs, s[:idx])
vs[idx] = rtid2ti{rtid, pti}
copy(vs[idx+1:], s[idx:])
x.infos.store(&vs)
}
x.infos[rtid] = pti
}
x.mu.Unlock()
// fmt.Printf(">>>>>>> TypeInfos: Num Elements: %v\n", len(*(x.infos.load())))
return
}
@@ -999,7 +932,7 @@ LOOP:
}
if ft.Kind() == reflect.Struct {
// if etypes contains this, don't call rget again (as fields are already seen here)
ftid := rt2id(ft)
ftid := reflect.ValueOf(ft).Pointer()
// We cannot recurse forever, but we need to track other field depths.
// So - we break if we see a type twice (not the first time).
// This should be sufficient to handle an embedded type that refers to its
@@ -1132,23 +1065,22 @@ func panicToErr(err *error) {
// }
func isImmutableKind(k reflect.Kind) (v bool) {
return immutableKindsSet[k]
// return false ||
// k == reflect.Int ||
// k == reflect.Int8 ||
// k == reflect.Int16 ||
// k == reflect.Int32 ||
// k == reflect.Int64 ||
// k == reflect.Uint ||
// k == reflect.Uint8 ||
// k == reflect.Uint16 ||
// k == reflect.Uint32 ||
// k == reflect.Uint64 ||
// k == reflect.Uintptr ||
// k == reflect.Float32 ||
// k == reflect.Float64 ||
// k == reflect.Bool ||
// k == reflect.String
return false ||
k == reflect.Int ||
k == reflect.Int8 ||
k == reflect.Int16 ||
k == reflect.Int32 ||
k == reflect.Int64 ||
k == reflect.Uint ||
k == reflect.Uint8 ||
k == reflect.Uint16 ||
k == reflect.Uint32 ||
k == reflect.Uint64 ||
k == reflect.Uintptr ||
k == reflect.Float32 ||
k == reflect.Float64 ||
k == reflect.Bool ||
k == reflect.String
}
// these functions must be inlinable, and not call anybody