grpc 1.60.2 → 1.61.0.pre2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Makefile +208 -165
- data/include/grpc/event_engine/event_engine.h +59 -12
- data/include/grpc/event_engine/internal/memory_allocator_impl.h +6 -0
- data/include/grpc/event_engine/internal/slice_cast.h +12 -0
- data/include/grpc/event_engine/memory_allocator.h +3 -1
- data/include/grpc/event_engine/slice.h +5 -0
- data/include/grpc/grpc_security.h +22 -1
- data/include/grpc/impl/call.h +29 -0
- data/include/grpc/impl/channel_arg_names.h +12 -1
- data/include/grpc/impl/slice_type.h +1 -1
- data/include/grpc/module.modulemap +1 -0
- data/src/core/ext/filters/backend_metrics/backend_metric_filter.cc +54 -7
- data/src/core/ext/filters/backend_metrics/backend_metric_filter.h +20 -6
- data/src/core/ext/filters/channel_idle/channel_idle_filter.cc +10 -13
- data/src/core/ext/filters/channel_idle/channel_idle_filter.h +18 -10
- data/src/core/ext/filters/channel_idle/legacy_channel_idle_filter.cc +326 -0
- data/src/core/ext/filters/channel_idle/legacy_channel_idle_filter.h +143 -0
- data/src/core/ext/filters/client_channel/backend_metric.cc +2 -2
- data/src/core/ext/filters/client_channel/client_channel.cc +32 -6
- data/src/core/ext/filters/client_channel/client_channel_internal.h +2 -0
- data/src/core/ext/filters/client_channel/global_subchannel_pool.cc +1 -1
- data/src/core/ext/filters/client_channel/lb_policy/address_filtering.cc +54 -21
- data/src/core/ext/filters/client_channel/lb_policy/address_filtering.h +3 -2
- data/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc +2 -1
- data/src/core/ext/filters/client_channel/lb_policy/endpoint_list.cc +12 -15
- data/src/core/ext/filters/client_channel/lb_policy/endpoint_list.h +8 -5
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +139 -92
- data/src/core/ext/filters/client_channel/lb_policy/health_check_client.cc +9 -4
- data/src/core/ext/filters/client_channel/lb_policy/oob_backend_metric.cc +9 -4
- data/src/core/ext/filters/client_channel/lb_policy/outlier_detection/outlier_detection.cc +10 -11
- data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +94 -93
- data/src/core/ext/filters/client_channel/lb_policy/priority/priority.cc +5 -3
- data/src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.cc +12 -15
- data/src/core/ext/filters/client_channel/lb_policy/rls/rls.cc +38 -16
- data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +25 -28
- data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +10 -10
- data/src/core/ext/filters/client_channel/lb_policy/weighted_round_robin/weighted_round_robin.cc +37 -35
- data/src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc +11 -9
- data/src/core/ext/filters/client_channel/lb_policy/xds/cds.cc +504 -461
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc +232 -122
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc +8 -6
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds_override_host.cc +642 -251
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds_override_host.h +2 -6
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds_wrr_locality.cc +7 -8
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +2 -1
- data/src/core/ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.cc +3 -1
- data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +2 -2
- data/src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc +2 -2
- data/src/core/ext/filters/client_channel/resolver/polling_resolver.cc +6 -8
- data/src/core/ext/filters/client_channel/resolver/xds/xds_dependency_manager.cc +1031 -0
- data/src/core/ext/filters/client_channel/resolver/xds/xds_dependency_manager.h +277 -0
- data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +128 -270
- data/src/core/ext/filters/client_channel/resolver/xds/{xds_resolver.h → xds_resolver_attributes.h} +5 -4
- data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver_trace.cc +25 -0
- data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver_trace.h +30 -0
- data/src/core/ext/filters/client_channel/retry_filter.cc +1 -0
- data/src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc +35 -17
- data/src/core/ext/filters/deadline/deadline_filter.cc +12 -0
- data/src/core/ext/filters/fault_injection/fault_injection_filter.cc +17 -13
- data/src/core/ext/filters/fault_injection/fault_injection_filter.h +13 -4
- data/src/core/ext/filters/http/client/http_client_filter.cc +23 -32
- data/src/core/ext/filters/http/client/http_client_filter.h +10 -5
- data/src/core/ext/filters/http/client_authority_filter.cc +14 -14
- data/src/core/ext/filters/http/client_authority_filter.h +12 -4
- data/src/core/ext/filters/http/http_filters_plugin.cc +42 -20
- data/src/core/ext/filters/http/message_compress/compression_filter.cc +55 -80
- data/src/core/ext/filters/http/message_compress/compression_filter.h +54 -12
- data/src/core/ext/filters/http/message_compress/legacy_compression_filter.cc +325 -0
- data/src/core/ext/filters/http/message_compress/legacy_compression_filter.h +139 -0
- data/src/core/ext/filters/http/server/http_server_filter.cc +41 -41
- data/src/core/ext/filters/http/server/http_server_filter.h +11 -4
- data/src/core/ext/filters/message_size/message_size_filter.cc +56 -76
- data/src/core/ext/filters/message_size/message_size_filter.h +35 -23
- data/src/core/ext/filters/rbac/rbac_filter.cc +15 -11
- data/src/core/ext/filters/rbac/rbac_filter.h +11 -4
- data/src/core/ext/filters/server_config_selector/server_config_selector_filter.cc +25 -13
- data/src/core/ext/filters/stateful_session/stateful_session_filter.cc +47 -50
- data/src/core/ext/filters/stateful_session/stateful_session_filter.h +21 -4
- data/src/core/ext/transport/chttp2/alpn/alpn.cc +1 -1
- data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +2 -2
- data/src/core/ext/transport/chttp2/server/chttp2_server.cc +11 -2
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +68 -145
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.h +3 -3
- data/src/core/ext/transport/chttp2/transport/flow_control.cc +21 -82
- data/src/core/ext/transport/chttp2/transport/flow_control.h +1 -8
- data/src/core/ext/transport/chttp2/transport/frame.cc +506 -0
- data/src/core/ext/transport/chttp2/transport/frame.h +214 -0
- data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +1 -1
- data/src/core/ext/transport/chttp2/transport/frame_settings.cc +33 -79
- data/src/core/ext/transport/chttp2/transport/frame_settings.h +4 -7
- data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +27 -36
- data/src/core/ext/transport/chttp2/transport/hpack_parser.h +0 -2
- data/src/core/ext/transport/chttp2/transport/http2_settings.cc +122 -32
- data/src/core/ext/transport/chttp2/transport/http2_settings.h +142 -37
- data/src/core/ext/transport/chttp2/transport/internal.h +1 -22
- data/src/core/ext/transport/chttp2/transport/parsing.cc +23 -37
- data/src/core/ext/transport/chttp2/transport/writing.cc +26 -58
- data/src/core/ext/transport/inproc/inproc_transport.cc +172 -13
- data/src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb.h +712 -0
- data/src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.c +151 -0
- data/src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.h +33 -0
- data/src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.c +133 -0
- data/src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.h +50 -0
- data/src/core/ext/xds/certificate_provider_store.cc +2 -1
- data/src/core/ext/xds/certificate_provider_store.h +0 -5
- data/src/core/ext/xds/xds_api.cc +31 -18
- data/src/core/ext/xds/xds_api.h +2 -2
- data/src/core/ext/xds/xds_bootstrap.h +3 -0
- data/src/core/ext/xds/xds_certificate_provider.cc +88 -287
- data/src/core/ext/xds/xds_certificate_provider.h +44 -111
- data/src/core/ext/xds/xds_client.cc +420 -414
- data/src/core/ext/xds/xds_client.h +31 -22
- data/src/core/ext/xds/xds_client_grpc.cc +3 -1
- data/src/core/ext/xds/xds_cluster.cc +104 -11
- data/src/core/ext/xds/xds_cluster.h +9 -1
- data/src/core/ext/xds/xds_cluster_specifier_plugin.cc +9 -5
- data/src/core/ext/xds/xds_common_types.cc +14 -10
- data/src/core/ext/xds/xds_endpoint.cc +9 -4
- data/src/core/ext/xds/xds_endpoint.h +5 -1
- data/src/core/ext/xds/xds_health_status.cc +12 -2
- data/src/core/ext/xds/xds_health_status.h +4 -2
- data/src/core/ext/xds/xds_http_rbac_filter.cc +5 -3
- data/src/core/ext/xds/xds_listener.cc +14 -8
- data/src/core/ext/xds/xds_resource_type_impl.h +6 -4
- data/src/core/ext/xds/xds_route_config.cc +34 -22
- data/src/core/ext/xds/xds_route_config.h +1 -0
- data/src/core/ext/xds/xds_server_config_fetcher.cc +61 -57
- data/src/core/ext/xds/xds_transport.h +3 -0
- data/src/core/ext/xds/xds_transport_grpc.cc +47 -50
- data/src/core/ext/xds/xds_transport_grpc.h +4 -0
- data/src/core/lib/channel/call_tracer.cc +12 -0
- data/src/core/lib/channel/call_tracer.h +17 -3
- data/src/core/lib/channel/channel_args.cc +24 -14
- data/src/core/lib/channel/channel_args.h +74 -13
- data/src/core/lib/channel/channel_stack.cc +27 -0
- data/src/core/lib/channel/channel_stack.h +10 -10
- data/src/core/lib/channel/connected_channel.cc +64 -18
- data/src/core/lib/channel/promise_based_filter.h +1041 -1
- data/src/core/lib/channel/server_call_tracer_filter.cc +43 -35
- data/src/core/lib/compression/compression_internal.cc +0 -3
- data/src/core/lib/event_engine/ares_resolver.cc +35 -14
- data/src/core/lib/event_engine/ares_resolver.h +9 -10
- data/src/core/lib/event_engine/cf_engine/dns_service_resolver.cc +8 -1
- data/src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc +132 -0
- data/src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.h +61 -0
- data/src/core/lib/event_engine/posix_engine/posix_engine.cc +52 -36
- data/src/core/lib/event_engine/posix_engine/posix_engine.h +4 -9
- data/src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.cc +11 -3
- data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.cc +9 -2
- data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.h +7 -0
- data/src/core/lib/event_engine/posix_engine/timer_manager.cc +17 -27
- data/src/core/lib/event_engine/posix_engine/timer_manager.h +0 -3
- data/src/core/lib/event_engine/ref_counted_dns_resolver_interface.h +55 -0
- data/src/core/lib/event_engine/windows/native_windows_dns_resolver.cc +114 -0
- data/src/core/lib/event_engine/windows/native_windows_dns_resolver.h +51 -0
- data/src/core/lib/event_engine/windows/windows_engine.cc +7 -7
- data/src/core/lib/experiments/config.cc +13 -0
- data/src/core/lib/experiments/config.h +3 -0
- data/src/core/lib/experiments/experiments.cc +245 -366
- data/src/core/lib/experiments/experiments.h +50 -156
- data/src/core/lib/gprpp/debug_location.h +13 -0
- data/src/core/lib/gprpp/dual_ref_counted.h +36 -7
- data/src/core/lib/gprpp/orphanable.h +27 -0
- data/src/core/lib/gprpp/ref_counted.h +63 -22
- data/src/core/lib/gprpp/ref_counted_ptr.h +70 -27
- data/src/core/lib/gprpp/ref_counted_string.h +13 -0
- data/src/core/lib/gprpp/status_helper.cc +1 -2
- data/src/core/lib/iomgr/combiner.cc +15 -51
- data/src/core/lib/iomgr/event_engine_shims/endpoint.cc +31 -0
- data/src/core/lib/iomgr/event_engine_shims/endpoint.h +16 -0
- data/src/core/lib/iomgr/tcp_client_posix.cc +4 -3
- data/src/core/lib/load_balancing/lb_policy.h +1 -1
- data/src/core/lib/promise/activity.cc +17 -2
- data/src/core/lib/promise/activity.h +5 -4
- data/src/core/lib/promise/all_ok.h +80 -0
- data/src/core/lib/promise/detail/join_state.h +2077 -0
- data/src/core/lib/promise/detail/promise_factory.h +1 -0
- data/src/core/lib/promise/detail/promise_like.h +8 -1
- data/src/core/lib/promise/detail/seq_state.h +3458 -150
- data/src/core/lib/promise/detail/status.h +42 -5
- data/src/core/lib/promise/for_each.h +13 -1
- data/src/core/lib/promise/if.h +4 -0
- data/src/core/lib/promise/latch.h +6 -3
- data/src/core/lib/promise/party.cc +33 -31
- data/src/core/lib/promise/party.h +142 -6
- data/src/core/lib/promise/poll.h +39 -13
- data/src/core/lib/promise/promise.h +4 -0
- data/src/core/lib/promise/seq.h +107 -7
- data/src/core/lib/promise/status_flag.h +196 -0
- data/src/core/lib/promise/try_join.h +132 -0
- data/src/core/lib/promise/try_seq.h +132 -10
- data/src/core/lib/resolver/endpoint_addresses.cc +0 -1
- data/src/core/lib/resolver/endpoint_addresses.h +48 -0
- data/src/core/lib/resource_quota/arena.h +2 -2
- data/src/core/lib/resource_quota/memory_quota.cc +57 -8
- data/src/core/lib/resource_quota/memory_quota.h +6 -0
- data/src/core/lib/security/authorization/grpc_server_authz_filter.cc +14 -11
- data/src/core/lib/security/authorization/grpc_server_authz_filter.h +14 -5
- data/src/core/lib/security/credentials/external/aws_external_account_credentials.cc +4 -0
- data/src/core/lib/security/credentials/external/aws_external_account_credentials.h +4 -0
- data/src/core/lib/security/credentials/external/external_account_credentials.cc +28 -20
- data/src/core/lib/security/credentials/external/external_account_credentials.h +4 -0
- data/src/core/lib/security/credentials/external/file_external_account_credentials.cc +4 -0
- data/src/core/lib/security/credentials/external/file_external_account_credentials.h +4 -0
- data/src/core/lib/security/credentials/external/url_external_account_credentials.cc +4 -0
- data/src/core/lib/security/credentials/external/url_external_account_credentials.h +4 -0
- data/src/core/lib/security/credentials/plugin/plugin_credentials.cc +2 -1
- data/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h +0 -3
- data/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc +12 -0
- data/src/core/lib/security/credentials/tls/grpc_tls_crl_provider.cc +22 -5
- data/src/core/lib/security/credentials/tls/grpc_tls_crl_provider.h +1 -5
- data/src/core/lib/security/credentials/tls/tls_credentials.cc +16 -0
- data/src/core/lib/security/credentials/xds/xds_credentials.cc +21 -28
- data/src/core/lib/security/credentials/xds/xds_credentials.h +2 -4
- data/src/core/lib/security/security_connector/tls/tls_security_connector.cc +4 -3
- data/src/core/lib/security/transport/auth_filters.h +71 -4
- data/src/core/lib/security/transport/client_auth_filter.cc +2 -4
- data/src/core/lib/security/transport/legacy_server_auth_filter.cc +244 -0
- data/src/core/lib/security/transport/server_auth_filter.cc +70 -90
- data/src/core/lib/slice/slice_buffer.h +3 -0
- data/src/core/lib/surface/builtins.cc +1 -1
- data/src/core/lib/surface/call.cc +683 -196
- data/src/core/lib/surface/call.h +26 -13
- data/src/core/lib/surface/call_trace.cc +42 -1
- data/src/core/lib/surface/channel.cc +0 -1
- data/src/core/lib/surface/channel.h +0 -6
- data/src/core/lib/surface/channel_init.h +26 -0
- data/src/core/lib/surface/init.cc +14 -8
- data/src/core/lib/surface/server.cc +256 -237
- data/src/core/lib/surface/server.h +26 -54
- data/src/core/lib/surface/version.cc +2 -2
- data/src/core/lib/surface/wait_for_cq_end_op.h +94 -0
- data/src/core/lib/transport/call_final_info.cc +38 -0
- data/src/core/lib/transport/call_final_info.h +54 -0
- data/src/core/lib/transport/connectivity_state.cc +3 -2
- data/src/core/lib/transport/connectivity_state.h +4 -0
- data/src/core/lib/transport/metadata_batch.h +4 -4
- data/src/core/lib/transport/transport.cc +70 -19
- data/src/core/lib/transport/transport.h +395 -25
- data/src/core/plugin_registry/grpc_plugin_registry.cc +3 -0
- data/src/core/plugin_registry/grpc_plugin_registry_extra.cc +0 -3
- data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +1 -1
- data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +1 -1
- data/src/core/tsi/alts/handshaker/transport_security_common_api.cc +1 -1
- data/src/core/tsi/ssl_transport_security.cc +65 -43
- data/src/ruby/ext/grpc/rb_channel_args.c +3 -1
- data/src/ruby/ext/grpc/rb_grpc.c +0 -1
- data/src/ruby/ext/grpc/rb_grpc.h +0 -2
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +4 -0
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +6 -0
- data/src/ruby/lib/grpc/version.rb +1 -1
- data/third_party/upb/upb/reflection/def_pool.h +2 -2
- data/third_party/zlib/adler32.c +5 -27
- data/third_party/zlib/compress.c +5 -16
- data/third_party/zlib/crc32.c +86 -162
- data/third_party/zlib/deflate.c +233 -336
- data/third_party/zlib/deflate.h +8 -8
- data/third_party/zlib/gzguts.h +11 -12
- data/third_party/zlib/infback.c +7 -23
- data/third_party/zlib/inffast.c +1 -4
- data/third_party/zlib/inffast.h +1 -1
- data/third_party/zlib/inflate.c +30 -99
- data/third_party/zlib/inftrees.c +6 -11
- data/third_party/zlib/inftrees.h +3 -3
- data/third_party/zlib/trees.c +224 -302
- data/third_party/zlib/uncompr.c +4 -12
- data/third_party/zlib/zconf.h +6 -2
- data/third_party/zlib/zlib.h +191 -188
- data/third_party/zlib/zutil.c +16 -44
- data/third_party/zlib/zutil.h +10 -10
- metadata +35 -13
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc +0 -1173
- data/src/core/lib/event_engine/memory_allocator.cc +0 -74
- data/src/core/lib/transport/pid_controller.cc +0 -51
- data/src/core/lib/transport/pid_controller.h +0 -116
- data/third_party/upb/upb/collections/array.h +0 -17
- data/third_party/upb/upb/collections/map.h +0 -17
- data/third_party/upb/upb/upb.hpp +0 -18
@@ -18,11 +18,9 @@
|
|
18
18
|
|
19
19
|
#include "src/core/ext/filters/client_channel/lb_policy/xds/xds_override_host.h"
|
20
20
|
|
21
|
-
#include <inttypes.h>
|
22
21
|
#include <stddef.h>
|
23
22
|
|
24
23
|
#include <algorithm>
|
25
|
-
#include <atomic>
|
26
24
|
#include <functional>
|
27
25
|
#include <map>
|
28
26
|
#include <memory>
|
@@ -34,6 +32,7 @@
|
|
34
32
|
#include <vector>
|
35
33
|
|
36
34
|
#include "absl/base/thread_annotations.h"
|
35
|
+
#include "absl/functional/function_ref.h"
|
37
36
|
#include "absl/status/status.h"
|
38
37
|
#include "absl/status/statusor.h"
|
39
38
|
#include "absl/strings/str_cat.h"
|
@@ -44,13 +43,16 @@
|
|
44
43
|
#include "absl/types/span.h"
|
45
44
|
#include "absl/types/variant.h"
|
46
45
|
|
46
|
+
#include <grpc/event_engine/event_engine.h>
|
47
47
|
#include <grpc/impl/connectivity_state.h>
|
48
48
|
#include <grpc/support/log.h>
|
49
49
|
|
50
50
|
#include "src/core/ext/filters/client_channel/client_channel_internal.h"
|
51
51
|
#include "src/core/ext/filters/client_channel/lb_policy/child_policy_handler.h"
|
52
|
+
#include "src/core/ext/filters/client_channel/resolver/xds/xds_dependency_manager.h"
|
52
53
|
#include "src/core/ext/filters/stateful_session/stateful_session_filter.h"
|
53
54
|
#include "src/core/ext/xds/xds_health_status.h"
|
55
|
+
#include "src/core/lib/address_utils/parse_address.h"
|
54
56
|
#include "src/core/lib/address_utils/sockaddr_utils.h"
|
55
57
|
#include "src/core/lib/channel/channel_args.h"
|
56
58
|
#include "src/core/lib/config/core_configuration.h"
|
@@ -82,6 +84,9 @@
|
|
82
84
|
#include "src/core/lib/transport/connectivity_state.h"
|
83
85
|
|
84
86
|
namespace grpc_core {
|
87
|
+
|
88
|
+
using ::grpc_event_engine::experimental::EventEngine;
|
89
|
+
|
85
90
|
TraceFlag grpc_lb_xds_override_host_trace(false, "xds_override_host_lb");
|
86
91
|
|
87
92
|
namespace {
|
@@ -102,16 +107,10 @@ struct PtrLessThan {
|
|
102
107
|
}
|
103
108
|
};
|
104
109
|
|
105
|
-
XdsHealthStatus GetEndpointHealthStatus(const EndpointAddresses& endpoint) {
|
106
|
-
return XdsHealthStatus(static_cast<XdsHealthStatus::HealthStatus>(
|
107
|
-
endpoint.args()
|
108
|
-
.GetInt(GRPC_ARG_XDS_HEALTH_STATUS)
|
109
|
-
.value_or(XdsHealthStatus::HealthStatus::kUnknown)));
|
110
|
-
}
|
111
|
-
|
112
110
|
//
|
113
111
|
// xds_override_host LB policy
|
114
112
|
//
|
113
|
+
|
115
114
|
class XdsOverrideHostLb : public LoadBalancingPolicy {
|
116
115
|
public:
|
117
116
|
explicit XdsOverrideHostLb(Args args);
|
@@ -125,12 +124,18 @@ class XdsOverrideHostLb : public LoadBalancingPolicy {
|
|
125
124
|
void ResetBackoffLocked() override;
|
126
125
|
|
127
126
|
private:
|
127
|
+
class SubchannelEntry;
|
128
|
+
|
128
129
|
class SubchannelWrapper : public DelegatingSubchannel {
|
129
130
|
public:
|
130
131
|
SubchannelWrapper(RefCountedPtr<SubchannelInterface> subchannel,
|
131
132
|
RefCountedPtr<XdsOverrideHostLb> policy);
|
132
133
|
|
133
|
-
|
134
|
+
// Called immediately after construction. We use two-phase initialization
|
135
|
+
// to avoid doing an allocation while holding the lock.
|
136
|
+
void set_subchannel_entry(RefCountedPtr<SubchannelEntry> subchannel_entry) {
|
137
|
+
subchannel_entry_ = std::move(subchannel_entry);
|
138
|
+
}
|
134
139
|
|
135
140
|
void WatchConnectivityState(
|
136
141
|
std::unique_ptr<ConnectivityStateWatcherInterface> watcher) override;
|
@@ -138,14 +143,24 @@ class XdsOverrideHostLb : public LoadBalancingPolicy {
|
|
138
143
|
void CancelConnectivityStateWatch(
|
139
144
|
ConnectivityStateWatcherInterface* watcher) override;
|
140
145
|
|
141
|
-
|
142
|
-
|
146
|
+
RefCountedStringValue address_list() const
|
147
|
+
ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsOverrideHostLb::mu_) {
|
148
|
+
return subchannel_entry_->address_list();
|
143
149
|
}
|
144
150
|
|
145
|
-
|
151
|
+
void set_last_used_time()
|
152
|
+
ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsOverrideHostLb::mu_) {
|
153
|
+
subchannel_entry_->set_last_used_time();
|
154
|
+
}
|
155
|
+
|
156
|
+
XdsOverrideHostLb* policy() const { return policy_.get(); }
|
146
157
|
|
147
|
-
|
148
|
-
|
158
|
+
RefCountedPtr<SubchannelWrapper> Clone() const {
|
159
|
+
auto subchannel =
|
160
|
+
MakeRefCounted<SubchannelWrapper>(wrapped_subchannel(), policy_);
|
161
|
+
subchannel->set_subchannel_entry(subchannel_entry_);
|
162
|
+
return subchannel;
|
163
|
+
}
|
149
164
|
|
150
165
|
private:
|
151
166
|
class ConnectivityStateWatcher : public ConnectivityStateWatcherInterface {
|
@@ -155,9 +170,13 @@ class XdsOverrideHostLb : public LoadBalancingPolicy {
|
|
155
170
|
: subchannel_(std::move(subchannel)) {}
|
156
171
|
|
157
172
|
void OnConnectivityStateChange(grpc_connectivity_state state,
|
158
|
-
absl::Status status) override
|
173
|
+
absl::Status status) override {
|
174
|
+
subchannel_->UpdateConnectivityState(state, status);
|
175
|
+
}
|
159
176
|
|
160
|
-
grpc_pollset_set* interested_parties() override
|
177
|
+
grpc_pollset_set* interested_parties() override {
|
178
|
+
return subchannel_->policy()->interested_parties();
|
179
|
+
}
|
161
180
|
|
162
181
|
private:
|
163
182
|
WeakRefCountedPtr<SubchannelWrapper> subchannel_;
|
@@ -168,68 +187,129 @@ class XdsOverrideHostLb : public LoadBalancingPolicy {
|
|
168
187
|
void UpdateConnectivityState(grpc_connectivity_state state,
|
169
188
|
absl::Status status);
|
170
189
|
|
171
|
-
ConnectivityStateWatcher* watcher_;
|
172
|
-
absl::optional<std::string> key_;
|
173
190
|
RefCountedPtr<XdsOverrideHostLb> policy_;
|
191
|
+
RefCountedPtr<SubchannelEntry> subchannel_entry_;
|
192
|
+
ConnectivityStateWatcher* watcher_;
|
174
193
|
std::set<std::unique_ptr<ConnectivityStateWatcherInterface>,
|
175
194
|
PtrLessThan<ConnectivityStateWatcherInterface>>
|
176
195
|
watchers_;
|
177
|
-
std::atomic<grpc_connectivity_state> connectivity_state_ = {
|
178
|
-
GRPC_CHANNEL_IDLE};
|
179
196
|
};
|
180
197
|
|
181
|
-
|
198
|
+
// An entry in the subchannel map.
|
199
|
+
//
|
200
|
+
// The entry may hold either an owned (RefCountedPtr<>) or unowned
|
201
|
+
// (raw pointer) SubchannelWrapper, but not both. It will be unowned
|
202
|
+
// in the case where the SubchannelWrapper is owned by the child policy.
|
203
|
+
// It will be owned in the case where the child policy has not created a
|
204
|
+
// subchannel but we have RPCs whose cookies point to that address.
|
205
|
+
//
|
206
|
+
// Note that when a SubchannelWrapper is orphaned, it will try to
|
207
|
+
// acquire the lock to remove itself from the entry. This means that
|
208
|
+
// whenever we need to remove an owned subchannel from an entry, if we
|
209
|
+
// released our ref to the SubchannelWrapper immediately, we would
|
210
|
+
// cause a deadlock, since our caller is already holding the lock. To
|
211
|
+
// avoid that, any method that may result in releasing a ref to the
|
212
|
+
// SubchannelWrapper will instead return that ref to the caller, who is
|
213
|
+
// responsible for releasing the ref after releasing the lock.
|
214
|
+
class SubchannelEntry : public RefCounted<SubchannelEntry> {
|
182
215
|
public:
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
if (eds_health_status_.status() == XdsHealthStatus::kDraining) {
|
188
|
-
subchannel_ = subchannel->Ref();
|
189
|
-
} else {
|
190
|
-
subchannel_ = subchannel->WeakRef();
|
191
|
-
}
|
216
|
+
bool HasOwnedSubchannel() const
|
217
|
+
ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsOverrideHostLb::mu_) {
|
218
|
+
auto* sc = absl::get_if<RefCountedPtr<SubchannelWrapper>>(&subchannel_);
|
219
|
+
return sc != nullptr && *sc != nullptr;
|
192
220
|
}
|
193
221
|
|
194
|
-
|
195
|
-
|
222
|
+
// Sets the unowned subchannel. If the entry previously had an
|
223
|
+
// owned subchannel, returns the ref to it.
|
224
|
+
RefCountedPtr<SubchannelWrapper> SetUnownedSubchannel(
|
225
|
+
SubchannelWrapper* subchannel)
|
226
|
+
ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsOverrideHostLb::mu_);
|
227
|
+
|
228
|
+
// Sets the owned subchannel. Must not be called if the entry
|
229
|
+
// already has an owned subchannel.
|
230
|
+
void SetOwnedSubchannel(RefCountedPtr<SubchannelWrapper> subchannel)
|
231
|
+
ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsOverrideHostLb::mu_) {
|
232
|
+
GPR_DEBUG_ASSERT(!HasOwnedSubchannel());
|
233
|
+
subchannel_ = std::move(subchannel);
|
196
234
|
}
|
197
235
|
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
236
|
+
// Returns a pointer to the subchannel, regardless of whether it's
|
237
|
+
// owned or not.
|
238
|
+
SubchannelWrapper* GetSubchannel() const
|
239
|
+
ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsOverrideHostLb::mu_);
|
240
|
+
|
241
|
+
// Returns a ref to the subchannel, regardless of whether it's owned
|
242
|
+
// or not. Returns null if there is no subchannel or if the
|
243
|
+
// subchannel's ref count is 0.
|
244
|
+
RefCountedPtr<SubchannelWrapper> GetSubchannelRef() const
|
245
|
+
ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsOverrideHostLb::mu_);
|
246
|
+
|
247
|
+
// If the entry has an owned subchannel, moves it out of the entry
|
248
|
+
// and returns it.
|
249
|
+
RefCountedPtr<SubchannelWrapper> TakeOwnedSubchannel()
|
250
|
+
ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsOverrideHostLb::mu_);
|
251
|
+
|
252
|
+
// Unsets the entry's subchannel.
|
253
|
+
// If the entry had an owned subchannel, moves the ref into
|
254
|
+
// owned_subchannels.
|
255
|
+
void UnsetSubchannel(
|
256
|
+
std::vector<RefCountedPtr<SubchannelWrapper>>* owned_subchannels)
|
257
|
+
ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsOverrideHostLb::mu_);
|
258
|
+
|
259
|
+
// Called when a SubchannelWrapper is orphaned. May replace the
|
260
|
+
// unowned SubchannelWrapper with an owned one based on
|
261
|
+
// last_used_time_ and connection_idle_timeout.
|
262
|
+
void OnSubchannelWrapperOrphan(SubchannelWrapper* wrapper,
|
263
|
+
Duration connection_idle_timeout)
|
264
|
+
ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsOverrideHostLb::mu_);
|
265
|
+
|
266
|
+
grpc_connectivity_state connectivity_state() const
|
267
|
+
ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsOverrideHostLb::mu_) {
|
268
|
+
return connectivity_state_;
|
269
|
+
}
|
270
|
+
void set_connectivity_state(grpc_connectivity_state state)
|
271
|
+
ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsOverrideHostLb::mu_) {
|
272
|
+
connectivity_state_ = state;
|
206
273
|
}
|
207
274
|
|
208
|
-
|
275
|
+
XdsHealthStatus eds_health_status() const
|
276
|
+
ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsOverrideHostLb::mu_) {
|
277
|
+
return eds_health_status_;
|
278
|
+
}
|
279
|
+
void set_eds_health_status(XdsHealthStatus eds_health_status)
|
280
|
+
ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsOverrideHostLb::mu_) {
|
209
281
|
eds_health_status_ = eds_health_status;
|
210
|
-
auto subchannel = GetSubchannel();
|
211
|
-
if (subchannel == nullptr) return;
|
212
|
-
if (eds_health_status_.status() == XdsHealthStatus::kDraining) {
|
213
|
-
subchannel_ = subchannel->Ref();
|
214
|
-
} else {
|
215
|
-
subchannel_ = subchannel->WeakRef();
|
216
|
-
}
|
217
282
|
}
|
218
283
|
|
219
|
-
|
220
|
-
|
221
|
-
|
284
|
+
RefCountedStringValue address_list() const
|
285
|
+
ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsOverrideHostLb::mu_) {
|
286
|
+
return address_list_;
|
287
|
+
}
|
288
|
+
void set_address_list(RefCountedStringValue address_list)
|
289
|
+
ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsOverrideHostLb::mu_) {
|
222
290
|
address_list_ = std::move(address_list);
|
223
291
|
}
|
224
292
|
|
225
|
-
|
293
|
+
Timestamp last_used_time() const
|
294
|
+
ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsOverrideHostLb::mu_) {
|
295
|
+
return last_used_time_;
|
296
|
+
}
|
297
|
+
void set_last_used_time()
|
298
|
+
ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsOverrideHostLb::mu_) {
|
299
|
+
last_used_time_ = Timestamp::Now();
|
300
|
+
}
|
226
301
|
|
227
302
|
private:
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
303
|
+
grpc_connectivity_state connectivity_state_
|
304
|
+
ABSL_GUARDED_BY(&XdsOverrideHostLb::mu_) = GRPC_CHANNEL_IDLE;
|
305
|
+
absl::variant<SubchannelWrapper*, RefCountedPtr<SubchannelWrapper>>
|
306
|
+
subchannel_ ABSL_GUARDED_BY(&XdsOverrideHostLb::mu_);
|
307
|
+
XdsHealthStatus eds_health_status_ ABSL_GUARDED_BY(
|
308
|
+
&XdsOverrideHostLb::mu_) = XdsHealthStatus(XdsHealthStatus::kUnknown);
|
309
|
+
RefCountedStringValue address_list_
|
310
|
+
ABSL_GUARDED_BY(&XdsOverrideHostLb::mu_);
|
311
|
+
Timestamp last_used_time_ ABSL_GUARDED_BY(&XdsOverrideHostLb::mu_) =
|
312
|
+
Timestamp::InfPast();
|
233
313
|
};
|
234
314
|
|
235
315
|
// A picker that wraps the picker from the child for cases when cookie is
|
@@ -249,8 +329,8 @@ class XdsOverrideHostLb : public LoadBalancingPolicy {
|
|
249
329
|
RefCountedPtr<SubchannelWrapper> subchannel)
|
250
330
|
: subchannel_(std::move(subchannel)) {
|
251
331
|
GRPC_CLOSURE_INIT(&closure_, RunInExecCtx, this, nullptr);
|
252
|
-
// Hop into ExecCtx, so that we'
|
253
|
-
// while
|
332
|
+
// Hop into ExecCtx, so that we don't get stuck running
|
333
|
+
// arbitrary WorkSerializer callbacks while doing a pick.
|
254
334
|
ExecCtx::Run(DEBUG_LOCATION, &closure_, absl::OkStatus());
|
255
335
|
}
|
256
336
|
|
@@ -269,6 +349,33 @@ class XdsOverrideHostLb : public LoadBalancingPolicy {
|
|
269
349
|
grpc_closure closure_;
|
270
350
|
};
|
271
351
|
|
352
|
+
class SubchannelCreationRequester {
|
353
|
+
public:
|
354
|
+
SubchannelCreationRequester(RefCountedPtr<XdsOverrideHostLb> policy,
|
355
|
+
absl::string_view address)
|
356
|
+
: policy_(std::move(policy)), address_(address) {
|
357
|
+
GRPC_CLOSURE_INIT(&closure_, RunInExecCtx, this, nullptr);
|
358
|
+
// Hop into ExecCtx, so that we don't get stuck running
|
359
|
+
// arbitrary WorkSerializer callbacks while doing a pick.
|
360
|
+
ExecCtx::Run(DEBUG_LOCATION, &closure_, absl::OkStatus());
|
361
|
+
}
|
362
|
+
|
363
|
+
private:
|
364
|
+
static void RunInExecCtx(void* arg, grpc_error_handle /*error*/) {
|
365
|
+
auto* self = static_cast<SubchannelCreationRequester*>(arg);
|
366
|
+
self->policy_->work_serializer()->Run(
|
367
|
+
[self]() {
|
368
|
+
self->policy_->CreateSubchannelForAddress(self->address_);
|
369
|
+
delete self;
|
370
|
+
},
|
371
|
+
DEBUG_LOCATION);
|
372
|
+
}
|
373
|
+
|
374
|
+
RefCountedPtr<XdsOverrideHostLb> policy_;
|
375
|
+
std::string address_;
|
376
|
+
grpc_closure closure_;
|
377
|
+
};
|
378
|
+
|
272
379
|
absl::optional<LoadBalancingPolicy::PickResult> PickOverridenHost(
|
273
380
|
XdsOverrideHostAttribute* override_host_attr) const;
|
274
381
|
|
@@ -291,31 +398,45 @@ class XdsOverrideHostLb : public LoadBalancingPolicy {
|
|
291
398
|
RefCountedPtr<SubchannelPicker> picker) override;
|
292
399
|
};
|
293
400
|
|
401
|
+
class IdleTimer : public InternallyRefCounted<IdleTimer> {
|
402
|
+
public:
|
403
|
+
IdleTimer(RefCountedPtr<XdsOverrideHostLb> policy, Duration duration);
|
404
|
+
|
405
|
+
void Orphan() override;
|
406
|
+
|
407
|
+
private:
|
408
|
+
void OnTimerLocked();
|
409
|
+
|
410
|
+
RefCountedPtr<XdsOverrideHostLb> policy_;
|
411
|
+
absl::optional<EventEngine::TaskHandle> timer_handle_;
|
412
|
+
};
|
413
|
+
|
294
414
|
~XdsOverrideHostLb() override;
|
295
415
|
|
296
416
|
void ShutdownLocked() override;
|
297
417
|
|
418
|
+
void ResetState();
|
419
|
+
void ReportTransientFailure(absl::Status status);
|
420
|
+
|
298
421
|
OrphanablePtr<LoadBalancingPolicy> CreateChildPolicyLocked(
|
299
422
|
const ChannelArgs& args);
|
300
423
|
|
301
424
|
void MaybeUpdatePickerLocked();
|
302
425
|
|
303
|
-
|
304
|
-
absl::StatusOr<EndpointAddressesList> endpoints);
|
426
|
+
void UpdateAddressMap(const EndpointAddressesIterator& endpoints);
|
305
427
|
|
306
428
|
RefCountedPtr<SubchannelWrapper> AdoptSubchannel(
|
307
429
|
const grpc_resolved_address& address,
|
308
430
|
RefCountedPtr<SubchannelInterface> subchannel);
|
309
431
|
|
310
|
-
void
|
432
|
+
void CreateSubchannelForAddress(absl::string_view address);
|
311
433
|
|
312
|
-
void
|
313
|
-
ABSL_NO_THREAD_SAFETY_ANALYSIS; // Called from within the
|
314
|
-
// WorkSerializer and does not require
|
315
|
-
// additional synchronization
|
434
|
+
void CleanupSubchannels();
|
316
435
|
|
317
|
-
//
|
318
|
-
|
436
|
+
// State from most recent resolver update.
|
437
|
+
ChannelArgs args_;
|
438
|
+
XdsHealthStatusSet override_host_status_set_;
|
439
|
+
Duration connection_idle_timeout_;
|
319
440
|
|
320
441
|
// Internal state.
|
321
442
|
bool shutting_down_ = false;
|
@@ -326,9 +447,12 @@ class XdsOverrideHostLb : public LoadBalancingPolicy {
|
|
326
447
|
grpc_connectivity_state state_ = GRPC_CHANNEL_CONNECTING;
|
327
448
|
absl::Status status_;
|
328
449
|
RefCountedPtr<SubchannelPicker> picker_;
|
329
|
-
Mutex
|
330
|
-
std::map<std::string, SubchannelEntry
|
331
|
-
ABSL_GUARDED_BY(
|
450
|
+
Mutex mu_;
|
451
|
+
std::map<std::string, RefCountedPtr<SubchannelEntry>, std::less<>>
|
452
|
+
subchannel_map_ ABSL_GUARDED_BY(mu_);
|
453
|
+
|
454
|
+
// Timer handle for periodic subchannel sweep.
|
455
|
+
OrphanablePtr<IdleTimer> idle_timer_;
|
332
456
|
};
|
333
457
|
|
334
458
|
//
|
@@ -355,34 +479,36 @@ XdsOverrideHostLb::Picker::PickOverridenHost(
|
|
355
479
|
auto cookie_address_list = override_host_attr->cookie_address_list();
|
356
480
|
if (cookie_address_list.empty()) return absl::nullopt;
|
357
481
|
// The cookie has an address list, so look through the addresses in order.
|
482
|
+
absl::string_view address_with_no_subchannel;
|
358
483
|
RefCountedPtr<SubchannelWrapper> idle_subchannel;
|
359
484
|
bool found_connecting = false;
|
360
485
|
{
|
361
|
-
MutexLock lock(&policy_->
|
486
|
+
MutexLock lock(&policy_->mu_);
|
362
487
|
for (absl::string_view address : absl::StrSplit(cookie_address_list, ',')) {
|
363
|
-
RefCountedPtr<SubchannelWrapper> subchannel;
|
364
488
|
auto it = policy_->subchannel_map_.find(address);
|
365
|
-
if (it
|
366
|
-
subchannel = it->second.GetSubchannel()->RefIfNonZero();
|
367
|
-
}
|
368
|
-
if (subchannel == nullptr) {
|
369
|
-
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_override_host_trace)) {
|
370
|
-
gpr_log(GPR_INFO, "Subchannel %s was not found",
|
371
|
-
std::string(address).c_str());
|
372
|
-
}
|
373
|
-
continue;
|
374
|
-
}
|
489
|
+
if (it == policy_->subchannel_map_.end()) continue;
|
375
490
|
if (!override_host_health_status_set_.Contains(
|
376
|
-
it->second
|
491
|
+
it->second->eds_health_status())) {
|
377
492
|
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_override_host_trace)) {
|
378
493
|
gpr_log(GPR_INFO,
|
379
494
|
"Subchannel %s health status is not overridden (%s)",
|
380
495
|
std::string(address).c_str(),
|
381
|
-
it->second
|
496
|
+
it->second->eds_health_status().ToString());
|
382
497
|
}
|
383
498
|
continue;
|
384
499
|
}
|
385
|
-
auto
|
500
|
+
auto subchannel = it->second->GetSubchannelRef();
|
501
|
+
if (subchannel == nullptr) {
|
502
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_override_host_trace)) {
|
503
|
+
gpr_log(GPR_INFO, "No subchannel for %s",
|
504
|
+
std::string(address).c_str());
|
505
|
+
}
|
506
|
+
if (address_with_no_subchannel.empty()) {
|
507
|
+
address_with_no_subchannel = it->first;
|
508
|
+
}
|
509
|
+
continue;
|
510
|
+
}
|
511
|
+
auto connectivity_state = it->second->connectivity_state();
|
386
512
|
if (connectivity_state == GRPC_CHANNEL_READY) {
|
387
513
|
// Found a READY subchannel. Pass back the actual address list
|
388
514
|
// and return the subchannel.
|
@@ -390,7 +516,8 @@ XdsOverrideHostLb::Picker::PickOverridenHost(
|
|
390
516
|
gpr_log(GPR_INFO, "Picker override found READY subchannel %s",
|
391
517
|
std::string(address).c_str());
|
392
518
|
}
|
393
|
-
|
519
|
+
it->second->set_last_used_time();
|
520
|
+
override_host_attr->set_actual_address_list(it->second->address_list());
|
394
521
|
return PickResult::Complete(subchannel->wrapped_subchannel());
|
395
522
|
} else if (connectivity_state == GRPC_CHANNEL_IDLE) {
|
396
523
|
if (idle_subchannel == nullptr) idle_subchannel = std::move(subchannel);
|
@@ -417,7 +544,26 @@ XdsOverrideHostLb::Picker::PickOverridenHost(
|
|
417
544
|
}
|
418
545
|
return PickResult::Queue();
|
419
546
|
}
|
420
|
-
// No READY, IDLE, or CONNECTING subchannels found.
|
547
|
+
// No READY, IDLE, or CONNECTING subchannels found. If we found an
|
548
|
+
// entry that has no subchannel, then queue the pick and trigger
|
549
|
+
// creation of a subchannel for that entry.
|
550
|
+
if (!address_with_no_subchannel.empty()) {
|
551
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_override_host_trace)) {
|
552
|
+
gpr_log(GPR_INFO, "Picker override found entry with no subchannel");
|
553
|
+
}
|
554
|
+
if (!IsWorkSerializerDispatchEnabled()) {
|
555
|
+
new SubchannelCreationRequester(policy_, address_with_no_subchannel);
|
556
|
+
} else {
|
557
|
+
policy_->work_serializer()->Run(
|
558
|
+
[policy = policy_,
|
559
|
+
address = std::string(address_with_no_subchannel)]() {
|
560
|
+
policy->CreateSubchannelForAddress(address);
|
561
|
+
},
|
562
|
+
DEBUG_LOCATION);
|
563
|
+
}
|
564
|
+
return PickResult::Queue();
|
565
|
+
}
|
566
|
+
// No entry found that was not in TRANSIENT_FAILURE.
|
421
567
|
return absl::nullopt;
|
422
568
|
}
|
423
569
|
|
@@ -444,15 +590,9 @@ LoadBalancingPolicy::PickResult XdsOverrideHostLb::Picker::Pick(PickArgs args) {
|
|
444
590
|
// Populate the address list in the override host attribute so that
|
445
591
|
// the StatefulSession filter can set the cookie.
|
446
592
|
if (override_host_attr != nullptr) {
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
auto it = policy_->subchannel_map_.find(*key);
|
451
|
-
if (it != policy_->subchannel_map_.end()) { // Should always be true.
|
452
|
-
override_host_attr->set_actual_address_list(
|
453
|
-
it->second.address_list());
|
454
|
-
}
|
455
|
-
}
|
593
|
+
MutexLock lock(&wrapper->policy()->mu_);
|
594
|
+
wrapper->set_last_used_time();
|
595
|
+
override_host_attr->set_actual_address_list(wrapper->address_list());
|
456
596
|
}
|
457
597
|
// Unwrap the subchannel.
|
458
598
|
complete_pick->subchannel = wrapper->wrapped_subchannel();
|
@@ -460,6 +600,56 @@ LoadBalancingPolicy::PickResult XdsOverrideHostLb::Picker::Pick(PickArgs args) {
|
|
460
600
|
return result;
|
461
601
|
}
|
462
602
|
|
603
|
+
//
|
604
|
+
// XdsOverrideHostLb::IdleTimer
|
605
|
+
//
|
606
|
+
|
607
|
+
XdsOverrideHostLb::IdleTimer::IdleTimer(RefCountedPtr<XdsOverrideHostLb> policy,
|
608
|
+
Duration duration)
|
609
|
+
: policy_(std::move(policy)) {
|
610
|
+
// Min time between timer runs is 5s so that we don't kill ourselves
|
611
|
+
// with lock contention and CPU usage due to sweeps over the map.
|
612
|
+
duration = std::max(duration, Duration::Seconds(5));
|
613
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_override_host_trace)) {
|
614
|
+
gpr_log(GPR_INFO,
|
615
|
+
"[xds_override_host_lb %p] idle timer %p: subchannel cleanup "
|
616
|
+
"pass will run in %s",
|
617
|
+
policy_.get(), this, duration.ToString().c_str());
|
618
|
+
}
|
619
|
+
timer_handle_ = policy_->channel_control_helper()->GetEventEngine()->RunAfter(
|
620
|
+
duration, [self = RefAsSubclass<IdleTimer>()]() mutable {
|
621
|
+
ApplicationCallbackExecCtx callback_exec_ctx;
|
622
|
+
ExecCtx exec_ctx;
|
623
|
+
auto self_ptr = self.get();
|
624
|
+
self_ptr->policy_->work_serializer()->Run(
|
625
|
+
[self = std::move(self)]() { self->OnTimerLocked(); },
|
626
|
+
DEBUG_LOCATION);
|
627
|
+
});
|
628
|
+
}
|
629
|
+
|
630
|
+
void XdsOverrideHostLb::IdleTimer::Orphan() {
|
631
|
+
if (timer_handle_.has_value()) {
|
632
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_override_host_trace)) {
|
633
|
+
gpr_log(GPR_INFO, "[xds_override_host_lb %p] idle timer %p: cancelling",
|
634
|
+
policy_.get(), this);
|
635
|
+
}
|
636
|
+
policy_->channel_control_helper()->GetEventEngine()->Cancel(*timer_handle_);
|
637
|
+
timer_handle_.reset();
|
638
|
+
}
|
639
|
+
Unref();
|
640
|
+
}
|
641
|
+
|
642
|
+
void XdsOverrideHostLb::IdleTimer::OnTimerLocked() {
|
643
|
+
if (timer_handle_.has_value()) {
|
644
|
+
timer_handle_.reset();
|
645
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_override_host_trace)) {
|
646
|
+
gpr_log(GPR_INFO, "[xds_override_host_lb %p] idle timer %p: timer fired",
|
647
|
+
policy_.get(), this);
|
648
|
+
}
|
649
|
+
policy_->CleanupSubchannels();
|
650
|
+
}
|
651
|
+
}
|
652
|
+
|
463
653
|
//
|
464
654
|
// XdsOverrideHostLb
|
465
655
|
//
|
@@ -484,10 +674,22 @@ void XdsOverrideHostLb::ShutdownLocked() {
|
|
484
674
|
gpr_log(GPR_INFO, "[xds_override_host_lb %p] shutting down", this);
|
485
675
|
}
|
486
676
|
shutting_down_ = true;
|
677
|
+
ResetState();
|
678
|
+
}
|
679
|
+
|
680
|
+
void XdsOverrideHostLb::ResetState() {
|
487
681
|
{
|
488
|
-
|
682
|
+
// Drop subchannel refs after releasing the lock to avoid deadlock.
|
683
|
+
std::vector<RefCountedPtr<SubchannelWrapper>> subchannel_refs_to_drop;
|
684
|
+
MutexLock lock(&mu_);
|
685
|
+
subchannel_refs_to_drop.reserve(subchannel_map_.size());
|
686
|
+
for (auto& p : subchannel_map_) {
|
687
|
+
p.second->UnsetSubchannel(&subchannel_refs_to_drop);
|
688
|
+
}
|
489
689
|
subchannel_map_.clear();
|
490
690
|
}
|
691
|
+
// Cancel timer, if any.
|
692
|
+
idle_timer_.reset();
|
491
693
|
// Remove the child policy's interested_parties pollset_set from the
|
492
694
|
// xDS policy.
|
493
695
|
if (child_policy_ != nullptr) {
|
@@ -500,6 +702,18 @@ void XdsOverrideHostLb::ShutdownLocked() {
|
|
500
702
|
picker_.reset();
|
501
703
|
}
|
502
704
|
|
705
|
+
void XdsOverrideHostLb::ReportTransientFailure(absl::Status status) {
|
706
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_override_host_trace)) {
|
707
|
+
gpr_log(GPR_INFO,
|
708
|
+
"[xds_override_host_lb %p] reporting TRANSIENT_FAILURE: %s", this,
|
709
|
+
status.ToString().c_str());
|
710
|
+
}
|
711
|
+
ResetState();
|
712
|
+
channel_control_helper()->UpdateState(
|
713
|
+
GRPC_CHANNEL_TRANSIENT_FAILURE, status,
|
714
|
+
MakeRefCounted<TransientFailurePicker>(status));
|
715
|
+
}
|
716
|
+
|
503
717
|
void XdsOverrideHostLb::ExitIdleLocked() {
|
504
718
|
if (child_policy_ != nullptr) child_policy_->ExitIdleLocked();
|
505
719
|
}
|
@@ -508,29 +722,99 @@ void XdsOverrideHostLb::ResetBackoffLocked() {
|
|
508
722
|
if (child_policy_ != nullptr) child_policy_->ResetBackoffLocked();
|
509
723
|
}
|
510
724
|
|
725
|
+
XdsHealthStatus GetEndpointHealthStatus(const EndpointAddresses& endpoint) {
|
726
|
+
return XdsHealthStatus(static_cast<XdsHealthStatus::HealthStatus>(
|
727
|
+
endpoint.args()
|
728
|
+
.GetInt(GRPC_ARG_XDS_HEALTH_STATUS)
|
729
|
+
.value_or(XdsHealthStatus::HealthStatus::kUnknown)));
|
730
|
+
}
|
731
|
+
|
732
|
+
// Wraps the endpoint iterator and filters out endpoints in state DRAINING.
|
733
|
+
class ChildEndpointIterator : public EndpointAddressesIterator {
|
734
|
+
public:
|
735
|
+
explicit ChildEndpointIterator(
|
736
|
+
std::shared_ptr<EndpointAddressesIterator> parent_it)
|
737
|
+
: parent_it_(std::move(parent_it)) {}
|
738
|
+
|
739
|
+
void ForEach(absl::FunctionRef<void(const EndpointAddresses&)> callback)
|
740
|
+
const override {
|
741
|
+
parent_it_->ForEach([&](const EndpointAddresses& endpoint) {
|
742
|
+
XdsHealthStatus status = GetEndpointHealthStatus(endpoint);
|
743
|
+
if (status.status() != XdsHealthStatus::kDraining) {
|
744
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_override_host_trace)) {
|
745
|
+
gpr_log(GPR_INFO,
|
746
|
+
"[xds_override_host_lb %p] endpoint %s: not draining, "
|
747
|
+
"passing to child",
|
748
|
+
this, endpoint.ToString().c_str());
|
749
|
+
}
|
750
|
+
callback(endpoint);
|
751
|
+
}
|
752
|
+
});
|
753
|
+
}
|
754
|
+
|
755
|
+
private:
|
756
|
+
std::shared_ptr<EndpointAddressesIterator> parent_it_;
|
757
|
+
};
|
758
|
+
|
511
759
|
absl::Status XdsOverrideHostLb::UpdateLocked(UpdateArgs args) {
|
512
760
|
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_override_host_trace)) {
|
513
|
-
gpr_log(GPR_INFO,
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
}
|
518
|
-
auto old_config = std::move(config_);
|
519
|
-
// Update config.
|
520
|
-
config_ = std::move(args.config);
|
521
|
-
if (config_ == nullptr) {
|
761
|
+
gpr_log(GPR_INFO, "[xds_override_host_lb %p] Received update", this);
|
762
|
+
}
|
763
|
+
// Grab new LB policy config.
|
764
|
+
if (args.config == nullptr) {
|
522
765
|
return absl::InvalidArgumentError("Missing policy config");
|
523
766
|
}
|
767
|
+
auto new_config = args.config.TakeAsSubclass<XdsOverrideHostLbConfig>();
|
768
|
+
// Get xDS config.
|
769
|
+
auto new_xds_config =
|
770
|
+
args.args.GetObjectRef<XdsDependencyManager::XdsConfig>();
|
771
|
+
if (new_xds_config == nullptr) {
|
772
|
+
// Should never happen.
|
773
|
+
absl::Status status = absl::InternalError(
|
774
|
+
"xDS config not passed to xds_cluster_impl LB policy");
|
775
|
+
ReportTransientFailure(status);
|
776
|
+
return status;
|
777
|
+
}
|
778
|
+
auto it = new_xds_config->clusters.find(new_config->cluster_name());
|
779
|
+
if (it == new_xds_config->clusters.end() || !it->second.ok() ||
|
780
|
+
it->second->cluster == nullptr) {
|
781
|
+
// Should never happen.
|
782
|
+
absl::Status status = absl::InternalError(absl::StrCat(
|
783
|
+
"xDS config has no entry for cluster ", new_config->cluster_name()));
|
784
|
+
ReportTransientFailure(status);
|
785
|
+
return status;
|
786
|
+
}
|
787
|
+
args_ = std::move(args.args);
|
788
|
+
override_host_status_set_ = it->second->cluster->override_host_statuses;
|
789
|
+
connection_idle_timeout_ = it->second->cluster->connection_idle_timeout;
|
790
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_override_host_trace)) {
|
791
|
+
gpr_log(GPR_INFO,
|
792
|
+
"[xds_override_host_lb %p] override host status set: %s "
|
793
|
+
"connection idle timeout: %s",
|
794
|
+
this, override_host_status_set_.ToString().c_str(),
|
795
|
+
connection_idle_timeout_.ToString().c_str());
|
796
|
+
}
|
797
|
+
// Update address map and wrap endpoint iterator for child policy.
|
798
|
+
if (args.addresses.ok()) {
|
799
|
+
UpdateAddressMap(**args.addresses);
|
800
|
+
args.addresses =
|
801
|
+
std::make_shared<ChildEndpointIterator>(std::move(*args.addresses));
|
802
|
+
} else {
|
803
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_override_host_trace)) {
|
804
|
+
gpr_log(GPR_INFO, "[xds_override_host_lb %p] address error: %s", this,
|
805
|
+
args.addresses.status().ToString().c_str());
|
806
|
+
}
|
807
|
+
}
|
524
808
|
// Create child policy if needed.
|
525
809
|
if (child_policy_ == nullptr) {
|
526
810
|
child_policy_ = CreateChildPolicyLocked(args.args);
|
527
811
|
}
|
528
812
|
// Update child policy.
|
529
813
|
UpdateArgs update_args;
|
530
|
-
update_args.addresses =
|
814
|
+
update_args.addresses = std::move(args.addresses);
|
531
815
|
update_args.resolution_note = std::move(args.resolution_note);
|
532
|
-
update_args.config =
|
533
|
-
update_args.args =
|
816
|
+
update_args.config = new_config->child_config();
|
817
|
+
update_args.args = args_;
|
534
818
|
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_override_host_trace)) {
|
535
819
|
gpr_log(GPR_INFO,
|
536
820
|
"[xds_override_host_lb %p] Updating child policy handler %p", this,
|
@@ -542,7 +826,7 @@ absl::Status XdsOverrideHostLb::UpdateLocked(UpdateArgs args) {
|
|
542
826
|
void XdsOverrideHostLb::MaybeUpdatePickerLocked() {
|
543
827
|
if (picker_ != nullptr) {
|
544
828
|
auto xds_override_host_picker = MakeRefCounted<Picker>(
|
545
|
-
|
829
|
+
RefAsSubclass<XdsOverrideHostLb>(), picker_, override_host_status_set_);
|
546
830
|
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_override_host_trace)) {
|
547
831
|
gpr_log(GPR_INFO,
|
548
832
|
"[xds_override_host_lb %p] updating connectivity: state=%s "
|
@@ -560,8 +844,8 @@ OrphanablePtr<LoadBalancingPolicy> XdsOverrideHostLb::CreateChildPolicyLocked(
|
|
560
844
|
LoadBalancingPolicy::Args lb_policy_args;
|
561
845
|
lb_policy_args.work_serializer = work_serializer();
|
562
846
|
lb_policy_args.args = args;
|
563
|
-
lb_policy_args.channel_control_helper =
|
564
|
-
|
847
|
+
lb_policy_args.channel_control_helper = std::make_unique<Helper>(
|
848
|
+
RefAsSubclass<XdsOverrideHostLb>(DEBUG_LOCATION, "Helper"));
|
565
849
|
OrphanablePtr<LoadBalancingPolicy> lb_policy =
|
566
850
|
MakeOrphanable<ChildPolicyHandler>(std::move(lb_policy_args),
|
567
851
|
&grpc_lb_xds_override_host_trace);
|
@@ -578,18 +862,9 @@ OrphanablePtr<LoadBalancingPolicy> XdsOverrideHostLb::CreateChildPolicyLocked(
|
|
578
862
|
return lb_policy;
|
579
863
|
}
|
580
864
|
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_override_host_trace)) {
|
585
|
-
gpr_log(GPR_INFO, "[xds_override_host_lb %p] address error: %s", this,
|
586
|
-
endpoints.status().ToString().c_str());
|
587
|
-
}
|
588
|
-
return endpoints;
|
589
|
-
}
|
590
|
-
// Construct the list of addresses to pass to the child policy and a
|
591
|
-
// map of address info from which to update subchannel_map_.
|
592
|
-
EndpointAddressesList child_addresses;
|
865
|
+
void XdsOverrideHostLb::UpdateAddressMap(
|
866
|
+
const EndpointAddressesIterator& endpoints) {
|
867
|
+
// Construct a map of address info from which to update subchannel_map_.
|
593
868
|
struct AddressInfo {
|
594
869
|
XdsHealthStatus eds_health_status;
|
595
870
|
RefCountedStringValue address_list;
|
@@ -597,36 +872,31 @@ absl::StatusOr<EndpointAddressesList> XdsOverrideHostLb::UpdateAddressMap(
|
|
597
872
|
: eds_health_status(status), address_list(std::move(addresses)) {}
|
598
873
|
};
|
599
874
|
std::map<const std::string, AddressInfo> addresses_for_map;
|
600
|
-
|
875
|
+
endpoints.ForEach([&](const EndpointAddresses& endpoint) {
|
601
876
|
XdsHealthStatus status = GetEndpointHealthStatus(endpoint);
|
602
|
-
if
|
603
|
-
|
604
|
-
|
605
|
-
"[xds_override_host_lb %p] endpoint %s: not draining, "
|
606
|
-
"passing to child",
|
607
|
-
this, endpoint.ToString().c_str());
|
608
|
-
}
|
609
|
-
child_addresses.push_back(endpoint);
|
610
|
-
} else if (!config_->override_host_status_set().Contains(status)) {
|
611
|
-
// Skip draining hosts if not in the override status set.
|
877
|
+
// Skip draining hosts if not in the override status set.
|
878
|
+
if (status.status() == XdsHealthStatus::kDraining &&
|
879
|
+
!override_host_status_set_.Contains(status)) {
|
612
880
|
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_override_host_trace)) {
|
613
881
|
gpr_log(GPR_INFO,
|
614
882
|
"[xds_override_host_lb %p] endpoint %s: draining but not in "
|
615
883
|
"override_host_status set -- ignoring",
|
616
884
|
this, endpoint.ToString().c_str());
|
617
885
|
}
|
618
|
-
|
886
|
+
return;
|
619
887
|
}
|
620
888
|
std::vector<std::string> addresses;
|
621
889
|
addresses.reserve(endpoint.addresses().size());
|
622
890
|
for (const auto& address : endpoint.addresses()) {
|
623
891
|
auto key = grpc_sockaddr_to_string(&address, /*normalize=*/false);
|
624
|
-
if (key.ok()) {
|
892
|
+
if (!key.ok()) {
|
625
893
|
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_override_host_trace)) {
|
626
894
|
gpr_log(GPR_INFO,
|
627
|
-
"[xds_override_host_lb %p]
|
628
|
-
|
895
|
+
"[xds_override_host_lb %p] no key for endpoint address; "
|
896
|
+
"not adding to map",
|
897
|
+
this);
|
629
898
|
}
|
899
|
+
} else {
|
630
900
|
addresses.push_back(*std::move(key));
|
631
901
|
}
|
632
902
|
}
|
@@ -641,16 +911,22 @@ absl::StatusOr<EndpointAddressesList> XdsOverrideHostLb::UpdateAddressMap(
|
|
641
911
|
std::piecewise_construct, std::forward_as_tuple(addresses[i]),
|
642
912
|
std::forward_as_tuple(status, std::move(address_list)));
|
643
913
|
}
|
644
|
-
}
|
914
|
+
});
|
645
915
|
// Now grab the lock and update subchannel_map_ from addresses_for_map.
|
916
|
+
const Timestamp now = Timestamp::Now();
|
917
|
+
const Timestamp idle_threshold = now - connection_idle_timeout_;
|
918
|
+
Duration next_time = connection_idle_timeout_;
|
646
919
|
{
|
647
|
-
|
920
|
+
// Drop subchannel refs after releasing the lock to avoid deadlock.
|
921
|
+
std::vector<RefCountedPtr<SubchannelWrapper>> subchannel_refs_to_drop;
|
922
|
+
MutexLock lock(&mu_);
|
648
923
|
for (auto it = subchannel_map_.begin(); it != subchannel_map_.end();) {
|
649
924
|
if (addresses_for_map.find(it->first) == addresses_for_map.end()) {
|
650
925
|
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_override_host_trace)) {
|
651
926
|
gpr_log(GPR_INFO, "[xds_override_host_lb %p] removing map key %s",
|
652
927
|
this, it->first.c_str());
|
653
928
|
}
|
929
|
+
it->second->UnsetSubchannel(&subchannel_refs_to_drop);
|
654
930
|
it = subchannel_map_.erase(it);
|
655
931
|
} else {
|
656
932
|
++it;
|
@@ -665,70 +941,116 @@ absl::StatusOr<EndpointAddressesList> XdsOverrideHostLb::UpdateAddressMap(
|
|
665
941
|
gpr_log(GPR_INFO, "[xds_override_host_lb %p] adding map key %s", this,
|
666
942
|
address.c_str());
|
667
943
|
}
|
668
|
-
it = subchannel_map_
|
669
|
-
.emplace(std::piecewise_construct,
|
670
|
-
std::forward_as_tuple(address),
|
671
|
-
std::forward_as_tuple(address_info.eds_health_status))
|
944
|
+
it = subchannel_map_.emplace(address, MakeRefCounted<SubchannelEntry>())
|
672
945
|
.first;
|
673
|
-
} else {
|
674
|
-
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_override_host_trace)) {
|
675
|
-
gpr_log(GPR_INFO,
|
676
|
-
"[xds_override_host_lb %p] setting EDS health status for "
|
677
|
-
"%s to %s",
|
678
|
-
this, address.c_str(),
|
679
|
-
address_info.eds_health_status.ToString());
|
680
|
-
}
|
681
|
-
it->second.SetEdsHealthStatus(address_info.eds_health_status);
|
682
946
|
}
|
683
947
|
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_override_host_trace)) {
|
684
948
|
gpr_log(GPR_INFO,
|
685
|
-
"[xds_override_host_lb %p]
|
686
|
-
|
949
|
+
"[xds_override_host_lb %p] map key %s: setting "
|
950
|
+
"eds_health_status=%s address_list=%s",
|
951
|
+
this, address.c_str(),
|
952
|
+
address_info.eds_health_status.ToString(),
|
953
|
+
address_info.address_list.c_str());
|
954
|
+
}
|
955
|
+
it->second->set_eds_health_status(address_info.eds_health_status);
|
956
|
+
it->second->set_address_list(std::move(address_info.address_list));
|
957
|
+
// Check the entry's last_used_time to determine the next time at
|
958
|
+
// which the timer needs to run.
|
959
|
+
if (it->second->last_used_time() > idle_threshold) {
|
960
|
+
const Duration next_time_for_entry =
|
961
|
+
it->second->last_used_time() + connection_idle_timeout_ - now;
|
962
|
+
next_time = std::min(next_time, next_time_for_entry);
|
687
963
|
}
|
688
|
-
it->second.set_address_list(std::move(address_info.address_list));
|
689
964
|
}
|
690
965
|
}
|
691
|
-
|
966
|
+
idle_timer_ =
|
967
|
+
MakeOrphanable<IdleTimer>(RefAsSubclass<XdsOverrideHostLb>(), next_time);
|
692
968
|
}
|
693
969
|
|
694
970
|
RefCountedPtr<XdsOverrideHostLb::SubchannelWrapper>
|
695
971
|
XdsOverrideHostLb::AdoptSubchannel(
|
696
972
|
const grpc_resolved_address& address,
|
697
973
|
RefCountedPtr<SubchannelInterface> subchannel) {
|
974
|
+
auto wrapper = MakeRefCounted<SubchannelWrapper>(
|
975
|
+
std::move(subchannel), RefAsSubclass<XdsOverrideHostLb>());
|
698
976
|
auto key = grpc_sockaddr_to_string(&address, /*normalize=*/false);
|
699
|
-
auto wrapper =
|
700
|
-
MakeRefCounted<SubchannelWrapper>(std::move(subchannel), Ref());
|
701
977
|
if (key.ok()) {
|
702
|
-
|
978
|
+
// Drop ref to previously owned subchannel (if any) after releasing
|
979
|
+
// the lock.
|
980
|
+
RefCountedPtr<SubchannelWrapper> subchannel_ref_to_drop;
|
981
|
+
MutexLock lock(&mu_);
|
703
982
|
auto it = subchannel_map_.find(*key);
|
704
983
|
if (it != subchannel_map_.end()) {
|
705
|
-
wrapper->
|
706
|
-
it->second
|
984
|
+
wrapper->set_subchannel_entry(it->second);
|
985
|
+
subchannel_ref_to_drop = it->second->SetUnownedSubchannel(wrapper.get());
|
707
986
|
}
|
708
987
|
}
|
709
988
|
return wrapper;
|
710
989
|
}
|
711
990
|
|
712
|
-
void XdsOverrideHostLb::
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
991
|
+
void XdsOverrideHostLb::CreateSubchannelForAddress(absl::string_view address) {
|
992
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_override_host_trace)) {
|
993
|
+
gpr_log(GPR_INFO,
|
994
|
+
"[xds_override_host_lb %p] creating owned subchannel for %s", this,
|
995
|
+
std::string(address).c_str());
|
996
|
+
}
|
997
|
+
auto addr = StringToSockaddr(address);
|
998
|
+
GPR_ASSERT(addr.ok());
|
999
|
+
// Note: We don't currently have any cases where per_address_args need to
|
1000
|
+
// be passed through. If we encounter any such cases in the future, we
|
1001
|
+
// will need to change this to store those attributes from the resolver
|
1002
|
+
// update in the map entry.
|
1003
|
+
auto subchannel = channel_control_helper()->CreateSubchannel(
|
1004
|
+
*addr, /*per_address_args=*/ChannelArgs(), args_);
|
1005
|
+
auto wrapper = MakeRefCounted<SubchannelWrapper>(
|
1006
|
+
std::move(subchannel), RefAsSubclass<XdsOverrideHostLb>());
|
1007
|
+
{
|
1008
|
+
MutexLock lock(&mu_);
|
1009
|
+
auto it = subchannel_map_.find(address);
|
1010
|
+
// This can happen if the map entry was removed between the time that
|
1011
|
+
// the picker requested the subchannel creation and the time that we got
|
1012
|
+
// here. In that case, we can just make it a no-op, since the update
|
1013
|
+
// that removed the entry will have generated a new picker already.
|
1014
|
+
if (it == subchannel_map_.end()) return;
|
1015
|
+
// This can happen if the picker requests subchannel creation for
|
1016
|
+
// the same address multiple times.
|
1017
|
+
if (it->second->HasOwnedSubchannel()) return;
|
1018
|
+
wrapper->set_subchannel_entry(it->second);
|
1019
|
+
it->second->SetOwnedSubchannel(std::move(wrapper));
|
720
1020
|
}
|
1021
|
+
MaybeUpdatePickerLocked();
|
721
1022
|
}
|
722
1023
|
|
723
|
-
void XdsOverrideHostLb::
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
1024
|
+
void XdsOverrideHostLb::CleanupSubchannels() {
|
1025
|
+
const Timestamp now = Timestamp::Now();
|
1026
|
+
const Timestamp idle_threshold = now - connection_idle_timeout_;
|
1027
|
+
Duration next_time = connection_idle_timeout_;
|
1028
|
+
std::vector<RefCountedPtr<SubchannelWrapper>> subchannel_refs_to_drop;
|
1029
|
+
{
|
1030
|
+
MutexLock lock(&mu_);
|
1031
|
+
if (subchannel_map_.empty()) return;
|
1032
|
+
for (const auto& p : subchannel_map_) {
|
1033
|
+
if (p.second->last_used_time() <= idle_threshold) {
|
1034
|
+
auto subchannel = p.second->TakeOwnedSubchannel();
|
1035
|
+
if (subchannel != nullptr) {
|
1036
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_override_host_trace)) {
|
1037
|
+
gpr_log(GPR_INFO,
|
1038
|
+
"[xds_override_host_lb %p] dropping subchannel for %s",
|
1039
|
+
this, p.first.c_str());
|
1040
|
+
}
|
1041
|
+
subchannel_refs_to_drop.push_back(std::move(subchannel));
|
1042
|
+
}
|
1043
|
+
} else {
|
1044
|
+
// Not dropping the subchannel. Check the entry's last_used_time to
|
1045
|
+
// determine the next time at which the timer needs to run.
|
1046
|
+
const Duration next_time_for_entry =
|
1047
|
+
p.second->last_used_time() + connection_idle_timeout_ - now;
|
1048
|
+
next_time = std::min(next_time, next_time_for_entry);
|
1049
|
+
}
|
1050
|
+
}
|
731
1051
|
}
|
1052
|
+
idle_timer_ =
|
1053
|
+
MakeOrphanable<IdleTimer>(RefAsSubclass<XdsOverrideHostLb>(), next_time);
|
732
1054
|
}
|
733
1055
|
|
734
1056
|
//
|
@@ -738,6 +1060,14 @@ void XdsOverrideHostLb::OnSubchannelConnectivityStateChange(
|
|
738
1060
|
RefCountedPtr<SubchannelInterface> XdsOverrideHostLb::Helper::CreateSubchannel(
|
739
1061
|
const grpc_resolved_address& address, const ChannelArgs& per_address_args,
|
740
1062
|
const ChannelArgs& args) {
|
1063
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_override_host_trace)) {
|
1064
|
+
auto key = grpc_sockaddr_to_string(&address, /*normalize=*/false);
|
1065
|
+
gpr_log(GPR_INFO,
|
1066
|
+
"[xds_override_host_lb %p] creating subchannel for %s, "
|
1067
|
+
"per_address_args=%s, args=%s",
|
1068
|
+
this, key.value_or("<unknown>").c_str(),
|
1069
|
+
per_address_args.ToString().c_str(), args.ToString().c_str());
|
1070
|
+
}
|
741
1071
|
auto subchannel = parent()->channel_control_helper()->CreateSubchannel(
|
742
1072
|
address, per_address_args, args);
|
743
1073
|
return parent()->AdoptSubchannel(address, std::move(subchannel));
|
@@ -756,24 +1086,19 @@ void XdsOverrideHostLb::Helper::UpdateState(
|
|
756
1086
|
}
|
757
1087
|
|
758
1088
|
//
|
759
|
-
// XdsOverrideHostLb::SubchannelWrapper
|
1089
|
+
// XdsOverrideHostLb::SubchannelWrapper
|
760
1090
|
//
|
761
1091
|
|
762
1092
|
XdsOverrideHostLb::SubchannelWrapper::SubchannelWrapper(
|
763
1093
|
RefCountedPtr<SubchannelInterface> subchannel,
|
764
1094
|
RefCountedPtr<XdsOverrideHostLb> policy)
|
765
1095
|
: DelegatingSubchannel(std::move(subchannel)), policy_(std::move(policy)) {
|
766
|
-
auto watcher = std::make_unique<ConnectivityStateWatcher>(
|
1096
|
+
auto watcher = std::make_unique<ConnectivityStateWatcher>(
|
1097
|
+
WeakRefAsSubclass<SubchannelWrapper>());
|
767
1098
|
watcher_ = watcher.get();
|
768
1099
|
wrapped_subchannel()->WatchConnectivityState(std::move(watcher));
|
769
1100
|
}
|
770
1101
|
|
771
|
-
XdsOverrideHostLb::SubchannelWrapper::~SubchannelWrapper() {
|
772
|
-
if (key_.has_value()) {
|
773
|
-
policy_->UnsetSubchannel(*key_, this);
|
774
|
-
}
|
775
|
-
}
|
776
|
-
|
777
1102
|
void XdsOverrideHostLb::SubchannelWrapper::WatchConnectivityState(
|
778
1103
|
std::unique_ptr<ConnectivityStateWatcherInterface> watcher) {
|
779
1104
|
watchers_.insert(std::move(watcher));
|
@@ -787,9 +1112,45 @@ void XdsOverrideHostLb::SubchannelWrapper::CancelConnectivityStateWatch(
|
|
787
1112
|
}
|
788
1113
|
}
|
789
1114
|
|
1115
|
+
void XdsOverrideHostLb::SubchannelWrapper::Orphan() {
|
1116
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_override_host_trace)) {
|
1117
|
+
gpr_log(GPR_INFO,
|
1118
|
+
"[xds_override_host_lb %p] subchannel wrapper %p orphaned",
|
1119
|
+
policy_.get(), this);
|
1120
|
+
}
|
1121
|
+
if (!IsWorkSerializerDispatchEnabled()) {
|
1122
|
+
wrapped_subchannel()->CancelConnectivityStateWatch(watcher_);
|
1123
|
+
if (subchannel_entry_ != nullptr) {
|
1124
|
+
MutexLock lock(&policy()->mu_);
|
1125
|
+
subchannel_entry_->OnSubchannelWrapperOrphan(
|
1126
|
+
this, policy()->connection_idle_timeout_);
|
1127
|
+
}
|
1128
|
+
return;
|
1129
|
+
}
|
1130
|
+
policy()->work_serializer()->Run(
|
1131
|
+
[self = WeakRefAsSubclass<SubchannelWrapper>()]() {
|
1132
|
+
self->wrapped_subchannel()->CancelConnectivityStateWatch(
|
1133
|
+
self->watcher_);
|
1134
|
+
if (self->subchannel_entry_ != nullptr) {
|
1135
|
+
MutexLock lock(&self->policy()->mu_);
|
1136
|
+
self->subchannel_entry_->OnSubchannelWrapperOrphan(
|
1137
|
+
self.get(), self->policy()->connection_idle_timeout_);
|
1138
|
+
}
|
1139
|
+
},
|
1140
|
+
DEBUG_LOCATION);
|
1141
|
+
}
|
1142
|
+
|
790
1143
|
void XdsOverrideHostLb::SubchannelWrapper::UpdateConnectivityState(
|
791
1144
|
grpc_connectivity_state state, absl::Status status) {
|
792
|
-
|
1145
|
+
bool update_picker = false;
|
1146
|
+
if (subchannel_entry_ != nullptr) {
|
1147
|
+
MutexLock lock(&policy()->mu_);
|
1148
|
+
if (subchannel_entry_->connectivity_state() != state) {
|
1149
|
+
subchannel_entry_->set_connectivity_state(state);
|
1150
|
+
update_picker = subchannel_entry_->HasOwnedSubchannel() &&
|
1151
|
+
subchannel_entry_->GetSubchannel() == this;
|
1152
|
+
}
|
1153
|
+
}
|
793
1154
|
// Sending connectivity state notifications to the watchers may cause the set
|
794
1155
|
// of watchers to change, so we can't be iterating over the set of watchers
|
795
1156
|
// while we send the notifications
|
@@ -803,41 +1164,94 @@ void XdsOverrideHostLb::SubchannelWrapper::UpdateConnectivityState(
|
|
803
1164
|
watcher->OnConnectivityStateChange(state, status);
|
804
1165
|
}
|
805
1166
|
}
|
806
|
-
if (
|
807
|
-
policy_->OnSubchannelConnectivityStateChange(*key_);
|
808
|
-
}
|
1167
|
+
if (update_picker) policy()->MaybeUpdatePickerLocked();
|
809
1168
|
}
|
810
1169
|
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
819
|
-
|
820
|
-
|
821
|
-
|
822
|
-
|
1170
|
+
//
|
1171
|
+
// XdsOverrideHostLb::SubchannelEntry
|
1172
|
+
//
|
1173
|
+
|
1174
|
+
RefCountedPtr<XdsOverrideHostLb::SubchannelWrapper>
|
1175
|
+
XdsOverrideHostLb::SubchannelEntry::SetUnownedSubchannel(
|
1176
|
+
SubchannelWrapper* subchannel)
|
1177
|
+
ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsOverrideHostLb::mu_) {
|
1178
|
+
auto owned_subchannel = TakeOwnedSubchannel();
|
1179
|
+
subchannel_ = subchannel;
|
1180
|
+
return owned_subchannel;
|
1181
|
+
}
|
1182
|
+
|
1183
|
+
XdsOverrideHostLb::SubchannelWrapper*
|
1184
|
+
XdsOverrideHostLb::SubchannelEntry::GetSubchannel() const
|
1185
|
+
ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsOverrideHostLb::mu_) {
|
1186
|
+
return Match(
|
1187
|
+
subchannel_, [](SubchannelWrapper* subchannel) { return subchannel; },
|
1188
|
+
[](const RefCountedPtr<SubchannelWrapper>& subchannel) {
|
1189
|
+
return subchannel.get();
|
1190
|
+
});
|
1191
|
+
}
|
1192
|
+
|
1193
|
+
RefCountedPtr<XdsOverrideHostLb::SubchannelWrapper>
|
1194
|
+
XdsOverrideHostLb::SubchannelEntry::GetSubchannelRef() const
|
1195
|
+
ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsOverrideHostLb::mu_) {
|
1196
|
+
auto* sc = GetSubchannel();
|
1197
|
+
if (sc == nullptr) return nullptr;
|
1198
|
+
return sc->RefIfNonZero().TakeAsSubclass<SubchannelWrapper>();
|
1199
|
+
}
|
1200
|
+
|
1201
|
+
RefCountedPtr<XdsOverrideHostLb::SubchannelWrapper>
|
1202
|
+
XdsOverrideHostLb::SubchannelEntry::TakeOwnedSubchannel()
|
1203
|
+
ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsOverrideHostLb::mu_) {
|
1204
|
+
return MatchMutable(
|
1205
|
+
&subchannel_,
|
1206
|
+
[](SubchannelWrapper**) -> RefCountedPtr<SubchannelWrapper> {
|
1207
|
+
return nullptr;
|
823
1208
|
},
|
824
|
-
|
1209
|
+
[](RefCountedPtr<SubchannelWrapper>* subchannel) {
|
1210
|
+
return std::move(*subchannel);
|
1211
|
+
});
|
825
1212
|
}
|
826
1213
|
|
827
|
-
|
828
|
-
|
829
|
-
|
1214
|
+
void XdsOverrideHostLb::SubchannelEntry::UnsetSubchannel(
|
1215
|
+
std::vector<RefCountedPtr<SubchannelWrapper>>* owned_subchannels)
|
1216
|
+
ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsOverrideHostLb::mu_) {
|
1217
|
+
auto subchannel = TakeOwnedSubchannel();
|
1218
|
+
if (subchannel != nullptr) {
|
1219
|
+
owned_subchannels->push_back(std::move(subchannel));
|
1220
|
+
}
|
1221
|
+
subchannel_ = nullptr;
|
830
1222
|
}
|
831
1223
|
|
832
|
-
void XdsOverrideHostLb::
|
833
|
-
|
834
|
-
|
835
|
-
|
1224
|
+
void XdsOverrideHostLb::SubchannelEntry::OnSubchannelWrapperOrphan(
|
1225
|
+
SubchannelWrapper* wrapper, Duration connection_idle_timeout)
|
1226
|
+
ABSL_EXCLUSIVE_LOCKS_REQUIRED(&XdsOverrideHostLb::mu_) {
|
1227
|
+
auto* subchannel = GetSubchannel();
|
1228
|
+
if (subchannel != wrapper) return;
|
1229
|
+
if (last_used_time_ < (Timestamp::Now() - connection_idle_timeout)) {
|
1230
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_override_host_trace)) {
|
1231
|
+
gpr_log(GPR_INFO,
|
1232
|
+
"[xds_override_host_lb] removing unowned subchannel wrapper %p",
|
1233
|
+
subchannel);
|
1234
|
+
}
|
1235
|
+
subchannel_ = nullptr;
|
1236
|
+
} else {
|
1237
|
+
// The subchannel is being released by the child policy, but it
|
1238
|
+
// is still within its idle timeout, so we make a new copy of
|
1239
|
+
// the wrapper with the same underlying subchannel, and we hold
|
1240
|
+
// our own ref to it.
|
1241
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_xds_override_host_trace)) {
|
1242
|
+
gpr_log(GPR_INFO,
|
1243
|
+
"[xds_override_host_lb] subchannel wrapper %p: cloning "
|
1244
|
+
"to gain ownership",
|
1245
|
+
subchannel);
|
1246
|
+
}
|
1247
|
+
subchannel_ = wrapper->Clone();
|
1248
|
+
}
|
836
1249
|
}
|
837
1250
|
|
838
1251
|
//
|
839
1252
|
// factory
|
840
1253
|
//
|
1254
|
+
|
841
1255
|
class XdsOverrideHostLbFactory : public LoadBalancingPolicyFactory {
|
842
1256
|
public:
|
843
1257
|
OrphanablePtr<LoadBalancingPolicy> CreateLoadBalancingPolicy(
|
@@ -864,57 +1278,34 @@ void RegisterXdsOverrideHostLbPolicy(CoreConfiguration::Builder* builder) {
|
|
864
1278
|
std::make_unique<XdsOverrideHostLbFactory>());
|
865
1279
|
}
|
866
1280
|
|
1281
|
+
//
|
867
1282
|
// XdsOverrideHostLbConfig
|
1283
|
+
//
|
868
1284
|
|
869
1285
|
const JsonLoaderInterface* XdsOverrideHostLbConfig::JsonLoader(
|
870
1286
|
const JsonArgs&) {
|
871
1287
|
static const auto kJsonLoader =
|
872
1288
|
JsonObjectLoader<XdsOverrideHostLbConfig>()
|
873
1289
|
// Child policy config is parsed in JsonPostLoad
|
1290
|
+
.Field("clusterName", &XdsOverrideHostLbConfig::cluster_name_)
|
874
1291
|
.Finish();
|
875
1292
|
return kJsonLoader;
|
876
1293
|
}
|
877
1294
|
|
878
|
-
void XdsOverrideHostLbConfig::JsonPostLoad(const Json& json,
|
879
|
-
const JsonArgs& args,
|
1295
|
+
void XdsOverrideHostLbConfig::JsonPostLoad(const Json& json, const JsonArgs&,
|
880
1296
|
ValidationErrors* errors) {
|
881
|
-
|
882
|
-
|
883
|
-
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
errors->AddError(child_policy_config.status().message());
|
892
|
-
} else {
|
893
|
-
child_config_ = std::move(*child_policy_config);
|
894
|
-
}
|
895
|
-
}
|
896
|
-
}
|
897
|
-
{
|
898
|
-
ValidationErrors::ScopedField field(errors, ".overrideHostStatus");
|
899
|
-
auto host_status_list = LoadJsonObjectField<std::vector<std::string>>(
|
900
|
-
json.object(), args, "overrideHostStatus", errors,
|
901
|
-
/*required=*/false);
|
902
|
-
if (host_status_list.has_value()) {
|
903
|
-
for (size_t i = 0; i < host_status_list->size(); ++i) {
|
904
|
-
const std::string& host_status = (*host_status_list)[i];
|
905
|
-
auto status = XdsHealthStatus::FromString(host_status);
|
906
|
-
if (!status.has_value()) {
|
907
|
-
ValidationErrors::ScopedField field(errors,
|
908
|
-
absl::StrCat("[", i, "]"));
|
909
|
-
errors->AddError("invalid host status");
|
910
|
-
} else {
|
911
|
-
override_host_status_set_.Add(*status);
|
912
|
-
}
|
913
|
-
}
|
1297
|
+
ValidationErrors::ScopedField field(errors, ".childPolicy");
|
1298
|
+
auto it = json.object().find("childPolicy");
|
1299
|
+
if (it == json.object().end()) {
|
1300
|
+
errors->AddError("field not present");
|
1301
|
+
} else {
|
1302
|
+
auto child_policy_config =
|
1303
|
+
CoreConfiguration::Get().lb_policy_registry().ParseLoadBalancingConfig(
|
1304
|
+
it->second);
|
1305
|
+
if (!child_policy_config.ok()) {
|
1306
|
+
errors->AddError(child_policy_config.status().message());
|
914
1307
|
} else {
|
915
|
-
|
916
|
-
{XdsHealthStatus(XdsHealthStatus::HealthStatus::kHealthy),
|
917
|
-
XdsHealthStatus(XdsHealthStatus::HealthStatus::kUnknown)});
|
1308
|
+
child_config_ = std::move(*child_policy_config);
|
918
1309
|
}
|
919
1310
|
}
|
920
1311
|
}
|