Merge pull request #2929 from murgatroid99/grpc-js-xds_dependency_manager_watcher_updates

grpc-js-xds: Implement updated xds dependency manager watcher API
This commit is contained in:
Michael Lumish 2025-03-25 09:44:56 -07:00 committed by GitHub
commit c4580fa80b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 45 additions and 25 deletions

View File

@ -135,18 +135,12 @@ class XdsResolver implements Resolver {
this.xdsClient = getSingletonXdsClient();
}
this.xdsConfigWatcher = {
onUpdate: xdsConfig => {
this.handleXdsConfig(xdsConfig);
},
onError: (context, status) => {
trace('Resolution error for target ' + uriToString(this.target) + ' due to xDS client transient error retrieving ' + context + ': ' + status.details);
this.reportResolutionError(`Error retrieving resource ${context}: ${status.details}`);
},
onResourceDoesNotExist: context => {
trace('Resolution error for target ' + uriToString(this.target) + ': ' + context + ' does not exist');
/* Return an empty endpoint list and service config, to explicitly
* invalidate any previously returned service config */
this.listener(statusOrFromValue([]), {}, null, '');
onUpdate: maybeXdsConfig => {
if (maybeXdsConfig.ok) {
this.handleXdsConfig(maybeXdsConfig.value);
} else {
this.listener(statusOrFromValue([]), {}, null, `Resolution error for target ${uriToString(this.target)}: ${maybeXdsConfig.error.details}`);
}
}
}
}

View File

@ -89,9 +89,7 @@ export interface XdsConfig {
}
export interface XdsConfigWatcher {
onUpdate(xdsConfig: XdsConfig): void;
onError(context: string, status: StatusObject): void;
onResourceDoesNotExist(context: string): void;
onUpdate(xdsConfig: StatusOr<XdsConfig>): void;
}
interface AggregateClusterInfo {
@ -394,7 +392,13 @@ export class XdsDependencyManager {
* not already provided a ServiceConfig for the upper layer to use */
if (!this.latestListener) {
this.trace('Resolution error due to xDS client transient error ' + error.details);
this.watcher.onError(`Listener ${listenerResourceName}`, error);
this.watcher.onUpdate({
ok: false,
error: {
...error,
details: `Listener ${listenerResourceName}: ${error.details}`
}
});
}
},
onResourceDoesNotExist: () => {
@ -408,11 +412,24 @@ export class XdsDependencyManager {
},
onError: (error: StatusObject) => {
if (!this.latestRouteConfiguration) {
this.watcher.onError(`RouteConfiguration ${this.latestRouteConfigName}`, error);
this.watcher.onUpdate({
ok: false,
error: {
...error,
details: `RouteConfiguration ${this.latestRouteConfigName}: ${error.details}`
}
});
}
},
onResourceDoesNotExist: () => {
this.watcher.onResourceDoesNotExist(`RouteConfiguration ${this.latestRouteConfigName}`);
this.watcher.onUpdate({
ok: false,
error: {
code: status.UNAVAILABLE,
details: `RouteConfiguration ${this.latestRouteConfigName} does not exist`,
metadata: new Metadata()
}
});
this.clusterRoots = [];
this.pruneOrphanClusters();
}
@ -434,8 +451,14 @@ export class XdsDependencyManager {
this.clusterRoots = [];
this.pruneOrphanClusters();
}
this.watcher.onResourceDoesNotExist(`Listener ${this.listenerResourceName}`);
this.watcher.onUpdate({
ok: false,
error: {
code: status.UNAVAILABLE,
details: `Listener ${this.listenerResourceName} does not exist`,
metadata: new Metadata()
}
});
}
private maybeSendUpdate() {
@ -491,7 +514,7 @@ export class XdsDependencyManager {
});
}
}
this.watcher.onUpdate(update);
this.watcher.onUpdate({ok: true, value: update});
}
private addCluster(clusterName: string) {
@ -763,10 +786,13 @@ export class XdsDependencyManager {
if (!virtualHost) {
this.clusterRoots = [];
this.pruneOrphanClusters();
this.watcher.onError(`RouteConfiguration ${routeConfig.name}`, {
code: status.UNAVAILABLE,
details: `No matching route found for ${this.dataPlaneAuthority}`,
metadata: new Metadata()
this.watcher.onUpdate({
ok: false,
error: {
code: status.UNAVAILABLE,
details: `RouteConfiguration ${routeConfig.name}: No matching route found for ${this.dataPlaneAuthority}`,
metadata: new Metadata()
}
});
// Report error
return;