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

Use dynamicMetadata to construct metadataMatchCriteria() #3254

Merged
Merged
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Return the cached result of metadataMatchCriteria()
Signed-off-by: Raul Gutierrez Segales <[email protected]>
  • Loading branch information
Raul Gutierrez Segales committed May 3, 2018
commit d29a4a5d3f47cd9c12bb759821262d619a513665
7 changes: 7 additions & 0 deletions source/common/router/router.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,13 @@ class Filter : Logger::Loggable<Logger::Id::router>,
}
const Router::MetadataMatchCriteria* metadataMatchCriteria() override {
Copy link
Member

Choose a reason for hiding this comment

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

In the retry case you may end up calling this method multiple times. Is it worth checking to see if metadata_match_ is not nullptr and returning if not? Is there any chance that doing the merge multiple times could have strange effects? If not to both of these, I would still add a comment about how this can happen multiple times for a single request.

Copy link
Member Author

Choose a reason for hiding this comment

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

I think checking for nullptr and returning early is worth it. Multiple calls to merge should yield the same result, but we can avoid the computation and creating new objects.

Copy link
Member Author

Choose a reason for hiding this comment

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

@mattklein123 hold on -- can the route_entry_ for a request change (e.g.: someone called clearRouteCache() and then metadataMatchCriteria() gets called again)? In that case, caching the result for metadataMatchCriteria() would be wrong... we'd want to recompute.

cc: @zuercher @htuch

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 it's ok, as long as metadataMatchCriteria() isn't invoked until LoadBalancer::chooseHost, which happens during Router::Filter::getConnPool in Filter::decodeHeaders and again in Filter::doRetry. The route_ and route_entry_ get set in decodeHeaders before load balancing, and I believe that once that happens they do not change.

clearRouteCache operates on the Http::ConnectionManagerImpl::ActiveStreamFilterBase which ends up being the source of the route_ and therefore route_entry_ via its implementation of StreamFilterCallbacks::route().

Copy link
Member

Choose a reason for hiding this comment

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

This seems right, can we add an ASSERT to this effect (i.e. if we get called twice, the route entry is the same)?

if (route_entry_) {
// Have we been called before? If so, there's no need to recompute because
// by the time this method is called for the first time, route_entry_ should
// not change anymore.
if (metadata_match_ != nullptr) {
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 a test for this as well? Thanks.

Copy link
Member Author

Choose a reason for hiding this comment

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

@htuch done — plus two bonus tests:

  • using > 1 key/value pair in dynamicMetadata()
  • mixing a key that overrides the route entry with one that doesn't

thanks for the review!

return metadata_match_.get();
}

// The request's metadata, if present, takes precedence over the route's.
const auto& request_metadata = callbacks_->requestInfo().dynamicMetadata().filter_metadata();
const auto filter_it = request_metadata.find(Envoy::Config::MetadataFilters::get().ENVOY_LB);
Expand Down