grpc 1.32.0 → 1.33.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of grpc might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Makefile +175 -376
- data/include/grpc/grpc.h +0 -5
- data/include/grpc/grpc_security.h +16 -0
- data/include/grpc/impl/codegen/grpc_types.h +0 -5
- data/src/core/ext/filters/client_channel/client_channel.cc +204 -170
- data/src/core/ext/filters/client_channel/config_selector.cc +0 -4
- data/src/core/ext/filters/client_channel/config_selector.h +34 -5
- data/src/core/ext/filters/client_channel/lb_policy.h +1 -1
- data/src/core/ext/filters/client_channel/lb_policy/address_filtering.cc +48 -35
- data/src/core/ext/filters/client_channel/lb_policy/address_filtering.h +7 -5
- data/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc +3 -2
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +106 -106
- data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +2 -2
- data/src/core/ext/filters/client_channel/lb_policy/priority/priority.cc +3 -3
- data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +3 -3
- data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +9 -32
- data/src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc +3 -3
- data/src/core/ext/filters/client_channel/lb_policy/xds/cds.cc +198 -126
- data/src/core/ext/filters/client_channel/lb_policy/xds/eds.cc +439 -249
- data/src/core/ext/filters/client_channel/lb_policy/xds/eds_drop.cc +571 -0
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc +727 -0
- data/src/core/ext/filters/client_channel/lb_policy_registry.cc +8 -1
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +1 -1
- data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +553 -358
- data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.h +28 -0
- data/src/core/ext/filters/client_channel/resolver_result_parsing.cc +8 -39
- data/src/core/ext/filters/client_channel/resolver_result_parsing.h +4 -2
- data/src/core/ext/filters/client_channel/resolving_lb_policy.cc +44 -43
- data/src/core/ext/filters/client_channel/resolving_lb_policy.h +5 -9
- data/src/core/ext/filters/client_channel/server_address.cc +80 -0
- data/src/core/ext/filters/client_channel/server_address.h +25 -36
- data/src/core/ext/filters/client_channel/service_config.cc +16 -13
- data/src/core/ext/filters/client_channel/service_config.h +7 -4
- data/src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc +2 -2
- data/src/core/ext/filters/client_channel/service_config_parser.cc +8 -6
- data/src/core/ext/filters/client_channel/service_config_parser.h +8 -5
- data/src/core/ext/filters/client_channel/subchannel_interface.h +44 -0
- data/src/core/ext/filters/message_size/message_size_filter.cc +2 -1
- data/src/core/ext/filters/message_size/message_size_filter.h +2 -1
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +17 -10
- data/src/core/ext/transport/chttp2/transport/flow_control.cc +10 -2
- data/src/core/ext/transport/chttp2/transport/flow_control.h +10 -0
- data/src/core/ext/transport/chttp2/transport/internal.h +5 -0
- data/src/core/ext/transport/chttp2/transport/parsing.cc +16 -2
- data/src/core/ext/upb-generated/envoy/config/accesslog/v3/accesslog.upb.c +29 -9
- data/src/core/ext/upb-generated/envoy/config/accesslog/v3/accesslog.upb.h +66 -0
- data/src/core/ext/upb-generated/envoy/config/cluster/v3/cluster.upb.c +123 -45
- data/src/core/ext/upb-generated/envoy/config/cluster/v3/cluster.upb.h +310 -53
- data/src/core/ext/upb-generated/envoy/config/core/v3/address.upb.c +17 -5
- data/src/core/ext/upb-generated/envoy/config/core/v3/address.upb.h +45 -0
- data/src/core/ext/upb-generated/envoy/config/core/v3/base.upb.c +1 -0
- data/src/core/ext/upb-generated/envoy/config/core/v3/config_source.upb.c +16 -9
- data/src/core/ext/upb-generated/envoy/config/core/v3/config_source.upb.h +38 -15
- data/src/core/ext/upb-generated/envoy/config/core/v3/extension.upb.c +53 -0
- data/src/core/ext/upb-generated/envoy/config/core/v3/extension.upb.h +133 -0
- data/src/core/ext/upb-generated/envoy/config/core/v3/grpc_service.upb.c +54 -8
- data/src/core/ext/upb-generated/envoy/config/core/v3/grpc_service.upb.h +123 -5
- data/src/core/ext/upb-generated/envoy/config/core/v3/protocol.upb.c +40 -16
- data/src/core/ext/upb-generated/envoy/config/core/v3/protocol.upb.h +114 -5
- data/src/core/ext/upb-generated/envoy/config/core/v3/substitution_format_string.upb.c +36 -0
- data/src/core/ext/upb-generated/envoy/config/core/v3/substitution_format_string.upb.h +85 -0
- data/src/core/ext/upb-generated/envoy/config/listener/v3/listener.upb.c +36 -16
- data/src/core/ext/upb-generated/envoy/config/listener/v3/listener.upb.h +86 -20
- data/src/core/ext/upb-generated/envoy/config/listener/v3/listener_components.upb.c +23 -6
- data/src/core/ext/upb-generated/envoy/config/listener/v3/listener_components.upb.h +54 -5
- data/src/core/ext/upb-generated/envoy/config/rbac/v3/rbac.upb.c +10 -6
- data/src/core/ext/upb-generated/envoy/config/rbac/v3/rbac.upb.h +28 -11
- data/src/core/ext/upb-generated/envoy/config/route/v3/route_components.upb.c +184 -57
- data/src/core/ext/upb-generated/envoy/config/route/v3/route_components.upb.h +504 -69
- data/src/core/ext/upb-generated/envoy/config/route/v3/scoped_route.upb.c +6 -5
- data/src/core/ext/upb-generated/envoy/config/route/v3/scoped_route.upb.h +11 -7
- data/src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.c +78 -26
- data/src/core/ext/upb-generated/envoy/extensions/filters/network/http_connection_manager/v3/http_connection_manager.upb.h +236 -25
- data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.c +8 -9
- data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/common.upb.h +19 -33
- data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/secret.upb.c +7 -3
- data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/secret.upb.h +16 -0
- data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/tls.upb.c +65 -23
- data/src/core/ext/upb-generated/envoy/extensions/transport_sockets/tls/v3/tls.upb.h +229 -47
- data/src/core/ext/upb-generated/envoy/service/discovery/v3/discovery.upb.c +20 -10
- data/src/core/ext/upb-generated/envoy/service/discovery/v3/discovery.upb.h +67 -4
- data/src/core/ext/upb-generated/envoy/type/matcher/v3/string.upb.c +3 -2
- data/src/core/ext/upb-generated/envoy/type/matcher/v3/string.upb.h +6 -0
- data/src/core/ext/upb-generated/google/api/expr/v1alpha1/checked.upb.c +242 -0
- data/src/core/ext/upb-generated/google/api/expr/v1alpha1/checked.upb.h +753 -0
- data/src/core/ext/upb-generated/udpa/annotations/security.upb.c +31 -0
- data/src/core/ext/upb-generated/udpa/annotations/security.upb.h +57 -0
- data/src/core/ext/upb-generated/udpa/core/v1/authority.upb.c +28 -0
- data/src/core/ext/upb-generated/udpa/core/v1/authority.upb.h +53 -0
- data/src/core/ext/upb-generated/udpa/core/v1/collection_entry.upb.c +52 -0
- data/src/core/ext/upb-generated/udpa/core/v1/collection_entry.upb.h +129 -0
- data/src/core/ext/upb-generated/udpa/core/v1/context_params.upb.c +42 -0
- data/src/core/ext/upb-generated/udpa/core/v1/context_params.upb.h +77 -0
- data/src/core/ext/upb-generated/udpa/core/v1/resource.upb.c +36 -0
- data/src/core/ext/upb-generated/udpa/core/v1/resource.upb.h +85 -0
- data/src/core/ext/upb-generated/udpa/core/v1/resource_locator.upb.c +54 -0
- data/src/core/ext/upb-generated/udpa/core/v1/resource_locator.upb.h +160 -0
- data/src/core/ext/upb-generated/udpa/core/v1/resource_name.upb.c +36 -0
- data/src/core/ext/upb-generated/udpa/core/v1/resource_name.upb.h +84 -0
- data/src/core/ext/xds/certificate_provider_factory.h +59 -0
- data/src/core/ext/xds/certificate_provider_registry.cc +103 -0
- data/src/core/ext/xds/certificate_provider_registry.h +57 -0
- data/src/core/ext/xds/certificate_provider_store.h +50 -0
- data/src/core/ext/xds/google_mesh_ca_certificate_provider_factory.cc +377 -0
- data/src/core/ext/xds/google_mesh_ca_certificate_provider_factory.h +102 -0
- data/src/core/ext/xds/xds_api.cc +301 -93
- data/src/core/ext/xds/xds_api.h +129 -92
- data/src/core/ext/xds/xds_channel_args.h +6 -3
- data/src/core/ext/xds/xds_client.cc +498 -410
- data/src/core/ext/xds/xds_client.h +105 -51
- data/src/core/ext/xds/xds_client_stats.cc +18 -12
- data/src/core/ext/xds/xds_client_stats.h +33 -5
- data/src/core/lib/channel/channel_args.h +0 -1
- data/src/core/lib/channel/channelz.cc +10 -45
- data/src/core/lib/channel/channelz.h +11 -19
- data/src/core/lib/channel/channelz_registry.cc +12 -11
- data/src/core/lib/channel/channelz_registry.h +3 -0
- data/src/core/lib/gpr/time_precise.cc +2 -0
- data/src/core/lib/gpr/time_precise.h +6 -2
- data/src/core/lib/gprpp/dual_ref_counted.h +336 -0
- data/src/core/lib/gprpp/ref_counted.h +51 -22
- data/src/core/lib/gprpp/ref_counted_ptr.h +153 -0
- data/src/core/lib/iomgr/endpoint_cfstream.cc +9 -5
- data/src/core/lib/iomgr/exec_ctx.h +10 -8
- data/src/core/lib/json/json_util.cc +58 -0
- data/src/core/lib/json/json_util.h +37 -0
- data/src/core/lib/security/certificate_provider.h +60 -0
- data/src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.cc +321 -0
- data/src/core/lib/security/credentials/tls/grpc_tls_certificate_distributor.h +214 -0
- data/src/core/lib/security/credentials/xds/xds_credentials.cc +45 -0
- data/src/core/lib/security/credentials/xds/xds_credentials.h +51 -0
- data/src/core/lib/security/security_connector/fake/fake_security_connector.cc +6 -10
- data/src/core/lib/security/security_connector/ssl_utils.h +5 -0
- data/src/core/lib/surface/channel.cc +9 -31
- data/src/core/lib/surface/channel.h +6 -1
- data/src/core/lib/surface/init.cc +26 -9
- data/src/core/lib/surface/version.cc +2 -2
- data/src/core/lib/transport/bdp_estimator.h +2 -1
- data/src/core/lib/transport/connectivity_state.h +2 -2
- data/src/core/lib/transport/metadata.cc +11 -1
- data/src/core/plugin_registry/grpc_plugin_registry.cc +35 -20
- data/src/core/tsi/ssl_transport_security.cc +2 -2
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +2 -2
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +3 -3
- data/src/ruby/lib/grpc/version.rb +1 -1
- data/third_party/boringssl-with-bazel/err_data.c +465 -463
- data/third_party/boringssl-with-bazel/src/crypto/asn1/asn1_lib.c +0 -6
- data/third_party/boringssl-with-bazel/src/crypto/dsa/dsa.c +9 -43
- data/third_party/boringssl-with-bazel/src/crypto/dsa/dsa_asn1.c +55 -4
- data/third_party/boringssl-with-bazel/src/crypto/dsa/internal.h +34 -0
- data/third_party/boringssl-with-bazel/src/crypto/evp/evp.c +4 -0
- data/third_party/boringssl-with-bazel/src/crypto/evp/p_dsa_asn1.c +6 -2
- data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/digest/digest.c +2 -0
- data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/rsa/internal.h +4 -0
- data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/rsa/rsa.c +30 -10
- data/third_party/boringssl-with-bazel/src/crypto/fipsmodule/rsa/rsa_impl.c +10 -15
- data/third_party/boringssl-with-bazel/src/crypto/hpke/hpke.c +98 -11
- data/third_party/boringssl-with-bazel/src/crypto/hpke/internal.h +51 -6
- data/third_party/boringssl-with-bazel/src/crypto/trust_token/internal.h +44 -2
- data/third_party/boringssl-with-bazel/src/crypto/trust_token/pmbtoken.c +221 -49
- data/third_party/boringssl-with-bazel/src/crypto/trust_token/trust_token.c +64 -20
- data/third_party/boringssl-with-bazel/src/crypto/x509/a_strex.c +3 -3
- data/third_party/boringssl-with-bazel/src/crypto/x509/algorithm.c +0 -8
- data/third_party/boringssl-with-bazel/src/crypto/x509/t_crl.c +3 -3
- data/third_party/boringssl-with-bazel/src/crypto/x509/t_x509.c +1 -1
- data/third_party/boringssl-with-bazel/src/crypto/x509/x509_cmp.c +7 -2
- data/third_party/boringssl-with-bazel/src/crypto/x509/x509_ext.c +21 -18
- data/third_party/boringssl-with-bazel/src/crypto/x509/x509_obj.c +1 -1
- data/third_party/boringssl-with-bazel/src/crypto/x509/x509_set.c +24 -3
- data/third_party/boringssl-with-bazel/src/crypto/x509/x509_trs.c +3 -3
- data/third_party/boringssl-with-bazel/src/crypto/x509/x509_txt.c +67 -67
- data/third_party/boringssl-with-bazel/src/crypto/x509/x509_v3.c +3 -3
- data/third_party/boringssl-with-bazel/src/crypto/x509/x509_vfy.c +29 -35
- data/third_party/boringssl-with-bazel/src/crypto/x509/x509cset.c +13 -2
- data/third_party/boringssl-with-bazel/src/crypto/x509/x509name.c +9 -8
- data/third_party/boringssl-with-bazel/src/crypto/x509/x_all.c +10 -10
- data/third_party/boringssl-with-bazel/src/crypto/x509/x_crl.c +2 -2
- data/third_party/boringssl-with-bazel/src/crypto/x509/x_name.c +28 -40
- data/third_party/boringssl-with-bazel/src/crypto/x509/x_x509.c +3 -1
- data/third_party/boringssl-with-bazel/src/crypto/x509v3/ext_dat.h +1 -4
- data/third_party/boringssl-with-bazel/src/crypto/x509v3/v3_conf.c +7 -3
- data/third_party/boringssl-with-bazel/src/crypto/x509v3/v3_genn.c +2 -2
- data/third_party/boringssl-with-bazel/src/crypto/x509v3/v3_info.c +1 -1
- data/third_party/boringssl-with-bazel/src/crypto/x509v3/v3_purp.c +55 -8
- data/third_party/boringssl-with-bazel/src/crypto/x509v3/v3_skey.c +1 -1
- data/third_party/boringssl-with-bazel/src/include/openssl/asn1.h +0 -1
- data/third_party/boringssl-with-bazel/src/include/openssl/base.h +1 -1
- data/third_party/boringssl-with-bazel/src/include/openssl/cipher.h +6 -0
- data/third_party/boringssl-with-bazel/src/include/openssl/crypto.h +1 -1
- data/third_party/boringssl-with-bazel/src/include/openssl/dh.h +12 -0
- data/third_party/boringssl-with-bazel/src/include/openssl/digest.h +9 -0
- data/third_party/boringssl-with-bazel/src/include/openssl/evp.h +4 -1
- data/third_party/boringssl-with-bazel/src/include/openssl/ssl.h +9 -2
- data/third_party/boringssl-with-bazel/src/include/openssl/trust_token.h +26 -6
- data/third_party/boringssl-with-bazel/src/include/openssl/x509.h +188 -78
- data/third_party/boringssl-with-bazel/src/include/openssl/x509v3.h +52 -43
- data/third_party/boringssl-with-bazel/src/ssl/handshake.cc +18 -18
- data/third_party/boringssl-with-bazel/src/ssl/handshake_client.cc +2 -3
- data/third_party/boringssl-with-bazel/src/ssl/handshake_server.cc +1 -1
- data/third_party/boringssl-with-bazel/src/ssl/internal.h +9 -9
- data/third_party/boringssl-with-bazel/src/ssl/ssl_cipher.cc +8 -9
- data/third_party/boringssl-with-bazel/src/ssl/tls13_both.cc +1 -2
- data/third_party/boringssl-with-bazel/src/ssl/tls13_client.cc +4 -8
- data/third_party/boringssl-with-bazel/src/ssl/tls13_server.cc +2 -2
- metadata +72 -42
- data/src/core/ext/filters/client_channel/lb_policy/xds/lrs.cc +0 -537
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds_routing.cc +0 -1141
- data/src/core/ext/upb-generated/gogoproto/gogo.upb.c +0 -17
- data/src/core/ext/upb-generated/gogoproto/gogo.upb.h +0 -29
- data/src/core/ext/xds/xds_channel.h +0 -46
- data/src/core/ext/xds/xds_channel_secure.cc +0 -103
- data/third_party/boringssl-with-bazel/src/crypto/x509v3/v3_pku.c +0 -110
- data/third_party/boringssl-with-bazel/src/crypto/x509v3/v3_sxnet.c +0 -274
@@ -0,0 +1,727 @@
|
|
1
|
+
//
|
2
|
+
// Copyright 2018 gRPC authors.
|
3
|
+
//
|
4
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
// you may not use this file except in compliance with the License.
|
6
|
+
// You may obtain a copy of the License at
|
7
|
+
//
|
8
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
//
|
10
|
+
// Unless required by applicable law or agreed to in writing, software
|
11
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
// See the License for the specific language governing permissions and
|
14
|
+
// limitations under the License.
|
15
|
+
//
|
16
|
+
|
17
|
+
#include <grpc/support/port_platform.h>
|
18
|
+
|
19
|
+
#include <inttypes.h>
|
20
|
+
#include <limits.h>
|
21
|
+
#include <string.h>
|
22
|
+
|
23
|
+
#include "absl/container/inlined_vector.h"
|
24
|
+
#include "absl/strings/match.h"
|
25
|
+
#include "absl/strings/numbers.h"
|
26
|
+
#include "absl/strings/str_cat.h"
|
27
|
+
#include "absl/strings/str_join.h"
|
28
|
+
#include "absl/strings/str_split.h"
|
29
|
+
#include "absl/strings/string_view.h"
|
30
|
+
#include "re2/re2.h"
|
31
|
+
|
32
|
+
#include <grpc/grpc.h>
|
33
|
+
|
34
|
+
#include "src/core/ext/filters/client_channel/lb_policy.h"
|
35
|
+
#include "src/core/ext/filters/client_channel/lb_policy/child_policy_handler.h"
|
36
|
+
#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
|
37
|
+
#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
|
38
|
+
#include "src/core/ext/filters/client_channel/resolver/xds/xds_resolver.h"
|
39
|
+
#include "src/core/ext/xds/xds_api.h"
|
40
|
+
#include "src/core/lib/channel/channel_args.h"
|
41
|
+
#include "src/core/lib/gpr/string.h"
|
42
|
+
#include "src/core/lib/gprpp/orphanable.h"
|
43
|
+
#include "src/core/lib/gprpp/ref_counted_ptr.h"
|
44
|
+
#include "src/core/lib/iomgr/timer.h"
|
45
|
+
#include "src/core/lib/iomgr/work_serializer.h"
|
46
|
+
#include "src/core/lib/transport/error_utils.h"
|
47
|
+
|
48
|
+
#define GRPC_XDS_CLUSTER_MANAGER_CHILD_RETENTION_INTERVAL_MS (15 * 60 * 1000)
|
49
|
+
|
50
|
+
namespace grpc_core {
|
51
|
+
|
52
|
+
TraceFlag grpc_xds_cluster_manager_lb_trace(false, "xds_cluster_manager_lb");
|
53
|
+
|
54
|
+
namespace {
|
55
|
+
|
56
|
+
constexpr char kXdsClusterManager[] = "xds_cluster_manager_experimental";
|
57
|
+
|
58
|
+
// Config for xds_cluster_manager LB policy.
|
59
|
+
class XdsClusterManagerLbConfig : public LoadBalancingPolicy::Config {
|
60
|
+
public:
|
61
|
+
using ClusterMap =
|
62
|
+
std::map<std::string, RefCountedPtr<LoadBalancingPolicy::Config>>;
|
63
|
+
|
64
|
+
XdsClusterManagerLbConfig(ClusterMap cluster_map)
|
65
|
+
: cluster_map_(std::move(cluster_map)) {}
|
66
|
+
|
67
|
+
const char* name() const override { return kXdsClusterManager; }
|
68
|
+
|
69
|
+
const ClusterMap& cluster_map() const { return cluster_map_; }
|
70
|
+
|
71
|
+
private:
|
72
|
+
ClusterMap cluster_map_;
|
73
|
+
};
|
74
|
+
|
75
|
+
// xds_cluster_manager LB policy.
|
76
|
+
class XdsClusterManagerLb : public LoadBalancingPolicy {
|
77
|
+
public:
|
78
|
+
explicit XdsClusterManagerLb(Args args);
|
79
|
+
|
80
|
+
const char* name() const override { return kXdsClusterManager; }
|
81
|
+
|
82
|
+
void UpdateLocked(UpdateArgs args) override;
|
83
|
+
void ExitIdleLocked() override;
|
84
|
+
void ResetBackoffLocked() override;
|
85
|
+
|
86
|
+
private:
|
87
|
+
// A simple wrapper for ref-counting a picker from the child policy.
|
88
|
+
class ChildPickerWrapper : public RefCounted<ChildPickerWrapper> {
|
89
|
+
public:
|
90
|
+
ChildPickerWrapper(std::string name,
|
91
|
+
std::unique_ptr<SubchannelPicker> picker)
|
92
|
+
: name_(std::move(name)), picker_(std::move(picker)) {}
|
93
|
+
PickResult Pick(PickArgs args) { return picker_->Pick(args); }
|
94
|
+
|
95
|
+
const std::string& name() const { return name_; }
|
96
|
+
|
97
|
+
private:
|
98
|
+
std::string name_;
|
99
|
+
std::unique_ptr<SubchannelPicker> picker_;
|
100
|
+
};
|
101
|
+
|
102
|
+
// Picks a child using prefix or path matching and then delegates to that
|
103
|
+
// child's picker.
|
104
|
+
class ClusterPicker : public SubchannelPicker {
|
105
|
+
public:
|
106
|
+
// Maintains a map of cluster names to pickers.
|
107
|
+
using ClusterMap = std::map<absl::string_view /*cluster_name*/,
|
108
|
+
RefCountedPtr<ChildPickerWrapper>>;
|
109
|
+
|
110
|
+
// It is required that the keys of cluster_map have to live at least as long
|
111
|
+
// as the ClusterPicker instance.
|
112
|
+
ClusterPicker(ClusterMap cluster_map,
|
113
|
+
RefCountedPtr<XdsClusterManagerLbConfig> config)
|
114
|
+
: cluster_map_(std::move(cluster_map)), config_(std::move(config)) {}
|
115
|
+
|
116
|
+
PickResult Pick(PickArgs args) override;
|
117
|
+
|
118
|
+
private:
|
119
|
+
ClusterMap cluster_map_;
|
120
|
+
// Take a reference to config so that we can use
|
121
|
+
// XdsApi::RdsUpdate::RdsRoute::Matchers from it.
|
122
|
+
RefCountedPtr<XdsClusterManagerLbConfig> config_;
|
123
|
+
};
|
124
|
+
|
125
|
+
// Each ClusterChild holds a ref to its parent XdsClusterManagerLb.
|
126
|
+
class ClusterChild : public InternallyRefCounted<ClusterChild> {
|
127
|
+
public:
|
128
|
+
ClusterChild(RefCountedPtr<XdsClusterManagerLb> xds_cluster_manager_policy,
|
129
|
+
const std::string& name);
|
130
|
+
~ClusterChild();
|
131
|
+
|
132
|
+
void Orphan() override;
|
133
|
+
|
134
|
+
void UpdateLocked(RefCountedPtr<LoadBalancingPolicy::Config> config,
|
135
|
+
const ServerAddressList& addresses,
|
136
|
+
const grpc_channel_args* args);
|
137
|
+
void ExitIdleLocked();
|
138
|
+
void ResetBackoffLocked();
|
139
|
+
void DeactivateLocked();
|
140
|
+
|
141
|
+
grpc_connectivity_state connectivity_state() const {
|
142
|
+
return connectivity_state_;
|
143
|
+
}
|
144
|
+
RefCountedPtr<ChildPickerWrapper> picker_wrapper() const {
|
145
|
+
return picker_wrapper_;
|
146
|
+
}
|
147
|
+
|
148
|
+
private:
|
149
|
+
class Helper : public ChannelControlHelper {
|
150
|
+
public:
|
151
|
+
explicit Helper(RefCountedPtr<ClusterChild> xds_cluster_manager_child)
|
152
|
+
: xds_cluster_manager_child_(std::move(xds_cluster_manager_child)) {}
|
153
|
+
|
154
|
+
~Helper() { xds_cluster_manager_child_.reset(DEBUG_LOCATION, "Helper"); }
|
155
|
+
|
156
|
+
RefCountedPtr<SubchannelInterface> CreateSubchannel(
|
157
|
+
ServerAddress address, const grpc_channel_args& args) override;
|
158
|
+
void UpdateState(grpc_connectivity_state state,
|
159
|
+
const absl::Status& status,
|
160
|
+
std::unique_ptr<SubchannelPicker> picker) override;
|
161
|
+
void RequestReresolution() override;
|
162
|
+
void AddTraceEvent(TraceSeverity severity,
|
163
|
+
absl::string_view message) override;
|
164
|
+
|
165
|
+
private:
|
166
|
+
RefCountedPtr<ClusterChild> xds_cluster_manager_child_;
|
167
|
+
};
|
168
|
+
|
169
|
+
// Methods for dealing with the child policy.
|
170
|
+
OrphanablePtr<LoadBalancingPolicy> CreateChildPolicyLocked(
|
171
|
+
const grpc_channel_args* args);
|
172
|
+
|
173
|
+
static void OnDelayedRemovalTimer(void* arg, grpc_error* error);
|
174
|
+
void OnDelayedRemovalTimerLocked(grpc_error* error);
|
175
|
+
|
176
|
+
// The owning LB policy.
|
177
|
+
RefCountedPtr<XdsClusterManagerLb> xds_cluster_manager_policy_;
|
178
|
+
|
179
|
+
// Points to the corresponding key in children map.
|
180
|
+
const std::string name_;
|
181
|
+
|
182
|
+
OrphanablePtr<LoadBalancingPolicy> child_policy_;
|
183
|
+
|
184
|
+
RefCountedPtr<ChildPickerWrapper> picker_wrapper_;
|
185
|
+
grpc_connectivity_state connectivity_state_ = GRPC_CHANNEL_IDLE;
|
186
|
+
bool seen_failure_since_ready_ = false;
|
187
|
+
|
188
|
+
// States for delayed removal.
|
189
|
+
grpc_timer delayed_removal_timer_;
|
190
|
+
grpc_closure on_delayed_removal_timer_;
|
191
|
+
bool delayed_removal_timer_callback_pending_ = false;
|
192
|
+
bool shutdown_ = false;
|
193
|
+
};
|
194
|
+
|
195
|
+
~XdsClusterManagerLb();
|
196
|
+
|
197
|
+
void ShutdownLocked() override;
|
198
|
+
|
199
|
+
void UpdateStateLocked();
|
200
|
+
|
201
|
+
// Current config from the resolver.
|
202
|
+
RefCountedPtr<XdsClusterManagerLbConfig> config_;
|
203
|
+
|
204
|
+
// Internal state.
|
205
|
+
bool shutting_down_ = false;
|
206
|
+
|
207
|
+
// Children.
|
208
|
+
std::map<std::string, OrphanablePtr<ClusterChild>> children_;
|
209
|
+
};
|
210
|
+
|
211
|
+
//
|
212
|
+
// XdsClusterManagerLb::ClusterPicker
|
213
|
+
//
|
214
|
+
|
215
|
+
XdsClusterManagerLb::PickResult XdsClusterManagerLb::ClusterPicker::Pick(
|
216
|
+
PickArgs args) {
|
217
|
+
auto cluster_name =
|
218
|
+
args.call_state->ExperimentalGetCallAttribute(kXdsClusterAttribute);
|
219
|
+
auto it = cluster_map_.find(cluster_name);
|
220
|
+
if (it != cluster_map_.end()) {
|
221
|
+
return it->second->Pick(args);
|
222
|
+
}
|
223
|
+
PickResult result;
|
224
|
+
result.type = PickResult::PICK_FAILED;
|
225
|
+
result.error = grpc_error_set_int(
|
226
|
+
GRPC_ERROR_CREATE_FROM_COPIED_STRING(
|
227
|
+
absl::StrCat("xds cluster manager picker: unknown cluster \"",
|
228
|
+
cluster_name, "\"")
|
229
|
+
.c_str()),
|
230
|
+
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_INTERNAL);
|
231
|
+
return result;
|
232
|
+
}
|
233
|
+
|
234
|
+
//
|
235
|
+
// XdsClusterManagerLb
|
236
|
+
//
|
237
|
+
|
238
|
+
XdsClusterManagerLb::XdsClusterManagerLb(Args args)
|
239
|
+
: LoadBalancingPolicy(std::move(args)) {}
|
240
|
+
|
241
|
+
XdsClusterManagerLb::~XdsClusterManagerLb() {
|
242
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_cluster_manager_lb_trace)) {
|
243
|
+
gpr_log(
|
244
|
+
GPR_INFO,
|
245
|
+
"[xds_cluster_manager_lb %p] destroying xds_cluster_manager LB policy",
|
246
|
+
this);
|
247
|
+
}
|
248
|
+
}
|
249
|
+
|
250
|
+
void XdsClusterManagerLb::ShutdownLocked() {
|
251
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_cluster_manager_lb_trace)) {
|
252
|
+
gpr_log(GPR_INFO, "[xds_cluster_manager_lb %p] shutting down", this);
|
253
|
+
}
|
254
|
+
shutting_down_ = true;
|
255
|
+
children_.clear();
|
256
|
+
}
|
257
|
+
|
258
|
+
void XdsClusterManagerLb::ExitIdleLocked() {
|
259
|
+
for (auto& p : children_) p.second->ExitIdleLocked();
|
260
|
+
}
|
261
|
+
|
262
|
+
void XdsClusterManagerLb::ResetBackoffLocked() {
|
263
|
+
for (auto& p : children_) p.second->ResetBackoffLocked();
|
264
|
+
}
|
265
|
+
|
266
|
+
void XdsClusterManagerLb::UpdateLocked(UpdateArgs args) {
|
267
|
+
if (shutting_down_) return;
|
268
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_cluster_manager_lb_trace)) {
|
269
|
+
gpr_log(GPR_INFO, "[xds_cluster_manager_lb %p] Received update", this);
|
270
|
+
}
|
271
|
+
// Update config.
|
272
|
+
config_ = std::move(args.config);
|
273
|
+
// Deactivate the children not in the new config.
|
274
|
+
for (const auto& p : children_) {
|
275
|
+
const std::string& name = p.first;
|
276
|
+
ClusterChild* child = p.second.get();
|
277
|
+
if (config_->cluster_map().find(name) == config_->cluster_map().end()) {
|
278
|
+
child->DeactivateLocked();
|
279
|
+
}
|
280
|
+
}
|
281
|
+
// Add or update the children in the new config.
|
282
|
+
for (const auto& p : config_->cluster_map()) {
|
283
|
+
const std::string& name = p.first;
|
284
|
+
const RefCountedPtr<LoadBalancingPolicy::Config>& config = p.second;
|
285
|
+
auto it = children_.find(name);
|
286
|
+
if (it == children_.end()) {
|
287
|
+
it = children_
|
288
|
+
.emplace(name, MakeOrphanable<ClusterChild>(
|
289
|
+
Ref(DEBUG_LOCATION, "ClusterChild"), name))
|
290
|
+
.first;
|
291
|
+
}
|
292
|
+
it->second->UpdateLocked(config, args.addresses, args.args);
|
293
|
+
}
|
294
|
+
UpdateStateLocked();
|
295
|
+
}
|
296
|
+
|
297
|
+
void XdsClusterManagerLb::UpdateStateLocked() {
|
298
|
+
// Also count the number of children in each state, to determine the
|
299
|
+
// overall state.
|
300
|
+
size_t num_ready = 0;
|
301
|
+
size_t num_connecting = 0;
|
302
|
+
size_t num_idle = 0;
|
303
|
+
size_t num_transient_failures = 0;
|
304
|
+
for (const auto& p : children_) {
|
305
|
+
const auto& child_name = p.first;
|
306
|
+
const ClusterChild* child = p.second.get();
|
307
|
+
// Skip the children that are not in the latest update.
|
308
|
+
if (config_->cluster_map().find(child_name) ==
|
309
|
+
config_->cluster_map().end()) {
|
310
|
+
continue;
|
311
|
+
}
|
312
|
+
switch (child->connectivity_state()) {
|
313
|
+
case GRPC_CHANNEL_READY: {
|
314
|
+
++num_ready;
|
315
|
+
break;
|
316
|
+
}
|
317
|
+
case GRPC_CHANNEL_CONNECTING: {
|
318
|
+
++num_connecting;
|
319
|
+
break;
|
320
|
+
}
|
321
|
+
case GRPC_CHANNEL_IDLE: {
|
322
|
+
++num_idle;
|
323
|
+
break;
|
324
|
+
}
|
325
|
+
case GRPC_CHANNEL_TRANSIENT_FAILURE: {
|
326
|
+
++num_transient_failures;
|
327
|
+
break;
|
328
|
+
}
|
329
|
+
default:
|
330
|
+
GPR_UNREACHABLE_CODE(return );
|
331
|
+
}
|
332
|
+
}
|
333
|
+
// Determine aggregated connectivity state.
|
334
|
+
grpc_connectivity_state connectivity_state;
|
335
|
+
if (num_ready > 0) {
|
336
|
+
connectivity_state = GRPC_CHANNEL_READY;
|
337
|
+
} else if (num_connecting > 0) {
|
338
|
+
connectivity_state = GRPC_CHANNEL_CONNECTING;
|
339
|
+
} else if (num_idle > 0) {
|
340
|
+
connectivity_state = GRPC_CHANNEL_IDLE;
|
341
|
+
} else {
|
342
|
+
connectivity_state = GRPC_CHANNEL_TRANSIENT_FAILURE;
|
343
|
+
}
|
344
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_cluster_manager_lb_trace)) {
|
345
|
+
gpr_log(GPR_INFO, "[xds_cluster_manager_lb %p] connectivity changed to %s",
|
346
|
+
this, ConnectivityStateName(connectivity_state));
|
347
|
+
}
|
348
|
+
std::unique_ptr<SubchannelPicker> picker;
|
349
|
+
absl::Status status;
|
350
|
+
switch (connectivity_state) {
|
351
|
+
case GRPC_CHANNEL_READY: {
|
352
|
+
ClusterPicker::ClusterMap cluster_map;
|
353
|
+
for (const auto& p : config_->cluster_map()) {
|
354
|
+
const std::string& cluster_name = p.first;
|
355
|
+
RefCountedPtr<ChildPickerWrapper>& child_picker =
|
356
|
+
cluster_map[cluster_name];
|
357
|
+
child_picker = children_[cluster_name]->picker_wrapper();
|
358
|
+
if (child_picker == nullptr) {
|
359
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_cluster_manager_lb_trace)) {
|
360
|
+
gpr_log(
|
361
|
+
GPR_INFO,
|
362
|
+
"[xds_cluster_manager_lb %p] child %s has not yet returned a "
|
363
|
+
"picker; creating a QueuePicker.",
|
364
|
+
this, cluster_name.c_str());
|
365
|
+
}
|
366
|
+
child_picker = MakeRefCounted<ChildPickerWrapper>(
|
367
|
+
cluster_name, absl::make_unique<QueuePicker>(
|
368
|
+
Ref(DEBUG_LOCATION, "QueuePicker")));
|
369
|
+
}
|
370
|
+
}
|
371
|
+
picker =
|
372
|
+
absl::make_unique<ClusterPicker>(std::move(cluster_map), config_);
|
373
|
+
break;
|
374
|
+
}
|
375
|
+
case GRPC_CHANNEL_CONNECTING:
|
376
|
+
case GRPC_CHANNEL_IDLE:
|
377
|
+
picker =
|
378
|
+
absl::make_unique<QueuePicker>(Ref(DEBUG_LOCATION, "QueuePicker"));
|
379
|
+
break;
|
380
|
+
default:
|
381
|
+
grpc_error* error = grpc_error_set_int(
|
382
|
+
GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
383
|
+
"TRANSIENT_FAILURE from XdsClusterManagerLb"),
|
384
|
+
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE);
|
385
|
+
status = grpc_error_to_absl_status(error);
|
386
|
+
picker = absl::make_unique<TransientFailurePicker>(error);
|
387
|
+
}
|
388
|
+
channel_control_helper()->UpdateState(connectivity_state, status,
|
389
|
+
std::move(picker));
|
390
|
+
}
|
391
|
+
|
392
|
+
//
|
393
|
+
// XdsClusterManagerLb::ClusterChild
|
394
|
+
//
|
395
|
+
|
396
|
+
XdsClusterManagerLb::ClusterChild::ClusterChild(
|
397
|
+
RefCountedPtr<XdsClusterManagerLb> xds_cluster_manager_policy,
|
398
|
+
const std::string& name)
|
399
|
+
: xds_cluster_manager_policy_(std::move(xds_cluster_manager_policy)),
|
400
|
+
name_(name) {
|
401
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_cluster_manager_lb_trace)) {
|
402
|
+
gpr_log(GPR_INFO,
|
403
|
+
"[xds_cluster_manager_lb %p] created ClusterChild %p for %s",
|
404
|
+
xds_cluster_manager_policy_.get(), this, name_.c_str());
|
405
|
+
}
|
406
|
+
GRPC_CLOSURE_INIT(&on_delayed_removal_timer_, OnDelayedRemovalTimer, this,
|
407
|
+
grpc_schedule_on_exec_ctx);
|
408
|
+
}
|
409
|
+
|
410
|
+
XdsClusterManagerLb::ClusterChild::~ClusterChild() {
|
411
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_cluster_manager_lb_trace)) {
|
412
|
+
gpr_log(GPR_INFO,
|
413
|
+
"[xds_cluster_manager_lb %p] ClusterChild %p: destroying "
|
414
|
+
"child",
|
415
|
+
xds_cluster_manager_policy_.get(), this);
|
416
|
+
}
|
417
|
+
xds_cluster_manager_policy_.reset(DEBUG_LOCATION, "ClusterChild");
|
418
|
+
}
|
419
|
+
|
420
|
+
void XdsClusterManagerLb::ClusterChild::Orphan() {
|
421
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_cluster_manager_lb_trace)) {
|
422
|
+
gpr_log(GPR_INFO,
|
423
|
+
"[xds_cluster_manager_lb %p] ClusterChild %p %s: "
|
424
|
+
"shutting down child",
|
425
|
+
xds_cluster_manager_policy_.get(), this, name_.c_str());
|
426
|
+
}
|
427
|
+
// Remove the child policy's interested_parties pollset_set from the
|
428
|
+
// xDS policy.
|
429
|
+
grpc_pollset_set_del_pollset_set(
|
430
|
+
child_policy_->interested_parties(),
|
431
|
+
xds_cluster_manager_policy_->interested_parties());
|
432
|
+
child_policy_.reset();
|
433
|
+
// Drop our ref to the child's picker, in case it's holding a ref to
|
434
|
+
// the child.
|
435
|
+
picker_wrapper_.reset();
|
436
|
+
if (delayed_removal_timer_callback_pending_) {
|
437
|
+
grpc_timer_cancel(&delayed_removal_timer_);
|
438
|
+
}
|
439
|
+
shutdown_ = true;
|
440
|
+
Unref();
|
441
|
+
}
|
442
|
+
|
443
|
+
OrphanablePtr<LoadBalancingPolicy>
|
444
|
+
XdsClusterManagerLb::ClusterChild::CreateChildPolicyLocked(
|
445
|
+
const grpc_channel_args* args) {
|
446
|
+
LoadBalancingPolicy::Args lb_policy_args;
|
447
|
+
lb_policy_args.work_serializer =
|
448
|
+
xds_cluster_manager_policy_->work_serializer();
|
449
|
+
lb_policy_args.args = args;
|
450
|
+
lb_policy_args.channel_control_helper =
|
451
|
+
absl::make_unique<Helper>(this->Ref(DEBUG_LOCATION, "Helper"));
|
452
|
+
OrphanablePtr<LoadBalancingPolicy> lb_policy =
|
453
|
+
MakeOrphanable<ChildPolicyHandler>(std::move(lb_policy_args),
|
454
|
+
&grpc_xds_cluster_manager_lb_trace);
|
455
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_cluster_manager_lb_trace)) {
|
456
|
+
gpr_log(GPR_INFO,
|
457
|
+
"[xds_cluster_manager_lb %p] ClusterChild %p %s: Created "
|
458
|
+
"new child "
|
459
|
+
"policy handler %p",
|
460
|
+
xds_cluster_manager_policy_.get(), this, name_.c_str(),
|
461
|
+
lb_policy.get());
|
462
|
+
}
|
463
|
+
// Add the xDS's interested_parties pollset_set to that of the newly created
|
464
|
+
// child policy. This will make the child policy progress upon activity on
|
465
|
+
// xDS LB, which in turn is tied to the application's call.
|
466
|
+
grpc_pollset_set_add_pollset_set(
|
467
|
+
lb_policy->interested_parties(),
|
468
|
+
xds_cluster_manager_policy_->interested_parties());
|
469
|
+
return lb_policy;
|
470
|
+
}
|
471
|
+
|
472
|
+
void XdsClusterManagerLb::ClusterChild::UpdateLocked(
|
473
|
+
RefCountedPtr<LoadBalancingPolicy::Config> config,
|
474
|
+
const ServerAddressList& addresses, const grpc_channel_args* args) {
|
475
|
+
if (xds_cluster_manager_policy_->shutting_down_) return;
|
476
|
+
// Update child weight.
|
477
|
+
// Reactivate if needed.
|
478
|
+
if (delayed_removal_timer_callback_pending_) {
|
479
|
+
delayed_removal_timer_callback_pending_ = false;
|
480
|
+
grpc_timer_cancel(&delayed_removal_timer_);
|
481
|
+
}
|
482
|
+
// Create child policy if needed.
|
483
|
+
if (child_policy_ == nullptr) {
|
484
|
+
child_policy_ = CreateChildPolicyLocked(args);
|
485
|
+
}
|
486
|
+
// Construct update args.
|
487
|
+
UpdateArgs update_args;
|
488
|
+
update_args.config = std::move(config);
|
489
|
+
update_args.addresses = addresses;
|
490
|
+
update_args.args = grpc_channel_args_copy(args);
|
491
|
+
// Update the policy.
|
492
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_cluster_manager_lb_trace)) {
|
493
|
+
gpr_log(GPR_INFO,
|
494
|
+
"[xds_cluster_manager_lb %p] ClusterChild %p %s: "
|
495
|
+
"Updating child "
|
496
|
+
"policy handler %p",
|
497
|
+
xds_cluster_manager_policy_.get(), this, name_.c_str(),
|
498
|
+
child_policy_.get());
|
499
|
+
}
|
500
|
+
child_policy_->UpdateLocked(std::move(update_args));
|
501
|
+
}
|
502
|
+
|
503
|
+
void XdsClusterManagerLb::ClusterChild::ExitIdleLocked() {
|
504
|
+
child_policy_->ExitIdleLocked();
|
505
|
+
}
|
506
|
+
|
507
|
+
void XdsClusterManagerLb::ClusterChild::ResetBackoffLocked() {
|
508
|
+
child_policy_->ResetBackoffLocked();
|
509
|
+
}
|
510
|
+
|
511
|
+
void XdsClusterManagerLb::ClusterChild::DeactivateLocked() {
|
512
|
+
// If already deactivated, don't do that again.
|
513
|
+
if (delayed_removal_timer_callback_pending_ == true) return;
|
514
|
+
// Set the child weight to 0 so that future picker won't contain this child.
|
515
|
+
// Start a timer to delete the child.
|
516
|
+
Ref(DEBUG_LOCATION, "ClusterChild+timer").release();
|
517
|
+
grpc_timer_init(&delayed_removal_timer_,
|
518
|
+
ExecCtx::Get()->Now() +
|
519
|
+
GRPC_XDS_CLUSTER_MANAGER_CHILD_RETENTION_INTERVAL_MS,
|
520
|
+
&on_delayed_removal_timer_);
|
521
|
+
delayed_removal_timer_callback_pending_ = true;
|
522
|
+
}
|
523
|
+
|
524
|
+
void XdsClusterManagerLb::ClusterChild::OnDelayedRemovalTimer(
|
525
|
+
void* arg, grpc_error* error) {
|
526
|
+
ClusterChild* self = static_cast<ClusterChild*>(arg);
|
527
|
+
GRPC_ERROR_REF(error); // Ref owned by the lambda
|
528
|
+
self->xds_cluster_manager_policy_->work_serializer()->Run(
|
529
|
+
[self, error]() { self->OnDelayedRemovalTimerLocked(error); },
|
530
|
+
DEBUG_LOCATION);
|
531
|
+
}
|
532
|
+
|
533
|
+
void XdsClusterManagerLb::ClusterChild::OnDelayedRemovalTimerLocked(
|
534
|
+
grpc_error* error) {
|
535
|
+
delayed_removal_timer_callback_pending_ = false;
|
536
|
+
if (error == GRPC_ERROR_NONE && !shutdown_) {
|
537
|
+
xds_cluster_manager_policy_->children_.erase(name_);
|
538
|
+
}
|
539
|
+
Unref(DEBUG_LOCATION, "ClusterChild+timer");
|
540
|
+
GRPC_ERROR_UNREF(error);
|
541
|
+
}
|
542
|
+
|
543
|
+
//
|
544
|
+
// XdsClusterManagerLb::ClusterChild::Helper
|
545
|
+
//
|
546
|
+
|
547
|
+
RefCountedPtr<SubchannelInterface>
|
548
|
+
XdsClusterManagerLb::ClusterChild::Helper::CreateSubchannel(
|
549
|
+
ServerAddress address, const grpc_channel_args& args) {
|
550
|
+
if (xds_cluster_manager_child_->xds_cluster_manager_policy_->shutting_down_)
|
551
|
+
return nullptr;
|
552
|
+
return xds_cluster_manager_child_->xds_cluster_manager_policy_
|
553
|
+
->channel_control_helper()
|
554
|
+
->CreateSubchannel(std::move(address), args);
|
555
|
+
}
|
556
|
+
|
557
|
+
void XdsClusterManagerLb::ClusterChild::Helper::UpdateState(
|
558
|
+
grpc_connectivity_state state, const absl::Status& status,
|
559
|
+
std::unique_ptr<SubchannelPicker> picker) {
|
560
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_xds_cluster_manager_lb_trace)) {
|
561
|
+
gpr_log(
|
562
|
+
GPR_INFO,
|
563
|
+
"[xds_cluster_manager_lb %p] child %s: received update: state=%s (%s) "
|
564
|
+
"picker=%p",
|
565
|
+
xds_cluster_manager_child_->xds_cluster_manager_policy_.get(),
|
566
|
+
xds_cluster_manager_child_->name_.c_str(), ConnectivityStateName(state),
|
567
|
+
status.ToString().c_str(), picker.get());
|
568
|
+
}
|
569
|
+
if (xds_cluster_manager_child_->xds_cluster_manager_policy_->shutting_down_)
|
570
|
+
return;
|
571
|
+
// Cache the picker in the ClusterChild.
|
572
|
+
xds_cluster_manager_child_->picker_wrapper_ =
|
573
|
+
MakeRefCounted<ChildPickerWrapper>(xds_cluster_manager_child_->name_,
|
574
|
+
std::move(picker));
|
575
|
+
// Decide what state to report for aggregation purposes.
|
576
|
+
// If we haven't seen a failure since the last time we were in state
|
577
|
+
// READY, then we report the state change as-is. However, once we do see
|
578
|
+
// a failure, we report TRANSIENT_FAILURE and ignore any subsequent state
|
579
|
+
// changes until we go back into state READY.
|
580
|
+
if (!xds_cluster_manager_child_->seen_failure_since_ready_) {
|
581
|
+
if (state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
|
582
|
+
xds_cluster_manager_child_->seen_failure_since_ready_ = true;
|
583
|
+
}
|
584
|
+
} else {
|
585
|
+
if (state != GRPC_CHANNEL_READY) return;
|
586
|
+
xds_cluster_manager_child_->seen_failure_since_ready_ = false;
|
587
|
+
}
|
588
|
+
xds_cluster_manager_child_->connectivity_state_ = state;
|
589
|
+
// Notify the LB policy.
|
590
|
+
xds_cluster_manager_child_->xds_cluster_manager_policy_->UpdateStateLocked();
|
591
|
+
}
|
592
|
+
|
593
|
+
void XdsClusterManagerLb::ClusterChild::Helper::RequestReresolution() {
|
594
|
+
if (xds_cluster_manager_child_->xds_cluster_manager_policy_->shutting_down_)
|
595
|
+
return;
|
596
|
+
xds_cluster_manager_child_->xds_cluster_manager_policy_
|
597
|
+
->channel_control_helper()
|
598
|
+
->RequestReresolution();
|
599
|
+
}
|
600
|
+
|
601
|
+
void XdsClusterManagerLb::ClusterChild::Helper::AddTraceEvent(
|
602
|
+
TraceSeverity severity, absl::string_view message) {
|
603
|
+
if (xds_cluster_manager_child_->xds_cluster_manager_policy_->shutting_down_)
|
604
|
+
return;
|
605
|
+
xds_cluster_manager_child_->xds_cluster_manager_policy_
|
606
|
+
->channel_control_helper()
|
607
|
+
->AddTraceEvent(severity, message);
|
608
|
+
}
|
609
|
+
|
610
|
+
//
|
611
|
+
// factory
|
612
|
+
//
|
613
|
+
|
614
|
+
class XdsClusterManagerLbFactory : public LoadBalancingPolicyFactory {
|
615
|
+
public:
|
616
|
+
OrphanablePtr<LoadBalancingPolicy> CreateLoadBalancingPolicy(
|
617
|
+
LoadBalancingPolicy::Args args) const override {
|
618
|
+
return MakeOrphanable<XdsClusterManagerLb>(std::move(args));
|
619
|
+
}
|
620
|
+
|
621
|
+
const char* name() const override { return kXdsClusterManager; }
|
622
|
+
|
623
|
+
RefCountedPtr<LoadBalancingPolicy::Config> ParseLoadBalancingConfig(
|
624
|
+
const Json& json, grpc_error** error) const override {
|
625
|
+
GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE);
|
626
|
+
if (json.type() == Json::Type::JSON_NULL) {
|
627
|
+
// xds_cluster_manager was mentioned as a policy in the deprecated
|
628
|
+
// loadBalancingPolicy field or in the client API.
|
629
|
+
*error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
630
|
+
"field:loadBalancingPolicy error:xds_cluster_manager policy requires "
|
631
|
+
"configuration. Please use loadBalancingConfig field of service "
|
632
|
+
"config instead.");
|
633
|
+
return nullptr;
|
634
|
+
}
|
635
|
+
std::vector<grpc_error*> error_list;
|
636
|
+
XdsClusterManagerLbConfig::ClusterMap cluster_map;
|
637
|
+
std::set<std::string /*cluster_name*/> clusters_to_be_used;
|
638
|
+
auto it = json.object_value().find("children");
|
639
|
+
if (it == json.object_value().end()) {
|
640
|
+
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
641
|
+
"field:children error:required field not present"));
|
642
|
+
} else if (it->second.type() != Json::Type::OBJECT) {
|
643
|
+
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
644
|
+
"field:children error:type should be object"));
|
645
|
+
} else {
|
646
|
+
for (const auto& p : it->second.object_value()) {
|
647
|
+
const std::string& child_name = p.first;
|
648
|
+
if (child_name.empty()) {
|
649
|
+
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
650
|
+
"field:children element error: name cannot be empty"));
|
651
|
+
continue;
|
652
|
+
}
|
653
|
+
RefCountedPtr<LoadBalancingPolicy::Config> child_config;
|
654
|
+
std::vector<grpc_error*> child_errors =
|
655
|
+
ParseChildConfig(p.second, &child_config);
|
656
|
+
if (!child_errors.empty()) {
|
657
|
+
// Can't use GRPC_ERROR_CREATE_FROM_VECTOR() here, because the error
|
658
|
+
// string is not static in this case.
|
659
|
+
grpc_error* error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(
|
660
|
+
absl::StrCat("field:children name:", child_name).c_str());
|
661
|
+
for (grpc_error* child_error : child_errors) {
|
662
|
+
error = grpc_error_add_child(error, child_error);
|
663
|
+
}
|
664
|
+
error_list.push_back(error);
|
665
|
+
} else {
|
666
|
+
cluster_map[child_name] = std::move(child_config);
|
667
|
+
clusters_to_be_used.insert(child_name);
|
668
|
+
}
|
669
|
+
}
|
670
|
+
}
|
671
|
+
if (cluster_map.empty()) {
|
672
|
+
error_list.push_back(
|
673
|
+
GRPC_ERROR_CREATE_FROM_STATIC_STRING("no valid children configured"));
|
674
|
+
}
|
675
|
+
if (!error_list.empty()) {
|
676
|
+
*error = GRPC_ERROR_CREATE_FROM_VECTOR(
|
677
|
+
"xds_cluster_manager_experimental LB policy config", &error_list);
|
678
|
+
return nullptr;
|
679
|
+
}
|
680
|
+
return MakeRefCounted<XdsClusterManagerLbConfig>(std::move(cluster_map));
|
681
|
+
}
|
682
|
+
|
683
|
+
private:
|
684
|
+
static std::vector<grpc_error*> ParseChildConfig(
|
685
|
+
const Json& json,
|
686
|
+
RefCountedPtr<LoadBalancingPolicy::Config>* child_config) {
|
687
|
+
std::vector<grpc_error*> error_list;
|
688
|
+
if (json.type() != Json::Type::OBJECT) {
|
689
|
+
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
690
|
+
"value should be of type object"));
|
691
|
+
return error_list;
|
692
|
+
}
|
693
|
+
auto it = json.object_value().find("childPolicy");
|
694
|
+
if (it == json.object_value().end()) {
|
695
|
+
error_list.push_back(
|
696
|
+
GRPC_ERROR_CREATE_FROM_STATIC_STRING("did not find childPolicy"));
|
697
|
+
} else {
|
698
|
+
grpc_error* parse_error = GRPC_ERROR_NONE;
|
699
|
+
*child_config = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(
|
700
|
+
it->second, &parse_error);
|
701
|
+
if (*child_config == nullptr) {
|
702
|
+
GPR_DEBUG_ASSERT(parse_error != GRPC_ERROR_NONE);
|
703
|
+
std::vector<grpc_error*> child_errors;
|
704
|
+
child_errors.push_back(parse_error);
|
705
|
+
error_list.push_back(
|
706
|
+
GRPC_ERROR_CREATE_FROM_VECTOR("field:childPolicy", &child_errors));
|
707
|
+
}
|
708
|
+
}
|
709
|
+
return error_list;
|
710
|
+
}
|
711
|
+
};
|
712
|
+
|
713
|
+
} // namespace
|
714
|
+
|
715
|
+
} // namespace grpc_core
|
716
|
+
|
717
|
+
//
|
718
|
+
// Plugin registration
|
719
|
+
//
|
720
|
+
|
721
|
+
void grpc_lb_policy_xds_cluster_manager_init() {
|
722
|
+
grpc_core::LoadBalancingPolicyRegistry::Builder::
|
723
|
+
RegisterLoadBalancingPolicyFactory(
|
724
|
+
absl::make_unique<grpc_core::XdsClusterManagerLbFactory>());
|
725
|
+
}
|
726
|
+
|
727
|
+
void grpc_lb_policy_xds_cluster_manager_shutdown() {}
|