@@ -41,15 +41,15 @@ type CloserSyncingSource interface {
41
41
}
42
42
43
43
type sourcerer interface {
44
- // Source returns a CloserSyncingSource for the provided
45
- // GroupVersionKind. If the CloserSyncingSource encounters an
44
+ // Source returns a CloserSyncingSource for the provided namespace
45
+ // and GroupVersionKind. If the CloserSyncingSource encounters an
46
46
// error after having initially synced, it should requeue the
47
47
// provided client.Object and call the provided callback function
48
- Source (schema.GroupVersionKind , client.Object , func (context.Context )) (CloserSyncingSource , error )
48
+ Source (string , schema.GroupVersionKind , client.Object , func (context.Context )) (CloserSyncingSource , error )
49
49
}
50
50
51
51
type cache struct {
52
- sources map [schema. GroupVersionKind ]CloserSyncingSource
52
+ sources map [sourceKey ]CloserSyncingSource
53
53
sourcerer sourcerer
54
54
owner client.Object
55
55
syncTimeout time.Duration
@@ -58,7 +58,7 @@ type cache struct {
58
58
59
59
func NewCache (sourcerer sourcerer , owner client.Object , syncTimeout time.Duration ) Cache {
60
60
return & cache {
61
- sources : make (map [schema. GroupVersionKind ]CloserSyncingSource ),
61
+ sources : make (map [sourceKey ]CloserSyncingSource ),
62
62
sourcerer : sourcerer ,
63
63
owner : owner ,
64
64
syncTimeout : syncTimeout ,
@@ -70,15 +70,15 @@ var _ Cache = (*cache)(nil)
70
70
func (c * cache ) Watch (ctx context.Context , watcher Watcher , objs ... client.Object ) error {
71
71
c .mu .Lock ()
72
72
defer c .mu .Unlock ()
73
- gvkSet , err := gvksForObjects (objs ... )
73
+ sourceKeySet , err := sourceKeysForObjects (objs ... )
74
74
if err != nil {
75
75
return fmt .Errorf ("getting set of GVKs for managed objects: %w" , err )
76
76
}
77
77
78
- if err := c .removeStaleSources (gvkSet ); err != nil {
78
+ if err := c .removeStaleSources (sourceKeySet ); err != nil {
79
79
return fmt .Errorf ("removing stale sources: %w" , err )
80
80
}
81
- return c .startNewSources (ctx , gvkSet , watcher )
81
+ return c .startNewSources (ctx , sourceKeySet , watcher )
82
82
}
83
83
84
84
func (c * cache ) Close () error {
@@ -99,29 +99,35 @@ func (c *cache) Close() error {
99
99
return errors .Join (errs ... )
100
100
}
101
101
102
- func (c * cache ) startNewSources (ctx context.Context , gvks sets.Set [schema.GroupVersionKind ], watcher Watcher ) error {
103
- cacheGvks := c .getCacheGVKs ()
104
- gvksToCreate := gvks .Difference (cacheGvks )
102
+ type sourceKey struct {
103
+ namespace string
104
+ gvk schema.GroupVersionKind
105
+ }
105
106
107
+ func (c * cache ) startNewSources (ctx context.Context , sources sets.Set [sourceKey ], watcher Watcher ) error {
106
108
type startResult struct {
107
109
source CloserSyncingSource
108
- gvk schema. GroupVersionKind
110
+ key sourceKey
109
111
err error
110
112
}
111
113
startResults := make (chan startResult )
112
114
wg := sync.WaitGroup {}
113
- for _ , gvk := range gvksToCreate .UnsortedList () {
115
+
116
+ existingSourceKeys := c .getCacheKeys ()
117
+ sourcesToCreate := sources .Difference (existingSourceKeys )
118
+ for _ , srcKey := range sourcesToCreate .UnsortedList () {
114
119
wg .Add (1 )
115
120
go func () {
116
121
defer wg .Done ()
117
- source , err := c .startNewSource (ctx , gvk , watcher )
122
+ source , err := c .startNewSource (ctx , srcKey , watcher )
118
123
startResults <- startResult {
119
124
source : source ,
120
- gvk : gvk ,
125
+ key : srcKey ,
121
126
err : err ,
122
127
}
123
128
}()
124
129
}
130
+
125
131
go func () {
126
132
wg .Wait ()
127
133
close (startResults )
@@ -134,7 +140,7 @@ func (c *cache) startNewSources(ctx context.Context, gvks sets.Set[schema.GroupV
134
140
continue
135
141
}
136
142
137
- err := c .addSource (result .gvk , result .source )
143
+ err := c .addSource (result .key , result .source )
138
144
if err != nil {
139
145
// If we made it here then there is a logic error in
140
146
// calculating the diffs between what is currently being
@@ -146,20 +152,19 @@ func (c *cache) startNewSources(ctx context.Context, gvks sets.Set[schema.GroupV
146
152
slices .SortFunc (sourcesErrors , func (a , b error ) int {
147
153
return strings .Compare (a .Error (), b .Error ())
148
154
})
149
-
150
155
return errors .Join (sourcesErrors ... )
151
156
}
152
157
153
- func (c * cache ) startNewSource (ctx context.Context , gvk schema. GroupVersionKind , watcher Watcher ) (CloserSyncingSource , error ) {
154
- s , err := c .sourcerer .Source (gvk , c .owner , func (ctx context.Context ) {
158
+ func (c * cache ) startNewSource (ctx context.Context , srcKey sourceKey , watcher Watcher ) (CloserSyncingSource , error ) {
159
+ s , err := c .sourcerer .Source (srcKey . namespace , srcKey . gvk , c .owner , func (ctx context.Context ) {
155
160
// this callback function ensures that we remove the source from the
156
161
// cache if it encounters an error after it initially synced successfully
157
162
c .mu .Lock ()
158
163
defer c .mu .Unlock ()
159
- err := c .removeSource (gvk )
164
+ err := c .removeSource (srcKey )
160
165
if err != nil {
161
166
logr := log .FromContext (ctx )
162
- logr .Error (err , "managed content cache postSyncError removing source failed" , "gvk" , gvk )
167
+ logr .Error (err , "managed content cache postSyncError removing source failed" , "namespace" , srcKey . namespace , " gvk" , srcKey . gvk )
163
168
}
164
169
})
165
170
if err != nil {
@@ -168,7 +173,7 @@ func (c *cache) startNewSource(ctx context.Context, gvk schema.GroupVersionKind,
168
173
169
174
err = watcher .Watch (s )
170
175
if err != nil {
171
- return nil , fmt .Errorf ("establishing watch for GVK %q: %w" , gvk , err )
176
+ return nil , fmt .Errorf ("establishing watch for GVK %q in namespace %q : %w" , srcKey . gvk , srcKey . namespace , err )
172
177
}
173
178
174
179
syncCtx , syncCancel := context .WithTimeout (ctx , c .syncTimeout )
@@ -181,19 +186,19 @@ func (c *cache) startNewSource(ctx context.Context, gvk schema.GroupVersionKind,
181
186
return s , nil
182
187
}
183
188
184
- func (c * cache ) addSource (gvk schema. GroupVersionKind , source CloserSyncingSource ) error {
185
- if _ , ok := c .sources [gvk ]; ! ok {
186
- c .sources [gvk ] = source
189
+ func (c * cache ) addSource (key sourceKey , source CloserSyncingSource ) error {
190
+ if _ , ok := c .sources [key ]; ! ok {
191
+ c .sources [key ] = source
187
192
return nil
188
193
}
189
194
return errors .New ("source already exists" )
190
195
}
191
196
192
- func (c * cache ) removeStaleSources (gvks sets.Set [schema. GroupVersionKind ]) error {
193
- cacheGvks := c .getCacheGVKs ()
197
+ func (c * cache ) removeStaleSources (srcKeys sets.Set [sourceKey ]) error {
198
+ existingSrcKeys := c .getCacheKeys ()
194
199
removeErrs := []error {}
195
- gvksToRemove := cacheGvks .Difference (gvks )
196
- for _ , gvk := range gvksToRemove .UnsortedList () {
200
+ srcKeysToRemove := existingSrcKeys .Difference (srcKeys )
201
+ for _ , gvk := range srcKeysToRemove .UnsortedList () {
197
202
err := c .removeSource (gvk )
198
203
if err != nil {
199
204
removeErrs = append (removeErrs , err )
@@ -207,23 +212,23 @@ func (c *cache) removeStaleSources(gvks sets.Set[schema.GroupVersionKind]) error
207
212
return errors .Join (removeErrs ... )
208
213
}
209
214
210
- func (c * cache ) removeSource (gvk schema. GroupVersionKind ) error {
211
- if source , ok := c .sources [gvk ]; ok {
212
- err := source .Close ()
215
+ func (c * cache ) removeSource (srcKey sourceKey ) error {
216
+ if src , ok := c .sources [srcKey ]; ok {
217
+ err := src .Close ()
213
218
if err != nil {
214
- return fmt .Errorf ("closing source for GVK %q: %w" , gvk , err )
219
+ return fmt .Errorf ("closing source for GVK %q in namespace %q : %w" , srcKey . gvk , srcKey . namespace , err )
215
220
}
216
221
}
217
- delete (c .sources , gvk )
222
+ delete (c .sources , srcKey )
218
223
return nil
219
224
}
220
225
221
- func (c * cache ) getCacheGVKs () sets.Set [schema. GroupVersionKind ] {
222
- cacheGvks := sets .New [schema. GroupVersionKind ]()
223
- for gvk := range c .sources {
224
- cacheGvks .Insert (gvk )
226
+ func (c * cache ) getCacheKeys () sets.Set [sourceKey ] {
227
+ sourceKeys := sets .New [sourceKey ]()
228
+ for key := range c .sources {
229
+ sourceKeys .Insert (key )
225
230
}
226
- return cacheGvks
231
+ return sourceKeys
227
232
}
228
233
229
234
// gvksForObjects builds a sets.Set of GroupVersionKinds for
@@ -233,9 +238,10 @@ func (c *cache) getCacheGVKs() sets.Set[schema.GroupVersionKind] {
233
238
//
234
239
// An empty Group is assumed to be the "core" Kubernetes
235
240
// API group.
236
- func gvksForObjects (objs ... client.Object ) (sets.Set [schema. GroupVersionKind ], error ) {
237
- gvkSet := sets .New [schema. GroupVersionKind ]()
241
+ func sourceKeysForObjects (objs ... client.Object ) (sets.Set [sourceKey ], error ) {
242
+ sourceKeys := sets .New [sourceKey ]()
238
243
for _ , obj := range objs {
244
+ ns := obj .GetNamespace ()
239
245
gvk := obj .GetObjectKind ().GroupVersionKind ()
240
246
241
247
// If the Kind or Version is not set in an object's GroupVersionKind
@@ -257,8 +263,8 @@ func gvksForObjects(objs ...client.Object) (sets.Set[schema.GroupVersionKind], e
257
263
)
258
264
}
259
265
260
- gvkSet .Insert (gvk )
266
+ sourceKeys .Insert (sourceKey { ns , gvk } )
261
267
}
262
268
263
- return gvkSet , nil
269
+ return sourceKeys , nil
264
270
}
0 commit comments