Skip to content

Commit 83bd3f2

Browse files
committed
linear: notifyAll could distinguish from deletion
1 parent dbfed69 commit 83bd3f2

File tree

1 file changed

+52
-11
lines changed

1 file changed

+52
-11
lines changed

pkg/cache/v3/linear.go

Lines changed: 52 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import (
2727
"github.com/envoyproxy/go-control-plane/pkg/server/stream/v3"
2828
)
2929

30-
type watches = map[chan Response]struct{}
30+
type watches = map[chan Response]stream.StreamState
3131

3232
// LinearCache supports collections of opaque resources. This cache has a
3333
// single collection indexed by resource names and manages resource versions
@@ -143,15 +143,31 @@ func (cache *LinearCache) respond(value chan Response, staleResources []string)
143143
}
144144
}
145145

146-
func (cache *LinearCache) notifyAll(modified map[string]struct{}) {
146+
func (cache *LinearCache) notifyAll(modified map[string]struct{}, fromDeletion bool) {
147147
// de-duplicate watches that need to be responded
148148
notifyList := make(map[chan Response][]string)
149-
for name := range modified {
150-
for watch := range cache.watches[name] {
151-
notifyList[watch] = append(notifyList[watch], name)
149+
if !fromDeletion {
150+
for name := range modified {
151+
for watch := range cache.watches[name] {
152+
notifyList[watch] = append(notifyList[watch], name)
153+
}
154+
delete(cache.watches, name)
155+
}
156+
} else {
157+
for deletedName := range modified {
158+
for watch, streamState := range cache.watches[deletedName] {
159+
resourceNames := streamState.GetKnownResourceNames(cache.typeURL)
160+
for resourceName := range resourceNames {
161+
// To avoid the stale in notifyList becomes empty slice.
162+
// Don't skip resource name that has been deleted here.
163+
// It would be filtered out in respond because the corresponding resource has been deleted.
164+
notifyList[watch] = append(notifyList[watch], resourceName)
165+
}
166+
}
167+
delete(cache.watches, deletedName)
152168
}
153-
delete(cache.watches, name)
154169
}
170+
155171
for value, stale := range notifyList {
156172
cache.respond(value, stale)
157173
}
@@ -173,6 +189,31 @@ func (cache *LinearCache) notifyAll(modified map[string]struct{}) {
173189
}
174190
}
175191

192+
func (cache *LinearCache) notifyAllFromDeletion(modified map[string]struct{}) {
193+
notifyList := make(map[chan Response][]string)
194+
for deletedName := range modified {
195+
for watch, streamState := range cache.watches[deletedName] {
196+
names := streamState.GetKnownResourceNames(cache.typeURL)
197+
for name := range names {
198+
if name == deletedName {
199+
// skip the resource name has been deleted.
200+
continue
201+
}
202+
notifyList[watch] = append(notifyList[watch], name)
203+
}
204+
}
205+
delete(cache.watches, deletedName)
206+
}
207+
208+
for value, stale := range notifyList {
209+
cache.respond(value, stale)
210+
}
211+
212+
for value := range cache.watchAll {
213+
cache.respond(value, nil)
214+
}
215+
}
216+
176217
func (cache *LinearCache) respondDelta(request *DeltaRequest, value chan DeltaResponse, state stream.StreamState) *RawDeltaResponse {
177218
resp := createDeltaResponse(context.Background(), request, state, resourceContainer{
178219
resourceMap: cache.resources,
@@ -205,7 +246,7 @@ func (cache *LinearCache) UpdateResource(name string, res types.Resource) error
205246
cache.resources[name] = res
206247

207248
// TODO: batch watch closures to prevent rapid updates
208-
cache.notifyAll(map[string]struct{}{name: {}})
249+
cache.notifyAll(map[string]struct{}{name: {}}, false)
209250

210251
return nil
211252
}
@@ -220,7 +261,7 @@ func (cache *LinearCache) DeleteResource(name string) error {
220261
delete(cache.resources, name)
221262

222263
// TODO: batch watch closures to prevent rapid updates
223-
cache.notifyAll(map[string]struct{}{name: {}})
264+
cache.notifyAll(map[string]struct{}{name: {}}, true)
224265
return nil
225266
}
226267

@@ -252,7 +293,7 @@ func (cache *LinearCache) SetResources(resources map[string]types.Resource) {
252293
modified[name] = struct{}{}
253294
}
254295

255-
cache.notifyAll(modified)
296+
cache.notifyAll(modified, false)
256297
}
257298

258299
// GetResources returns current resources stored in the cache
@@ -315,7 +356,7 @@ func (cache *LinearCache) CreateWatch(request *Request, streamState stream.Strea
315356
}
316357
// Create open watches since versions are up to date.
317358
if len(request.ResourceNames) == 0 {
318-
cache.watchAll[value] = struct{}{}
359+
cache.watchAll[value] = streamState
319360
return func() {
320361
cache.mu.Lock()
321362
defer cache.mu.Unlock()
@@ -328,7 +369,7 @@ func (cache *LinearCache) CreateWatch(request *Request, streamState stream.Strea
328369
set = make(watches)
329370
cache.watches[name] = set
330371
}
331-
set[value] = struct{}{}
372+
set[value] = streamState
332373
}
333374
return func() {
334375
cache.mu.Lock()

0 commit comments

Comments
 (0)