From 3abdb2859f4f9d3576fe98d50a6f59eaff20c3b5 Mon Sep 17 00:00:00 2001 From: ZHANG Dapeng Date: Wed, 16 Sep 2020 16:48:22 -0700 Subject: [PATCH] grpclb: cache requestConnection if no subchannel created An issue was found during CBT RLS client testing: The RLS lb creates grplb child balancer, calls `grpclb.handleResolvedAddress()` then immediately calls `grpclb.requestConnection()`. The subchannel in `GrpclbState.currentPicker.pickList` contains only `GrpclbState.BUFFER_ENTRY` at the moment `grpclb.requestConnection()` is called, and therefore the `requestConnection()` is no-op, and RPC is hanging. --- grpclb/src/main/java/io/grpc/grpclb/GrpclbState.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/grpclb/src/main/java/io/grpc/grpclb/GrpclbState.java b/grpclb/src/main/java/io/grpc/grpclb/GrpclbState.java index b6c99135e22..3630db63a16 100644 --- a/grpclb/src/main/java/io/grpc/grpclb/GrpclbState.java +++ b/grpclb/src/main/java/io/grpc/grpclb/GrpclbState.java @@ -158,6 +158,7 @@ enum Mode { private List backendList = Collections.emptyList(); private RoundRobinPicker currentPicker = new RoundRobinPicker(Collections.emptyList(), Arrays.asList(BUFFER_ENTRY)); + private boolean requestConnectionPending; GrpclbState( GrpclbConfig config, @@ -242,9 +243,11 @@ void handleAddresses( } void requestConnection() { + requestConnectionPending = true; for (RoundRobinEntry entry : currentPicker.pickList) { if (entry instanceof IdleSubchannelEntry) { ((IdleSubchannelEntry) entry).subchannel.requestConnection(); + requestConnectionPending = false; } } } @@ -471,6 +474,10 @@ public void onSubchannelState(ConnectivityStateInfo newState) { handleSubchannelState(subchannel, newState); } }); + if (requestConnectionPending) { + subchannel.requestConnection(); + requestConnectionPending = false; + } } else { subchannel = subchannels.values().iterator().next(); subchannel.updateAddresses(eagList);