Ext proc client flow control - #12956
Conversation
…onformance - Bypass sidecar readiness checks in `request(int)` when observability mode is false and response body mode is not `GRPC`. - Ensure that when response headers, body, or trailers are skipped/disabled, they bypass request draining and stream directly downstream instead of being blocked. - Fix sidecar mocks in tests to properly call `onCompleted()` when the request stream completes, preventing background stream leaks. - Set appropriate processing modes in existing tests to match their flow control expectations under the updated logic.
…ffered use response processing mode GRPC so that buffered requests are actually sent to ext_proc instead of directly upstream in this test.
…send-mode-is-off' into ext-proc-client-flow-control # Conflicts: # xds/src/test/java/io/grpc/xds/ExternalProcessorClientInterceptorTest.java
…RequestsAreNotBuffered to verify that when response_body_mode is NONE (and observability mode is disabled), request(int) calls are passed upstream immediately without being gated by sidecar readiness or buffered.
…ying the current message size, rather than after.
…port readiness - Gated the transmission of `ClientWindowUpdate` messages by transport readiness. If the upstream client call is not ready (`isReady() == false`), the upstream window increment is kept at 0 to enforce backpressure. - Modified `trySendAccumulatedWindowUpdates()` to avoid transmitting redundant, zero-increment window updates when transport readiness prevents replenishment. A `ClientWindowUpdate` is now sent only if at least one window increment is positive (`incrementUpstream > 0 || incrementDownstream > 0`). - Updated `testClientWindowUpdateSentImmediatelyOnWindowExhaustion` to verify that no redundant window updates are sent while the transport is not ready, and that the accumulated `65536` increment is correctly flushed immediately upon calling `onReady()`. - Fixed checkstyle violations (missing line separator) in the test code.
… client interceptor - Queue mutated request body messages received from ext_proc in a new `pendingUpstreamBodyMessages` queue if the upstream transport is not ready (`isReady() == false`). - Drain the queued request body messages and forward them to the transport when the transport becomes ready (triggered in `onReady()`). - Defer request half-close if there are still body messages in the queue, executing the half-close once the queue is fully drained. - Remove the `isReady()` check when merging or sending accumulated client window updates (`accumulatedWindowUpdateSidestreamToUpstream`), ensuring window updates are always propagated. - Add a new unit test `testSidestreamToUpstreamFlowControl_QueuingAndDraining` in `ExternalProcessorClientInterceptorTest` to verify flow control queuing, transport transitions, and draining behavior.
…w-control # Conflicts: # xds/src/test/java/io/grpc/xds/ExternalProcessorClientInterceptorTest.java
…w-control # Conflicts: # xds/src/main/java/io/grpc/xds/ExternalProcessorClientInterceptor.java # xds/src/test/java/io/grpc/xds/ExternalProcessorClientInterceptorTest.java
Revert nit changes causing diffs. Revert nit changes causing diffs. Revert nit changes causing diffs.
399a16d to
98ec5be
Compare
Move the onExternalBody calls in deliverResponseBody and drainPendingMutatedResponseBodies outside of the streamLock synchronized block to prevent deadlocks. TAG=agy CONV=841033be-dc17-46b4-93ef-502e462c23da
…c interceptor - Implement fail-open queue draining for both inbound and outbound directions. - Defer transport half-close during fail-open until all outbound queues are drained. - Refactor DataPlaneClientCall.onReady to release streamLock before calling drain/update methods, avoiding deadlocks. - Consolidate and batch outbound draining in drainPendingDrainingMessages.
…rt readiness Revert the batching optimization in drainPendingUpstreamBodyMessages and drainPendingDrainingMessages back to loop-based implementations. This ensures we check super.isReady() and poll messages one-by-one under lock, correctly respecting synchronous changes in transport readiness and ensuring incremental window updates as required by tests. TAG=agy CONV=841033be-dc17-46b4-93ef-502e462c23da
…ngRequestBodyMessages Remove the redundant synchronized(streamLock) block inside drainPendingRequestBodyMessages, as its only caller already holds the lock. Annotate the method with @GuardedBy("streamLock") to document this requirement. TAG=agy CONV=841033be-dc17-46b4-93ef-502e462c23da
|
First pass at source done. Mostly okay. I have some concerns about the unbounded receiver buffering and some non-urgent concerns about growing complexity and size of the file, but the latter can potentially be addressed in the future, since it'll likely be a large refactor. Will look at the tests later. |
|
|
||
| assertThat(firstRequest.hasRequestHeaders()).isTrue(); | ||
| assertThat(firstRequest.hasFlowControlInit()).isTrue(); | ||
| assertThat(firstRequest.getFlowControlInit().getInitialWindowDownstreamToSidestream()) |
There was a problem hiding this comment.
Should we be covering all 4 windows here?
|
Looked at the tests. Things seem reasonable. Unfortunately the CI are failing. I'll be OOO for most of next weeek, but feel free to ping me once the remaining comments are addresses and the CI is passing. I'll gladly approve. |
sauravzg
left a comment
There was a problem hiding this comment.
There's probably a small minor comment remaining and the CI still needs to be fixed. Approving, please take care of these before submitting
No description provided.