-
Notifications
You must be signed in to change notification settings - Fork 24
Expand file tree
/
Copy pathcache.go
More file actions
99 lines (86 loc) · 3.07 KB
/
cache.go
File metadata and controls
99 lines (86 loc) · 3.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package k8s
import (
"fmt"
"time"
"github.com/go-logr/logr"
"github.com/pmylund/go-cache"
"k8s.io/apimachinery/pkg/types"
"github.com/jetstack/preflight/api"
)
// time interface, this is used to fetch the current time
// whenever a k8s resource is deleted
type timeInterface interface {
now() time.Time
}
var clock timeInterface = &realTime{}
type realTime struct {
}
func (*realTime) now() time.Time {
return time.Now()
}
type cacheResource interface {
GetUID() types.UID
GetNamespace() string
}
func logCacheUpdateFailure(log logr.Logger, obj interface{}, operation string) {
// We use WithCallStackHelper to ensure the correct caller line numbers in the log messages
helper, log := log.WithCallStackHelper()
helper()
err := fmt.Errorf("not a cacheResource type: %T missing metadata/uid field", obj)
log.Error(err, "Cache update failure", "operation", operation)
}
// onAdd handles the informer creation events, adding the created runtime.Object
// to the data gatherer's cache. The cache key is the uid of the object
func onAdd(log logr.Logger, obj interface{}, dgCache *cache.Cache) {
item, ok := obj.(cacheResource)
if ok {
cacheObject := &api.GatheredResource{
Resource: obj,
}
dgCache.Set(string(item.GetUID()), cacheObject, cache.DefaultExpiration)
return
}
logCacheUpdateFailure(log, obj, "add")
}
// onUpdate handles the informer update events, replacing the old object with the new one
// if it's present in the data gatherer's cache, (if the object isn't present, it gets added).
// The cache key is the uid of the object
func onUpdate(log logr.Logger, old, new interface{}, dgCache *cache.Cache) {
item, ok := old.(cacheResource)
if ok {
cacheObject := updateCacheGatheredResource(string(item.GetUID()), new, dgCache)
dgCache.Set(string(item.GetUID()), cacheObject, cache.DefaultExpiration)
return
}
logCacheUpdateFailure(log, old, "update")
}
// onDelete handles the informer deletion events, updating the object's properties with the deletion
// time of the object (but not removing the object from the cache).
// The cache key is the uid of the object
func onDelete(log logr.Logger, obj interface{}, dgCache *cache.Cache) {
item, ok := obj.(cacheResource)
if ok {
cacheObject := updateCacheGatheredResource(string(item.GetUID()), obj, dgCache)
cacheObject.DeletedAt = api.Time{Time: clock.now()}
dgCache.Set(string(item.GetUID()), cacheObject, cache.DefaultExpiration)
return
}
logCacheUpdateFailure(log, obj, "delete")
}
// creates a new updated instance of a cache object, with the resource
// argument. If the object is present in the cache it fetches the object's
// properties.
func updateCacheGatheredResource(cacheKey string, resource interface{}, dgCache *cache.Cache) *api.GatheredResource {
// updated cache object
cacheObject := &api.GatheredResource{
Resource: resource,
}
// update the object's properties, if it's already in the cache
if o, ok := dgCache.Get(cacheKey); ok {
deletedAt := o.(*api.GatheredResource).DeletedAt
if deletedAt.IsZero() && !deletedAt.IsZero() {
cacheObject.DeletedAt = deletedAt
}
}
return cacheObject
}