@@ -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+
176217func (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