mirror of https://github.com/grpc/grpc-node.git
grpc-js-xds: Fix a couple of bugs with the config tears change
This commit is contained in:
parent
8a314311f8
commit
eee7030a28
|
@ -653,8 +653,9 @@ export class XdsDependencyManager {
|
||||||
this.subscribedClusters[clusterName] -= 1;
|
this.subscribedClusters[clusterName] -= 1;
|
||||||
if (this.subscribedClusters[clusterName] <= 0) {
|
if (this.subscribedClusters[clusterName] <= 0) {
|
||||||
delete this.subscribedClusters[clusterName];
|
delete this.subscribedClusters[clusterName];
|
||||||
this.pruneOrphanClusters();
|
if (this.pruneOrphanClusters()) {
|
||||||
this.maybeSendUpdate();
|
this.maybeSendUpdate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -682,7 +683,12 @@ export class XdsDependencyManager {
|
||||||
delete this.clusterForest[clusterName];
|
delete this.clusterForest[clusterName];
|
||||||
}
|
}
|
||||||
|
|
||||||
private pruneOrphanClusters() {
|
/**
|
||||||
|
* Prune any clusters that are not descendents of any root clusters,
|
||||||
|
* including subscribed clusters.
|
||||||
|
* @returns True if any clusters were pruned, false otherwise
|
||||||
|
*/
|
||||||
|
private pruneOrphanClusters(): boolean {
|
||||||
const toCheck = [...this.clusterRoots, ...Object.keys(this.subscribedClusters)];
|
const toCheck = [...this.clusterRoots, ...Object.keys(this.subscribedClusters)];
|
||||||
const visited = new Set<string>();
|
const visited = new Set<string>();
|
||||||
while(toCheck.length > 0) {
|
while(toCheck.length > 0) {
|
||||||
|
@ -695,11 +701,14 @@ export class XdsDependencyManager {
|
||||||
}
|
}
|
||||||
visited.add(next);
|
visited.add(next);
|
||||||
}
|
}
|
||||||
|
let removedAnyClusters = false;
|
||||||
for (const clusterName of Object.keys(this.clusterForest)) {
|
for (const clusterName of Object.keys(this.clusterForest)) {
|
||||||
if (!visited.has(clusterName)) {
|
if (!visited.has(clusterName)) {
|
||||||
|
removedAnyClusters = true;
|
||||||
this.removeCluster(clusterName);
|
this.removeCluster(clusterName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return removedAnyClusters;
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleRouteConfig(routeConfig: RouteConfiguration__Output) {
|
private handleRouteConfig(routeConfig: RouteConfiguration__Output) {
|
||||||
|
|
|
@ -107,7 +107,7 @@ export class BackoffTimeout {
|
||||||
private runTimer(delay: number) {
|
private runTimer(delay: number) {
|
||||||
this.endTime = this.startTime;
|
this.endTime = this.startTime;
|
||||||
this.endTime.setMilliseconds(
|
this.endTime.setMilliseconds(
|
||||||
this.endTime.getMilliseconds() + this.nextDelay
|
this.endTime.getMilliseconds() + delay
|
||||||
);
|
);
|
||||||
clearTimeout(this.timerId);
|
clearTimeout(this.timerId);
|
||||||
this.timerId = setTimeout(() => {
|
this.timerId = setTimeout(() => {
|
||||||
|
|
|
@ -275,6 +275,13 @@ export class PickFirstLoadBalancer implements LoadBalancer {
|
||||||
new PickFirstPicker(this.currentPick)
|
new PickFirstPicker(this.currentPick)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
} else if (this.latestAddressList?.length === 0) {
|
||||||
|
this.updateState(
|
||||||
|
ConnectivityState.TRANSIENT_FAILURE,
|
||||||
|
new UnavailablePicker({
|
||||||
|
details: `No connection established. Last error: ${this.lastError}`,
|
||||||
|
})
|
||||||
|
);
|
||||||
} else if (this.children.length === 0) {
|
} else if (this.children.length === 0) {
|
||||||
this.updateState(ConnectivityState.IDLE, new QueuePicker(this));
|
this.updateState(ConnectivityState.IDLE, new QueuePicker(this));
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -690,6 +690,19 @@ describe('pick_first load balancing policy', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
it('Should report TRANSIENT_FAILURE with no addresses', done => {
|
||||||
|
const channelControlHelper = createChildChannelControlHelper(
|
||||||
|
baseChannelControlHelper,
|
||||||
|
{
|
||||||
|
updateState: updateStateCallBackForExpectedStateSequence(
|
||||||
|
[ConnectivityState.TRANSIENT_FAILURE],
|
||||||
|
done
|
||||||
|
),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const pickFirst = new PickFirstLoadBalancer(channelControlHelper, creds, {});
|
||||||
|
pickFirst.updateAddressList([], config);
|
||||||
|
});
|
||||||
describe('Address list randomization', () => {
|
describe('Address list randomization', () => {
|
||||||
const shuffleConfig = new PickFirstLoadBalancingConfig(true);
|
const shuffleConfig = new PickFirstLoadBalancingConfig(true);
|
||||||
it('Should pick different subchannels after multiple updates', done => {
|
it('Should pick different subchannels after multiple updates', done => {
|
||||||
|
|
Loading…
Reference in New Issue