envoy icon indicating copy to clipboard operation
envoy copied to clipboard

Allow multiplexed upstream servers to half close the stream before the downstream

Open yanavlasov opened this issue 1 year ago • 3 comments

Commit Message: Allow HTTP/2 (and HTTP/3) upstream servers to half close the stream before the downstream. This enables bidirectional gRPC streams where server completes streaming before the client. Behavior of HTTP/1 or TCP proxy upstream servers is unchanged and the stream is reset if the upstream server completes response before the downstream. The stream is also reset if the upstream server responds with an error status before the downstream. This behavior is disabled by default and can be enabled by setting the envoy.reloadable_features.allow_multiplexed_upstream_half_close runtime key to true.

Change details: Presently there are two places where the stream was reset when upstream half-closed.

  1. In the router filter's Filter::onUpstreamComplete method, which covers HTTP upstreams.
  2. In the filter manager's FilterManager::commonEncodePrefix which covers local reply's by filters and TCP upstreams.

When the envoy.reloadable_features.allow_multiplexed_upstream_half_close is enabled the router filter no longer forces reset in the Filter::onUpstreamComplete and allows fully independent half closes. To preserve existing half close behavior of HTTP/1 protocol the force reset is added in the H/1 codec's ClientConnectionImpl::onMessageCompleteBase() method.

When the envoy.reloadable_features.allow_multiplexed_upstream_half_close is enabled the filter manager closes stream after it observes END_STREAM indicator in both direction, except in two cases:

  1. local reply.
  2. error (non 1xx or 2xx) response from the server.

The state_.force_close_stream_ is added to track these cases.

To preserver behavior for TCP upstream the force reset is moved into the TcpUpstream::onUpstreamData method.

Risk Level: High (flag protected, disabled by default) Testing: Unit Tests Docs Changes: No Release Notes: Yes Platform Specific Features: N/A Runtime guard: envoy.reloadable_features.allow_multiplexed_upstream_half_close Fixes #30149

yanavlasov avatar May 31 '24 17:05 yanavlasov

As a reminder, PRs marked as draft will not be automatically assigned reviewers, or be handled by maintainer-oncall triage.

Please mark your PR as ready when you want it to be reviewed!

:cat:

Caused by: https://github.com/envoyproxy/envoy/pull/34461 was opened by yanavlasov.

see: more, trace.

CC @envoyproxy/runtime-guard-changes: FYI only for changes made to (source/common/runtime/runtime_features.cc).

:cat:

Caused by: https://github.com/envoyproxy/envoy/pull/34461 was opened by yanavlasov.

see: more, trace.

Sanitizer failures look related to #34354

yanavlasov avatar Jun 24 '24 22:06 yanavlasov

(also please be aware I'm out for a week starting mid-week next week so there's a limited window for reviews)

alyssawilk avatar Jul 03 '24 14:07 alyssawilk

Cleaning-up after main merge. Please hold off the review.

/wait

yanavlasov avatar Jul 30 '24 15:07 yanavlasov

/wait

yanavlasov avatar Jul 30 '24 19:07 yanavlasov

/wait

alyssawilk avatar Aug 14 '24 13:08 alyssawilk

@KBaichoo @RyanTheOptimist can you PTAL?

adisuissa avatar Aug 20 '24 20:08 adisuissa

Blocked by the #35815 . Some tests with independent half-close enabled do not pass without it.

yanavlasov avatar Aug 22 '24 21:08 yanavlasov

/wait

RyanTheOptimist avatar Aug 23 '24 14:08 RyanTheOptimist

Blocked by the #35815 . Some tests with independent half-close enabled do not pass without it.

Unblocked

yanavlasov avatar Aug 23 '24 23:08 yanavlasov