Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

router: allow propagating attempt count in header #4536

Merged
merged 23 commits into from
Oct 8, 2018

Conversation

snowp
Copy link
Contributor

@snowp snowp commented Sep 26, 2018

Adds the ability to configure x-envoy-attempt-count to be set to the attempt count to allow upstreams to infer how many times the request has been retried.

Risk Level: Medium
Testing: Integration test
Docs Changes: Updated the header documentation to include new header
Release Notes: Added release note
Fixes #4210

Signed-off-by: Snow Pettersen <[email protected]>
Signed-off-by: Snow Pettersen <[email protected]>
Signed-off-by: Snow Pettersen <[email protected]>
@junr03 junr03 self-assigned this Sep 27, 2018
Copy link
Member

@junr03 junr03 left a comment

Choose a reason for hiding this comment

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

thanks! A few comments

@@ -109,6 +109,10 @@ message VirtualHost {
// specific; see the :ref:`HTTP filter documentation <config_http_filters>`
// for if and how it is utilized.
map<string, google.protobuf.Struct> per_filter_config = 12;

// Decides whether the x-envoy-attempt-count header should be included in upstream
Copy link
Member

Choose a reason for hiding this comment

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

add what the default is.

@@ -563,6 +568,7 @@ class RouteEntryImplBase : public RouteEntry,
HeaderParserPtr response_headers_parser_;
envoy::api::v2::core::Metadata metadata_;
const bool match_grpc_;
const bool include_attempt_count_;
Copy link
Member

Choose a reason for hiding this comment

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

looks to me like this instance variable in the route entry is not actually being used, as we end up getting the setting from the vhost, right?

@@ -734,6 +734,47 @@ void HttpIntegrationTest::testRetry() {
EXPECT_EQ(512U, response->body().size());
}

// Tests that the x-envoy-attempt-count header is propagated set on the upstream request
Copy link
Member

Choose a reason for hiding this comment

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

nit: is propagated properly set // propagated set. Not sure which one you were going for.

@@ -109,6 +109,8 @@ TEST_P(IntegrationTest, RouterUpstreamResponseBeforeRequestComplete) {

TEST_P(IntegrationTest, Retry) { testRetry(); }

TEST_P(IntegrationTest, RetryAttemptCount) { testRetryAttemptCountHeader(); }
Copy link
Member

Choose a reason for hiding this comment

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

I think we are lacking unit test on making sure the configuration is wired up correctly, probably in test/common/router/config_impl_test.cc.

Less clear to me is if we should also have unit testing at the router level in test/common/router/router_test.cc

@@ -77,6 +77,7 @@ Version history
* rbac network filter: a :ref:`role-based access control network filter <config_network_filters_rbac>` has been added.
* rest-api: added ability to set the :ref:`request timeout <envoy_api_field_core.ApiConfigSource.request_timeout>` for REST API requests.
* router: added ability to set request/response headers at the :ref:`envoy_api_msg_route.Route` level.
* router: addded ability to set attempt count in upstream requests, see :ref:`envoy_api_field_route.VirtualHost.include_request_attempt_count`.
Copy link
Member

Choose a reason for hiding this comment

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

nit: s/addded/added.

And also this introduces warning,

Warning, treated as error:
/../generated/rst/intro/version_history.rst:80:undefined label: envoy_api_field_route.virtualhost.include_request_attempt_count (if the link has no caption the label must precede a section header)

Probably something like the following might work:

* 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>`.

snowp added 4 commits October 2, 2018 14:36
Signed-off-by: Snow Pettersen <[email protected]>
Signed-off-by: Snow Pettersen <[email protected]>
Signed-off-by: Snow Pettersen <[email protected]>
@snowp
Copy link
Contributor Author

snowp commented Oct 4, 2018

@junr03 This is ready for another review

@junr03
Copy link
Member

junr03 commented Oct 5, 2018

looks good to me @ggreenway can you take a look?

@ggreenway
Copy link
Contributor

This is not my area of expertise. @alyssawilk can you take this one?

@ggreenway ggreenway assigned alyssawilk and unassigned ggreenway Oct 5, 2018
@ggreenway
Copy link
Contributor

@snowp you have merge conflict :(

@mattklein123
Copy link
Member

@alyssawilk is out today. I can take it.

@mattklein123 mattklein123 self-assigned this Oct 5, 2018
Copy link
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

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

Looks great. A few comments. Thank you!

@@ -109,6 +109,10 @@ message VirtualHost {
// specific; see the :ref:`HTTP filter documentation <config_http_filters>`
// for if and how it is utilized.
map<string, google.protobuf.Struct> per_filter_config = 12;

// Decides whether the x-envoy-attempt-count header should be included in upstream
Copy link
Member

Choose a reason for hiding this comment

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

/**
* @return bool whether x-envoy-attempt-count should be included on the upstream request.
*/
virtual bool includeAttemptCount() const PURE;
Copy link
Member

Choose a reason for hiding this comment

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

I only see configuration for virtual host. Is this used? Do we need route configuration also? If we don't want this now can you comment that this is pulled from the virtual host config currently?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's used since I plumb through the option from the vhost. I'll add a comment

Re whether we want it on the route configuration: at least for our purposes we want to enable it on per domain/vhost level, so I'd defer per route configuration until somebody needs it

@@ -287,6 +287,11 @@ Http::FilterHeadersStatus Filter::decodeHeaders(Http::HeaderMap& headers, bool e
headers.removeEnvoyUpstreamRequestTimeoutAltResponse();
}

include_attempt_count_ = route_entry_->includeAttemptCount();
if (include_attempt_count_) {
headers.insertEnvoyAttemptCount().value(1);
Copy link
Member

Choose a reason for hiding this comment

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

nit: use attempt_count_ here which you initialize to 1?

Copy link
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

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

LGTM, small doc issues. Thank you!

@@ -22,6 +22,16 @@ ingress/response path. They are documented in this section.
.. contents::
:local:

.. _config_http_filters_router_x-envoy-attempt-count:
Copy link
Member

Choose a reason for hiding this comment

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

I think this should be in the "set" section below vs. the "consumed" section?

// Decides whether the x-envoy-attempt-count header should be included in upstream
// <config_http_filters_router_x-envoy-original-path>` header.
// Decides whether the :ref:`x-envoy-attempt-count
// <config_http_filters_router_x-envoy-attempt-count>` header should be included in upstream
Copy link
Member

Choose a reason for hiding this comment

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

nit: s/in/in the

snowp added 2 commits October 5, 2018 18:11
Signed-off-by: Snow Pettersen <[email protected]>
mattklein123
mattklein123 previously approved these changes Oct 5, 2018
Copy link
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

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

Thank you!

@mattklein123
Copy link
Member

@snowp sorry needs a master merge.

// Decides whether the :ref:`x-envoy-attempt-count
// <config_http_filters_router_x-envoy-attempt-count>` header should be included
// in the upstream request. Defaults to false.
bool include_request_attempt_count = 14;
Copy link
Member

Choose a reason for hiding this comment

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

nit: update next free id in comment above.

@@ -109,6 +109,12 @@ message VirtualHost {
// specific; see the :ref:`HTTP filter documentation <config_http_filters>`
// for if and how it is utilized.
map<string, google.protobuf.Struct> per_filter_config = 12;

// <config_http_filters_router_x-envoy-original-path>` header.
Copy link
Member

Choose a reason for hiding this comment

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

is this related to x-envoy-original-path?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

no it's not, that must have snuck it somehow

@@ -109,6 +109,12 @@ message VirtualHost {
// specific; see the :ref:`HTTP filter documentation <config_http_filters>`
// for if and how it is utilized.
map<string, google.protobuf.Struct> per_filter_config = 12;

// <config_http_filters_router_x-envoy-original-path>` header.
// Decides whether the :ref:`x-envoy-attempt-count
Copy link
Member

Choose a reason for hiding this comment

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

How this play with suppress_envoy_headers in router.proto?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right now it doesn't interact with it at all, not sure if it would be more confusing to have two different flags affect whether it's enabled? My take on suppress_envoy_headers is that it's a way to disable headers that are injected by Envoy by default, although I can see how still getting x-envoy-* headers sent with that true (with include_request_attempt_count_header: true) could be confusing. Thoughts?

Copy link
Member

Choose a reason for hiding this comment

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

I'm fine either way, perhaps document the behavior when both are true? @htuch any suggestion?

@@ -287,6 +287,11 @@ Http::FilterHeadersStatus Filter::decodeHeaders(Http::HeaderMap& headers, bool e
headers.removeEnvoyUpstreamRequestTimeoutAltResponse();
}

include_attempt_count_ = route_entry_->includeAttemptCount();
if (include_attempt_count_) {
headers.insertEnvoyAttemptCount().value(attempt_count_);
Copy link
Contributor

Choose a reason for hiding this comment

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

My one drive by comment is it's worth documenting how this will work when you have 2 levels of Envoys. It's not uncommon in production to have [L1 Envoy][L2 Envoy][upstream]. Granted, it's often a bad idea to have both levels doing retries as more often than not you end up with exponential retries (L2 retries 3 times, fails, L1 retries to new L1, L2 retries 3 times fails, etc) so I don't think it's a bad thing for the last Envoy in the chain to force-overwritten, but I think it's worth calling out it replaces any existing header.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That sounds reasonable, I'll update the documentation

Copy link
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

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

LGTM, thank you!

@@ -3,6 +3,8 @@ Version history

1.9.0 (pending)
===============
* router: added ability to set attempt count in upstream requests, see :ref:`virtual host's include request
Copy link
Member

Choose a reason for hiding this comment

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

nit: alpha order.

@snowp
Copy link
Contributor Author

snowp commented Oct 8, 2018

@mattklein123 ptal

@mattklein123 mattklein123 merged commit fdfa5bd into envoyproxy:master Oct 8, 2018
@snowp snowp deleted the attempted-count branch October 8, 2018 21:40
@perlun perlun mentioned this pull request Oct 9, 2018
perlun added a commit to perlun/envoy that referenced this pull request Oct 9, 2018
Noted while skimming through envoyproxy#4536.

Signed-off-by: Per Lundberg <[email protected]>
alyssawilk pushed a commit that referenced this pull request Oct 9, 2018
Noted while skimming through #4536.

Signed-off-by: Per Lundberg <[email protected]>
aa-stripe pushed a commit to aa-stripe/envoy that referenced this pull request Oct 11, 2018
aa-stripe pushed a commit to aa-stripe/envoy that referenced this pull request Oct 11, 2018
Noted while skimming through envoyproxy#4536.

Signed-off-by: Per Lundberg <[email protected]>
Signed-off-by: Aaltan Ahmad <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants