@@ -40,15 +40,17 @@ type DeltaRequest = discovery.DeltaDiscoveryRequest
4040// Though the methods may return mutable parts of the state for performance reasons,
4141// the cache is expected to consider this state as immutable and thread safe between a watch creation and its cancellation.
4242type Subscription interface {
43- // ReturnedResources returns a list of resources that were sent to the client and their associated versions.
43+ // ReturnedResources returns the list of resources the client currently knows and their associated versions.
4444 // The versions are:
4545 // - delta protocol: version of the specific resource set in the response.
4646 // - sotw protocol: version of the global response when the resource was last sent.
47+ // The returned map must not be altered by the Cache.
4748 ReturnedResources () map [string ]string
4849
4950 // SubscribedResources returns the list of resources currently subscribed to by the client for the type.
5051 // For delta it keeps track of subscription updates across requests
5152 // For sotw it is a normalized view of the last request resources
53+ // The returned map must not be altered by the Cache.
5254 SubscribedResources () map [string ]struct {}
5355
5456 // IsWildcard returns whether the client has a wildcard watch.
@@ -118,6 +120,11 @@ type Response interface {
118120 // Get the version in the Response.
119121 GetVersion () (string , error )
120122
123+ // GetReturnedResources returns the map of resources and their versions returned in the subscription.
124+ // It may include more resources than directly set in the response to consider the full state of the client.
125+ // The caller is expected to provide this unchanged to the next call to CreateWatch as part of the subscription.
126+ GetReturnedResources () map [string ]string
127+
121128 // Get the context provided during response creation.
122129 GetContext () context.Context
123130}
@@ -155,6 +162,12 @@ type RawResponse struct {
155162 // Resources to be included in the response.
156163 Resources []types.ResourceWithTTL
157164
165+ // ReturnedResources tracks the resources returned for the subscription and the version when it was last returned,
166+ // including previously returned ones when using non-full state resources.
167+ // It allows the cache to know what the client knows. The server will transparently forward this
168+ // across requests, and the cache is responsible for its interpretation.
169+ ReturnedResources map [string ]string
170+
158171 // Whether this is a heartbeat response. For xDS versions that support TTL, this
159172 // will be converted into a response that doesn't contain the actual resource protobuf.
160173 // This allows for more lightweight updates that server only to update the TTL timer.
@@ -207,6 +220,12 @@ type PassthroughResponse struct {
207220 DiscoveryResponse * discovery.DiscoveryResponse
208221
209222 ctx context.Context
223+
224+ // ReturnedResources tracks the resources returned for the subscription and the version when it was last returned,
225+ // including previously returned ones when using non-full state resources.
226+ // It allows the cache to know what the client knows. The server will transparently forward this
227+ // across requests, and the cache is responsible for its interpretation.
228+ ReturnedResources map [string ]string
210229}
211230
212231// DeltaPassthroughResponse is a pre constructed xDS response that need not go through marshaling transformations.
@@ -264,6 +283,10 @@ func (r *RawResponse) GetDiscoveryResponse() (*discovery.DiscoveryResponse, erro
264283 return marshaledResponse .(* discovery.DiscoveryResponse ), nil
265284}
266285
286+ func (r * RawResponse ) GetReturnedResources () map [string ]string {
287+ return r .ReturnedResources
288+ }
289+
267290// GetDeltaDiscoveryResponse performs the marshaling the first time its called and uses the cached response subsequently.
268291// We can do this because the marshaled response does not change across the calls.
269292// This caching behavior is important in high throughput scenarios because grpc marshaling has a cost and it drives the cpu utilization under load.
@@ -367,6 +390,10 @@ func (r *PassthroughResponse) GetDiscoveryResponse() (*discovery.DiscoveryRespon
367390 return r .DiscoveryResponse , nil
368391}
369392
393+ func (r * PassthroughResponse ) GetReturnedResources () map [string ]string {
394+ return r .ReturnedResources
395+ }
396+
370397// GetDeltaDiscoveryResponse returns the final passthrough Delta Discovery Response.
371398func (r * DeltaPassthroughResponse ) GetDeltaDiscoveryResponse () (* discovery.DeltaDiscoveryResponse , error ) {
372399 return r .DeltaDiscoveryResponse , nil
0 commit comments