diff --git a/BUILD b/BUILD index 2eafa5b92fe..436ebb07180 100644 --- a/BUILD +++ b/BUILD @@ -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", diff --git a/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc b/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc index 6c655f5d932..283fdc76638 100644 --- a/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +++ b/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc @@ -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(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 method_config; - if (route_action->action.index() == - XdsRouteConfigResource::Route::RouteAction::kClusterIndex) { - cluster_name = absl::StrCat( - "cluster:", - absl::get( - 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(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. diff --git a/src/core/ext/xds/xds_route_config.cc b/src/core/ext/xds/xds_route_config.cc index 4b1c227885a..653b9dd9d14 100644 --- a/src/core/ext/xds/xds_route_config.cc +++ b/src/core/ext/xds/xds_route_config.cc @@ -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(action))); - } else if (action.index() == kWeightedClustersIndex) { - auto& action_weighted_clusters = absl::get(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(action))); - } + Match( + action, + [&contents](const ClusterName& cluster_name) { + contents.push_back( + absl::StrFormat("Cluster name: %s", cluster_name.cluster_name)); + }, + [&contents](const std::vector& 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( - 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 @@ -825,9 +829,9 @@ grpc_error_handle RouteActionParse( plugin_name)); } if (it->second.empty()) *ignore_route = true; - route->action.emplace( - 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( - &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])) { diff --git a/src/core/ext/xds/xds_route_config.h b/src/core/ext/xds/xds_route_config.h index 5abdd081e24..0022bc1b930 100644 --- a/src/core/ext/xds/xds_route_config.h +++ b/src/core/ext/xds/xds_route_config.h @@ -19,7 +19,6 @@ #include -#include #include #include @@ -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 hash_policies; absl::optional 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> + absl::variant, + ClusterSpecifierPluginName> action; // Storing the timeout duration from route action: // RouteAction.max_stream_duration.grpc_timeout_header_max or