XdsClient: work around gcc bug in std::variant<> (#30394)

* XdsClient: work around gcc bug in std::variant<>

* Automated change: Fix sanity tests

Co-authored-by: markdroth <markdroth@users.noreply.github.com>
pull/30346/head
Mark D. Roth 3 years ago committed by GitHub
parent 5ac68916df
commit dc0fd42d7b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      BUILD
  2. 169
      src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc
  3. 50
      src/core/ext/xds/xds_route_config.cc
  4. 24
      src/core/ext/xds/xds_route_config.h

@ -3998,6 +3998,7 @@ grpc_cc_library(
"iomgr_timer",
"json",
"json_util",
"match",
"orphanable",
"protobuf_any_upb",
"protobuf_duration_upb",
@ -4994,6 +4995,7 @@ grpc_cc_library(
"grpc_trace",
"grpc_xds_client",
"iomgr_fwd",
"match",
"orphanable",
"ref_counted_ptr",
"server_address",

@ -70,6 +70,7 @@
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/gprpp/debug_location.h"
#include "src/core/lib/gprpp/dual_ref_counted.h"
#include "src/core/lib/gprpp/match.h"
#include "src/core/lib/gprpp/orphanable.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
#include "src/core/lib/gprpp/time.h"
@ -472,45 +473,43 @@ XdsResolver::XdsConfigSelector::XdsConfigSelector(
resolver_->current_listener_.http_connection_manager
.http_max_stream_duration;
}
if (route_action->action.index() ==
XdsRouteConfigResource::Route::RouteAction::kClusterIndex) {
*error = CreateMethodConfig(route_entry.route, nullptr,
&route_entry.method_config);
MaybeAddCluster(absl::StrCat(
"cluster:",
absl::get<
XdsRouteConfigResource::Route::RouteAction::kClusterIndex>(
route_action->action)));
} else if (route_action->action.index() ==
XdsRouteConfigResource::Route::RouteAction::
kWeightedClustersIndex) {
auto& action_weighted_clusters = absl::get<
XdsRouteConfigResource::Route::RouteAction::kWeightedClustersIndex>(
route_action->action);
uint32_t end = 0;
for (const auto& weighted_cluster : action_weighted_clusters) {
Route::ClusterWeightState cluster_weight_state;
*error = CreateMethodConfig(route_entry.route, &weighted_cluster,
&cluster_weight_state.method_config);
if (!GRPC_ERROR_IS_NONE(*error)) return;
end += weighted_cluster.weight;
cluster_weight_state.range_end = end;
cluster_weight_state.cluster = weighted_cluster.name;
route_entry.weighted_cluster_state.push_back(
std::move(cluster_weight_state));
MaybeAddCluster(absl::StrCat("cluster:", weighted_cluster.name));
}
} else if (route_action->action.index() ==
XdsRouteConfigResource::Route::RouteAction::
kClusterSpecifierPluginIndex) {
// cluster_specifier_plugin case:
*error = CreateMethodConfig(route_entry.route, nullptr,
&route_entry.method_config);
MaybeAddCluster(absl::StrCat(
"cluster_specifier_plugin:",
absl::get<XdsRouteConfigResource::Route::RouteAction::
kClusterSpecifierPluginIndex>(route_action->action)));
}
Match(
route_action->action,
// cluster name
[&](const XdsRouteConfigResource::Route::RouteAction::ClusterName&
cluster_name) {
*error = CreateMethodConfig(route_entry.route, nullptr,
&route_entry.method_config);
MaybeAddCluster(
absl::StrCat("cluster:", cluster_name.cluster_name));
},
// WeightedClusters
[&](const std::vector<
XdsRouteConfigResource::Route::RouteAction::ClusterWeight>&
weighted_clusters) {
uint32_t end = 0;
for (const auto& weighted_cluster : weighted_clusters) {
Route::ClusterWeightState cluster_weight_state;
*error = CreateMethodConfig(route_entry.route, &weighted_cluster,
&cluster_weight_state.method_config);
if (!GRPC_ERROR_IS_NONE(*error)) return;
end += weighted_cluster.weight;
cluster_weight_state.range_end = end;
cluster_weight_state.cluster = weighted_cluster.name;
route_entry.weighted_cluster_state.push_back(
std::move(cluster_weight_state));
MaybeAddCluster(absl::StrCat("cluster:", weighted_cluster.name));
}
},
// ClusterSpecifierPlugin
[&](const XdsRouteConfigResource::Route::RouteAction::
ClusterSpecifierPluginName& cluster_specifier_plugin_name) {
*error = CreateMethodConfig(route_entry.route, nullptr,
&route_entry.method_config);
MaybeAddCluster(absl::StrCat(
"cluster_specifier_plugin:",
cluster_specifier_plugin_name.cluster_specifier_plugin_name));
});
}
}
// Populate filter list.
@ -686,50 +685,54 @@ ConfigSelector::CallConfig XdsResolver::XdsConfigSelector::GetCallConfig(
}
std::string cluster_name;
RefCountedPtr<ServiceConfig> method_config;
if (route_action->action.index() ==
XdsRouteConfigResource::Route::RouteAction::kClusterIndex) {
cluster_name = absl::StrCat(
"cluster:",
absl::get<XdsRouteConfigResource::Route::RouteAction::kClusterIndex>(
route_action->action));
method_config = entry.method_config;
} else if (route_action->action.index() ==
XdsRouteConfigResource::Route::RouteAction::
kWeightedClustersIndex) {
const uint32_t key =
rand() %
entry.weighted_cluster_state[entry.weighted_cluster_state.size() - 1]
.range_end;
// Find the index in weighted clusters corresponding to key.
size_t mid = 0;
size_t start_index = 0;
size_t end_index = entry.weighted_cluster_state.size() - 1;
size_t index = 0;
while (end_index > start_index) {
mid = (start_index + end_index) / 2;
if (entry.weighted_cluster_state[mid].range_end > key) {
end_index = mid;
} else if (entry.weighted_cluster_state[mid].range_end < key) {
start_index = mid + 1;
} else {
index = mid + 1;
break;
}
}
if (index == 0) index = start_index;
GPR_ASSERT(entry.weighted_cluster_state[index].range_end > key);
cluster_name =
absl::StrCat("cluster:", entry.weighted_cluster_state[index].cluster);
method_config = entry.weighted_cluster_state[index].method_config;
} else if (route_action->action.index() ==
XdsRouteConfigResource::Route::RouteAction::
kClusterSpecifierPluginIndex) {
cluster_name = absl::StrCat(
"cluster_specifier_plugin:",
absl::get<XdsRouteConfigResource::Route::RouteAction::
kClusterSpecifierPluginIndex>(route_action->action));
method_config = entry.method_config;
}
Match(
route_action->action,
// cluster name
[&](const XdsRouteConfigResource::Route::RouteAction::ClusterName&
action_cluster_name) {
cluster_name =
absl::StrCat("cluster:", action_cluster_name.cluster_name);
method_config = entry.method_config;
},
// WeightedClusters
[&](const std::vector<
XdsRouteConfigResource::Route::RouteAction::ClusterWeight>&
/*weighted_clusters*/) {
const uint32_t key =
rand() %
entry
.weighted_cluster_state[entry.weighted_cluster_state.size() - 1]
.range_end;
// Find the index in weighted clusters corresponding to key.
size_t mid = 0;
size_t start_index = 0;
size_t end_index = entry.weighted_cluster_state.size() - 1;
size_t index = 0;
while (end_index > start_index) {
mid = (start_index + end_index) / 2;
if (entry.weighted_cluster_state[mid].range_end > key) {
end_index = mid;
} else if (entry.weighted_cluster_state[mid].range_end < key) {
start_index = mid + 1;
} else {
index = mid + 1;
break;
}
}
if (index == 0) index = start_index;
GPR_ASSERT(entry.weighted_cluster_state[index].range_end > key);
cluster_name = absl::StrCat(
"cluster:", entry.weighted_cluster_state[index].cluster);
method_config = entry.weighted_cluster_state[index].method_config;
},
// ClusterSpecifierPlugin
[&](const XdsRouteConfigResource::Route::RouteAction::
ClusterSpecifierPluginName& cluster_specifier_plugin_name) {
cluster_name = absl::StrCat(
"cluster_specifier_plugin:",
cluster_specifier_plugin_name.cluster_specifier_plugin_name);
method_config = entry.method_config;
});
auto it = clusters_.find(cluster_name);
GPR_ASSERT(it != clusters_.end());
// Generate a hash.

@ -69,6 +69,7 @@
#include "src/core/lib/debug/trace.h"
#include "src/core/lib/gpr/env.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gprpp/match.h"
#include "src/core/lib/gprpp/status_helper.h"
#include "src/core/lib/gprpp/time.h"
#include "src/core/lib/iomgr/error.h"
@ -250,19 +251,23 @@ std::string XdsRouteConfigResource::Route::RouteAction::ToString() const {
if (retry_policy.has_value()) {
contents.push_back(absl::StrCat("retry_policy=", retry_policy->ToString()));
}
if (action.index() == kClusterIndex) {
contents.push_back(
absl::StrFormat("Cluster name: %s", absl::get<kClusterIndex>(action)));
} else if (action.index() == kWeightedClustersIndex) {
auto& action_weighted_clusters = absl::get<kWeightedClustersIndex>(action);
for (const ClusterWeight& cluster_weight : action_weighted_clusters) {
contents.push_back(cluster_weight.ToString());
}
} else if (action.index() == kClusterSpecifierPluginIndex) {
contents.push_back(
absl::StrFormat("Cluster specifier plugin name: %s",
absl::get<kClusterSpecifierPluginIndex>(action)));
}
Match(
action,
[&contents](const ClusterName& cluster_name) {
contents.push_back(
absl::StrFormat("Cluster name: %s", cluster_name.cluster_name));
},
[&contents](const std::vector<ClusterWeight>& weighted_clusters) {
for (const ClusterWeight& cluster_weight : weighted_clusters) {
contents.push_back(cluster_weight.ToString());
}
},
[&contents](
const ClusterSpecifierPluginName& cluster_specifier_plugin_name) {
contents.push_back(absl::StrFormat(
"Cluster specifier plugin name: %s",
cluster_specifier_plugin_name.cluster_specifier_plugin_name));
});
if (max_stream_duration.has_value()) {
contents.push_back(max_stream_duration->ToString());
}
@ -743,9 +748,8 @@ grpc_error_handle RouteActionParse(
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"RouteAction cluster contains empty cluster name.");
}
route->action
.emplace<XdsRouteConfigResource::Route::RouteAction::kClusterIndex>(
std::move(cluster_name));
route->action = XdsRouteConfigResource::Route::RouteAction::ClusterName{
std::move(cluster_name)};
} else if (envoy_config_route_v3_RouteAction_has_weighted_clusters(
route_action)) {
std::vector<XdsRouteConfigResource::Route::RouteAction::ClusterWeight>
@ -825,9 +829,9 @@ grpc_error_handle RouteActionParse(
plugin_name));
}
if (it->second.empty()) *ignore_route = true;
route->action.emplace<XdsRouteConfigResource::Route::RouteAction::
kClusterSpecifierPluginIndex>(
std::move(plugin_name));
route->action =
XdsRouteConfigResource::Route::RouteAction::ClusterSpecifierPluginName{
std::move(plugin_name)};
} else {
// No cluster or weighted_clusters or plugin found in RouteAction, ignore
// this route.
@ -1048,12 +1052,12 @@ grpc_error_handle XdsRouteConfigResource::Parse(
route_action.retry_policy = virtual_host_retry_policy;
}
// Mark off plugins used in route action.
std::string* cluster_specifier_action =
auto* cluster_specifier_action =
absl::get_if<XdsRouteConfigResource::Route::RouteAction::
kClusterSpecifierPluginIndex>(
&route_action.action);
ClusterSpecifierPluginName>(&route_action.action);
if (cluster_specifier_action != nullptr) {
cluster_specifier_plugins.erase(*cluster_specifier_action);
cluster_specifier_plugins.erase(
cluster_specifier_action->cluster_specifier_plugin_name);
}
} else if (envoy_config_route_v3_Route_has_non_forwarding_action(
routes[j])) {

@ -19,7 +19,6 @@
#include <grpc/support/port_platform.h>
#include <stddef.h>
#include <stdint.h>
#include <algorithm>
@ -122,6 +121,14 @@ struct XdsRouteConfigResource {
std::string ToString() const;
};
struct ClusterName {
std::string cluster_name;
bool operator==(const ClusterName& other) const {
return cluster_name == other.cluster_name;
}
};
struct ClusterWeight {
std::string name;
uint32_t weight;
@ -134,14 +141,21 @@ struct XdsRouteConfigResource {
std::string ToString() const;
};
struct ClusterSpecifierPluginName {
std::string cluster_specifier_plugin_name;
bool operator==(const ClusterSpecifierPluginName& other) const {
return cluster_specifier_plugin_name ==
other.cluster_specifier_plugin_name;
}
};
std::vector<HashPolicy> hash_policies;
absl::optional<RetryPolicy> retry_policy;
// Action for this route.
static constexpr size_t kClusterIndex = 0;
static constexpr size_t kWeightedClustersIndex = 1;
static constexpr size_t kClusterSpecifierPluginIndex = 2;
absl::variant<std::string, std::vector<ClusterWeight>, std::string>
absl::variant<ClusterName, std::vector<ClusterWeight>,
ClusterSpecifierPluginName>
action;
// Storing the timeout duration from route action:
// RouteAction.max_stream_duration.grpc_timeout_header_max or

Loading…
Cancel
Save