Skip to content

xds: Fix ext_proc client hang on unary and server-streaming RPCs when upstream is not ready - #13147

Merged
kannanjgithub merged 2 commits into
grpc:masterfrom
kannanjgithub:ext-proc-unary-rpc-hang-issue
Nov 6, 2026
Merged

kannanjgithub merged 2 commits into
grpc:masterfrom
kannanjgithub:ext-proc-unary-rpc-hang-issue

Conversation

@kannanjgithub

@kannanjgithub kannanjgithub commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

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().

Thanks @ran-su for reporting this.

…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
}

private boolean isUpstreamReady() {
return method.getType().clientSendsOneMessage() || super.isReady();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will result in isUpstreamReady returning true always for any unary or serverstreaming call. I'd expect this to return false after the call has been half closed.

It's less likely to matter because for these cases the call doesn't respect isReady anyways, but we should try to be semantically correct.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Ensure isUpstreamReady() returns false once the call has been half-closed
upstream, maintaining semantic correctness for unary and server-streaming calls.

TAG=agy
CONV=581f86a6-097d-44a2-9d6e-6f9d2e83cbc0
@kannanjgithub
kannanjgithub merged commit 750b0da into grpc:master Nov 6, 2026
18 checks passed
@kannanjgithub
kannanjgithub deleted the ext-proc-unary-rpc-hang-issue branch November 6, 2026 02:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants