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
Implement cookie hashing for v2 API #1766
Conversation
Support using a cookie as an input source for HTTP ketama hashing. Not yet implemented for the v2 API: setting a cookie if TTL is nonzero. Signed-off-by: Alex Konradi <akonradi@google.com>
Signed-off-by: Alex Konradi <akonradi@google.com>
This will be used to implement the second half of cookie-based HTTP ketama routing. If the route is appropriately configured, clients without the routing cookie set should receive a "Set-Cookie" header in the response that sets the appropriate cookie. Signed-off-by: Alex Konradi <akonradi@google.com>
If the configured TTL for the cookie hash policy is nonzero, then add a Set-Cookie header to the stream and use the randomly selected value for routing. Fixes envoyproxy#1295 Signed-off-by: Alex Konradi <akonradi@google.com>
@alyssawilk can you take this review? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, a few comments on hasSetCookie(). Can we avoid repeated iteration over all the headers?
source/common/http/utility.cc
Outdated
@@ -121,6 +121,41 @@ std::string Utility::parseCookieValue(const HeaderMap& headers, const std::strin | |||
return state.ret_; | |||
} | |||
|
|||
bool Utility::hasSetCookie(const HeaderMap& headers, const std::string& key) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like it shouldn't require iteration. Is there an issue with using HeaderMap::get() ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, I think I see the issue which is that get() only returns the first occurrence of that header, and that's not sufficient. But maybe we can avoid calling hasSetCookie()
multiple times and having the scan all the headers each time.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, get() is insufficient. I'll make it do something a little smarter.
source/common/router/config_impl.cc
Outdated
|
||
private: | ||
const std::string key_; | ||
const long ttl_; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you use a comment (or change variable name) to make it clear that the units of ttl_ are seconds?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
drive by: I would just use std::chrono::seconds
source/common/router/config_impl.cc
Outdated
Optional<uint64_t> hash; | ||
for (const HashMethodPtr& hash_impl : hash_impls_) { | ||
const Optional<uint64_t> new_hash = hash_impl->evaluate(downstream_addr, headers); | ||
Optional<uint64_t> new_hash = hash_impl->evaluate(downstream_addr, headers, add_cookie); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not clear to me why this can't be const anymore.
source/common/router/router.cc
Outdated
const int max_age = std::get<2>(cookie); | ||
|
||
// Don't overwrite a cookie if it's already set by the upstream host | ||
if (Http::Utility::hasSetCookie(*headers, key)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The iteration in hasSetCookie()
seems especially unpleasant given the call here: We call hasSetCookie() multiple times if there are multiple downstream_set_cookies_, and each time it iterates over the entire header map.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the best that can be done right now is to add a perf TODO here. This can be dealt with by potentially working on the TODO in header_map_impl which would allow set-cookie to become an O(1) header but still support append/multiples. I have thoughts on how to do this but probabably out of scope for this PR.
source/common/router/router.h
Outdated
@@ -264,6 +274,7 @@ class Filter : Logger::Loggable<Logger::Id::router>, | |||
UpstreamRequestPtr upstream_request_; | |||
Http::HeaderMap* downstream_headers_{}; | |||
Http::HeaderMap* downstream_trailers_{}; | |||
std::list<std::tuple<std::string, std::string, int>> downstream_set_cookies_; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it might be a good idea to create an explicit type instead of using tuple here.
Why std::list
instead of std::vector
?
This preserves the const-ness of Filter::hashKey(). While addDownstreamSetCookie does modify internal state, the changes are only visible to callers of onUpstreamHeaders, which is not const. Signed-off-by: Alex Konradi <akonradi@google.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great start!
Glad you started off getting multiple cookie headers - I probably would have missed that possibility in review :-P
source/common/router/router.cc
Outdated
const int max_age = std::get<2>(cookie); | ||
|
||
// Don't overwrite a cookie if it's already set by the upstream host | ||
if (Http::Utility::hasSetCookie(*headers, key)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we think there's a need for this yet? It seems unlikely that upstream can set a cookie which will hash back to the "correct" server. I suppose we could check to make sure we're replacing - I'm not sure what browsers do if they get two set-cookies with the same key in the same response...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair. I guess the only thing this actually does is allow the upstream host to throw the downstream client to another random server since it can't really even pick which one. Chrome picks the second value if the same cookie is set twice, and I'd guess the last one generally.
source/common/http/utility.cc
Outdated
State* state = static_cast<State*>(context); | ||
// If the key matches, parse the value from the rest of the cookie string. | ||
if (k == state->key_) { | ||
state->ret_ = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can early return true at this point correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, the iterate() function doesn't return early, though that'd make sense for both of the cookie-related functions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feel free to make iterate callback return a bool for early exit. Or just put in a TODO
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@akonradi Can you add a TODO for this? I think it'd be a useful feature for the iterate to allow early-exit.
state.key_ = key; | ||
state.ret_ = false; | ||
|
||
headers.iterate( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is basically the same as parseCookieValue but skipping the string copy, right? I wonder if it's worth having a comon helper with a boolean to copy the string or not. Optional - if you prefer it this way feel free to leave it this way
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Cookie header has multiple cookie values inline whereas a Set-Cookie header has only a single cookie value. There's an extra inner loop in parseCookieValue that hasSetCookie doesn't need.
} else if (!value.empty()) { | ||
hash.value(HashUtil::xxHash64(value)); | ||
} | ||
return hash; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So if there's no existing cookie and the TTL is 0, shouldn't we still hash, and just not set the cookie?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not here, because there's nothing to hash on. The Router::Filter does that already when none of the policies return a hash.
include/envoy/router/router.h
Outdated
@@ -216,14 +216,23 @@ class HashPolicy { | |||
virtual ~HashPolicy() {} | |||
|
|||
/** | |||
* A callback used for requesting that a random cookie be set with the given |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we really want a random cookie.
Imagine we're doing this because we want a client to consistently land on the same server. now imagine the client is using H2, and sends 3 requests "simultaneously" on one connection. Each will have no set cookie, so each will get a random hash, land on a random backend, and get a random cookie set. Whichever response lands last will "win". We probably want to hash on something stable for the connection to ensure we get consistent routing before the cookie is received.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also an integration test for this case would be nice, making sure the cookie is consistent (don't care what it is) between requests. You should be able to crib heavily from (or simply extend config for) existing http2 tests which have multiple simultaneous requests and responses.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this comment ("random") be updated?
I think I may be way way late to this party, but I wanted to briefly discuss an alternate design with some different tradeoffs: What if instead of hashing on a cookie, we make envoy generate a cookie with the chosen upstream instance encoded in it. Advantages:
Disadvantages:
Sorry if this has been discussed previously. |
@ggreenway The issue there is that the load will become unbalanced as new upstream hosts are added/discovered, since only downstream clients that have cookies assigned after those hosts join will have any chance of being assigned to them. The other clients will continue to be routed to their previous hosts. |
That could be managed by defaulting to picking least loaded in the case
there's no cookie, but I think that'd be well outside the scope of this PR
:-)
…On Thu, Sep 28, 2017 at 4:51 PM, akonradi ***@***.***> wrote:
@ggreenway <https://github.com/ggreenway> The issue there is that the
load will become unbalanced as new upstream hosts are added/discovered,
since only downstream clients that have cookies assigned after those hosts
join will have any chance of being assigned to them.
—
You are receiving this because your review was requested.
Reply to this email directly, view it on GitHub
<#1766 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/ARYFvR3grxVVU5dLwp19IrNPtlz3vk5Rks5snAbAgaJpZM4PnWva>
.
|
@akonradi Agreed. I think it depends on the upstream app which is better (more stickiness vs more even distribution). And it depends on how long the clients stick around (if they make a handful of requests in under a minute, the load will stay pretty evenly balanced; if they make requests over hours/days with the same cookie, it will get more unbalanced). |
…ie-hash Signed-off-by: Alex Konradi <akonradi@google.com>
Signed-off-by: Alex Konradi <akonradi@google.com>
Signed-off-by: Alex Konradi <akonradi@google.com>
Signed-off-by: Alex Konradi <akonradi@google.com>
Signed-off-by: Alex Konradi <akonradi@google.com>
@ggreenway can you clarify on what you mean by "What if instead of hashing on a cookie, we make envoy generate a cookie with the chosen upstream instance encoded in it." ? |
@rshriram I mean that, instead of generating a cookie with a random value that then gets fed into a consistent-hash load-balancer algorithm, we generate a cookie that contains "ip:port" (probably encrypted or hashed or similar to not leak internals). When the client makes the next request and sends us this cookie, we check if the specified ip:port is still in the upstream pool. If it is, we use it. If it is not, we use a fallback load balancing mechanism (round-robin, random, least-conns, etc) and send back a new cookie with the new ip:port. |
Signed-off-by: Alex Konradi <akonradi@google.com>
Signed-off-by: Alex Konradi <akonradi@google.com>
…p-routing-cookie-hash Signed-off-by: Alex Konradi <akonradi@google.com>
The tests fail because one of the added integration tests won't work until #1798 is resolved (and merged into this branch). |
Now that #1812 has merged, could you merge and rerun tests? Thanks. |
…ie-hash Signed-off-by: Alex Konradi <akonradi@google.com>
Passes all tests after merging head (which includes #1812) |
@alyssawilk can you do the final approval/merge as appropriate? |
include/envoy/router/router.h
Outdated
@@ -216,14 +216,23 @@ class HashPolicy { | |||
virtual ~HashPolicy() {} | |||
|
|||
/** | |||
* A callback used for requesting that a random cookie be set with the given |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this comment ("random") be updated?
source/common/router/router.h
Outdated
* to be sent to the downstream host. | ||
* @return std::string the value of the new cookie | ||
* | ||
* marked const so it can be called from hashKey(), and because all mutated |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not seeing much use of mutable in the envoy code base, and generally for things like stats.
I'm having trouble sorting this out without patching and compiling but would it be possible to instead pass in a list downstream_set_cookies in as an argument rather than accessing it as a member variable, so the member doesn't have to be mutable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After talking in-person and thinking about this some more, I realized that there's no way to avoid having mutable
somewhere. The call graph that hits addDownstreamSetCookie()
always goes through Filter::hashKey()
, which is itself const. Passing a mutable list of cookies in would also work but hashKey()
would then be the mutating function masquerading as const.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we should change hashKey()
to be non-const? While conceptually it starts out as a simple computational hash, if we're going to start modifying the actual request, let's just be upfront about it I reckon.
source/common/router/router.h
Outdated
// The cookie value should be the same per connection so that if multiple | ||
// streams race on the same path, they all receive the same cookie. | ||
std::string value; | ||
const Network::Connection* conn = callbacks_->connection(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
downstreamConnection()?
|
||
EXPECT_FALSE(config.usesRuntime()); | ||
|
||
{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not in the style guide (so optional) but Harvey and I encourage test comments so folks less familiar with the code can easily see what's going on. Like
// With no cookie set no hash will be generated
// With non-configured cookies set, the hash still will not be generated
// Finally with the configured "hash" cookie set, a hash will be generated.
hash_2 = | ||
route->routeEntry()->hashPolicy()->generateHash("", headers, add_cookie_nop_).value(); | ||
} | ||
EXPECT_NE(hash_1, hash_2); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this could be a separate test since it's going from "is a hash generated or not" to "are generated hashes the same"
If you stick cm_ and runtime_ as member variables of the test fixture and have a utility function which creates and returns cookie policy, you'll be able to minimize code duplication
source/common/router/router.h
Outdated
*/ | ||
std::string addDownstreamSetCookie(const std::string& key, std::chrono::seconds max_age) const { | ||
// The cookie value should be the same per connection so that if multiple | ||
// streams race on the same path, they all receive the same cookie. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed, in person I'm not quite sure what the right thing to do here is on path diversity vs hashing consistency.
If most Envoy servers were set up with HTTP browsers hitting a single Envoy it'd be nice to hash on IP rather than Address to have consistent hashing for the 8 HTTP connections. Unfortunately that greatly reduces hash diversity so if you instead have a lot of connections from one source to one dest they'd end up all pointed at the same place.
I'd be inclined to err on the side of not overloading backends, but maybe worth a comment that for the HTTP + multiple connections case there will still be a cookie race.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we going to want to go to a harder form of sticky further down the track? If so, then some of this will be moot.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is part of the convo above, which I think partly happened IRL, but, I'm a little confused as to why the local address is part of the hash. Also related to stickiness per @htuch. Can you maybe add some more detailed comments here on the rationale behind how this is being set / the overall algorithm being used?
served_by.insert( | ||
response.headers().get(Http::LowerCaseString("x-served-by"))->value().c_str()); | ||
}); | ||
EXPECT_EQ(served_by.size(), num_upstreams_); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a bit twitchy about this as it's technically non-deterministic and eventually you'll get an unlucky hash. Think it's worth making num_upstreams_ non-const and bringing it down to 2 for this test or unlikely enough as-is?
|
||
void Http2RingHashIntegrationTest::createUpstreams() { | ||
for (int i = 0; i < num_upstreams_; i++) { | ||
fake_upstreams_.emplace_back(new FakeUpstream(0, FakeHttpConnection::Type::HTTP1, version_)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this would be a generally useful extension to the base integration test but definitely outside the scope of this PR. Consider it as a follow up though :-)
Signed-off-by: Alex Konradi <akonradi@google.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great, almost ready to ship, some final round of comments.
@@ -216,14 +216,23 @@ class HashPolicy { | |||
virtual ~HashPolicy() {} | |||
|
|||
/** | |||
* A callback used for requesting that a cookie be set with the given lifetime. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does this return? What is key
? etc.
@@ -121,6 +121,47 @@ std::string Utility::parseCookieValue(const HeaderMap& headers, const std::strin | |||
return state.ret_; | |||
} | |||
|
|||
std::string Utility::makeSetCookieValue(const std::string& key, const std::string& value, | |||
const std::chrono::seconds max_age) { | |||
return fmt::format("{}=\"{}\"; Max-Age={}", key, value, max_age.count()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any situation in which we might want to ensure that value
is correctly escaped? Probably not today, but seems like something dangerous if value
could come from the user.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed; I've added a comment to the function declaration comment.
source/common/http/utility.cc
Outdated
} | ||
std::string k = value.substr(0, equals_index); | ||
State* state = static_cast<State*>(context); | ||
// If the key matches, parse the value from the rest of the cookie string. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: here we're not doing any further parsing after key match.
source/common/http/utility.cc
Outdated
// Find the set-cookie headers in the request | ||
if (header.key() == Http::Headers::get().SetCookie.get().c_str()) { | ||
const std::string value{header.value().c_str()}; | ||
size_t equals_index = value.find('='); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: const size_t
.
source/common/http/utility.cc
Outdated
// The cookie is malformed if it does not have an `=`. | ||
return; | ||
} | ||
std::string k = value.substr(0, equals_index); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: const
.
@@ -109,6 +134,10 @@ HashPolicyImpl::HashPolicyImpl( | |||
case envoy::api::v2::RouteAction::HashPolicy::kHeader: | |||
hash_impls_.emplace_back(new HeaderHashMethod(hash_policy.header().header_name())); | |||
break; | |||
case envoy::api::v2::RouteAction::HashPolicy::kCookie: | |||
hash_impls_.emplace_back( | |||
new CookieHashMethod(hash_policy.cookie().name(), hash_policy.cookie().ttl().seconds())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would probably be more correct to convert from Duration
to milliseconds and then round or something, but it's probably fine, I don't think anyone is going to care about fractional seconds here.
source/common/router/router.h
Outdated
@@ -138,6 +145,33 @@ class Filter : Logger::Loggable<Logger::Id::router>, | |||
return callbacks_->connection(); | |||
} | |||
|
|||
/** | |||
* Set a pseudo-random cookie with the name @param key and TTL @param max_age |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
source/common/router/router.h
Outdated
* to be sent to the downstream host. | ||
* @return std::string the value of the new cookie | ||
* | ||
* marked const so it can be called from hashKey(), and because all mutated |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we should change hashKey()
to be non-const? While conceptually it starts out as a simple computational hash, if we're going to start modifying the actual request, let's just be upfront about it I reckon.
source/common/router/router.h
Outdated
*/ | ||
std::string addDownstreamSetCookie(const std::string& key, std::chrono::seconds max_age) const { | ||
// The cookie value should be the same per connection so that if multiple | ||
// streams race on the same path, they all receive the same cookie. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we going to want to go to a harder form of sticky further down the track? If so, then some of this will be moot.
source/common/router/router.h
Outdated
if (conn) { | ||
value = conn->remoteAddress().asString() + conn->localAddress().asString(); | ||
} else { | ||
// TODO(akonradi) talk to mattklein123 and figure out when this can happen |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Vague recollection that this could only happen if we had this hash policy on a connection we initiated from Envoy via AsyncClient
, which we never would have? So maybe it should also be an ASSERT
?
source/common/router/router.h
Outdated
// list of cookies to add to upstream headers | ||
// 'mutable' is safe because this is only read in onUpstreamHeaders(), which | ||
// is not const | ||
mutable std::vector<std::string> downstream_set_cookies_; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you know if the default allocator/constructor for vector pre-allocates space? It would be unfortunate to allocate anything in the common case. Wondering if this should be a pointer to a vector and you can allocate it when needed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The clang and GCC standard library vectors don't pre-allocate.
Another random comment: This is a feature this is going to need full end user docs when we figure out the v2 doc situation. @htuch thoughts on just starting a v2_docs.md file on a temporary basis where we at least list things that need full docs? I don't want to lose things that need docs that are not getting implemented in v1. |
Signed-off-by: Alex Konradi <akonradi@google.com>
Signed-off-by: Alex Konradi <akonradi@google.com>
Signed-off-by: Alex Konradi <akonradi@google.com>
Emphasize that this is a method that can modify state. Signed-off-by: Alex Konradi <akonradi@google.com>
source/common/router/router.h
Outdated
ENVOY_LOG(warn, "Downstream connection was null while trying to make a routing cookie"); | ||
} | ||
// need to check for null conn if this is ever used by Http::AsyncClient in the fiture | ||
ASSERT(conn); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: You can remove this ASSERT() as it will crash in an obvious way on the next line.
Signed-off-by: Alex Konradi <akonradi@google.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM pending more comments/docs about the algorithm and some resolution on where to stash temp v2 docs. Unless @htuch has a better idea I would say let's create a v2_temp_docs.md file and stick stuff in there until it can be put into sphinx. This can be a holding ground for doc notes for v2 features that do not exist in v1.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM modulo nits. I think the cookie affinity should be documented separately to this PR, in https://github.com/envoyproxy/data-plane-api/blob/master/api/rds.proto#L222. This is not as feature rich as MD for writing docs, but it's where we will be drawing from when putting together the new docs.
source/common/router/router.h
Outdated
@@ -130,7 +130,7 @@ class Filter : Logger::Loggable<Logger::Id::router>, | |||
void setDecoderFilterCallbacks(Http::StreamDecoderFilterCallbacks& callbacks) override; | |||
|
|||
// Upstream::LoadBalancerContext | |||
Optional<uint64_t> hashKey() const override { | |||
Optional<uint64_t> hashKey() override { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you ASSERT
at the top of here that the downstream cookies are empty? That would help catch multiple accidental calls.
…ie-hash Signed-off-by: Alex Konradi <akonradi@google.com>
Signed-off-by: Alex Konradi <akonradi@google.com>
I think this is ready to ship if we can get a merge. Would be nice to see a PR at https://github.com/envoyproxy/data-plane-api/ for the docs as mentioned above as well. |
…ie-hash Manual resolution of merge conflicts Signed-off-by: Alex Konradi <akonradi@google.com>
Docs pull request: envoyproxy/data-plane-api#194 |
I think the Mac failure is unrelated and that the RDS docs are a good place to continue that conversation, so let's merge. |
* Update api sha (envoyproxy#1753) * Release-0.8: Update envoy sha to bb6762a (envoyproxy#1759) * Update envoy sha to bb6762a * update envoy sha to 12c470e * fix authn/integration tasn issue * Update_Dependencies (envoyproxy#1766) * Build addition artifacts with debug symbols (envoyproxy#1767) * Update_Dependencies (envoyproxy#1768)
…roxy#1780) * Update api sha (envoyproxy#1753) * Release-0.8: Update envoy sha to bb6762a (envoyproxy#1759) * Update envoy sha to bb6762a * update envoy sha to 12c470e * fix authn/integration tasn issue * Update_Dependencies (envoyproxy#1766) * Build addition artifacts with debug symbols (envoyproxy#1767) * Update_Dependencies (envoyproxy#1768) * Update api version to b549a3f770c833bad8f4f3871768c43960ab7309 (envoyproxy#1769) * Update istio.deps * Update repositories.bzl * Update istio.deps * Update istio.deps * Update Envoy to c2baf34. (envoyproxy#1773) Signed-off-by: Piotr Sikora <piotrsikora@google.com> * Update api sha to 8d67e57e3612dae1a3423795bce93a372cfe4fa4 (envoyproxy#1775) * revert api sha change
Description: Similar to #1764, this will help prevent port reuse from concurrently running tests. Risk Level: Low Testing: Local & CI Signed-off-by: Mike Schore <mike.schore@gmail.com> Signed-off-by: JP Simard <jp@jpsim.com>
Description: Similar to #1764, this will help prevent port reuse from concurrently running tests. Risk Level: Low Testing: Local & CI Signed-off-by: Mike Schore <mike.schore@gmail.com> Signed-off-by: JP Simard <jp@jpsim.com>
Add a new Http::CookieHashMethod class that hashes on a cookie in the headers sent by the downstream host. The behavior if a cookie is not found is configurable: if the configured TTL is nonzero, a new cookie is randomly generated and returned to the downstream host as an additional "Set-Cookie" header; otherwise, no hash is returned.
Fixes #1295