Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

grpc-js-xds: xds_cluster_manager: pass along updates to existing children #2846

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions packages/grpc-js-xds/src/load-balancer-xds-cluster-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,13 +227,14 @@ class XdsClusterManager implements LoadBalancer {
this.children.get(name)!.destroy();
this.children.delete(name);
}
// Add new children that were not in the previous config
// Update all children, and add any new ones
for (const [name, childConfig] of configChildren.entries()) {
if (!this.children.has(name)) {
const newChild = new this.XdsClusterManagerChildImpl(this, name);
newChild.updateAddressList(endpointList, childConfig, attributes);
this.children.set(name, newChild);
let child = this.children.get(name);
if (!child) {
child = new this.XdsClusterManagerChildImpl(this, name);
this.children.set(name, child);
}
child.updateAddressList(endpointList, childConfig, attributes);
}
this.updatesPaused = false;
this.updateState();
Expand Down
4 changes: 2 additions & 2 deletions packages/grpc-js-xds/test/framework.ts
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@ export class FakeServerRoute {
private listener: Listener;
private routeConfiguration: RouteConfiguration;
constructor(port: number, routeName: string, baseListener?: Listener | undefined, baseRouteConfiguration?: RouteConfiguration) {
this.listener = baseListener ?? DEFAULT_BASE_SERVER_LISTENER;
this.listener = baseListener ?? {...DEFAULT_BASE_SERVER_LISTENER};
this.listener.name = `[::1]:${port}`;
this.listener.address = {
socket_address: {
Expand Down Expand Up @@ -414,7 +414,7 @@ export class FakeServerRoute {
filterChain.filters = filterList;
}

this.routeConfiguration = baseRouteConfiguration ?? DEFAULT_BASE_SERVER_ROUTE_CONFIG;
this.routeConfiguration = baseRouteConfiguration ?? {...DEFAULT_BASE_SERVER_ROUTE_CONFIG};
this.routeConfiguration.name = routeName;
}

Expand Down
31 changes: 31 additions & 0 deletions packages/grpc-js-xds/test/test-core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,5 +134,36 @@ describe('core xDS functionality', () => {
});
}, reason => done(reason));
}, reason => done(reason));
});
it('should handle cluster config changes', async () => {
const [backend1, backend2] = await createBackends(2);
const serverRoute1 = new FakeServerRoute(backend1.getPort(), 'serverRoute');
const serverRoute2 = new FakeServerRoute(backend2.getPort(), 'serverRoute2');
xdsServer.setRdsResource(serverRoute1.getRouteConfiguration());
xdsServer.setLdsResource(serverRoute1.getListener());
xdsServer.setRdsResource(serverRoute2.getRouteConfiguration());
xdsServer.setLdsResource(serverRoute2.getListener());
xdsServer.addResponseListener((typeUrl, responseState) => {
if (responseState.state === 'NACKED') {
client?.stopCalls();
assert.fail(`Client NACKED ${typeUrl} resource with message ${responseState.errorMessage}`);
}
});
const cluster1 = new FakeEdsCluster('cluster1', 'endpoint1', [{backends: [backend1], locality:{region: 'region1'}}]);
const routeGroup1 = new FakeRouteGroup('listener1', 'route1', [{cluster: cluster1}]);
await routeGroup1.startAllBackends(xdsServer);
xdsServer.setEdsResource(cluster1.getEndpointConfig());
xdsServer.setCdsResource(cluster1.getClusterConfig());
xdsServer.setRdsResource(routeGroup1.getRouteConfiguration());
xdsServer.setLdsResource(routeGroup1.getListener());
client = XdsTestClient.createFromServer('listener1', xdsServer);
client.startCalls(100);
await cluster1.waitForAllBackendsToReceiveTraffic();
const cluster2 = new FakeEdsCluster('cluster1', 'endpoint1', [{backends: [backend2], locality:{region: 'region2'}}]);
await cluster2.startAllBackends(xdsServer);
xdsServer.setEdsResource(cluster2.getEndpointConfig());
await cluster2.waitForAllBackendsToReceiveTraffic();
client.stopCalls();

})
});
Loading