cloudbase-ai opened a new issue, #7927: URL: https://github.com/apache/shenyu/issues/7927
### Is there an existing issue for this? - [x] I searched open/closed issues and PRs for gRPC backpressure, streaming, buffering and flow control; I did not find an equivalent report. ### Current Behavior `ShenyuGrpcClient.invoke()` sends CLIENT_STREAMING and BIDI_STREAMING requests by traversing the entire request list: ```java requestObserver = asyncClientStreamingCall(createCall(callParams), compositeObserver); requestList.forEach(requestObserver::onNext); requestObserver.onCompleted(); ``` The bidi branch uses the same loop. Neither branch observes `ClientCallStreamObserver.isReady()` or resumes sending through an `onReadyHandler`. grpc-java still provides HTTP/2 transport flow control. However, `StreamObserver.onNext()` can enqueue a message before the peer can consume it; ignoring readiness can create additional outbound buffering when the backend reads slowly. This is a missing application-level sending policy, not evidence that HTTP/2 flow control is absent or that an OOM has occurred. The request JSON is already materialized as a list before this loop. A readiness-aware drain would bound additional sending work; it would not by itself bound the original HTTP request body/list. ### Expected Behavior Drain pending client/bidi requests according to gRPC outbound readiness, preserving message order, termination and existing RPC semantics. ### Evidence - [Request materialization](https://github.com/apache/shenyu/blob/87c22dde7be14c1c3755440a4d8b082a86d10a87/shenyu-plugin/shenyu-plugin-proxy/shenyu-plugin-rpc/shenyu-plugin-grpc/src/main/java/org/apache/shenyu/plugin/grpc/client/ShenyuGrpcClient.java#L80-L84). - [CLIENT_STREAMING/BIDI_STREAMING send loops](https://github.com/apache/shenyu/blob/87c22dde7be14c1c3755440a4d8b082a86d10a87/shenyu-plugin/shenyu-plugin-proxy/shenyu-plugin-rpc/shenyu-plugin-grpc/src/main/java/org/apache/shenyu/plugin/grpc/client/ShenyuGrpcClient.java#L148-L157). - grpc-java 1.65.1's [`CallStreamObserver.isReady()` contract](https://github.com/grpc/grpc-java/blob/v1.65.1/stub/src/main/java/io/grpc/stub/CallStreamObserver.java) explains that ignoring readiness can cause excessive internal buffering. ### Suggested Verification and Acceptance - [ ] Capture the actual client call observer through the supported client-observer lifecycle; use `isReady`/`onReady` or an equivalent bounded mechanism. - [ ] When readiness is false, pause the drain; resume after readiness becomes true, checking readiness again during the callback. - [ ] Preserve order and exactly-once delivery to `onNext`; invoke `onCompleted` only after pending messages have been submitted. - [ ] Stop pending sends on termination/cancellation, and serialize drain work to prevent duplicate sends from reentrant/concurrent readiness callbacks. - [ ] Add deterministic tests that alternate ready/not-ready states, including termination while requests remain. Keep unary/server-streaming behavior unchanged. - [ ] Exercise a slow-reading backend with a large finite request list; record pending work, memory and convergence. Do not replace the loop with an unbounded executor/queue. ### Environment and Validation Boundary Reviewed ShenYu `2.7.2-SNAPSHOT`, master `87c22dde7be14c1c3755440a4d8b082a86d10a87`, grpc-java `1.65.1`. This report is based on source inspection and the installed official grpc-java source. The slow-backend scenario above is proposed validation; no load benchmark or production failure was reproduced. The separate response-aggregation issue concerns received results and the HTTP response contract. WebSocket forwarding uses a separate reactive `receive -> send` bridge and is outside this report. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
