Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions api/envoy/config/route/v3/route_components.proto
Original file line number Diff line number Diff line change
Expand Up @@ -763,14 +763,15 @@ message RouteAction {
ConnectConfig connect_config = 3;
}

// [#not-implemented-hide:]
message MaxStreamDuration {
// Specifies the maximum duration allowed for streams on the route. If not specified, the value
// from the :ref:`max_stream_duration
// <envoy_api_field_config.core.v3.HttpProtocolOptions.max_stream_duration>` field in
// :ref:`HttpConnectionManager.common_http_protocol_options
// <envoy_api_field_extensions.filters.network.http_connection_manager.v3.HttpConnectionManager.common_http_protocol_options>`
// is used.
// is used. If this field is set explicitly to zero, any
// HttpConnectionManager max_stream_duration timeout will be disabled for
// this route.
google.protobuf.Duration max_stream_duration = 1;

// If present, and the request contains a `grpc-timeout header
Expand Down Expand Up @@ -1017,6 +1018,7 @@ message RouteAction {
// Indicates that the route has a CORS policy.
CorsPolicy cors = 17;

// Deprecated by :ref:`grpc_timeout_header_max <envoy_api_field_config.route.v3.RouteAction.MaxStreamDuration.grpc_timeout_header_max>`
// If present, and the request is a gRPC request, use the
// `grpc-timeout header <https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md>`_,
// or its default value (infinity) instead of
Expand All @@ -1036,16 +1038,17 @@ message RouteAction {
// :ref:`config_http_filters_router_x-envoy-upstream-rq-timeout-ms`,
// :ref:`config_http_filters_router_x-envoy-upstream-rq-per-try-timeout-ms`, and the
// :ref:`retry overview <arch_overview_http_routing_retry>`.
google.protobuf.Duration max_grpc_timeout = 23;
google.protobuf.Duration max_grpc_timeout = 23 [deprecated = true];

// Deprecated by :ref:`grpc_timeout_header_offset <envoy_api_field_config.route.v3.RouteAction.MaxStreamDuration.grpc_timeout_header_offset>`.
// If present, Envoy will adjust the timeout provided by the `grpc-timeout` header by subtracting
// the provided duration from the header. This is useful in allowing Envoy to set its global
// timeout to be less than that of the deadline imposed by the calling client, which makes it more
// likely that Envoy will handle the timeout instead of having the call canceled by the client.
// The offset will only be applied if the provided grpc_timeout is greater than the offset. This
// ensures that the offset will only ever decrease the timeout and never set it to 0 (meaning
// infinity).
google.protobuf.Duration grpc_timeout_offset = 28;
google.protobuf.Duration grpc_timeout_offset = 28 [deprecated = true];

repeated UpgradeConfig upgrade_configs = 25;

Expand Down Expand Up @@ -1079,7 +1082,6 @@ message RouteAction {
HedgePolicy hedge_policy = 27;

// Specifies the maximum stream duration for this route.
// [#not-implemented-hide:]
MaxStreamDuration max_stream_duration = 36;
}

Expand Down
42 changes: 6 additions & 36 deletions api/envoy/config/route/v4alpha/route_components.proto

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions docs/root/faq/configuration/timeouts.rst
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@ stream timeouts already introduced above.
is sent to the downstream, which normally happens after the upstream has sent response headers.
This timeout can be used with streaming endpoints to retry if the upstream fails to begin a
response within the timeout.
* The route :ref:`MaxStreamDuration proto <envoy_v3_api_msg_config.route.v3.RouteAction.MaxStreamDuration>`
can be used to override the HttpConnectionManager's
:ref:`max_stream_duration <envoy_v3_api_field_config.core.v3.HttpProtocolOptions.max_stream_duration>`
for individual routes as well as setting both limits and a fixed time offset on grpc-timeout headers.

TCP
---
Expand Down
3 changes: 3 additions & 0 deletions docs/root/version_history/current.rst
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ New Features
* http: added support for :ref:`%DOWNSTREAM_PEER_FINGERPRINT_1% <config_http_conn_man_headers_custom_request_headers>` as custom header.
* http: added :ref:`allow_chunked_length <envoy_v3_api_field_config.core.v3.Http1ProtocolOptions.allow_chunked_length>` configuration option for HTTP/1 codec to allow processing requests/responses with both Content-Length and Transfer-Encoding: chunked headers. If such message is served and option is enabled - per RFC Content-Length is ignored and removed.
* http: added :ref:`CDN Loop filter <envoy_v3_api_msg_extensions.filters.http.cdn_loop.v3alpha.CdnLoopConfig>` and :ref:`documentation <config_http_filters_cdn_loop>`.
* http: added :ref:`MaxStreamDuration proto <envoy_v3_api_msg_config.route.v3.RouteAction.MaxStreamDuration>` for configuring per-route downstream duration timeouts.
* http: introduced new HTTP/1 and HTTP/2 codec implementations that will remove the use of exceptions for control flow due to high risk factors and instead use error statuses. The old behavior is used by default, but the new codecs can be enabled for testing by setting the runtime feature `envoy.reloadable_features.new_codec_behavior` to true. The new codecs will be in development for one month, and then enabled by default while the old codecs are deprecated.
* load balancer: added :ref:`RingHashLbConfig<envoy_v3_api_msg_config.cluster.v3.Cluster.MaglevLbConfig>` to configure the table size of Maglev consistent hash.
* load balancer: added a :ref:`configuration<envoy_v3_api_msg_config.cluster.v3.Cluster.LeastRequestLbConfig>` option to specify the active request bias used by the least request load balancer.
Expand Down Expand Up @@ -151,6 +152,8 @@ Deprecated
field has been deprecated in favor of :ref:`cluster_endpoints_health <envoy_v3_api_field_service.health.v3.EndpointHealthResponse.cluster_endpoints_health>` to maintain
grouping by cluster and locality.
* router: the :ref:`include_vh_rate_limits <envoy_v3_api_field_config.route.v3.RouteAction.include_vh_rate_limits>` field has been deprecated in favor of :ref:`vh_rate_limits <envoy_v3_api_field_extensions.filters.http.ratelimit.v3.RateLimitPerRoute.vh_rate_limits>`.
* router: the :ref:`max_grpc_timeout <envoy_v3_api_field_config.route.v3.RouteAction.max_grpc_timeout>` field has been deprecated in favor of :ref:`grpc_timeout_header_max <envoy_v3_api_field_config.route.v3.RouteAction.MaxStreamDuration.grpc_timeout_header_max>`.
* router: the :ref:`grpc_timeout_offset <envoy_v3_api_field_config.route.v3.RouteAction.grpc_timeout_offset>` field has been deprecated in favor of :ref:`grpc_timeout_header_offset <envoy_v3_api_field_config.route.v3.RouteAction.MaxStreamDuration.grpc_timeout_header_offset>`.
* tap: the :ref:`match_config <envoy_v3_api_field_config.tap.v3.TapConfig.match_config>` field has been deprecated in favor of
:ref:`match <envoy_v3_api_field_config.tap.v3.TapConfig.match>` field.
* ext_authz: the :ref:`dynamic metadata <envoy_v3_api_field_service.auth.v3.OkHttpResponse.dynamic_metadata>` field in :ref:`OkHttpResponse <envoy_v3_api_msg_service.auth.v3.OkHttpResponse>`
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions include/envoy/router/router.h
Original file line number Diff line number Diff line change
Expand Up @@ -795,6 +795,22 @@ class RouteEntry : public ResponseEntry {
*/
virtual absl::optional<std::chrono::milliseconds> idleTimeout() const PURE;

/**
* @return optional<std::chrono::milliseconds> the route's maximum stream duration.
*/
virtual absl::optional<std::chrono::milliseconds> maxStreamDuration() const PURE;

/**
* @return optional<std::chrono::milliseconds> the max grpc-timeout this route will allow.
*/
virtual absl::optional<std::chrono::milliseconds> grpcTimeoutHeaderMax() const PURE;

/**
* @return optional<std::chrono::milliseconds> the delta between grpc-timeout and enforced grpc
* timeout.
*/
virtual absl::optional<std::chrono::milliseconds> grpcTimeoutHeaderOffset() const PURE;

/**
* @return absl::optional<std::chrono::milliseconds> the maximum allowed timeout value derived
* from 'grpc-timeout' header of a gRPC request. Non-present value disables use of 'grpc-timeout'
Expand Down
22 changes: 10 additions & 12 deletions source/common/grpc/common.cc
Original file line number Diff line number Diff line change
Expand Up @@ -161,9 +161,10 @@ Buffer::InstancePtr Common::serializeMessage(const Protobuf::Message& message) {
return body;
}

std::chrono::milliseconds Common::getGrpcTimeout(const Http::RequestHeaderMap& request_headers) {
std::chrono::milliseconds timeout(0);
absl::optional<std::chrono::milliseconds>
Common::getGrpcTimeout(const Http::RequestHeaderMap& request_headers) {
const Http::HeaderEntry* header_grpc_timeout_entry = request_headers.GrpcTimeout();
std::chrono::milliseconds timeout;
if (header_grpc_timeout_entry) {
uint64_t grpc_timeout;
// TODO(dnoe): Migrate to pure string_view (#6580)
Expand All @@ -172,35 +173,32 @@ std::chrono::milliseconds Common::getGrpcTimeout(const Http::RequestHeaderMap& r
if (unit != nullptr && *unit != '\0') {
switch (*unit) {
case 'H':
timeout = std::chrono::hours(grpc_timeout);
break;
return std::chrono::hours(grpc_timeout);
case 'M':
timeout = std::chrono::minutes(grpc_timeout);
break;
return std::chrono::minutes(grpc_timeout);
case 'S':
timeout = std::chrono::seconds(grpc_timeout);
break;
return std::chrono::seconds(grpc_timeout);
case 'm':
timeout = std::chrono::milliseconds(grpc_timeout);
return std::chrono::milliseconds(grpc_timeout);
break;
case 'u':
timeout = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::microseconds(grpc_timeout));
if (timeout < std::chrono::microseconds(grpc_timeout)) {
timeout++;
}
break;
return timeout;
case 'n':
timeout = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::nanoseconds(grpc_timeout));
if (timeout < std::chrono::nanoseconds(grpc_timeout)) {
timeout++;
}
break;
return timeout;
}
}
}
return timeout;
return absl::nullopt;
}

void Common::toGrpcTimeout(const std::chrono::milliseconds& timeout,
Expand Down
Loading