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
3 changes: 3 additions & 0 deletions docs/root/configuration/http_filters/router_filter.rst
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,9 @@ cancelled
deadline-exceeded
Envoy will attempt a retry if the gRPC status code in the response headers is "deadline-exceeded" (4)

internal
Copy link
Member

Choose a reason for hiding this comment

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

Please add a release note for this.

Envoy will attempt to retry if the gRPC status code in the response headers is "internal" (13)
Copy link
Member

Choose a reason for hiding this comment

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

nit: empty line after this


resource-exhausted
Envoy will attempt a retry if the gRPC status code in the response headers is "resource-exhausted" (8)

Expand Down
1 change: 1 addition & 0 deletions docs/root/intro/version_history.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Version history
* router: added ability to configure arbitrary :ref:`retriable status codes. <envoy_api_field_route.RouteAction.RetryPolicy.retriable_status_codes>`
* router: added ability to set attempt count in upstream requests, see :ref:`virtual host's include request
attempt count flag <envoy_api_field_route.VirtualHost.include_request_attempt_count>`.
* router: added internal :ref:`grpc-retry-on <config_http_filters_router_x-envoy-retry-grpc-on>` policy.
* router: when :ref:`max_grpc_timeout <envoy_api_field_route.RouteAction.max_grpc_timeout>`
is set, Envoy will now add or update the grpc-timeout header to reflect Envoy's expected timeout.
* stats: added :ref:`stats_matcher <envoy_api_field_config.metrics.v2.StatsConfig.stats_matcher>` to the bootstrap config for granular control of stat instantiation.
Expand Down
3 changes: 2 additions & 1 deletion include/envoy/router/router.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,8 @@ class RetryPolicy {
static const uint32_t RETRY_ON_GRPC_DEADLINE_EXCEEDED = 0x40;
static const uint32_t RETRY_ON_GRPC_RESOURCE_EXHAUSTED = 0x80;
static const uint32_t RETRY_ON_GRPC_UNAVAILABLE = 0x100;
static const uint32_t RETRY_ON_RETRIABLE_STATUS_CODES = 0x200;
static const uint32_t RETRY_ON_GRPC_INTERNAL = 0x200;
Copy link
Member

Choose a reason for hiding this comment

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

This is going to conflict with your other change, so up to you how you want to sequence this.

static const uint32_t RETRY_ON_RETRIABLE_STATUS_CODES = 0x400;
// clang-format on

virtual ~RetryPolicy() {}
Expand Down
1 change: 1 addition & 0 deletions source/common/http/headers.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ class HeaderValues {
const std::string DeadlineExceeded{"deadline-exceeded"};
const std::string ResourceExhausted{"resource-exhausted"};
const std::string Unavailable{"unavailable"};
const std::string Internal{"internal"};
} EnvoyRetryOnGrpcValues;

struct {
Expand Down
10 changes: 7 additions & 3 deletions source/common/router/retry_state_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ uint32_t RetryStateImpl::parseRetryGrpcOn(absl::string_view retry_grpc_on_header
ret |= RetryPolicy::RETRY_ON_GRPC_RESOURCE_EXHAUSTED;
} else if (retry_on == Http::Headers::get().EnvoyRetryOnGrpcValues.Unavailable) {
ret |= RetryPolicy::RETRY_ON_GRPC_UNAVAILABLE;
} else if (retry_on == Http::Headers::get().EnvoyRetryOnGrpcValues.Internal) {
ret |= RetryPolicy::RETRY_ON_GRPC_INTERNAL;
}
}

Expand Down Expand Up @@ -239,8 +241,8 @@ bool RetryStateImpl::wouldRetry(const Http::HeaderMap* response_headers,

if (retry_on_ &
(RetryPolicy::RETRY_ON_GRPC_CANCELLED | RetryPolicy::RETRY_ON_GRPC_DEADLINE_EXCEEDED |
RetryPolicy::RETRY_ON_GRPC_RESOURCE_EXHAUSTED |
RetryPolicy::RETRY_ON_GRPC_UNAVAILABLE) &&
RetryPolicy::RETRY_ON_GRPC_RESOURCE_EXHAUSTED | RetryPolicy::RETRY_ON_GRPC_UNAVAILABLE |
RetryPolicy::RETRY_ON_GRPC_INTERNAL) &&
response_headers) {
absl::optional<Grpc::Status::GrpcStatus> status =
Grpc::Common::getGrpcStatus(*response_headers);
Expand All @@ -252,7 +254,9 @@ bool RetryStateImpl::wouldRetry(const Http::HeaderMap* response_headers,
(status.value() == Grpc::Status::ResourceExhausted &&
(retry_on_ & RetryPolicy::RETRY_ON_GRPC_RESOURCE_EXHAUSTED)) ||
(status.value() == Grpc::Status::Unavailable &&
(retry_on_ & RetryPolicy::RETRY_ON_GRPC_UNAVAILABLE))) {
(retry_on_ & RetryPolicy::RETRY_ON_GRPC_UNAVAILABLE)) ||
(status.value() == Grpc::Status::Internal &&
(retry_on_ & RetryPolicy::RETRY_ON_GRPC_INTERNAL))) {
return true;
}
}
Expand Down
14 changes: 14 additions & 0 deletions test/common/router/retry_state_impl_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,20 @@ TEST_F(RouterRetryStateImplTest, PolicyGrpcUnavilable) {
EXPECT_EQ(RetryStatus::No, state_->shouldRetry(&response_headers, no_reset_, callback_));
}

TEST_F(RouterRetryStateImplTest, PolicyGrpcInternal) {
Http::TestHeaderMapImpl request_headers{{"x-envoy-retry-grpc-on", "internal"}};
setup(request_headers);
EXPECT_TRUE(state_->enabled());

Http::TestHeaderMapImpl response_headers{{":status", "200"}, {"grpc-status", "13"}};
expectTimerCreateAndEnable();
EXPECT_EQ(RetryStatus::Yes, state_->shouldRetry(&response_headers, no_reset_, callback_));
EXPECT_CALL(callback_ready_, ready());
retry_timer_->callback_();

EXPECT_EQ(RetryStatus::No, state_->shouldRetry(&response_headers, no_reset_, callback_));
}

TEST_F(RouterRetryStateImplTest, Policy5xxRemote200RemoteReset) {
// Don't retry after reply start.
Http::TestHeaderMapImpl request_headers{{"x-envoy-retry-on", "5xx"}};
Expand Down