Skip to content

Commit 08d0792

Browse files
xdsclient: call resourceError methods from serializer (#8725)
Fixes an issue where ResourceError methods were incorrectly called outside of the serializer's scope. Updates the documentation for the ResourceWatcher interface to explicitly state the guarantee that all its defined methods will always be called from the serializer. RELEASE NOTES: None
1 parent 5bb2bef commit 08d0792

File tree

2 files changed

+16
-6
lines changed

2 files changed

+16
-6
lines changed

internal/xds/clients/xdsclient/clientimpl_watchers.go

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
package xdsclient
2020

2121
import (
22+
"context"
2223
"fmt"
2324

2425
"google.golang.org/grpc/internal/xds/clients/xdsclient/internal/xdsresource"
@@ -41,9 +42,11 @@ func (w *wrappingWatcher) ResourceError(err error, done func()) {
4142

4243
// WatchResource starts watching the specified resource.
4344
//
44-
// typeURL specifies the resource type implementation to use. The watch fails
45-
// if there is no resource type implementation for the given typeURL. See the
46-
// ResourceTypes field in the Config struct used to create the XDSClient.
45+
// The watch fails to start if:
46+
// - There is no ResourceType implementation for the given typeURL in the
47+
// ResourceTypes field of the Config struct used to create the XDSClient.
48+
// - The provided resourceName contains an authority that is not present in the
49+
// Authorities field.
4750
//
4851
// The returned function cancels the watch and prevents future calls to the
4952
// watcher.
@@ -61,16 +64,20 @@ func (c *XDSClient) WatchResource(typeURL, resourceName string, watcher Resource
6164

6265
rType, ok := c.config.ResourceTypes[typeURL]
6366
if !ok {
64-
logger.Warningf("ResourceType implementation for resource type url %v is not found", rType.TypeURL)
65-
watcher.ResourceError(fmt.Errorf("ResourceType implementation for resource type url %v is not found", rType.TypeURL), func() {})
67+
logger.Warningf("ResourceType implementation for resource type url %q is not found", rType.TypeURL)
68+
c.serializer.TrySchedule(func(context.Context) {
69+
watcher.ResourceError(fmt.Errorf("no ResourceType implementation found for typeURL %q", rType.TypeURL), func() {})
70+
})
6671
return func() {}
6772
}
6873

6974
n := xdsresource.ParseName(resourceName)
7075
a := c.getAuthorityForResource(n)
7176
if a == nil {
7277
logger.Warningf("Watch registered for name %q of type %q, authority %q is not found", rType.TypeName, resourceName, n.Authority)
73-
watcher.ResourceError(fmt.Errorf("authority %q not found in bootstrap config for resource %q", n.Authority, resourceName), func() {})
78+
c.serializer.TrySchedule(func(context.Context) {
79+
watcher.ResourceError(fmt.Errorf("authority %q not found in the config for resource %q", n.Authority, resourceName), func() {})
80+
})
7481
return func() {}
7582
}
7683
// The watchResource method on the authority is invoked with n.String()

internal/xds/clients/xdsclient/resource_watcher.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ package xdsclient
2121
// ResourceWatcher is notified of the resource updates and errors that are
2222
// received by the xDS client from the management server.
2323
//
24+
// All methods on this interface are guaranteed to be called serially by the xDS
25+
// client.
26+
//
2427
// All methods contain a done parameter which should be called when processing
2528
// of the update has completed. For example, if processing a resource requires
2629
// watching new resources, those watches should be completed before done is

0 commit comments

Comments
 (0)