Fscache support for multiple kubernetes objects (#435)

Modifies the fsCache to support a list of arbitrary kubernetes objects instead of just one pod.  This allows better support for the newdeploy backend.

Also removes the byKubeObject cache index; cleanup is changed to use the byFunction index, and byKubeObject is no longer needed.
This commit is contained in:
Vishal
2018-01-16 13:05:24 -08:00
committed by Soam Vasani
parent 80a4bcbcff
commit bed189c715
3 changed files with 96 additions and 126 deletions
+29 -76
View File
@@ -35,7 +35,6 @@ const (
TOUCH fscRequestType = iota
LISTOLD
LOG
DELETE_BY_OBJECT
)
const (
@@ -45,33 +44,32 @@ const (
type (
FuncSvc struct {
Function *metav1.ObjectMeta // function this pod/service is for
Environment *crd.Environment // function's environment
Address string // Host:Port or IP:Port that the function's service can be reached at.
KubernetesObject api.ObjectReference // Kubernetes Object (within the function namespace)
Backend backendType
Function *metav1.ObjectMeta // function this pod/service is for
Environment *crd.Environment // function's environment
Address string // Host:Port or IP:Port that the function's service can be reached at.
KubernetesObjects []api.ObjectReference // Kubernetes Objects (within the function namespace)
Backend backendType
Ctime time.Time
Atime time.Time
}
FunctionServiceCache struct {
byFunction *cache.Cache // function-key -> funcSvc : map[string]*funcSvc
byAddress *cache.Cache // address -> function : map[string]metav1.ObjectMeta
byKubeObject *cache.Cache // obj -> function : map[api.ObjectReference]metav1.ObjectMeta
byFunction *cache.Cache // function-key -> funcSvc : map[string]*funcSvc
byAddress *cache.Cache // address -> function : map[string]metav1.ObjectMeta
requestChannel chan *fscRequest
}
fscRequest struct {
requestType fscRequestType
address string
kubernetesObject api.ObjectReference
age time.Duration
env *metav1.ObjectMeta // used for ListOld
responseChannel chan *fscResponse
requestType fscRequestType
address string
kubernetesObjects []api.ObjectReference
age time.Duration
env *metav1.ObjectMeta // used for ListOld
responseChannel chan *fscResponse
}
fscResponse struct {
objects []api.ObjectReference
objects []*FuncSvc
deleted bool
error
}
@@ -81,7 +79,6 @@ func MakeFunctionServiceCache() *FunctionServiceCache {
fsc := &FunctionServiceCache{
byFunction: cache.MakeCache(0, 0),
byAddress: cache.MakeCache(0, 0),
byKubeObject: cache.MakeCache(0, 0),
requestChannel: make(chan *fscRequest),
}
go fsc.service()
@@ -98,33 +95,25 @@ func (fsc *FunctionServiceCache) service() {
resp.error = fsc._touchByAddress(req.address)
case LISTOLD:
// get svcs idle for > req.age
byKubeObjectCopy := fsc.byKubeObject.Copy()
kubeObjects := make([]api.ObjectReference, 0)
for objI, mI := range byKubeObjectCopy {
m := mI.(metav1.ObjectMeta)
fsvcI, err := fsc.byFunction.Get(crd.CacheKey(&m))
if err != nil {
resp.error = err
} else {
fsvc := fsvcI.(*FuncSvc)
if fsvc.Environment.Metadata.UID == req.env.UID &&
time.Now().Sub(fsvc.Atime) > req.age {
obj := objI.(api.ObjectReference)
kubeObjects = append(kubeObjects, obj)
}
fscs := fsc.byFunction.Copy()
funcObjects := make([]*FuncSvc, 0)
for _, funcSvc := range fscs {
fsvc := funcSvc.(*FuncSvc)
if fsvc.Environment.Metadata.UID == req.env.UID &&
time.Now().Sub(fsvc.Atime) > req.age {
funcObjects = append(funcObjects, fsvc)
}
}
resp.objects = kubeObjects
resp.objects = funcObjects
case LOG:
funcCopy := fsc.byFunction.Copy()
log.Printf("Cache has %v entries", len(funcCopy))
for key, fsvcI := range funcCopy {
fsvc := fsvcI.(*FuncSvc)
log.Printf("%v\t%v\t%v", key, fsvc.KubernetesObject.Kind, fsvc.KubernetesObject.Name)
for _, kubeObj := range fsvc.KubernetesObjects {
log.Printf("%v\t%v\t%v", key, kubeObj.Kind, kubeObj.Name)
}
}
case DELETE_BY_OBJECT:
resp.deleted, resp.error = fsc._deleteByKubeObject(req.kubernetesObject, req.age)
}
req.responseChannel <- resp
}
@@ -165,7 +154,7 @@ func (fsc *FunctionServiceCache) Add(fsvc FuncSvc) (error, *FuncSvc) {
fsvc.Ctime = now
fsvc.Atime = now
// Add to byAddress and byKubernetesObject caches. Ignore NameExists errors
// Add to byAddress cache. Ignore NameExists errors
// because of multiple-specialization. See issue #331.
err, _ = fsc.byAddress.Set(fsvc.Address, *fsvc.Function)
if err != nil {
@@ -177,16 +166,6 @@ func (fsc *FunctionServiceCache) Add(fsvc FuncSvc) (error, *FuncSvc) {
log.Printf("error caching fsvc: %v", err)
return err, nil
}
err, _ = fsc.byKubeObject.Set(fsvc.KubernetesObject, *fsvc.Function)
if err != nil {
if fe, ok := err.(fission.Error); ok {
if fe.Code == fission.ErrorNameExists {
err = nil
}
}
log.Printf("error caching fsvc: %v", err)
return err, nil
}
return nil, nil
}
@@ -216,44 +195,18 @@ func (fsc *FunctionServiceCache) _touchByAddress(address string) error {
return nil
}
func (fsc *FunctionServiceCache) DeleteByKubeObject(obj api.ObjectReference, minAge time.Duration) (bool, error) {
responseChannel := make(chan *fscResponse)
fsc.requestChannel <- &fscRequest{
requestType: DELETE_BY_OBJECT,
kubernetesObject: obj,
age: minAge,
responseChannel: responseChannel,
}
resp := <-responseChannel
return resp.deleted, resp.error
}
// _deleteByKubeObject deletes the entry keyed by Kubernetes Object, but only if it is
// at least minAge old.
func (fsc *FunctionServiceCache) _deleteByKubeObject(obj api.ObjectReference, minAge time.Duration) (bool, error) {
mI, err := fsc.byKubeObject.Get(obj)
if err != nil {
return false, err
}
m := mI.(metav1.ObjectMeta)
fsvcI, err := fsc.byFunction.Get(crd.CacheKey(&m))
if err != nil {
return false, err
}
fsvc := fsvcI.(*FuncSvc)
func (fsc *FunctionServiceCache) DeleteOld(fsvc *FuncSvc, minAge time.Duration) (bool, error) {
if time.Now().Sub(fsvc.Atime) < minAge {
return false, nil
}
fsc.byFunction.Delete(crd.CacheKey(&m))
fsc.byFunction.Delete(crd.CacheKey(fsvc.Function))
fsc.byAddress.Delete(fsvc.Address)
fsc.byKubeObject.Delete(obj)
return true, nil
}
func (fsc *FunctionServiceCache) ListOld(env *metav1.ObjectMeta, age time.Duration) ([]api.ObjectReference, error) {
func (fsc *FunctionServiceCache) ListOld(env *metav1.ObjectMeta, age time.Duration) ([]*FuncSvc, error) {
responseChannel := make(chan *fscResponse)
fsc.requestChannel <- &fscRequest{
requestType: LISTOLD,