-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
config: Honor transport_api_version for non-ADS xDS services #11788
config: Honor transport_api_version for non-ADS xDS services #11788
Conversation
This patch makes sure the chosen endpoint is controlled by the specified `transport_api_version`. For `envoy::config::core::v3::ApiVersion::AUTO`, the endpoint will be inferred from the `type_url`. Signed-off-by: Dhi Aurrahman <[email protected]>
Signed-off-by: Dhi Aurrahman <[email protected]>
Signed-off-by: Dhi Aurrahman <[email protected]>
Signed-off-by: Dhi Aurrahman <[email protected]>
/azp run envoy-presubmit |
Azure Pipelines successfully started running 1 pipeline(s). |
Signed-off-by: Dhi Aurrahman <[email protected]>
/azp run envoy-presubmit |
Azure Pipelines successfully started running 1 pipeline(s). |
Interesting (unrelated) errors on Windows CI:
This is resolved. |
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.
Thanks for taking this on before the next release. Looking at the tests and call sites, I think this makes total sense. However, I'd like to see what we can do to make the implementation in type_to_endpoint.cc
a bit more comprehensible to simple folks like me :)
createServiceToVersionedMap(absl::string_view service, envoy::config::core::v3::ApiVersion version, | ||
const std::array<std::string, 2>& versioned_services) { | ||
return {{static_cast<std::string>(service), | ||
VersionedMap{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.
This is a bit confusing to the reader. Why is there a version, which then maps to more versions and services? Is one of these supported to be transport and one resource version? It's a bit unclear.
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 this loop: https://github.com/envoyproxy/envoy/pull/11788/files#diff-539488a0c7c9a3a8c07a208efbafaf08R73.
This is the list of maps (as the input):
[
{
"envoy.api.v2.RouteDiscoveryService": {
"version_": "V2",
"entries_": {
"V2": "envoy.api.v2.RouteDiscoveryService",
"V3": "envoy.service.route.v3.RouteDiscoveryService"
}
},
"envoy.service.route.v3.RouteDiscoveryService": {
"version_": "V3",
"entries_": {
"V2": "envoy.api.v2.RouteDiscoveryService",
"V3": "envoy.service.route.v3.RouteDiscoveryService"
}
}
},
...
]
The above list of maps will be transformed into:
{
"type.googleapis.com/envoy.api.v2.RouteConfiguration": {
"sotw_grpc_": {
"type_url_versions_": {
"type.googleapis.com/envoy.api.v2.RouteConfiguration": "V2",
"type.googleapis.com/envoy.config.route.v3.RouteConfiguration": "V3"
},
"methods_": {
"V2": "envoy.api.v2.RouteDiscoveryService.StreamRoutes",
"V3": "envoy.service.route.v3.RouteDiscoveryService.StreamRoutes"
},
...
}
},
"type.googleapis.com/envoy.config.route.v3.RouteConfiguration": {
"sotw_grpc_": {
"type_url_versions_": {
"type.googleapis.com/envoy.api.v2.RouteConfiguration": "V2",
"type.googleapis.com/envoy.config.route.v3.RouteConfiguration": "V3"
},
"methods_": {
"V2": "envoy.api.v2.RouteDiscoveryService.StreamRoutes",
"V3": "envoy.service.route.v3.RouteDiscoveryService.StreamRoutes"
}
},
...
}
...
}
So it is convenient to get the effective transport_api_version
when the value isAUTO
: given a resource_type_url
(e.g. type.googleapis.com/envoy.api.v2.RouteConfiguration
) and type_url_versions_
map (we carry this along for each entry).
effective_version = type_url_versions_[resource_type_url]
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 probably fine as is, but I'd suggest adding in some type aliases for the keys that are std::string
, so it's clear what is being keyed on, and also adding to the code comments some examples like above.
The other alternative is to compute all of this at runtime, instead of building all the maps, but it's unclear to me if that would be any simpler.
}; | ||
|
||
// Map from resource type URL to versioned service RPC methods. | ||
using ServiceToVersionedMap = std::unordered_map<std::string, VersionedMap>; |
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 all this complexity because you want to support resource/transport independence still? I think it might be clearer if you provide some example maps and explain how this structure is used.
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.
Haha. I think I made this too complicated in the price to support AUTO
to default to the inferred "version" from a particular resource type URL. I will try to play around and simplify this.
Correct, this covered at line 66 of the proposed porting doc. https://github.com/envoyproxy/envoy/pull/11721/files#diff-d437a64a5901ee0232b3ba2fc7edff7aR66 In short we aren't talking c++ but K&R CPP, and although GCC and CLang make provisions to entangle line parsing and macro invocation, this still isn't part of the spec. |
Signed-off-by: Dhi Aurrahman <[email protected]>
Signed-off-by: Dhi Aurrahman <[email protected]>
Signed-off-by: Dhi Aurrahman <[email protected]>
Signed-off-by: Dhi Aurrahman <[email protected]>
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.
Thanks, this is a lot clearer. Flushing a few comments.
/wait
// } | ||
using ServiceVersionInfoMap = std::unordered_map<ServiceName, ServiceVersionInfo>; | ||
|
||
// This creates a ServiceToServiceVersionInfoMap, with service name (e.g. |
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 returns a ServiceVersionInfoMap
, not ServiceToServiceVersionInfoMap
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.
Thanks for catching this! Updated.
using VersionedMethodMap = std::unordered_map<envoy::config::core::v3::ApiVersion, MethodName>; | ||
|
||
struct VersionedDiscoveryType { | ||
// This holds a map of type url to its corresponding version. For example: |
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.
Corresponding transport or resource version
// } | ||
TypeUrlVersionMap type_url_versions_; | ||
|
||
// Versioned discovery service RPC method fully qualified names. e.g. |
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.
Again, would be good to clarify resource or transport version where possible (even if somewhat obvious here). Because, later we do tend to conflate them when making a default decision.
Signed-off-by: Dhi Aurrahman <[email protected]>
@dio PR looks good now. I guess one question I have is whether we are technically breaking behavior here (taking a step back). Honoring transport API version makes sense, but the default for AUTO was set as v2, see https://github.com/envoyproxy/envoy/blob/master/api/envoy/config/core/v3/config_source.proto#L27. Do we need a semantically breaking API change as well? CC @envoyproxy/api-shepherds |
@htuch that's interesting. I missed that part. Before this is in, the behavior was defaulting to v3 when you have v3 resource, so that's why I chose this path for |
@lizan @markdroth interested if you have any opinions on this as API shepherds. Basically, we've been saying that AUTO really means you retain v2 (for backwards compatibility). This PR moved the default transport version when AUTO to that of the resource version. Is this a breaking change? Is it preferable? |
Since gRPC hasn't yet implemented v3 support, there are no backward-compatibility issues for us; it's just a question of what behavior we actually want. Given that both Envoy and gRPC are going to support receiving a different resource version than the one we requested, I am wondering if setting the transport version from the resource version is actually a bit backwards. It seems like what we actually want is the other way around: we should by default set the resource version from the transport version, so that what we send is always consistently within a particular version. What we receive is completely independent of that, so setting the resource version differently from the transport version should be extremely rare. (I don't think we would even bother supporting that ability in gRPC.) If we do go with setting the transport version from the resource version, the description here will need to be more nuanced, since there are cases where there is no resource version -- e.g., when using |
Interesting. Since the way of writing config for envoy is by specifying the resource |
I think going forward, it would be ideal to have explicit versions specified, so we eliminate ambiguity during versions transitions. So, really, we want to discourage use of |
Signed-off-by: Dhi Aurrahman <[email protected]>
Sounds good. Updated to default to |
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, thanks!
/azp run envoy-presubmit |
Azure Pipelines successfully started running 1 pipeline(s). |
macOS 😔. |
/azp run envoy-presubmit |
Azure Pipelines successfully started running 1 pipeline(s). |
/azp run envoy-presubmit |
Azure Pipelines successfully started running 1 pipeline(s). |
/azp run envoy-presubmit |
Azure Pipelines successfully started running 1 pipeline(s). |
…oxy#11788) This patch makes sure the chosen endpoint is controlled by the specified transport_api_version. For transport_api_version that equals envoy::config::core::v3::ApiVersion::AUTO, the endpoint will be defaulted to envoy::config::core::v3::ApiVersion::V2. Risk Level: Low Testing: Unit. Docs Changes: N/A Release Notes: N/A (no behavior change) Fix envoyproxy#10650 Signed-off-by: Dhi Aurrahman <[email protected]> Signed-off-by: scheler <[email protected]>
Commit Message:
This patch makes sure the chosen endpoint is controlled by the specified
transport_api_version
. Fortransport_api_version
that equalsenvoy::config::core::v3::ApiVersion::AUTO
, the endpoint will be defaulted toenvoy::config::core::v3::ApiVersion::V2
.Additional Description:
Risk Level: Low
Testing: Unit.
Docs Changes: N/A
Release Notes: N/A (no behavior change)
Fix #10650
Signed-off-by: Dhi Aurrahman [email protected]