Skip to content

Commit 2f5ddc7

Browse files
committed
grpc-js: pick_first: fix happy eyeballs and reresolution in sticky TF mode
1 parent ebc2c3e commit 2f5ddc7

File tree

2 files changed

+26
-6
lines changed

2 files changed

+26
-6
lines changed

packages/grpc-js/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@grpc/grpc-js",
3-
"version": "1.9.6",
3+
"version": "1.9.7",
44
"description": "gRPC Library for Node - pure JS implementation",
55
"homepage": "https://grpc.io/",
66
"repository": "https://github.com/grpc/grpc-node/tree/master/packages/grpc-js",

packages/grpc-js/src/load-balancer-pick-first.ts

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,12 @@ export class PickFirstLoadBalancer implements LoadBalancer {
174174
*/
175175
private stickyTransientFailureMode = false;
176176

177+
/**
178+
* Indicates whether we called channelControlHelper.requestReresolution since
179+
* the last call to updateAddressList
180+
*/
181+
private requestedResolutionSinceLastUpdate = false;
182+
177183
/**
178184
* The most recent error reported by any subchannel as it transitioned to
179185
* TRANSIENT_FAILURE.
@@ -216,15 +222,28 @@ export class PickFirstLoadBalancer implements LoadBalancer {
216222
}
217223
}
218224

225+
private requestReresolution() {
226+
this.requestedResolutionSinceLastUpdate = true;
227+
this.channelControlHelper.requestReresolution();
228+
}
229+
219230
private maybeEnterStickyTransientFailureMode() {
220-
if (this.stickyTransientFailureMode) {
231+
if (!this.allChildrenHaveReportedTF()) {
221232
return;
222233
}
223-
if (!this.allChildrenHaveReportedTF()) {
234+
if (!this.requestedResolutionSinceLastUpdate) {
235+
/* Each time we get an update we reset each subchannel's
236+
* hasReportedTransientFailure flag, so the next time we get to this
237+
* point after that, each subchannel has reported TRANSIENT_FAILURE
238+
* at least once since then. That is the trigger for requesting
239+
* reresolution, whether or not the LB policy is already in sticky TF
240+
* mode. */
241+
this.requestReresolution();
242+
}
243+
if (this.stickyTransientFailureMode) {
224244
return;
225245
}
226246
this.stickyTransientFailureMode = true;
227-
this.channelControlHelper.requestReresolution();
228247
for (const { subchannel } of this.children) {
229248
subchannel.startConnecting();
230249
}
@@ -256,7 +275,7 @@ export class PickFirstLoadBalancer implements LoadBalancer {
256275
if (newState !== ConnectivityState.READY) {
257276
this.removeCurrentPick();
258277
this.calculateAndReportNewState();
259-
this.channelControlHelper.requestReresolution();
278+
this.requestReresolution();
260279
}
261280
return;
262281
}
@@ -283,7 +302,7 @@ export class PickFirstLoadBalancer implements LoadBalancer {
283302

284303
private startNextSubchannelConnecting(startIndex: number) {
285304
clearTimeout(this.connectionDelayTimeout);
286-
if (this.triedAllSubchannels || this.stickyTransientFailureMode) {
305+
if (this.triedAllSubchannels) {
287306
return;
288307
}
289308
for (const [index, child] of this.children.entries()) {
@@ -382,6 +401,7 @@ export class PickFirstLoadBalancer implements LoadBalancer {
382401
this.currentSubchannelIndex = 0;
383402
this.children = [];
384403
this.triedAllSubchannels = false;
404+
this.requestedResolutionSinceLastUpdate = false;
385405
}
386406

387407
updateAddressList(

0 commit comments

Comments
 (0)