@@ -32,6 +32,7 @@ import (
32
32
33
33
"github.com/kubernetes-sigs/controller-runtime/pkg/client"
34
34
logf "github.com/kubernetes-sigs/controller-runtime/pkg/runtime/log"
35
+ toolscache "k8s.io/client-go/tools/cache"
35
36
)
36
37
37
38
var log = logf .KBLog .WithName ("object-cache" )
@@ -43,6 +44,7 @@ var _ client.ReadInterface = &objectCache{}
43
44
type objectCache struct {
44
45
cachesByType map [reflect.Type ]* singleObjectCache
45
46
scheme * runtime.Scheme
47
+ informers * informers
46
48
}
47
49
48
50
var _ client.ReadInterface = & objectCache {}
@@ -54,7 +56,7 @@ func (o *objectCache) addInformer(gvk schema.GroupVersionKind, c cache.SharedInd
54
56
log .Error (err , "could not register informer in objectCache for GVK" , "GroupVersionKind" , gvk )
55
57
return
56
58
}
57
- if _ , found := o . cacheFor (obj ); found {
59
+ if o . has (obj ) {
58
60
return
59
61
}
60
62
o .registerCache (obj , gvk , c .GetIndexer ())
@@ -68,18 +70,52 @@ func (o *objectCache) registerCache(obj runtime.Object, gvk schema.GroupVersionK
68
70
}
69
71
}
70
72
71
- func (o * objectCache ) cacheFor (obj runtime.Object ) ( * singleObjectCache , bool ) {
73
+ func (o * objectCache ) has (obj runtime.Object ) bool {
72
74
objType := reflect .TypeOf (obj )
75
+ _ , found := o .cachesByType [objType ]
76
+ return found
77
+ }
78
+
79
+ func (o * objectCache ) init (obj runtime.Object ) error {
80
+ i , err := o .informers .GetInformer (obj )
81
+ if err != nil {
82
+ return err
83
+ }
84
+ log .Info ("Waiting to sync cache for type." , "Type" , fmt .Sprintf ("%T" , obj ))
85
+ toolscache .WaitForCacheSync (o .informers .stop , i .HasSynced )
86
+ log .Info ("Finished to syncing cache for type." , "Type" , fmt .Sprintf ("%T" , obj ))
87
+ return nil
88
+ }
89
+
90
+ func (o * objectCache ) cacheFor (obj runtime.Object ) (* singleObjectCache , error ) {
91
+ if ! o .informers .started {
92
+ return nil , fmt .Errorf ("Must start Cache before calling Get or List %s %s" ,
93
+ "Object" , fmt .Sprintf ("%T" , obj ))
94
+ }
95
+ objType := reflect .TypeOf (obj )
96
+
73
97
cache , isKnown := o .cachesByType [objType ]
74
- return cache , isKnown
98
+ if ! isKnown {
99
+ return nil , fmt .Errorf ("No Cache found for %T. Must call GetInformer." , obj )
100
+ }
101
+ return cache , nil
75
102
}
76
103
77
104
// Get implements populatingClient.ReadInterface
78
105
func (o * objectCache ) Get (ctx context.Context , key client.ObjectKey , out runtime.Object ) error {
79
- cache , isKnown := o .cacheFor (out )
80
- if ! isKnown {
81
- return fmt .Errorf ("no cache for objects of type %T, must have asked for an watch/informer first" , out )
106
+ // Make sure there is a Cache for this type
107
+ if ! o .has (out ) {
108
+ err := o .init (out )
109
+ if err != nil {
110
+ return err
111
+ }
112
+ }
113
+
114
+ cache , err := o .cacheFor (out )
115
+ if err != nil {
116
+ return err
82
117
}
118
+
83
119
return cache .Get (ctx , key , out )
84
120
}
85
121
@@ -89,6 +125,15 @@ func (o *objectCache) List(ctx context.Context, opts *client.ListOptions, out ru
89
125
if err != nil {
90
126
return nil
91
127
}
128
+
129
+ ro , ok := itemsPtr .(runtime.Object )
130
+ if ok && ! o .has (ro ) {
131
+ err = o .init (ro )
132
+ if err != nil {
133
+ return err
134
+ }
135
+ }
136
+
92
137
// http://knowyourmeme.com/memes/this-is-fine
93
138
outType := reflect .Indirect (reflect .ValueOf (itemsPtr )).Type ().Elem ()
94
139
cache , isKnown := o .cachesByType [outType ]
0 commit comments