Skip to content

Commit 55a8b57

Browse files
committed
xds: Fix ext_proc client deadlock on unary and server-streaming RPCs when upstream is not ready
Outbound request body messages in ExternalProcessorClientInterceptor were gated on super.isReady() before being forwarded to the upstream ClientCall. On unary and server-streaming RPCs (method.getType().clientSendsOneMessage()), ClientCallImpl intentionally suppresses onReady() notifications, meaning queued messages and halfClose were never drained when the upstream transport stream connected, causing the RPC to hang indefinitely. Treat the upstream call as ready for outbound message forwarding when method.getType().clientSendsOneMessage() is true via isUpstreamReady(). TAG=agy CONV=581f86a6-097d-44a2-9d6e-6f9d2e83cbc0
1 parent 15d64a4 commit 55a8b57

2 files changed

Lines changed: 833 additions & 5 deletions

File tree

‎xds/src/main/java/io/grpc/xds/ExternalProcessorClientInterceptor.java‎

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -934,6 +934,10 @@ boolean isSidecarReady() {
934934
return observer != null && observer.isReady();
935935
}
936936

937+
private boolean isUpstreamReady() {
938+
return method.getType().clientSendsOneMessage() || super.isReady();
939+
}
940+
937941
@Override
938942
public boolean isReady() {
939943
if (passThroughMode.get()) {
@@ -1193,7 +1197,7 @@ private void handleRequestBodyResponse(BodyResponse bodyResponse) {
11931197
boolean sendImmediately = false;
11941198
synchronized (streamLock) {
11951199
sidestreamToUpstreamWindow -= body.size();
1196-
if (pendingUpstreamBodyMessages.isEmpty() && super.isReady()) {
1200+
if (pendingUpstreamBodyMessages.isEmpty() && isUpstreamReady()) {
11971201
sendImmediately = true;
11981202
accumulatedWindowUpdateSidestreamToUpstream += body.size();
11991203
} else {
@@ -1307,7 +1311,7 @@ void drainPendingUpstreamBodyMessages() {
13071311
ByteString body = null;
13081312
boolean triggerHalfClose = false;
13091313
synchronized (streamLock) {
1310-
if (!pendingUpstreamBodyMessages.isEmpty() && super.isReady()) {
1314+
if (!pendingUpstreamBodyMessages.isEmpty() && isUpstreamReady()) {
13111315
body = pendingUpstreamBodyMessages.poll();
13121316
accumulatedWindowUpdateSidestreamToUpstream += body.size();
13131317
if (pendingUpstreamBodyMessages.isEmpty()
@@ -1366,16 +1370,16 @@ private void drainPendingDrainingMessages() {
13661370
boolean triggerHalfClose = false;
13671371

13681372
synchronized (streamLock) {
1369-
if (!pendingUpstreamBodyMessages.isEmpty() && super.isReady()) {
1373+
if (!pendingUpstreamBodyMessages.isEmpty() && isUpstreamReady()) {
13701374
msg = pendingUpstreamBodyMessages.poll();
13711375
isMutated = true;
13721376
} else if (pendingUpstreamBodyMessages.isEmpty()
1373-
&& !pendingRequestBodyMessages.isEmpty() && super.isReady()) {
1377+
&& !pendingRequestBodyMessages.isEmpty() && isUpstreamReady()) {
13741378
msg = pendingRequestBodyMessages.poll();
13751379
isMutated = true;
13761380
} else if (pendingUpstreamBodyMessages.isEmpty()
13771381
&& pendingRequestBodyMessages.isEmpty()
1378-
&& !pendingDrainingMessages.isEmpty() && super.isReady()) {
1382+
&& !pendingDrainingMessages.isEmpty() && isUpstreamReady()) {
13791383
msg = pendingDrainingMessages.poll();
13801384
isMutated = false;
13811385
}

0 commit comments

Comments
 (0)