services/allocator/allocatord: Add owner cache
Add a cache to make checking the ownership of an instance faster. This
is currently only used by the dashboard since it will benefit from it
the most.
Change-Id: I02de555b53c48e1ec55aa72b60f0f5ff8404b14f
diff --git a/services/allocator/allocatord/cache.go b/services/allocator/allocatord/cache.go
new file mode 100644
index 0000000..be7bc4a
--- /dev/null
+++ b/services/allocator/allocatord/cache.go
@@ -0,0 +1,40 @@
+// Copyright 2016 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "sync"
+
+ "github.com/golang/groupcache/lru"
+
+ "v.io/v23/verror"
+)
+
+var (
+ ownerCache *lru.Cache
+ ownerCacheMutex sync.Mutex
+)
+
+func checkOwner(email, kName string) error {
+ ownerCacheMutex.Lock()
+ if ownerCache == nil {
+ ownerCache = lru.New(maxInstancesFlag)
+ } else if v, ok := ownerCache.Get(kName); ok {
+ ownerCacheMutex.Unlock()
+ if email != v {
+ return verror.New(verror.ErrNoExistOrNoAccess, nil)
+ }
+ return nil
+ }
+ ownerCacheMutex.Unlock()
+
+ if err := isOwnerOfInstance(email, kName); err != nil {
+ return err
+ }
+ ownerCacheMutex.Lock()
+ ownerCache.Add(kName, email)
+ ownerCacheMutex.Unlock()
+ return nil
+}
diff --git a/services/allocator/allocatord/dashboard.go b/services/allocator/allocatord/dashboard.go
index 8eb5aaa..19a6ed8 100644
--- a/services/allocator/allocatord/dashboard.go
+++ b/services/allocator/allocatord/dashboard.go
@@ -15,7 +15,6 @@
"google.golang.org/api/monitoring/v3"
- "v.io/v23/verror"
"v.io/x/lib/gcm"
)
@@ -55,15 +54,12 @@
}
func handleDashboard(ss *serverState, rs *requestState) error {
- ctx := ss.ctx
instance := rs.r.FormValue(paramDashboardName)
if instance == "" {
return fmt.Errorf("parameter %q required for instance name", paramDashboardName)
}
- if isOwner, err := isOwnerOfInstance(rs.email, kubeNameFromMountName(instance)); err != nil {
+ if err := checkOwner(rs.email, kubeNameFromMountName(instance)); err != nil {
return err
- } else if !isOwner {
- return verror.New(verror.ErrNoExistOrNoAccess, ctx)
}
tmplArgs := struct {
@@ -90,10 +86,8 @@
if mountedName == "" {
return fmt.Errorf("parameter %q required for instance name", paramDashboardName)
}
- if isOwner, err := isOwnerOfInstance(rs.email, kubeNameFromMountName(mountedName)); err != nil {
+ if err := checkOwner(rs.email, kubeNameFromMountName(mountedName)); err != nil {
return err
- } else if !isOwner {
- return verror.New(verror.ErrNoExistOrNoAccess, ctx)
}
now := time.Now()
diff --git a/services/allocator/allocatord/service.go b/services/allocator/allocatord/service.go
index d673456..2036300 100644
--- a/services/allocator/allocatord/service.go
+++ b/services/allocator/allocatord/service.go
@@ -135,10 +135,8 @@
func destroy(ctx *context.T, email, mName string) error {
kName := kubeNameFromMountName(mName)
- if isOwner, err := isOwnerOfInstance(email, kName); err != nil {
+ if err := isOwnerOfInstance(email, kName); err != nil {
return err
- } else if !isOwner {
- return verror.New(verror.ErrNoExistOrNoAccess, ctx)
}
cfg, cleanup, err := createDeploymentConfig(ctx, email, kName, mName)
@@ -321,17 +319,17 @@
return instances, nil
}
-func isOwnerOfInstance(email, kName string) (bool, error) {
+func isOwnerOfInstance(email, kName string) error {
instances, err := serverInstances(email)
if err != nil {
- return false, err
+ return err
}
for _, i := range instances {
if i.name == kName {
- return true, nil
+ return nil
}
}
- return false, nil
+ return verror.New(verror.ErrNoExistOrNoAccess, nil)
}
func createPersistentDisk(ctx *context.T, name string) error {