Skip to content

Conversation

stevenzzzz
Copy link
Contributor

@stevenzzzz stevenzzzz commented Aug 29, 2018

Add a terminal attribute to request hash policy.

Think about a case where customers want to hash on a cookie if it's present but if it's not present, do best-effort sticky based on something like IP so the customer has a stable hash.

This "terminal" allows request hashing to have the ability of "if A not working, fallback to B.", which also saves time to generate the hash.

Changes:
* Add a terminal attribute to HashMethod, which shortcircuit the hash generating process if a policy is marked terminal and there is a hash computed already.

Signed-off-by: Xin Zhuang stevenzzz@google.com

Description: Add terminal attribute to request hash.
Risk Level: Low
Testing: unit tests.
[Optional Fixes #Issue]
[Optional Deprecated:]

…ow CookieHashMethod to use whole cookies header by not specifying a cookie name.

Changes:
    * Add a terminal attribute to HashMethod, which shortcircuit the hash generating process if a policy is marked terminal and there is a hash computed already.
    * Add QueryParams hash method to hash on URL query parameter value.
    * Add HostPath hash method to hash on HOST and PATH in URL.
    * Allow CookieHashMethod to hash on the cookies header if no cookie key specified.

Signed-off-by: Xin Zhuang <stevenzzz@google.com>
@htuch htuch requested a review from akonradi August 29, 2018 17:41
@htuch
Copy link
Member

htuch commented Aug 29, 2018

@akonradi has best context on this code, so will defer to him for primary review.

Signed-off-by: Xin Zhuang <stevenzzz@stevenzzz6.cam.corp.google.com>
Copy link
Contributor

@akonradi akonradi left a comment

Choose a reason for hiding this comment

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

Sending initial thoughts for discussion while I keep reading the tests.

}

// Specifies a list of hash policies to use for ring hash load balancing. Each
// hash policy is evaluated individually and the combined result is used to
// route the request. The method of combination is deterministic such that
// identical lists of hash policies will produce the same hash. Since a hash
// identical lists of hash policies will produce the same hash.Since a hash
// policy examines specific parts of a request, it can fail to produce a hash
// (i.e. if the hashed header is not present). If (and only if) all configured
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you update this section with info about the terminal field? It seems important but the documentation for it is kind of buried up above.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done.

@@ -190,6 +259,11 @@ HashPolicyImpl::generateHash(const Network::Address::Instance* downstream_addr,
const uint64_t old_value = hash ? ((hash.value() << 1) | (hash.value() >> 63)) : 0;
hash = old_value ^ new_hash.value();
}
// If the policy is a terminal policy and there are hash generated, ignore
Copy link
Contributor

Choose a reason for hiding this comment

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

nits:
"there are hash" -> "a hash was"
"rest" -> "rest of the"

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

Copy link
Contributor

@akonradi akonradi left a comment

Choose a reason for hiding this comment

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

Review of tests.

…about adding the "terminal" attribute.

Test adjusted accordingly.

Signed-off-by: Xin Zhuang <stevenzzz@stevenzzz6.cam.corp.google.com>
@stevenzzzz
Copy link
Contributor Author

@akonradi Hey Alex please take a look at your convenience. :) Thx!

akonradi
akonradi previously approved these changes Aug 31, 2018
Copy link
Contributor

@akonradi akonradi left a comment

Choose a reason for hiding this comment

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

LGTM modulo minor nits.

@@ -1699,6 +1699,63 @@ TEST_F(RouterMatcherHashPolicyTest, HashMultiple) {
EXPECT_NE(hash_h, hash_both);
}

TEST_F(RouterMatcherHashPolicyTest, HashTerminal) {
// Hash pilicy list: cookie, header [terminal=true], user_ip.
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: policy

Copy link
Contributor Author

Choose a reason for hiding this comment

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

oops.


uint64_t hash_1, hash_2;
// Test terminal works when there is hash computed, the rest of the policy
// list is ignored.
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you add a note about how these are using different addresses? It was hard to make out the one-character difference at first glance.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, and done.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

test 123 ( I don't know how github UI works)

@@ -585,6 +585,18 @@ message RouteAction {
// Connection properties hash policy.
ConnectionProperties connection_properties = 3;
}
// Reserve for new policy_specifier.
/* RESERVED */ reserved 4 to 20;
Copy link
Contributor

Choose a reason for hiding this comment

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

Out of curiosity, why are we reserving these field numbers?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think we will add more hash method into the oneof list above and I naively think it'd be nice if we have a ascending order for all the policy_specifier to be added.
Revert it as it's not the general recognition.

Thanks Alex!

Signed-off-by: Xin Zhuang <stevenzzz@stevenzzz6.cam.corp.google.com>
@stevenzzzz stevenzzzz changed the title Add terminal attribute to request hash and two more hash methods. Add terminal attribute to request hash. Aug 31, 2018
Copy link
Member

@htuch htuch left a comment

Choose a reason for hiding this comment

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

Yeah, PR changes look great (thanks @akonradi for the review). I would like to make sure we communicate clearly the value being delivered here.

// [(Header A, true),
// (Cookie B, false),
// (Cookie C, false)]
// The generateHash process ends after computing "header A", as it's a terminal policy.
Copy link
Member

Choose a reason for hiding this comment

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

Can you add to the commit message and comments here the motivation for the terminal attribute; is there some real-world use case where this is important? Knowing what you are working on, I'm sure there is, but it would be helpful to share.

Xin Zhuang added 2 commits September 4, 2018 14:09
Merge updates from upstream.

Signed-off-by: Xin Zhuang <stevenzzz@stevenzzz6.cam.corp.google.com>
Signed-off-by: Xin Zhuang <stevenzzz@stevenzzz6.cam.corp.google.com>
@stevenzzzz
Copy link
Contributor Author

@htuch @akonradi PTAL at your convenience.
Thanks!

Signed-off-by: Xin Zhuang <stevenzzz@stevenzzz6.cam.corp.google.com>

// The flag that shortcircuits the hash computing. This field provides a
// 'fallback' style of configuration: "if a terminal policy doesn't work,
// fallback to rest of the policy list", it saves time when the terminal
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 only about performance, or is there a functional aspect? I.e. avoiding taking unnecessary detail into account when computing the hash? We can talk IRL tomorrow if it would be easier to describe the use case then.

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 about functionality: it provides a fallback for a primary hash method when it didn't work. The performance part is a little gain comes with this attribute.
Updated the PR description to sate it a little bit more clear. Thanks for pointing it out!

Copy link
Member

@htuch htuch left a comment

Choose a reason for hiding this comment

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

Thanks!

@htuch htuch merged commit ee710d0 into envoyproxy:master Sep 5, 2018
@stevenzzzz stevenzzzz deleted the request-hashing branch September 6, 2018 14:10
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.

3 participants