grpc 1.46.3-x86_64-linux → 1.47.0-x86_64-linux
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 +49 -97
- data/include/grpc/event_engine/event_engine.h +42 -7
- data/include/grpc/event_engine/memory_allocator.h +0 -15
- data/include/grpc/event_engine/port.h +1 -1
- data/include/grpc/event_engine/slice.h +286 -0
- data/include/grpc/event_engine/slice_buffer.h +112 -0
- data/include/grpc/grpc_security.h +11 -0
- data/include/grpc/impl/codegen/port_platform.h +100 -36
- data/include/grpc/impl/codegen/slice.h +1 -1
- data/src/core/ext/filters/channel_idle/channel_idle_filter.cc +18 -30
- data/src/core/ext/filters/channel_idle/channel_idle_filter.h +4 -1
- data/src/core/ext/filters/client_channel/backend_metric.cc +17 -12
- data/src/core/ext/filters/client_channel/backend_metric.h +19 -9
- data/src/core/ext/filters/client_channel/backup_poller.cc +5 -5
- data/src/core/ext/filters/client_channel/backup_poller.h +2 -4
- data/src/core/ext/filters/client_channel/channel_connectivity.cc +42 -20
- data/src/core/ext/filters/client_channel/client_channel.cc +60 -17
- data/src/core/ext/filters/client_channel/client_channel.h +26 -6
- data/src/core/ext/filters/client_channel/client_channel_channelz.cc +3 -5
- data/src/core/ext/filters/client_channel/client_channel_channelz.h +12 -2
- data/src/core/ext/filters/client_channel/client_channel_factory.cc +5 -0
- data/src/core/ext/filters/client_channel/client_channel_factory.h +8 -0
- data/src/core/ext/filters/client_channel/client_channel_plugin.cc +4 -13
- data/src/core/ext/filters/client_channel/config_selector.cc +1 -0
- data/src/core/ext/filters/client_channel/config_selector.h +7 -5
- data/src/core/ext/filters/client_channel/connector.h +8 -2
- data/src/core/ext/filters/client_channel/dynamic_filters.cc +13 -2
- data/src/core/ext/filters/client_channel/dynamic_filters.h +11 -1
- data/src/core/ext/filters/client_channel/global_subchannel_pool.cc +2 -0
- data/src/core/ext/filters/client_channel/global_subchannel_pool.h +3 -0
- data/src/core/ext/filters/client_channel/health/health_check_client.cc +14 -1
- data/src/core/ext/filters/client_channel/health/health_check_client.h +2 -0
- data/src/core/ext/filters/client_channel/http_proxy.cc +10 -2
- data/src/core/ext/filters/client_channel/http_proxy.h +3 -0
- data/src/core/ext/filters/client_channel/lb_policy/address_filtering.cc +6 -2
- data/src/core/ext/filters/client_channel/lb_policy/address_filtering.h +1 -0
- data/src/core/ext/filters/client_channel/lb_policy/backend_metric_data.h +49 -0
- data/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc +12 -0
- data/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.h +5 -0
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc +9 -3
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +59 -19
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_balancer_addresses.cc +4 -0
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h +6 -0
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc +10 -1
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h +6 -3
- data/src/core/ext/filters/client_channel/lb_policy/oob_backend_metric.cc +408 -0
- data/src/core/ext/filters/client_channel/lb_policy/oob_backend_metric.h +57 -0
- data/src/core/ext/filters/client_channel/lb_policy/outlier_detection/outlier_detection.cc +1038 -0
- data/src/core/ext/filters/client_channel/lb_policy/outlier_detection/outlier_detection.h +54 -0
- data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +60 -52
- data/src/core/ext/filters/client_channel/lb_policy/priority/priority.cc +102 -60
- data/src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.cc +157 -96
- data/src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.h +2 -0
- data/src/core/ext/filters/client_channel/lb_policy/rls/rls.cc +45 -10
- data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +182 -171
- data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +39 -36
- data/src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc +30 -5
- data/src/core/ext/filters/client_channel/lb_policy/xds/cds.cc +99 -23
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds.h +6 -0
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc +30 -4
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc +23 -3
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc +75 -11
- data/src/core/ext/filters/client_channel/lb_policy.cc +4 -2
- data/src/core/ext/filters/client_channel/lb_policy.h +18 -24
- data/src/core/ext/filters/client_channel/lb_policy_factory.h +2 -0
- data/src/core/ext/filters/client_channel/lb_policy_registry.cc +8 -1
- data/src/core/ext/filters/client_channel/lb_policy_registry.h +6 -1
- data/src/core/ext/filters/client_channel/local_subchannel_pool.cc +4 -0
- data/src/core/ext/filters/client_channel/local_subchannel_pool.h +1 -0
- data/src/core/ext/filters/client_channel/proxy_mapper.h +1 -1
- data/src/core/ext/filters/client_channel/proxy_mapper_registry.cc +2 -0
- data/src/core/ext/filters/client_channel/proxy_mapper_registry.h +5 -0
- data/src/core/ext/filters/client_channel/resolver/binder/binder_resolver.cc +23 -5
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +134 -43
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h +8 -1
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc +10 -8
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +1 -1
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +26 -9
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +13 -4
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc +2 -1
- data/src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc +2 -0
- data/src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.h +2 -1
- data/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +30 -7
- data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +13 -14
- data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h +5 -2
- data/src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc +59 -13
- data/src/core/ext/filters/client_channel/resolver/polling_resolver.cc +13 -1
- data/src/core/ext/filters/client_channel/resolver/polling_resolver.h +8 -1
- data/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc +15 -11
- data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +89 -33
- data/src/core/ext/filters/client_channel/resolver_result_parsing.cc +5 -11
- data/src/core/ext/filters/client_channel/resolver_result_parsing.h +11 -5
- data/src/core/ext/filters/client_channel/retry_filter.cc +42 -2
- data/src/core/ext/filters/client_channel/retry_service_config.cc +8 -9
- data/src/core/ext/filters/client_channel/retry_service_config.h +10 -1
- data/src/core/ext/filters/client_channel/retry_throttle.cc +1 -8
- data/src/core/ext/filters/client_channel/retry_throttle.h +7 -1
- data/src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc +22 -5
- data/src/core/ext/filters/client_channel/subchannel.cc +156 -160
- data/src/core/ext/filters/client_channel/subchannel.h +80 -20
- data/src/core/ext/filters/client_channel/subchannel_interface.h +41 -23
- data/src/core/ext/filters/client_channel/subchannel_interface_internal.h +38 -0
- data/src/core/ext/filters/client_channel/subchannel_pool_interface.cc +12 -2
- data/src/core/ext/filters/client_channel/subchannel_pool_interface.h +6 -3
- data/src/core/ext/filters/client_channel/subchannel_stream_client.cc +16 -2
- data/src/core/ext/filters/client_channel/subchannel_stream_client.h +12 -0
- data/src/core/ext/filters/deadline/deadline_filter.cc +6 -2
- data/src/core/ext/filters/fault_injection/fault_injection_filter.cc +1 -4
- data/src/core/ext/filters/http/client/http_client_filter.cc +14 -5
- data/src/core/ext/filters/http/client/http_client_filter.h +7 -1
- data/src/core/ext/filters/http/client_authority_filter.cc +5 -10
- data/src/core/ext/filters/http/http_filters_plugin.cc +7 -8
- data/src/core/ext/filters/http/message_compress/message_compress_filter.cc +1 -0
- data/src/core/ext/filters/http/message_compress/message_decompress_filter.cc +3 -1
- data/src/core/ext/filters/http/server/http_server_filter.cc +80 -247
- data/src/core/ext/filters/http/server/http_server_filter.h +31 -2
- data/src/core/ext/filters/message_size/message_size_filter.cc +20 -26
- data/src/core/ext/filters/message_size/message_size_filter.h +2 -2
- data/src/core/ext/filters/rbac/rbac_filter.cc +1 -0
- data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +101 -135
- data/src/core/ext/transport/chttp2/client/chttp2_connector.h +9 -7
- data/src/core/ext/transport/chttp2/server/chttp2_server.cc +44 -15
- data/src/core/ext/transport/chttp2/server/chttp2_server.h +2 -0
- data/src/core/ext/transport/chttp2/transport/bin_decoder.cc +3 -3
- data/src/core/ext/transport/chttp2/transport/bin_decoder.h +2 -1
- data/src/core/ext/transport/chttp2/transport/bin_encoder.cc +1 -0
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +69 -20
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.h +5 -0
- data/src/core/ext/transport/chttp2/transport/context_list.cc +4 -0
- data/src/core/ext/transport/chttp2/transport/context_list.h +4 -1
- data/src/core/ext/transport/chttp2/transport/flow_control.cc +6 -2
- data/src/core/ext/transport/chttp2/transport/flow_control.h +6 -2
- data/src/core/ext/transport/chttp2/transport/frame.h +0 -4
- data/src/core/ext/transport/chttp2/transport/frame_data.cc +7 -1
- data/src/core/ext/transport/chttp2/transport/frame_data.h +4 -1
- data/src/core/ext/transport/chttp2/transport/frame_goaway.cc +3 -0
- data/src/core/ext/transport/chttp2/transport/frame_goaway.h +3 -1
- data/src/core/ext/transport/chttp2/transport/frame_ping.cc +5 -0
- data/src/core/ext/transport/chttp2/transport/frame_ping.h +3 -0
- data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +6 -2
- data/src/core/ext/transport/chttp2/transport/frame_rst_stream.h +3 -0
- data/src/core/ext/transport/chttp2/transport/frame_settings.cc +12 -3
- data/src/core/ext/transport/chttp2/transport/frame_settings.h +4 -0
- data/src/core/ext/transport/chttp2/transport/frame_window_update.cc +4 -1
- data/src/core/ext/transport/chttp2/transport/frame_window_update.h +3 -0
- data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +14 -12
- data/src/core/ext/transport/chttp2/transport/hpack_encoder.h +15 -2
- data/src/core/ext/transport/chttp2/transport/hpack_encoder_table.cc +3 -0
- data/src/core/ext/transport/chttp2/transport/hpack_encoder_table.h +3 -0
- data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +25 -7
- data/src/core/ext/transport/chttp2/transport/hpack_parser.h +8 -1
- data/src/core/ext/transport/chttp2/transport/hpack_parser_table.cc +55 -37
- data/src/core/ext/transport/chttp2/transport/hpack_parser_table.h +38 -21
- data/src/core/ext/transport/chttp2/transport/http2_settings.h +0 -1
- data/src/core/ext/transport/chttp2/transport/internal.h +24 -3
- data/src/core/ext/transport/chttp2/transport/parsing.cc +27 -6
- data/src/core/ext/transport/chttp2/transport/stream_lists.cc +13 -9
- data/src/core/ext/transport/chttp2/transport/stream_map.cc +1 -1
- data/src/core/ext/transport/chttp2/transport/stream_map.h +1 -0
- data/src/core/ext/transport/chttp2/transport/varint.h +2 -0
- data/src/core/ext/transport/chttp2/transport/writing.cc +38 -2
- data/src/core/ext/transport/inproc/inproc_transport.cc +8 -5
- data/src/core/ext/upb-generated/xds/service/orca/v3/orca.upb.c +47 -0
- data/src/core/ext/upb-generated/xds/service/orca/v3/orca.upb.h +109 -0
- data/src/core/ext/xds/certificate_provider_store.cc +4 -2
- data/src/core/ext/xds/certificate_provider_store.h +1 -1
- data/src/core/ext/xds/xds_certificate_provider.cc +4 -1
- data/src/core/ext/xds/xds_certificate_provider.h +1 -1
- data/src/core/ext/xds/xds_channel_stack_modifier.cc +5 -5
- data/src/core/ext/xds/xds_client.cc +46 -22
- data/src/core/ext/xds/xds_cluster.cc +106 -16
- data/src/core/ext/xds/xds_cluster.h +3 -0
- data/src/core/ext/xds/xds_http_fault_filter.cc +3 -3
- data/src/core/ext/xds/xds_listener.cc +19 -9
- data/src/core/ext/xds/xds_server_config_fetcher.cc +2 -1
- data/src/core/lib/address_utils/sockaddr_utils.cc +56 -23
- data/src/core/lib/address_utils/sockaddr_utils.h +7 -4
- data/src/core/lib/avl/avl.h +3 -1
- data/src/core/lib/channel/call_finalization.h +4 -0
- data/src/core/lib/channel/call_tracer.h +8 -2
- data/src/core/lib/channel/channel_args.cc +41 -22
- data/src/core/lib/channel/channel_args.h +33 -3
- data/src/core/lib/channel/channel_args_preconditioning.cc +3 -3
- data/src/core/lib/channel/channel_args_preconditioning.h +3 -2
- data/src/core/lib/channel/channel_stack.cc +41 -3
- data/src/core/lib/channel/channel_stack.h +49 -3
- data/src/core/lib/channel/channel_stack_builder.cc +9 -19
- data/src/core/lib/channel/channel_stack_builder.h +15 -27
- data/src/core/lib/channel/channel_stack_builder_impl.cc +36 -41
- data/src/core/lib/channel/channel_stack_builder_impl.h +3 -6
- data/src/core/lib/channel/channel_trace.cc +8 -13
- data/src/core/lib/channel/channel_trace.h +6 -3
- data/src/core/lib/channel/channelz.cc +8 -13
- data/src/core/lib/channel/channelz.h +13 -4
- data/src/core/lib/channel/channelz_registry.cc +7 -14
- data/src/core/lib/channel/channelz_registry.h +10 -9
- data/src/core/lib/channel/connected_channel.cc +21 -31
- data/src/core/lib/channel/connected_channel.h +1 -0
- data/src/core/lib/channel/promise_based_filter.cc +444 -189
- data/src/core/lib/channel/promise_based_filter.h +160 -27
- data/src/core/lib/channel/status_util.cc +2 -0
- data/src/core/lib/channel/status_util.h +0 -3
- data/src/core/lib/compression/compression_internal.cc +45 -10
- data/src/core/lib/compression/compression_internal.h +1 -1
- data/src/core/lib/config/core_configuration.cc +3 -0
- data/src/core/lib/config/core_configuration.h +2 -1
- data/src/core/lib/event_engine/channel_args_endpoint_config.cc +4 -2
- data/src/core/lib/event_engine/channel_args_endpoint_config.h +3 -2
- data/src/core/lib/event_engine/default_event_engine_factory.cc +8 -2
- data/src/core/lib/event_engine/event_engine.cc +12 -2
- data/src/core/lib/event_engine/event_engine_factory.h +5 -0
- data/src/core/lib/event_engine/handle_containers.h +67 -0
- data/src/core/lib/event_engine/iomgr_engine.cc +206 -0
- data/src/core/lib/event_engine/iomgr_engine.h +118 -0
- data/src/core/lib/event_engine/memory_allocator.cc +12 -4
- data/src/core/lib/event_engine/resolved_address.cc +4 -2
- data/src/core/lib/event_engine/slice.cc +102 -0
- data/src/core/lib/event_engine/slice_buffer.cc +50 -0
- data/src/core/lib/{iomgr/event_engine/pollset.h → event_engine/trace.cc} +3 -10
- data/src/core/lib/{iomgr/endpoint_pair_event_engine.cc → event_engine/trace.h} +12 -14
- data/src/core/lib/gpr/log.cc +5 -0
- data/src/core/lib/gpr/tls.h +3 -5
- data/src/core/lib/gprpp/bitset.h +5 -1
- data/src/core/lib/gprpp/chunked_vector.h +4 -0
- data/src/core/lib/gprpp/construct_destruct.h +1 -0
- data/src/core/lib/gprpp/dual_ref_counted.h +1 -4
- data/src/core/lib/gprpp/examine_stack.h +0 -1
- data/src/core/lib/gprpp/fork.cc +3 -6
- data/src/core/lib/gprpp/global_config.h +2 -4
- data/src/core/lib/gprpp/global_config_env.cc +3 -2
- data/src/core/lib/gprpp/global_config_env.h +3 -1
- data/src/core/lib/gprpp/global_config_generic.h +0 -4
- data/src/core/lib/gprpp/host_port.cc +2 -0
- data/src/core/lib/gprpp/manual_constructor.h +0 -1
- data/src/core/lib/gprpp/match.h +2 -0
- data/src/core/lib/gprpp/memory.h +1 -5
- data/src/core/lib/gprpp/orphanable.h +1 -4
- data/src/core/lib/gprpp/ref_counted.h +1 -3
- data/src/core/lib/gprpp/ref_counted_ptr.h +1 -1
- data/src/core/lib/gprpp/stat.h +0 -2
- data/src/core/lib/gprpp/stat_posix.cc +7 -2
- data/src/core/lib/gprpp/status_helper.cc +8 -4
- data/src/core/lib/gprpp/status_helper.h +4 -0
- data/src/core/lib/gprpp/sync.h +3 -1
- data/src/core/lib/gprpp/table.h +10 -0
- data/src/core/lib/gprpp/thd.h +2 -5
- data/src/core/lib/gprpp/thd_posix.cc +4 -2
- data/src/core/lib/gprpp/thd_windows.cc +2 -0
- data/src/core/lib/gprpp/time.cc +8 -0
- data/src/core/lib/gprpp/time.h +6 -1
- data/src/core/lib/gprpp/time_util.cc +4 -0
- data/src/core/lib/gprpp/time_util.h +1 -1
- data/src/core/lib/gprpp/unique_type_name.h +104 -0
- data/src/core/lib/http/format_request.cc +29 -0
- data/src/core/lib/http/format_request.h +2 -0
- data/src/core/lib/http/httpcli.cc +88 -81
- data/src/core/lib/http/httpcli.h +39 -7
- data/src/core/lib/http/httpcli_security_connector.cc +3 -4
- data/src/core/lib/iomgr/endpoint.cc +4 -4
- data/src/core/lib/iomgr/endpoint.h +6 -4
- data/src/core/lib/iomgr/endpoint_cfstream.cc +7 -4
- data/src/core/lib/iomgr/endpoint_pair_posix.cc +2 -1
- data/src/core/lib/iomgr/ev_posix.cc +1 -4
- data/src/core/lib/iomgr/exec_ctx.h +1 -2
- data/src/core/lib/iomgr/internal_errqueue.cc +38 -47
- data/src/core/lib/iomgr/internal_errqueue.h +1 -6
- data/src/core/lib/iomgr/iomgr.cc +0 -1
- data/src/core/{ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_event_engine.cc → lib/iomgr/iomgr_fwd.h} +9 -12
- data/src/core/lib/iomgr/pollset_set.h +1 -2
- data/src/core/lib/iomgr/port.h +25 -6
- data/src/core/lib/iomgr/resolve_address.cc +8 -0
- data/src/core/lib/iomgr/resolve_address.h +21 -14
- data/src/core/lib/iomgr/resolve_address_impl.h +2 -3
- data/src/core/lib/iomgr/resolve_address_posix.cc +8 -14
- data/src/core/lib/iomgr/resolve_address_posix.h +5 -2
- data/src/core/lib/iomgr/resolve_address_windows.cc +7 -14
- data/src/core/lib/iomgr/resolve_address_windows.h +5 -2
- data/src/core/lib/iomgr/sockaddr.h +2 -3
- data/src/core/lib/iomgr/sockaddr_posix.h +2 -0
- data/src/core/lib/iomgr/sockaddr_windows.h +2 -0
- data/src/core/lib/iomgr/socket_utils_common_posix.cc +3 -2
- data/src/core/lib/iomgr/tcp_client_cfstream.cc +10 -2
- data/src/core/lib/iomgr/tcp_client_posix.cc +12 -5
- data/src/core/lib/iomgr/tcp_client_windows.cc +13 -6
- data/src/core/lib/iomgr/tcp_posix.cc +9 -27
- data/src/core/lib/iomgr/tcp_server_posix.cc +26 -12
- data/src/core/lib/iomgr/tcp_server_utils_posix_common.cc +30 -27
- data/src/core/lib/iomgr/tcp_server_utils_posix_ifaddrs.cc +7 -4
- data/src/core/lib/iomgr/tcp_server_windows.cc +13 -5
- data/src/core/lib/iomgr/tcp_windows.cc +7 -4
- data/src/core/lib/json/json.h +1 -2
- data/src/core/lib/json/json_reader.cc +9 -1
- data/src/core/lib/json/json_util.cc +7 -0
- data/src/core/lib/json/json_util.h +10 -1
- data/src/core/lib/json/json_writer.cc +6 -1
- data/src/core/lib/promise/activity.cc +1 -1
- data/src/core/lib/promise/activity.h +6 -6
- data/src/core/lib/promise/arena_promise.h +11 -1
- data/src/core/lib/promise/call_push_pull.h +4 -0
- data/src/core/lib/promise/context.h +1 -1
- data/src/core/lib/promise/detail/basic_seq.h +2 -2
- data/src/core/lib/promise/detail/promise_factory.h +0 -1
- data/src/core/lib/promise/latch.h +0 -1
- data/src/core/lib/promise/loop.h +1 -0
- data/src/core/lib/promise/race.h +0 -1
- data/src/core/lib/promise/seq.h +0 -2
- data/src/core/lib/promise/sleep.cc +2 -0
- data/src/core/lib/promise/sleep.h +10 -0
- data/src/core/lib/promise/try_seq.h +2 -2
- data/src/core/lib/resolver/resolver_factory.h +1 -2
- data/src/core/lib/resolver/server_address.cc +9 -3
- data/src/core/lib/resolver/server_address.h +4 -4
- data/src/core/lib/resource_quota/api.cc +14 -1
- data/src/core/lib/resource_quota/api.h +4 -1
- data/src/core/lib/resource_quota/arena.cc +0 -6
- data/src/core/lib/resource_quota/arena.h +1 -2
- data/src/core/lib/resource_quota/memory_quota.cc +47 -5
- data/src/core/lib/resource_quota/memory_quota.h +24 -5
- data/src/core/lib/resource_quota/resource_quota.h +8 -0
- data/src/core/lib/resource_quota/thread_quota.cc +2 -0
- data/src/core/lib/resource_quota/thread_quota.h +4 -0
- data/src/core/lib/security/authorization/grpc_server_authz_filter.cc +3 -0
- data/src/core/lib/security/credentials/alts/alts_credentials.cc +8 -2
- data/src/core/lib/security/credentials/alts/alts_credentials.h +2 -2
- data/src/core/lib/security/credentials/call_creds_util.cc +2 -0
- data/src/core/lib/security/credentials/channel_creds_registry.h +1 -0
- data/src/core/lib/security/credentials/composite/composite_credentials.cc +7 -3
- data/src/core/lib/security/credentials/composite/composite_credentials.h +5 -4
- data/src/core/lib/security/credentials/credentials.h +17 -10
- data/src/core/lib/security/credentials/external/aws_external_account_credentials.cc +81 -0
- data/src/core/lib/security/credentials/external/aws_external_account_credentials.h +8 -0
- data/src/core/lib/security/credentials/external/external_account_credentials.cc +3 -0
- data/src/core/lib/security/credentials/external/url_external_account_credentials.cc +2 -0
- data/src/core/lib/security/credentials/fake/fake_credentials.cc +13 -3
- data/src/core/lib/security/credentials/fake/fake_credentials.h +2 -2
- data/src/core/lib/security/credentials/google_default/google_default_credentials.cc +25 -15
- data/src/core/lib/security/credentials/google_default/google_default_credentials.h +2 -2
- data/src/core/lib/security/credentials/iam/iam_credentials.cc +4 -1
- data/src/core/lib/security/credentials/iam/iam_credentials.h +2 -2
- data/src/core/lib/security/credentials/insecure/insecure_credentials.cc +8 -2
- data/src/core/lib/security/credentials/insecure/insecure_credentials.h +4 -4
- data/src/core/lib/security/credentials/jwt/jwt_credentials.cc +3 -2
- data/src/core/lib/security/credentials/jwt/jwt_credentials.h +2 -2
- data/src/core/lib/security/credentials/local/local_credentials.cc +8 -2
- data/src/core/lib/security/credentials/local/local_credentials.h +2 -2
- data/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +10 -6
- data/src/core/lib/security/credentials/oauth2/oauth2_credentials.h +4 -4
- data/src/core/lib/security/credentials/plugin/plugin_credentials.cc +4 -1
- data/src/core/lib/security/credentials/plugin/plugin_credentials.h +1 -1
- data/src/core/lib/security/credentials/ssl/ssl_credentials.cc +8 -2
- data/src/core/lib/security/credentials/ssl/ssl_credentials.h +4 -4
- data/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc +10 -0
- data/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h +5 -7
- data/src/core/lib/security/credentials/tls/grpc_tls_certificate_verifier.cc +26 -1
- data/src/core/lib/security/credentials/tls/grpc_tls_certificate_verifier.h +28 -4
- data/src/core/lib/security/credentials/tls/tls_credentials.cc +10 -0
- data/src/core/lib/security/credentials/tls/tls_credentials.h +2 -2
- data/src/core/lib/security/credentials/xds/xds_credentials.cc +12 -3
- data/src/core/lib/security/credentials/xds/xds_credentials.h +5 -5
- data/src/core/lib/security/security_connector/fake/fake_security_connector.cc +1 -1
- data/src/core/lib/security/security_connector/fake/fake_security_connector.h +1 -1
- data/src/core/lib/security/security_connector/security_connector.cc +1 -1
- data/src/core/lib/security/security_connector/security_connector.h +1 -1
- data/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +1 -1
- data/src/core/lib/security/transport/client_auth_filter.cc +6 -8
- data/src/core/lib/security/transport/secure_endpoint.cc +23 -12
- data/src/core/lib/security/transport/security_handshaker.cc +5 -5
- data/src/core/lib/security/transport/security_handshaker.h +1 -1
- data/src/core/lib/security/transport/server_auth_filter.cc +3 -2
- data/src/core/lib/service_config/service_config.h +4 -8
- data/src/core/lib/service_config/service_config_call_data.h +4 -1
- data/src/core/lib/service_config/service_config_impl.cc +7 -0
- data/src/core/lib/service_config/service_config_impl.h +9 -2
- data/src/core/lib/service_config/service_config_parser.cc +8 -0
- data/src/core/lib/service_config/service_config_parser.h +7 -0
- data/src/core/lib/slice/b64.cc +1 -1
- data/src/core/lib/slice/b64.h +2 -0
- data/src/core/lib/slice/percent_encoding.cc +4 -1
- data/src/core/lib/slice/percent_encoding.h +0 -6
- data/src/core/lib/slice/slice.cc +2 -1
- data/src/core/lib/slice/slice.h +10 -5
- data/src/core/lib/slice/slice_api.cc +1 -1
- data/src/core/lib/slice/slice_buffer.cc +50 -23
- data/src/core/lib/slice/slice_buffer.h +106 -0
- data/src/core/lib/slice/slice_buffer_api.cc +35 -0
- data/src/core/lib/slice/slice_internal.h +4 -3
- data/src/core/lib/slice/slice_refcount.h +2 -3
- data/src/core/lib/slice/slice_refcount_base.h +2 -3
- data/src/core/lib/slice/slice_split.cc +3 -0
- data/src/core/lib/slice/slice_split.h +0 -4
- data/src/core/lib/slice/slice_string_helpers.cc +4 -0
- data/src/core/lib/slice/slice_string_helpers.h +1 -4
- data/src/core/lib/surface/builtins.cc +7 -2
- data/src/core/lib/surface/byte_buffer.cc +7 -1
- data/src/core/lib/surface/byte_buffer_reader.cc +4 -4
- data/src/core/lib/surface/call.cc +41 -26
- data/src/core/lib/surface/call.h +16 -2
- data/src/core/lib/surface/call_details.cc +4 -4
- data/src/core/lib/surface/call_log_batch.cc +7 -1
- data/src/core/lib/surface/call_test_only.h +4 -1
- data/src/core/lib/surface/channel.cc +179 -242
- data/src/core/lib/surface/channel.h +94 -57
- data/src/core/lib/surface/channel_init.h +2 -0
- data/src/core/lib/surface/channel_ping.cc +8 -2
- data/src/core/lib/surface/channel_stack_type.cc +0 -2
- data/src/core/lib/surface/channel_stack_type.h +0 -2
- data/src/core/lib/surface/completion_queue.cc +14 -6
- data/src/core/lib/surface/completion_queue.h +5 -1
- data/src/core/lib/surface/completion_queue_factory.cc +1 -0
- data/src/core/lib/surface/completion_queue_factory.h +1 -3
- data/src/core/lib/surface/event_string.cc +1 -7
- data/src/core/lib/surface/event_string.h +1 -1
- data/src/core/lib/surface/init.cc +17 -45
- data/src/core/lib/surface/init.h +0 -8
- data/src/core/lib/surface/lame_client.cc +64 -110
- data/src/core/lib/surface/lame_client.h +40 -2
- data/src/core/lib/surface/metadata_array.cc +2 -0
- data/src/core/lib/surface/server.cc +69 -56
- data/src/core/lib/surface/server.h +39 -9
- data/src/core/lib/surface/validate_metadata.cc +2 -5
- data/src/core/lib/surface/validate_metadata.h +3 -0
- data/src/core/lib/surface/version.cc +2 -2
- data/src/core/lib/transport/bdp_estimator.cc +3 -1
- data/src/core/lib/transport/bdp_estimator.h +2 -3
- data/src/core/lib/transport/byte_stream.cc +4 -3
- data/src/core/lib/transport/byte_stream.h +5 -1
- data/src/core/lib/transport/connectivity_state.cc +6 -4
- data/src/core/lib/transport/connectivity_state.h +2 -3
- data/src/core/lib/transport/error_utils.cc +4 -2
- data/src/core/lib/transport/error_utils.h +5 -1
- data/src/core/lib/{channel → transport}/handshaker.cc +9 -4
- data/src/core/lib/{channel → transport}/handshaker.h +13 -6
- data/src/core/lib/{channel → transport}/handshaker_factory.h +9 -10
- data/src/core/lib/{channel → transport}/handshaker_registry.cc +5 -1
- data/src/core/lib/{channel → transport}/handshaker_registry.h +5 -4
- data/src/core/{ext/filters/client_channel → lib/transport}/http_connect_handshaker.cc +24 -10
- data/src/core/{ext/filters/client_channel → lib/transport}/http_connect_handshaker.h +3 -3
- data/src/core/lib/transport/metadata_batch.cc +287 -0
- data/src/core/lib/transport/metadata_batch.h +133 -264
- data/src/core/lib/transport/parsed_metadata.cc +2 -0
- data/src/core/lib/transport/parsed_metadata.h +10 -3
- data/src/core/lib/transport/status_conversion.cc +2 -0
- data/src/core/lib/transport/status_conversion.h +2 -2
- data/src/core/lib/transport/tcp_connect_handshaker.cc +253 -0
- data/src/core/lib/transport/tcp_connect_handshaker.h +39 -0
- data/src/core/lib/transport/timeout_encoding.cc +2 -6
- data/src/core/lib/transport/timeout_encoding.h +5 -1
- data/src/core/lib/transport/transport.cc +18 -17
- data/src/core/lib/transport/transport.h +28 -2
- data/src/core/lib/transport/transport_impl.h +10 -0
- data/src/core/lib/transport/transport_op_string.cc +9 -10
- data/src/core/lib/uri/uri_parser.cc +11 -3
- data/src/core/lib/uri/uri_parser.h +0 -2
- data/src/core/plugin_registry/grpc_plugin_registry.cc +11 -0
- data/src/core/tsi/ssl/session_cache/ssl_session.h +2 -0
- data/src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc +2 -0
- data/src/core/tsi/ssl/session_cache/ssl_session_openssl.cc +2 -0
- data/src/ruby/ext/grpc/extconf.rb +2 -2
- data/src/ruby/lib/grpc/2.5/grpc_c.so +0 -0
- data/src/ruby/lib/grpc/2.6/grpc_c.so +0 -0
- data/src/ruby/lib/grpc/2.7/grpc_c.so +0 -0
- data/src/ruby/lib/grpc/3.0/grpc_c.so +0 -0
- data/src/ruby/lib/grpc/3.1/grpc_c.so +0 -0
- data/src/ruby/lib/grpc/grpc_c.so +0 -0
- data/src/ruby/lib/grpc/version.rb +1 -1
- data/third_party/abseil-cpp/absl/cleanup/cleanup.h +140 -0
- data/third_party/abseil-cpp/absl/cleanup/internal/cleanup.h +100 -0
- data/third_party/abseil-cpp/absl/container/flat_hash_set.h +504 -0
- metadata +36 -29
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_event_engine.cc +0 -31
- data/src/core/lib/event_engine/sockaddr.cc +0 -40
- data/src/core/lib/event_engine/sockaddr.h +0 -44
- data/src/core/lib/gprpp/capture.h +0 -76
- data/src/core/lib/iomgr/event_engine/closure.cc +0 -77
- data/src/core/lib/iomgr/event_engine/closure.h +0 -42
- data/src/core/lib/iomgr/event_engine/endpoint.cc +0 -172
- data/src/core/lib/iomgr/event_engine/endpoint.h +0 -52
- data/src/core/lib/iomgr/event_engine/iomgr.cc +0 -85
- data/src/core/lib/iomgr/event_engine/pollset.cc +0 -87
- data/src/core/lib/iomgr/event_engine/promise.h +0 -51
- data/src/core/lib/iomgr/event_engine/resolved_address_internal.cc +0 -47
- data/src/core/lib/iomgr/event_engine/resolved_address_internal.h +0 -37
- data/src/core/lib/iomgr/event_engine/resolver.cc +0 -133
- data/src/core/lib/iomgr/event_engine/resolver.h +0 -56
- data/src/core/lib/iomgr/event_engine/tcp.cc +0 -296
- data/src/core/lib/iomgr/event_engine/timer.cc +0 -62
@@ -0,0 +1,1038 @@
|
|
1
|
+
//
|
2
|
+
// Copyright 2022 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 "src/core/ext/filters/client_channel/lb_policy/outlier_detection/outlier_detection.h"
|
20
|
+
|
21
|
+
#include <stddef.h>
|
22
|
+
|
23
|
+
#include <algorithm>
|
24
|
+
#include <atomic>
|
25
|
+
#include <cmath>
|
26
|
+
#include <cstdint>
|
27
|
+
#include <map>
|
28
|
+
#include <memory>
|
29
|
+
#include <set>
|
30
|
+
#include <string>
|
31
|
+
#include <utility>
|
32
|
+
#include <vector>
|
33
|
+
|
34
|
+
#include "absl/container/inlined_vector.h"
|
35
|
+
#include "absl/memory/memory.h"
|
36
|
+
#include "absl/random/random.h"
|
37
|
+
#include "absl/status/status.h"
|
38
|
+
#include "absl/status/statusor.h"
|
39
|
+
#include "absl/strings/string_view.h"
|
40
|
+
#include "absl/types/variant.h"
|
41
|
+
|
42
|
+
#include <grpc/impl/codegen/connectivity_state.h>
|
43
|
+
#include <grpc/impl/codegen/grpc_types.h>
|
44
|
+
#include <grpc/support/alloc.h>
|
45
|
+
#include <grpc/support/log.h>
|
46
|
+
|
47
|
+
#include "src/core/ext/filters/client_channel/lb_policy.h"
|
48
|
+
#include "src/core/ext/filters/client_channel/lb_policy/child_policy_handler.h"
|
49
|
+
#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
|
50
|
+
#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
|
51
|
+
#include "src/core/ext/filters/client_channel/subchannel_interface.h"
|
52
|
+
#include "src/core/lib/channel/channel_args.h"
|
53
|
+
#include "src/core/lib/debug/trace.h"
|
54
|
+
#include "src/core/lib/gpr/env.h"
|
55
|
+
#include "src/core/lib/gpr/string.h"
|
56
|
+
#include "src/core/lib/gprpp/debug_location.h"
|
57
|
+
#include "src/core/lib/gprpp/orphanable.h"
|
58
|
+
#include "src/core/lib/gprpp/ref_counted.h"
|
59
|
+
#include "src/core/lib/gprpp/ref_counted_ptr.h"
|
60
|
+
#include "src/core/lib/iomgr/closure.h"
|
61
|
+
#include "src/core/lib/iomgr/error.h"
|
62
|
+
#include "src/core/lib/iomgr/exec_ctx.h"
|
63
|
+
#include "src/core/lib/iomgr/iomgr_fwd.h"
|
64
|
+
#include "src/core/lib/iomgr/pollset_set.h"
|
65
|
+
#include "src/core/lib/iomgr/timer.h"
|
66
|
+
#include "src/core/lib/iomgr/work_serializer.h"
|
67
|
+
#include "src/core/lib/json/json.h"
|
68
|
+
#include "src/core/lib/json/json_util.h"
|
69
|
+
#include "src/core/lib/resolver/server_address.h"
|
70
|
+
#include "src/core/lib/transport/connectivity_state.h"
|
71
|
+
|
72
|
+
namespace grpc_core {
|
73
|
+
|
74
|
+
TraceFlag grpc_outlier_detection_lb_trace(false, "outlier_detection_lb");
|
75
|
+
|
76
|
+
// TODO(donnadionne): Remove once outlier detection is no longer experimental
|
77
|
+
bool XdsOutlierDetectionEnabled() {
|
78
|
+
char* value = gpr_getenv("GRPC_EXPERIMENTAL_ENABLE_OUTLIER_DETECTION");
|
79
|
+
bool parsed_value;
|
80
|
+
bool parse_succeeded = gpr_parse_bool_value(value, &parsed_value);
|
81
|
+
gpr_free(value);
|
82
|
+
return parse_succeeded && parsed_value;
|
83
|
+
}
|
84
|
+
|
85
|
+
namespace {
|
86
|
+
|
87
|
+
constexpr char kOutlierDetection[] = "outlier_detection_experimental";
|
88
|
+
|
89
|
+
// Config for xDS Cluster Impl LB policy.
|
90
|
+
class OutlierDetectionLbConfig : public LoadBalancingPolicy::Config {
|
91
|
+
public:
|
92
|
+
OutlierDetectionLbConfig(
|
93
|
+
OutlierDetectionConfig outlier_detection_config,
|
94
|
+
RefCountedPtr<LoadBalancingPolicy::Config> child_policy)
|
95
|
+
: outlier_detection_config_(outlier_detection_config),
|
96
|
+
child_policy_(std::move(child_policy)) {}
|
97
|
+
|
98
|
+
const char* name() const override { return kOutlierDetection; }
|
99
|
+
|
100
|
+
bool CountingEnabled() const {
|
101
|
+
return (
|
102
|
+
outlier_detection_config_.interval != Duration::Infinity() &&
|
103
|
+
(outlier_detection_config_.success_rate_ejection.has_value() ||
|
104
|
+
outlier_detection_config_.failure_percentage_ejection.has_value()));
|
105
|
+
}
|
106
|
+
|
107
|
+
const OutlierDetectionConfig& outlier_detection_config() const {
|
108
|
+
return outlier_detection_config_;
|
109
|
+
}
|
110
|
+
|
111
|
+
RefCountedPtr<LoadBalancingPolicy::Config> child_policy() const {
|
112
|
+
return child_policy_;
|
113
|
+
}
|
114
|
+
|
115
|
+
private:
|
116
|
+
OutlierDetectionConfig outlier_detection_config_;
|
117
|
+
RefCountedPtr<LoadBalancingPolicy::Config> child_policy_;
|
118
|
+
};
|
119
|
+
|
120
|
+
// xDS Cluster Impl LB policy.
|
121
|
+
class OutlierDetectionLb : public LoadBalancingPolicy {
|
122
|
+
public:
|
123
|
+
explicit OutlierDetectionLb(Args args);
|
124
|
+
|
125
|
+
const char* name() const override { return kOutlierDetection; }
|
126
|
+
|
127
|
+
void UpdateLocked(UpdateArgs args) override;
|
128
|
+
void ExitIdleLocked() override;
|
129
|
+
void ResetBackoffLocked() override;
|
130
|
+
|
131
|
+
private:
|
132
|
+
class SubchannelState;
|
133
|
+
class SubchannelWrapper : public DelegatingSubchannel {
|
134
|
+
public:
|
135
|
+
SubchannelWrapper(RefCountedPtr<SubchannelState> subchannel_state,
|
136
|
+
RefCountedPtr<SubchannelInterface> subchannel)
|
137
|
+
: DelegatingSubchannel(std::move(subchannel)),
|
138
|
+
subchannel_state_(std::move(subchannel_state)) {
|
139
|
+
if (subchannel_state_ != nullptr) {
|
140
|
+
subchannel_state_->AddSubchannel(this);
|
141
|
+
if (subchannel_state_->ejection_time().has_value()) {
|
142
|
+
ejected_ = true;
|
143
|
+
}
|
144
|
+
}
|
145
|
+
}
|
146
|
+
|
147
|
+
~SubchannelWrapper() override {
|
148
|
+
if (subchannel_state_ != nullptr) {
|
149
|
+
subchannel_state_->RemoveSubchannel(this);
|
150
|
+
}
|
151
|
+
}
|
152
|
+
|
153
|
+
void Eject();
|
154
|
+
|
155
|
+
void Uneject();
|
156
|
+
|
157
|
+
grpc_connectivity_state CheckConnectivityState() override;
|
158
|
+
|
159
|
+
void WatchConnectivityState(
|
160
|
+
grpc_connectivity_state initial_state,
|
161
|
+
std::unique_ptr<ConnectivityStateWatcherInterface> watcher) override;
|
162
|
+
|
163
|
+
void CancelConnectivityStateWatch(
|
164
|
+
ConnectivityStateWatcherInterface* watcher) override;
|
165
|
+
|
166
|
+
RefCountedPtr<SubchannelState> subchannel_state() const {
|
167
|
+
return subchannel_state_;
|
168
|
+
}
|
169
|
+
|
170
|
+
private:
|
171
|
+
class WatcherWrapper
|
172
|
+
: public SubchannelInterface::ConnectivityStateWatcherInterface {
|
173
|
+
public:
|
174
|
+
WatcherWrapper(std::unique_ptr<
|
175
|
+
SubchannelInterface::ConnectivityStateWatcherInterface>
|
176
|
+
watcher,
|
177
|
+
grpc_connectivity_state initial_state, bool ejected)
|
178
|
+
: watcher_(std::move(watcher)),
|
179
|
+
last_seen_state_(initial_state),
|
180
|
+
ejected_(ejected) {}
|
181
|
+
|
182
|
+
void Eject() {
|
183
|
+
ejected_ = true;
|
184
|
+
if (last_seen_state_ != GRPC_CHANNEL_TRANSIENT_FAILURE) {
|
185
|
+
watcher_->OnConnectivityStateChange(GRPC_CHANNEL_TRANSIENT_FAILURE);
|
186
|
+
}
|
187
|
+
}
|
188
|
+
|
189
|
+
void Uneject() {
|
190
|
+
ejected_ = false;
|
191
|
+
if (last_seen_state_ != GRPC_CHANNEL_TRANSIENT_FAILURE) {
|
192
|
+
watcher_->OnConnectivityStateChange(last_seen_state_);
|
193
|
+
}
|
194
|
+
}
|
195
|
+
|
196
|
+
void OnConnectivityStateChange(
|
197
|
+
grpc_connectivity_state new_state) override {
|
198
|
+
last_seen_state_ = new_state;
|
199
|
+
if (!ejected_) {
|
200
|
+
watcher_->OnConnectivityStateChange(new_state);
|
201
|
+
}
|
202
|
+
}
|
203
|
+
|
204
|
+
grpc_pollset_set* interested_parties() override {
|
205
|
+
return watcher_->interested_parties();
|
206
|
+
}
|
207
|
+
|
208
|
+
private:
|
209
|
+
std::unique_ptr<SubchannelInterface::ConnectivityStateWatcherInterface>
|
210
|
+
watcher_;
|
211
|
+
grpc_connectivity_state last_seen_state_;
|
212
|
+
bool ejected_;
|
213
|
+
};
|
214
|
+
|
215
|
+
RefCountedPtr<SubchannelState> subchannel_state_;
|
216
|
+
bool ejected_ = false;
|
217
|
+
std::map<SubchannelInterface::ConnectivityStateWatcherInterface*,
|
218
|
+
WatcherWrapper*>
|
219
|
+
watchers_;
|
220
|
+
};
|
221
|
+
|
222
|
+
class SubchannelState : public RefCounted<SubchannelState> {
|
223
|
+
public:
|
224
|
+
struct Bucket {
|
225
|
+
std::atomic<uint64_t> successes;
|
226
|
+
std::atomic<uint64_t> failures;
|
227
|
+
};
|
228
|
+
|
229
|
+
void RotateBucket() {
|
230
|
+
backup_bucket_->successes = 0;
|
231
|
+
backup_bucket_->failures = 0;
|
232
|
+
current_bucket_.swap(backup_bucket_);
|
233
|
+
active_bucket_.store(current_bucket_.get());
|
234
|
+
}
|
235
|
+
|
236
|
+
absl::optional<std::pair<double, uint64_t>> GetSuccessRateAndVolume() {
|
237
|
+
uint64_t total_request =
|
238
|
+
backup_bucket_->successes + backup_bucket_->failures;
|
239
|
+
if (total_request == 0) {
|
240
|
+
return absl::nullopt;
|
241
|
+
}
|
242
|
+
double success_rate =
|
243
|
+
backup_bucket_->successes * 100.0 /
|
244
|
+
(backup_bucket_->successes + backup_bucket_->failures);
|
245
|
+
return {
|
246
|
+
{success_rate, backup_bucket_->successes + backup_bucket_->failures}};
|
247
|
+
}
|
248
|
+
|
249
|
+
void AddSubchannel(SubchannelWrapper* wrapper) {
|
250
|
+
subchannels_.insert(wrapper);
|
251
|
+
}
|
252
|
+
|
253
|
+
void RemoveSubchannel(SubchannelWrapper* wrapper) {
|
254
|
+
subchannels_.erase(wrapper);
|
255
|
+
}
|
256
|
+
|
257
|
+
void AddSuccessCount() { active_bucket_.load()->successes.fetch_add(1); }
|
258
|
+
|
259
|
+
void AddFailureCount() { active_bucket_.load()->failures.fetch_add(1); }
|
260
|
+
|
261
|
+
absl::optional<Timestamp> ejection_time() const { return ejection_time_; }
|
262
|
+
|
263
|
+
void Eject(const Timestamp& time) {
|
264
|
+
ejection_time_ = time;
|
265
|
+
++multiplier_;
|
266
|
+
for (auto& subchannel : subchannels_) {
|
267
|
+
subchannel->Eject();
|
268
|
+
}
|
269
|
+
}
|
270
|
+
|
271
|
+
void Uneject() {
|
272
|
+
ejection_time_.reset();
|
273
|
+
for (auto& subchannel : subchannels_) {
|
274
|
+
subchannel->Uneject();
|
275
|
+
}
|
276
|
+
}
|
277
|
+
|
278
|
+
void MaybeUneject(uint64_t base_ejection_time_in_millis,
|
279
|
+
uint64_t max_ejection_time_in_millis) {
|
280
|
+
if (!ejection_time_.has_value()) {
|
281
|
+
if (multiplier_ > 0) {
|
282
|
+
--multiplier_;
|
283
|
+
}
|
284
|
+
} else {
|
285
|
+
GPR_ASSERT(ejection_time_.has_value());
|
286
|
+
auto change_time = ejection_time_.value() +
|
287
|
+
Duration::Milliseconds(std::min(
|
288
|
+
base_ejection_time_in_millis * multiplier_,
|
289
|
+
std::max(base_ejection_time_in_millis,
|
290
|
+
max_ejection_time_in_millis)));
|
291
|
+
if (change_time < ExecCtx::Get()->Now()) {
|
292
|
+
Uneject();
|
293
|
+
}
|
294
|
+
}
|
295
|
+
}
|
296
|
+
|
297
|
+
private:
|
298
|
+
std::unique_ptr<Bucket> current_bucket_ = absl::make_unique<Bucket>();
|
299
|
+
std::unique_ptr<Bucket> backup_bucket_ = absl::make_unique<Bucket>();
|
300
|
+
// The bucket used to update call counts.
|
301
|
+
// Points to either current_bucket or active_bucket.
|
302
|
+
std::atomic<Bucket*> active_bucket_{current_bucket_.get()};
|
303
|
+
uint32_t multiplier_ = 0;
|
304
|
+
absl::optional<Timestamp> ejection_time_;
|
305
|
+
std::set<SubchannelWrapper*> subchannels_;
|
306
|
+
};
|
307
|
+
|
308
|
+
// A simple wrapper for ref-counting a picker from the child policy.
|
309
|
+
class RefCountedPicker : public RefCounted<RefCountedPicker> {
|
310
|
+
public:
|
311
|
+
explicit RefCountedPicker(std::unique_ptr<SubchannelPicker> picker)
|
312
|
+
: picker_(std::move(picker)) {}
|
313
|
+
PickResult Pick(PickArgs args) { return picker_->Pick(args); }
|
314
|
+
|
315
|
+
private:
|
316
|
+
std::unique_ptr<SubchannelPicker> picker_;
|
317
|
+
};
|
318
|
+
|
319
|
+
// A picker that wraps the picker from the child to perform outlier detection.
|
320
|
+
class Picker : public SubchannelPicker {
|
321
|
+
public:
|
322
|
+
Picker(OutlierDetectionLb* outlier_detection_lb,
|
323
|
+
RefCountedPtr<RefCountedPicker> picker, bool counting_enabled);
|
324
|
+
|
325
|
+
PickResult Pick(PickArgs args) override;
|
326
|
+
|
327
|
+
private:
|
328
|
+
class SubchannelCallTracker;
|
329
|
+
RefCountedPtr<RefCountedPicker> picker_;
|
330
|
+
bool counting_enabled_;
|
331
|
+
};
|
332
|
+
|
333
|
+
class Helper : public ChannelControlHelper {
|
334
|
+
public:
|
335
|
+
explicit Helper(RefCountedPtr<OutlierDetectionLb> outlier_detection_policy)
|
336
|
+
: outlier_detection_policy_(std::move(outlier_detection_policy)) {}
|
337
|
+
|
338
|
+
~Helper() override {
|
339
|
+
outlier_detection_policy_.reset(DEBUG_LOCATION, "Helper");
|
340
|
+
}
|
341
|
+
|
342
|
+
RefCountedPtr<SubchannelInterface> CreateSubchannel(
|
343
|
+
ServerAddress address, const grpc_channel_args& args) override;
|
344
|
+
void UpdateState(grpc_connectivity_state state, const absl::Status& status,
|
345
|
+
std::unique_ptr<SubchannelPicker> picker) override;
|
346
|
+
void RequestReresolution() override;
|
347
|
+
absl::string_view GetAuthority() override;
|
348
|
+
void AddTraceEvent(TraceSeverity severity,
|
349
|
+
absl::string_view message) override;
|
350
|
+
|
351
|
+
private:
|
352
|
+
RefCountedPtr<OutlierDetectionLb> outlier_detection_policy_;
|
353
|
+
};
|
354
|
+
|
355
|
+
class EjectionTimer : public InternallyRefCounted<EjectionTimer> {
|
356
|
+
public:
|
357
|
+
EjectionTimer(RefCountedPtr<OutlierDetectionLb> parent,
|
358
|
+
Timestamp start_time);
|
359
|
+
|
360
|
+
void Orphan() override;
|
361
|
+
|
362
|
+
Timestamp StartTime() const { return start_time_; }
|
363
|
+
|
364
|
+
private:
|
365
|
+
static void OnTimer(void* arg, grpc_error_handle error);
|
366
|
+
void OnTimerLocked(grpc_error_handle);
|
367
|
+
|
368
|
+
RefCountedPtr<OutlierDetectionLb> parent_;
|
369
|
+
grpc_timer timer_;
|
370
|
+
grpc_closure on_timer_;
|
371
|
+
bool timer_pending_ = true;
|
372
|
+
Timestamp start_time_;
|
373
|
+
absl::BitGen bit_gen_;
|
374
|
+
};
|
375
|
+
|
376
|
+
~OutlierDetectionLb() override;
|
377
|
+
|
378
|
+
static std::string MakeKeyForAddress(const ServerAddress& address);
|
379
|
+
|
380
|
+
void ShutdownLocked() override;
|
381
|
+
|
382
|
+
OrphanablePtr<LoadBalancingPolicy> CreateChildPolicyLocked(
|
383
|
+
const grpc_channel_args* args);
|
384
|
+
|
385
|
+
void MaybeUpdatePickerLocked();
|
386
|
+
|
387
|
+
// Current config from the resolver.
|
388
|
+
RefCountedPtr<OutlierDetectionLbConfig> config_;
|
389
|
+
|
390
|
+
// Internal state.
|
391
|
+
bool shutting_down_ = false;
|
392
|
+
|
393
|
+
OrphanablePtr<LoadBalancingPolicy> child_policy_;
|
394
|
+
|
395
|
+
// Latest state and picker reported by the child policy.
|
396
|
+
grpc_connectivity_state state_ = GRPC_CHANNEL_IDLE;
|
397
|
+
absl::Status status_;
|
398
|
+
RefCountedPtr<RefCountedPicker> picker_;
|
399
|
+
std::map<std::string, RefCountedPtr<SubchannelState>> subchannel_state_map_;
|
400
|
+
OrphanablePtr<EjectionTimer> ejection_timer_;
|
401
|
+
};
|
402
|
+
|
403
|
+
//
|
404
|
+
// OutlierDetectionLb::SubchannelWrapper
|
405
|
+
//
|
406
|
+
|
407
|
+
void OutlierDetectionLb::SubchannelWrapper::Eject() {
|
408
|
+
ejected_ = true;
|
409
|
+
for (auto& watcher : watchers_) {
|
410
|
+
watcher.second->Eject();
|
411
|
+
}
|
412
|
+
}
|
413
|
+
|
414
|
+
void OutlierDetectionLb::SubchannelWrapper::Uneject() {
|
415
|
+
ejected_ = false;
|
416
|
+
for (auto& watcher : watchers_) {
|
417
|
+
watcher.second->Uneject();
|
418
|
+
}
|
419
|
+
}
|
420
|
+
|
421
|
+
grpc_connectivity_state
|
422
|
+
OutlierDetectionLb::SubchannelWrapper::CheckConnectivityState() {
|
423
|
+
if (ejected_) return GRPC_CHANNEL_TRANSIENT_FAILURE;
|
424
|
+
return wrapped_subchannel()->CheckConnectivityState();
|
425
|
+
}
|
426
|
+
|
427
|
+
void OutlierDetectionLb::SubchannelWrapper::WatchConnectivityState(
|
428
|
+
grpc_connectivity_state initial_state,
|
429
|
+
std::unique_ptr<ConnectivityStateWatcherInterface> watcher) {
|
430
|
+
ConnectivityStateWatcherInterface* watcher_ptr = watcher.get();
|
431
|
+
auto watcher_wrapper = absl::make_unique<WatcherWrapper>(
|
432
|
+
std::move(watcher), initial_state, ejected_);
|
433
|
+
watchers_.emplace(watcher_ptr, watcher_wrapper.get());
|
434
|
+
wrapped_subchannel()->WatchConnectivityState(initial_state,
|
435
|
+
std::move(watcher_wrapper));
|
436
|
+
}
|
437
|
+
|
438
|
+
void OutlierDetectionLb::SubchannelWrapper::CancelConnectivityStateWatch(
|
439
|
+
ConnectivityStateWatcherInterface* watcher) {
|
440
|
+
auto it = watchers_.find(watcher);
|
441
|
+
if (it == watchers_.end()) return;
|
442
|
+
wrapped_subchannel()->CancelConnectivityStateWatch(it->second);
|
443
|
+
watchers_.erase(it);
|
444
|
+
}
|
445
|
+
|
446
|
+
//
|
447
|
+
// OutlierDetectionLb::Picker::SubchannelCallTracker
|
448
|
+
//
|
449
|
+
|
450
|
+
class OutlierDetectionLb::Picker::SubchannelCallTracker
|
451
|
+
: public LoadBalancingPolicy::SubchannelCallTrackerInterface {
|
452
|
+
public:
|
453
|
+
SubchannelCallTracker(
|
454
|
+
std::unique_ptr<LoadBalancingPolicy::SubchannelCallTrackerInterface>
|
455
|
+
original_subchannel_call_tracker,
|
456
|
+
RefCountedPtr<SubchannelState> subchannel_state)
|
457
|
+
: original_subchannel_call_tracker_(
|
458
|
+
std::move(original_subchannel_call_tracker)),
|
459
|
+
subchannel_state_(std::move(subchannel_state)) {}
|
460
|
+
|
461
|
+
~SubchannelCallTracker() override {
|
462
|
+
subchannel_state_.reset(DEBUG_LOCATION, "SubchannelCallTracker");
|
463
|
+
}
|
464
|
+
|
465
|
+
void Start() override {
|
466
|
+
// This tracker does not care about started calls only finished calls.
|
467
|
+
// Delegate if needed.
|
468
|
+
if (original_subchannel_call_tracker_ != nullptr) {
|
469
|
+
original_subchannel_call_tracker_->Start();
|
470
|
+
}
|
471
|
+
}
|
472
|
+
|
473
|
+
void Finish(FinishArgs args) override {
|
474
|
+
// Delegate if needed.
|
475
|
+
if (original_subchannel_call_tracker_ != nullptr) {
|
476
|
+
original_subchannel_call_tracker_->Finish(args);
|
477
|
+
}
|
478
|
+
// Record call completion based on status for outlier detection
|
479
|
+
// calculations.
|
480
|
+
if (subchannel_state_ != nullptr) {
|
481
|
+
if (args.status.ok()) {
|
482
|
+
subchannel_state_->AddSuccessCount();
|
483
|
+
} else {
|
484
|
+
subchannel_state_->AddFailureCount();
|
485
|
+
}
|
486
|
+
}
|
487
|
+
}
|
488
|
+
|
489
|
+
private:
|
490
|
+
std::unique_ptr<LoadBalancingPolicy::SubchannelCallTrackerInterface>
|
491
|
+
original_subchannel_call_tracker_;
|
492
|
+
RefCountedPtr<SubchannelState> subchannel_state_;
|
493
|
+
};
|
494
|
+
|
495
|
+
//
|
496
|
+
// OutlierDetectionLb::Picker
|
497
|
+
//
|
498
|
+
|
499
|
+
OutlierDetectionLb::Picker::Picker(OutlierDetectionLb* outlier_detection_lb,
|
500
|
+
RefCountedPtr<RefCountedPicker> picker,
|
501
|
+
bool counting_enabled)
|
502
|
+
: picker_(std::move(picker)), counting_enabled_(counting_enabled) {
|
503
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_outlier_detection_lb_trace)) {
|
504
|
+
gpr_log(GPR_INFO,
|
505
|
+
"[outlier_detection_lb %p] constructed new picker %p and counting "
|
506
|
+
"is %s",
|
507
|
+
outlier_detection_lb, this,
|
508
|
+
(counting_enabled ? "enabled" : "disabled"));
|
509
|
+
}
|
510
|
+
}
|
511
|
+
|
512
|
+
LoadBalancingPolicy::PickResult OutlierDetectionLb::Picker::Pick(
|
513
|
+
LoadBalancingPolicy::PickArgs args) {
|
514
|
+
if (picker_ == nullptr) { // Should never happen.
|
515
|
+
return PickResult::Fail(absl::InternalError(
|
516
|
+
"outlier_detection picker not given any child picker"));
|
517
|
+
}
|
518
|
+
// Delegate to child picker
|
519
|
+
PickResult result = picker_->Pick(args);
|
520
|
+
auto* complete_pick = absl::get_if<PickResult::Complete>(&result.result);
|
521
|
+
if (complete_pick != nullptr) {
|
522
|
+
// Unwrap subchannel to pass back up the stack.
|
523
|
+
auto* subchannel_wrapper =
|
524
|
+
static_cast<SubchannelWrapper*>(complete_pick->subchannel.get());
|
525
|
+
// Inject subchannel call tracker to record call completion as long as
|
526
|
+
// not both success_rate_ejection and failure_percentage_ejection are unset.
|
527
|
+
if (counting_enabled_) {
|
528
|
+
complete_pick->subchannel_call_tracker =
|
529
|
+
absl::make_unique<SubchannelCallTracker>(
|
530
|
+
std::move(complete_pick->subchannel_call_tracker),
|
531
|
+
subchannel_wrapper->subchannel_state());
|
532
|
+
}
|
533
|
+
complete_pick->subchannel = subchannel_wrapper->wrapped_subchannel();
|
534
|
+
}
|
535
|
+
return result;
|
536
|
+
}
|
537
|
+
|
538
|
+
//
|
539
|
+
// OutlierDetectionLb
|
540
|
+
//
|
541
|
+
|
542
|
+
OutlierDetectionLb::OutlierDetectionLb(Args args)
|
543
|
+
: LoadBalancingPolicy(std::move(args)) {
|
544
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_outlier_detection_lb_trace)) {
|
545
|
+
gpr_log(GPR_INFO, "[outlier_detection_lb %p] created", this);
|
546
|
+
}
|
547
|
+
}
|
548
|
+
|
549
|
+
OutlierDetectionLb::~OutlierDetectionLb() {
|
550
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_outlier_detection_lb_trace)) {
|
551
|
+
gpr_log(GPR_INFO,
|
552
|
+
"[outlier_detection_lb %p] destroying outlier_detection LB policy",
|
553
|
+
this);
|
554
|
+
}
|
555
|
+
}
|
556
|
+
|
557
|
+
std::string OutlierDetectionLb::MakeKeyForAddress(
|
558
|
+
const ServerAddress& address) {
|
559
|
+
// Strip off attributes to construct the key.
|
560
|
+
return ServerAddress(address.address(),
|
561
|
+
grpc_channel_args_copy(address.args()))
|
562
|
+
.ToString();
|
563
|
+
}
|
564
|
+
|
565
|
+
void OutlierDetectionLb::ShutdownLocked() {
|
566
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_outlier_detection_lb_trace)) {
|
567
|
+
gpr_log(GPR_INFO, "[outlier_detection_lb %p] shutting down", this);
|
568
|
+
}
|
569
|
+
ejection_timer_.reset();
|
570
|
+
shutting_down_ = true;
|
571
|
+
// Remove the child policy's interested_parties pollset_set from the
|
572
|
+
// xDS policy.
|
573
|
+
if (child_policy_ != nullptr) {
|
574
|
+
grpc_pollset_set_del_pollset_set(child_policy_->interested_parties(),
|
575
|
+
interested_parties());
|
576
|
+
child_policy_.reset();
|
577
|
+
}
|
578
|
+
// Drop our ref to the child's picker, in case it's holding a ref to
|
579
|
+
// the child.
|
580
|
+
picker_.reset();
|
581
|
+
}
|
582
|
+
|
583
|
+
void OutlierDetectionLb::ExitIdleLocked() {
|
584
|
+
if (child_policy_ != nullptr) child_policy_->ExitIdleLocked();
|
585
|
+
}
|
586
|
+
|
587
|
+
void OutlierDetectionLb::ResetBackoffLocked() {
|
588
|
+
if (child_policy_ != nullptr) child_policy_->ResetBackoffLocked();
|
589
|
+
}
|
590
|
+
|
591
|
+
void OutlierDetectionLb::UpdateLocked(UpdateArgs args) {
|
592
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_outlier_detection_lb_trace)) {
|
593
|
+
gpr_log(GPR_INFO, "[outlier_detection_lb %p] Received update", this);
|
594
|
+
}
|
595
|
+
auto old_config = std::move(config_);
|
596
|
+
// Update config.
|
597
|
+
config_ = std::move(args.config);
|
598
|
+
// Update outlier detection timer.
|
599
|
+
if (!config_->CountingEnabled()) {
|
600
|
+
// No need for timer. Cancel the current timer, if any.
|
601
|
+
ejection_timer_.reset();
|
602
|
+
} else if (ejection_timer_ == nullptr) {
|
603
|
+
// No timer running. Start it now.
|
604
|
+
ejection_timer_ =
|
605
|
+
MakeOrphanable<EjectionTimer>(Ref(), ExecCtx::Get()->Now());
|
606
|
+
for (const auto& p : subchannel_state_map_) {
|
607
|
+
p.second->RotateBucket(); // Reset call counters.
|
608
|
+
}
|
609
|
+
} else if (old_config->outlier_detection_config().interval !=
|
610
|
+
config_->outlier_detection_config().interval) {
|
611
|
+
// Timer interval changed. Cancel the current timer and start a new one
|
612
|
+
// with the same start time.
|
613
|
+
// Note that if the new deadline is in the past, the timer will fire
|
614
|
+
// immediately.
|
615
|
+
ejection_timer_ =
|
616
|
+
MakeOrphanable<EjectionTimer>(Ref(), ejection_timer_->StartTime());
|
617
|
+
}
|
618
|
+
// Create policy if needed.
|
619
|
+
if (child_policy_ == nullptr) {
|
620
|
+
child_policy_ = CreateChildPolicyLocked(args.args);
|
621
|
+
}
|
622
|
+
if (args.addresses.ok()) {
|
623
|
+
std::set<std::string> current_addresses;
|
624
|
+
for (const ServerAddress& address : *args.addresses) {
|
625
|
+
std::string address_key = MakeKeyForAddress(address);
|
626
|
+
auto& subchannel_state = subchannel_state_map_[address_key];
|
627
|
+
if (subchannel_state == nullptr) {
|
628
|
+
subchannel_state = MakeRefCounted<SubchannelState>();
|
629
|
+
}
|
630
|
+
current_addresses.emplace(address_key);
|
631
|
+
}
|
632
|
+
for (auto it = subchannel_state_map_.begin();
|
633
|
+
it != subchannel_state_map_.end();) {
|
634
|
+
if (current_addresses.find(it->first) == current_addresses.end()) {
|
635
|
+
// remove each map entry for a subchannel address not in the updated
|
636
|
+
// address list.
|
637
|
+
it = subchannel_state_map_.erase(it);
|
638
|
+
} else {
|
639
|
+
++it;
|
640
|
+
}
|
641
|
+
}
|
642
|
+
}
|
643
|
+
// Construct update args.
|
644
|
+
UpdateArgs update_args;
|
645
|
+
update_args.addresses = std::move(args.addresses);
|
646
|
+
update_args.config = config_->child_policy();
|
647
|
+
update_args.args = grpc_channel_args_copy(args.args);
|
648
|
+
// Update the policy.
|
649
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_outlier_detection_lb_trace)) {
|
650
|
+
gpr_log(GPR_INFO,
|
651
|
+
"[outlier_detection_lb %p] Updating child policy handler %p", this,
|
652
|
+
child_policy_.get());
|
653
|
+
}
|
654
|
+
child_policy_->UpdateLocked(std::move(update_args));
|
655
|
+
}
|
656
|
+
|
657
|
+
void OutlierDetectionLb::MaybeUpdatePickerLocked() {
|
658
|
+
if (picker_ != nullptr) {
|
659
|
+
auto outlier_detection_picker =
|
660
|
+
absl::make_unique<Picker>(this, picker_, config_->CountingEnabled());
|
661
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_outlier_detection_lb_trace)) {
|
662
|
+
gpr_log(GPR_INFO,
|
663
|
+
"[outlier_detection_lb %p] updating connectivity: state=%s "
|
664
|
+
"status=(%s) picker=%p",
|
665
|
+
this, ConnectivityStateName(state_), status_.ToString().c_str(),
|
666
|
+
outlier_detection_picker.get());
|
667
|
+
}
|
668
|
+
channel_control_helper()->UpdateState(state_, status_,
|
669
|
+
std::move(outlier_detection_picker));
|
670
|
+
}
|
671
|
+
}
|
672
|
+
|
673
|
+
OrphanablePtr<LoadBalancingPolicy> OutlierDetectionLb::CreateChildPolicyLocked(
|
674
|
+
const grpc_channel_args* args) {
|
675
|
+
LoadBalancingPolicy::Args lb_policy_args;
|
676
|
+
lb_policy_args.work_serializer = work_serializer();
|
677
|
+
lb_policy_args.args = args;
|
678
|
+
lb_policy_args.channel_control_helper =
|
679
|
+
absl::make_unique<Helper>(Ref(DEBUG_LOCATION, "Helper"));
|
680
|
+
OrphanablePtr<LoadBalancingPolicy> lb_policy =
|
681
|
+
MakeOrphanable<ChildPolicyHandler>(std::move(lb_policy_args),
|
682
|
+
&grpc_outlier_detection_lb_trace);
|
683
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_outlier_detection_lb_trace)) {
|
684
|
+
gpr_log(GPR_INFO,
|
685
|
+
"[outlier_detection_lb %p] Created new child policy handler %p",
|
686
|
+
this, lb_policy.get());
|
687
|
+
}
|
688
|
+
// Add our interested_parties pollset_set to that of the newly created
|
689
|
+
// child policy. This will make the child policy progress upon activity on
|
690
|
+
// this policy, which in turn is tied to the application's call.
|
691
|
+
grpc_pollset_set_add_pollset_set(lb_policy->interested_parties(),
|
692
|
+
interested_parties());
|
693
|
+
return lb_policy;
|
694
|
+
}
|
695
|
+
|
696
|
+
//
|
697
|
+
// OutlierDetectionLb::Helper
|
698
|
+
//
|
699
|
+
|
700
|
+
RefCountedPtr<SubchannelInterface> OutlierDetectionLb::Helper::CreateSubchannel(
|
701
|
+
ServerAddress address, const grpc_channel_args& args) {
|
702
|
+
if (outlier_detection_policy_->shutting_down_) return nullptr;
|
703
|
+
std::string key = MakeKeyForAddress(address);
|
704
|
+
RefCountedPtr<SubchannelState> subchannel_state;
|
705
|
+
auto it = outlier_detection_policy_->subchannel_state_map_.find(key);
|
706
|
+
if (it != outlier_detection_policy_->subchannel_state_map_.end()) {
|
707
|
+
subchannel_state = it->second->Ref();
|
708
|
+
}
|
709
|
+
auto subchannel = MakeRefCounted<SubchannelWrapper>(
|
710
|
+
subchannel_state,
|
711
|
+
outlier_detection_policy_->channel_control_helper()->CreateSubchannel(
|
712
|
+
std::move(address), args));
|
713
|
+
if (subchannel_state != nullptr) {
|
714
|
+
subchannel_state->AddSubchannel(subchannel.get());
|
715
|
+
}
|
716
|
+
return subchannel;
|
717
|
+
}
|
718
|
+
|
719
|
+
void OutlierDetectionLb::Helper::UpdateState(
|
720
|
+
grpc_connectivity_state state, const absl::Status& status,
|
721
|
+
std::unique_ptr<SubchannelPicker> picker) {
|
722
|
+
if (outlier_detection_policy_->shutting_down_) return;
|
723
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_outlier_detection_lb_trace)) {
|
724
|
+
gpr_log(GPR_INFO,
|
725
|
+
"[outlier_detection_lb %p] child connectivity state update: "
|
726
|
+
"state=%s (%s) "
|
727
|
+
"picker=%p",
|
728
|
+
outlier_detection_policy_.get(), ConnectivityStateName(state),
|
729
|
+
status.ToString().c_str(), picker.get());
|
730
|
+
}
|
731
|
+
// Save the state and picker.
|
732
|
+
outlier_detection_policy_->state_ = state;
|
733
|
+
outlier_detection_policy_->status_ = status;
|
734
|
+
outlier_detection_policy_->picker_ =
|
735
|
+
MakeRefCounted<RefCountedPicker>(std::move(picker));
|
736
|
+
// Wrap the picker and return it to the channel.
|
737
|
+
outlier_detection_policy_->MaybeUpdatePickerLocked();
|
738
|
+
}
|
739
|
+
|
740
|
+
void OutlierDetectionLb::Helper::RequestReresolution() {
|
741
|
+
if (outlier_detection_policy_->shutting_down_) return;
|
742
|
+
outlier_detection_policy_->channel_control_helper()->RequestReresolution();
|
743
|
+
}
|
744
|
+
|
745
|
+
absl::string_view OutlierDetectionLb::Helper::GetAuthority() {
|
746
|
+
return outlier_detection_policy_->channel_control_helper()->GetAuthority();
|
747
|
+
}
|
748
|
+
|
749
|
+
void OutlierDetectionLb::Helper::AddTraceEvent(TraceSeverity severity,
|
750
|
+
absl::string_view message) {
|
751
|
+
if (outlier_detection_policy_->shutting_down_) return;
|
752
|
+
outlier_detection_policy_->channel_control_helper()->AddTraceEvent(severity,
|
753
|
+
message);
|
754
|
+
}
|
755
|
+
|
756
|
+
//
|
757
|
+
// OutlierDetectionLb::EjectionTimer
|
758
|
+
//
|
759
|
+
|
760
|
+
OutlierDetectionLb::EjectionTimer::EjectionTimer(
|
761
|
+
RefCountedPtr<OutlierDetectionLb> parent, Timestamp start_time)
|
762
|
+
: parent_(std::move(parent)), start_time_(start_time) {
|
763
|
+
GRPC_CLOSURE_INIT(&on_timer_, OnTimer, this, nullptr);
|
764
|
+
Ref().release();
|
765
|
+
grpc_timer_init(
|
766
|
+
&timer_,
|
767
|
+
start_time_ + parent_->config_->outlier_detection_config().interval,
|
768
|
+
&on_timer_);
|
769
|
+
}
|
770
|
+
|
771
|
+
void OutlierDetectionLb::EjectionTimer::Orphan() {
|
772
|
+
if (timer_pending_) {
|
773
|
+
timer_pending_ = false;
|
774
|
+
grpc_timer_cancel(&timer_);
|
775
|
+
}
|
776
|
+
Unref();
|
777
|
+
}
|
778
|
+
|
779
|
+
void OutlierDetectionLb::EjectionTimer::OnTimer(void* arg,
|
780
|
+
grpc_error_handle error) {
|
781
|
+
auto* self = static_cast<EjectionTimer*>(arg);
|
782
|
+
(void)GRPC_ERROR_REF(error); // ref owned by lambda
|
783
|
+
self->parent_->work_serializer()->Run(
|
784
|
+
[self, error]() { self->OnTimerLocked(error); }, DEBUG_LOCATION);
|
785
|
+
}
|
786
|
+
|
787
|
+
void OutlierDetectionLb::EjectionTimer::OnTimerLocked(grpc_error_handle error) {
|
788
|
+
if (error == GRPC_ERROR_NONE && timer_pending_) {
|
789
|
+
std::map<SubchannelState*, double> success_rate_ejection_candidates;
|
790
|
+
std::map<SubchannelState*, double> failure_percentage_ejection_candidates;
|
791
|
+
size_t ejected_host_count = 0;
|
792
|
+
double success_rate_sum = 0;
|
793
|
+
auto time_now = ExecCtx::Get()->Now();
|
794
|
+
auto& config = parent_->config_->outlier_detection_config();
|
795
|
+
for (auto& state : parent_->subchannel_state_map_) {
|
796
|
+
auto* subchannel_state = state.second.get();
|
797
|
+
// For each address, swap the call counter's buckets in that address's
|
798
|
+
// map entry.
|
799
|
+
subchannel_state->RotateBucket();
|
800
|
+
// Gather data to run success rate algorithm or failure percentage
|
801
|
+
// algorithm.
|
802
|
+
if (subchannel_state->ejection_time().has_value()) {
|
803
|
+
++ejected_host_count;
|
804
|
+
}
|
805
|
+
absl::optional<std::pair<double, uint64_t>> host_success_rate_and_volume =
|
806
|
+
subchannel_state->GetSuccessRateAndVolume();
|
807
|
+
if (!host_success_rate_and_volume.has_value()) {
|
808
|
+
continue;
|
809
|
+
}
|
810
|
+
double success_rate = host_success_rate_and_volume->first;
|
811
|
+
uint64_t request_volume = host_success_rate_and_volume->second;
|
812
|
+
if (config.success_rate_ejection.has_value()) {
|
813
|
+
if (request_volume >= config.success_rate_ejection->request_volume) {
|
814
|
+
success_rate_ejection_candidates[subchannel_state] = success_rate;
|
815
|
+
success_rate_sum += success_rate;
|
816
|
+
}
|
817
|
+
}
|
818
|
+
if (config.failure_percentage_ejection.has_value()) {
|
819
|
+
if (request_volume >=
|
820
|
+
config.failure_percentage_ejection->request_volume) {
|
821
|
+
failure_percentage_ejection_candidates[subchannel_state] =
|
822
|
+
success_rate;
|
823
|
+
}
|
824
|
+
}
|
825
|
+
}
|
826
|
+
// success rate algorithm
|
827
|
+
if (!success_rate_ejection_candidates.empty() &&
|
828
|
+
success_rate_ejection_candidates.size() >=
|
829
|
+
config.success_rate_ejection->minimum_hosts) {
|
830
|
+
// calculate ejection threshold: (mean - stdev *
|
831
|
+
// (success_rate_ejection.stdev_factor / 1000))
|
832
|
+
double mean = success_rate_sum / success_rate_ejection_candidates.size();
|
833
|
+
double variance = 0;
|
834
|
+
std::for_each(success_rate_ejection_candidates.begin(),
|
835
|
+
success_rate_ejection_candidates.end(),
|
836
|
+
[&variance, mean](std::pair<SubchannelState*, double> v) {
|
837
|
+
variance += std::pow(v.second - mean, 2);
|
838
|
+
});
|
839
|
+
variance /= success_rate_ejection_candidates.size();
|
840
|
+
double stdev = std::sqrt(variance);
|
841
|
+
const double success_rate_stdev_factor =
|
842
|
+
static_cast<double>(config.success_rate_ejection->stdev_factor) /
|
843
|
+
1000;
|
844
|
+
double ejection_threshold = mean - stdev * success_rate_stdev_factor;
|
845
|
+
for (auto& candidate : success_rate_ejection_candidates) {
|
846
|
+
if (candidate.second < ejection_threshold) {
|
847
|
+
uint32_t random_key = absl::Uniform(bit_gen_, 1, 100);
|
848
|
+
double current_percent = 100.0 * ejected_host_count /
|
849
|
+
parent_->subchannel_state_map_.size();
|
850
|
+
if (random_key <
|
851
|
+
config.success_rate_ejection->enforcement_percentage &&
|
852
|
+
(ejected_host_count == 0 ||
|
853
|
+
(current_percent < config.max_ejection_percent))) {
|
854
|
+
// Eject and record the timestamp for use when ejecting addresses in
|
855
|
+
// this iteration.
|
856
|
+
candidate.first->Eject(time_now);
|
857
|
+
++ejected_host_count;
|
858
|
+
}
|
859
|
+
}
|
860
|
+
}
|
861
|
+
}
|
862
|
+
// failure percentage algorithm
|
863
|
+
if (!failure_percentage_ejection_candidates.empty() &&
|
864
|
+
failure_percentage_ejection_candidates.size() >=
|
865
|
+
config.failure_percentage_ejection->minimum_hosts) {
|
866
|
+
for (auto& candidate : failure_percentage_ejection_candidates) {
|
867
|
+
// Extra check to make sure success rate algorithm didn't already
|
868
|
+
// eject this backend.
|
869
|
+
if (candidate.first->ejection_time().has_value()) continue;
|
870
|
+
if ((100.0 - candidate.second) >
|
871
|
+
config.failure_percentage_ejection->threshold) {
|
872
|
+
uint32_t random_key = absl::Uniform(bit_gen_, 1, 100);
|
873
|
+
double current_percent = 100.0 * ejected_host_count /
|
874
|
+
parent_->subchannel_state_map_.size();
|
875
|
+
if (random_key <
|
876
|
+
config.failure_percentage_ejection->enforcement_percentage &&
|
877
|
+
(ejected_host_count == 0 ||
|
878
|
+
(current_percent < config.max_ejection_percent))) {
|
879
|
+
// Eject and record the timestamp for use when ejecting addresses in
|
880
|
+
// this iteration.
|
881
|
+
candidate.first->Eject(time_now);
|
882
|
+
++ejected_host_count;
|
883
|
+
}
|
884
|
+
}
|
885
|
+
}
|
886
|
+
}
|
887
|
+
// For each address in the map:
|
888
|
+
// If the address is not ejected and the multiplier is greater than 0,
|
889
|
+
// decrease the multiplier by 1. If the address is ejected, and the
|
890
|
+
// current time is after ejection_timestamp + min(base_ejection_time *
|
891
|
+
// multiplier, max(base_ejection_time, max_ejection_time)), un-eject the
|
892
|
+
// address.
|
893
|
+
for (auto& state : parent_->subchannel_state_map_) {
|
894
|
+
auto* subchannel_state = state.second.get();
|
895
|
+
subchannel_state->MaybeUneject(config.base_ejection_time.millis(),
|
896
|
+
config.max_ejection_time.millis());
|
897
|
+
}
|
898
|
+
timer_pending_ = false;
|
899
|
+
parent_->ejection_timer_ =
|
900
|
+
MakeOrphanable<EjectionTimer>(parent_, ExecCtx::Get()->Now());
|
901
|
+
}
|
902
|
+
Unref(DEBUG_LOCATION, "Timer");
|
903
|
+
GRPC_ERROR_UNREF(error);
|
904
|
+
}
|
905
|
+
|
906
|
+
//
|
907
|
+
// factory
|
908
|
+
//
|
909
|
+
|
910
|
+
class OutlierDetectionLbFactory : public LoadBalancingPolicyFactory {
|
911
|
+
public:
|
912
|
+
OrphanablePtr<LoadBalancingPolicy> CreateLoadBalancingPolicy(
|
913
|
+
LoadBalancingPolicy::Args args) const override {
|
914
|
+
return MakeOrphanable<OutlierDetectionLb>(std::move(args));
|
915
|
+
}
|
916
|
+
|
917
|
+
const char* name() const override { return kOutlierDetection; }
|
918
|
+
|
919
|
+
RefCountedPtr<LoadBalancingPolicy::Config> ParseLoadBalancingConfig(
|
920
|
+
const Json& json, grpc_error_handle* error) const override {
|
921
|
+
GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE);
|
922
|
+
if (json.type() == Json::Type::JSON_NULL) {
|
923
|
+
// This policy was configured in the deprecated loadBalancingPolicy
|
924
|
+
// field or in the client API.
|
925
|
+
*error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
926
|
+
"field:loadBalancingPolicy error:outlier_detection policy requires "
|
927
|
+
"configuration. Please use loadBalancingConfig field of service "
|
928
|
+
"config instead.");
|
929
|
+
return nullptr;
|
930
|
+
}
|
931
|
+
std::vector<grpc_error_handle> error_list;
|
932
|
+
// Outlier detection config
|
933
|
+
OutlierDetectionConfig outlier_detection_config;
|
934
|
+
auto it = json.object_value().find("successRateEjection");
|
935
|
+
if (it != json.object_value().end()) {
|
936
|
+
if (it->second.type() != Json::Type::OBJECT) {
|
937
|
+
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
938
|
+
"field:successRateEjection error:type must be object"));
|
939
|
+
} else {
|
940
|
+
OutlierDetectionConfig::SuccessRateEjection success_config;
|
941
|
+
const Json::Object& object = it->second.object_value();
|
942
|
+
ParseJsonObjectField(object, "stdevFactor",
|
943
|
+
&success_config.stdev_factor, &error_list,
|
944
|
+
/*required=*/false);
|
945
|
+
ParseJsonObjectField(object, "enforcementPercentage",
|
946
|
+
&success_config.enforcement_percentage,
|
947
|
+
&error_list, /*required=*/false);
|
948
|
+
ParseJsonObjectField(object, "minimumHosts",
|
949
|
+
&success_config.minimum_hosts, &error_list,
|
950
|
+
/*required=*/false);
|
951
|
+
ParseJsonObjectField(object, "requestVolume",
|
952
|
+
&success_config.request_volume, &error_list,
|
953
|
+
/*required=*/false);
|
954
|
+
outlier_detection_config.success_rate_ejection = success_config;
|
955
|
+
}
|
956
|
+
}
|
957
|
+
it = json.object_value().find("failurePercentageEjection");
|
958
|
+
if (it != json.object_value().end()) {
|
959
|
+
if (it->second.type() != Json::Type::OBJECT) {
|
960
|
+
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
961
|
+
"field:successRateEjection error:type must be object"));
|
962
|
+
} else {
|
963
|
+
OutlierDetectionConfig::FailurePercentageEjection failure_config;
|
964
|
+
const Json::Object& object = it->second.object_value();
|
965
|
+
ParseJsonObjectField(object, "threshold", &failure_config.threshold,
|
966
|
+
&error_list, /*required=*/false);
|
967
|
+
ParseJsonObjectField(object, "enforcementPercentage",
|
968
|
+
&failure_config.enforcement_percentage,
|
969
|
+
&error_list, /*required=*/false);
|
970
|
+
ParseJsonObjectField(object, "minimumHosts",
|
971
|
+
&failure_config.minimum_hosts, &error_list,
|
972
|
+
/*required=*/false);
|
973
|
+
ParseJsonObjectField(object, "requestVolume",
|
974
|
+
&failure_config.request_volume, &error_list,
|
975
|
+
/*required=*/false);
|
976
|
+
outlier_detection_config.failure_percentage_ejection = failure_config;
|
977
|
+
}
|
978
|
+
}
|
979
|
+
ParseJsonObjectFieldAsDuration(json.object_value(), "interval",
|
980
|
+
&outlier_detection_config.interval,
|
981
|
+
&error_list);
|
982
|
+
ParseJsonObjectFieldAsDuration(json.object_value(), "baseEjectionTime",
|
983
|
+
&outlier_detection_config.base_ejection_time,
|
984
|
+
&error_list, /*required=*/false);
|
985
|
+
if (!ParseJsonObjectFieldAsDuration(
|
986
|
+
json.object_value(), "maxEjectionTime",
|
987
|
+
&outlier_detection_config.max_ejection_time, &error_list,
|
988
|
+
/*required=*/false)) {
|
989
|
+
outlier_detection_config.max_ejection_time = std::max(
|
990
|
+
outlier_detection_config.base_ejection_time, Duration::Seconds(300));
|
991
|
+
}
|
992
|
+
ParseJsonObjectField(json.object_value(), "maxEjectionPercent",
|
993
|
+
&outlier_detection_config.max_ejection_percent,
|
994
|
+
&error_list, /*required=*/false);
|
995
|
+
RefCountedPtr<LoadBalancingPolicy::Config> child_policy;
|
996
|
+
it = json.object_value().find("childPolicy");
|
997
|
+
if (it == json.object_value().end()) {
|
998
|
+
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
999
|
+
"field:childPolicy error:required field missing"));
|
1000
|
+
} else {
|
1001
|
+
grpc_error_handle parse_error = GRPC_ERROR_NONE;
|
1002
|
+
child_policy = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(
|
1003
|
+
it->second, &parse_error);
|
1004
|
+
if (child_policy == nullptr) {
|
1005
|
+
GPR_DEBUG_ASSERT(parse_error != GRPC_ERROR_NONE);
|
1006
|
+
std::vector<grpc_error_handle> child_errors;
|
1007
|
+
child_errors.push_back(parse_error);
|
1008
|
+
error_list.push_back(
|
1009
|
+
GRPC_ERROR_CREATE_FROM_VECTOR("field:childPolicy", &child_errors));
|
1010
|
+
}
|
1011
|
+
}
|
1012
|
+
if (!error_list.empty()) {
|
1013
|
+
*error = GRPC_ERROR_CREATE_FROM_VECTOR(
|
1014
|
+
"outlier_detection_experimental LB policy config", &error_list);
|
1015
|
+
return nullptr;
|
1016
|
+
}
|
1017
|
+
return MakeRefCounted<OutlierDetectionLbConfig>(outlier_detection_config,
|
1018
|
+
std::move(child_policy));
|
1019
|
+
}
|
1020
|
+
};
|
1021
|
+
|
1022
|
+
} // namespace
|
1023
|
+
|
1024
|
+
} // namespace grpc_core
|
1025
|
+
|
1026
|
+
//
|
1027
|
+
// Plugin registration
|
1028
|
+
//
|
1029
|
+
|
1030
|
+
void grpc_lb_policy_outlier_detection_init() {
|
1031
|
+
if (grpc_core::XdsOutlierDetectionEnabled()) {
|
1032
|
+
grpc_core::LoadBalancingPolicyRegistry::Builder::
|
1033
|
+
RegisterLoadBalancingPolicyFactory(
|
1034
|
+
absl::make_unique<grpc_core::OutlierDetectionLbFactory>());
|
1035
|
+
}
|
1036
|
+
}
|
1037
|
+
|
1038
|
+
void grpc_lb_policy_outlier_detection_shutdown() {}
|