grpc 1.49.0.pre1-x86_64-linux → 1.50.0.pre1-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 +54 -153
- data/include/grpc/event_engine/endpoint_config.h +11 -5
- data/include/grpc/event_engine/event_engine.h +1 -1
- data/include/grpc/impl/codegen/atm_gcc_atomic.h +19 -28
- data/include/grpc/impl/codegen/atm_gcc_sync.h +0 -2
- data/include/grpc/impl/codegen/atm_windows.h +0 -2
- data/include/grpc/impl/codegen/grpc_types.h +6 -0
- data/src/core/ext/filters/channel_idle/channel_idle_filter.cc +3 -3
- data/src/core/ext/filters/client_channel/backup_poller.cc +4 -6
- data/src/core/ext/filters/client_channel/client_channel.cc +41 -22
- data/src/core/ext/filters/client_channel/client_channel.h +1 -1
- data/src/core/ext/filters/client_channel/client_channel_plugin.cc +0 -16
- data/src/core/ext/filters/client_channel/http_proxy.cc +12 -19
- data/src/core/ext/filters/client_channel/http_proxy.h +3 -2
- data/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc +6 -4
- data/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.h +5 -4
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc +0 -2
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +114 -103
- data/src/core/ext/filters/client_channel/lb_policy/oob_backend_metric.cc +20 -11
- data/src/core/ext/filters/client_channel/lb_policy/outlier_detection/outlier_detection.cc +106 -108
- data/src/core/ext/filters/client_channel/lb_policy/outlier_detection/outlier_detection.h +16 -0
- data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +20 -13
- data/src/core/ext/filters/client_channel/lb_policy/priority/priority.cc +165 -257
- data/src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.cc +218 -231
- data/src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.h +10 -6
- data/src/core/ext/filters/client_channel/lb_policy/rls/rls.cc +389 -444
- data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +16 -16
- data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +8 -13
- data/src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc +87 -96
- data/src/core/ext/filters/client_channel/lb_policy/xds/cds.cc +38 -37
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc +106 -186
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc +106 -93
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc +170 -218
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +2 -2
- data/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +1 -1
- data/src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc +38 -18
- data/src/core/ext/filters/client_channel/resolver/polling_resolver.cc +84 -37
- data/src/core/ext/filters/client_channel/resolver/polling_resolver.h +11 -0
- data/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc +1 -0
- data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +5 -3
- data/src/core/ext/filters/client_channel/resolver_result_parsing.cc +5 -4
- data/src/core/ext/filters/client_channel/retry_filter.cc +25 -29
- data/src/core/ext/filters/client_channel/subchannel.cc +38 -33
- data/src/core/ext/filters/client_channel/subchannel.h +12 -3
- data/src/core/ext/filters/client_channel/subchannel_stream_client.cc +1 -2
- data/src/core/ext/filters/fault_injection/fault_injection_filter.cc +23 -16
- data/src/core/ext/filters/fault_injection/fault_injection_filter.h +8 -0
- data/src/core/ext/filters/http/client/http_client_filter.cc +1 -2
- data/src/core/ext/filters/http/message_compress/message_compress_filter.cc +2 -4
- data/src/core/ext/filters/http/message_compress/message_decompress_filter.cc +0 -2
- data/src/core/ext/filters/http/server/http_server_filter.cc +1 -2
- data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +12 -8
- data/src/core/ext/transport/chttp2/server/chttp2_server.cc +32 -26
- data/src/core/ext/transport/chttp2/transport/bin_encoder.cc +1 -1
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +25 -130
- data/src/core/ext/transport/chttp2/transport/decode_huff.cc +287 -0
- data/src/core/ext/transport/chttp2/transport/decode_huff.h +1018 -0
- data/src/core/ext/transport/chttp2/transport/flow_control.cc +83 -51
- data/src/core/ext/transport/chttp2/transport/flow_control.h +11 -6
- data/src/core/ext/transport/chttp2/transport/frame_ping.cc +1 -2
- data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +2 -20
- data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +28 -28
- data/src/core/ext/transport/chttp2/transport/hpack_parser_table.cc +1 -10
- data/src/core/ext/transport/chttp2/transport/hpack_parser_table.h +11 -6
- data/src/core/ext/transport/chttp2/transport/internal.h +2 -0
- data/src/core/ext/transport/chttp2/transport/parsing.cc +44 -0
- data/src/core/ext/transport/chttp2/transport/writing.cc +3 -14
- data/src/core/ext/transport/inproc/inproc_transport.cc +1 -3
- data/src/core/ext/xds/certificate_provider_store.cc +63 -3
- data/src/core/ext/xds/certificate_provider_store.h +9 -1
- data/src/core/ext/xds/file_watcher_certificate_provider_factory.cc +5 -5
- data/src/core/ext/xds/file_watcher_certificate_provider_factory.h +1 -1
- data/src/core/ext/xds/xds_api.cc +21 -17
- data/src/core/ext/xds/xds_api.h +7 -0
- data/src/core/ext/xds/xds_bootstrap.cc +5 -537
- data/src/core/ext/xds/xds_bootstrap.h +39 -111
- data/src/core/ext/xds/xds_bootstrap_grpc.cc +370 -0
- data/src/core/ext/xds/xds_bootstrap_grpc.h +169 -0
- data/src/core/ext/xds/xds_client.cc +219 -145
- data/src/core/ext/xds/xds_client.h +19 -17
- data/src/core/ext/xds/xds_client_grpc.cc +18 -80
- data/src/core/ext/xds/xds_client_grpc.h +2 -25
- data/src/core/ext/xds/xds_client_stats.cc +4 -4
- data/src/core/ext/xds/xds_cluster.cc +87 -79
- data/src/core/ext/xds/xds_cluster.h +5 -5
- data/src/core/ext/xds/xds_cluster_specifier_plugin.cc +3 -1
- data/src/core/ext/xds/xds_common_types.cc +13 -5
- data/src/core/ext/xds/xds_endpoint.cc +8 -6
- data/src/core/ext/xds/xds_endpoint.h +3 -4
- data/src/core/ext/xds/xds_lb_policy_registry.cc +4 -2
- data/src/core/ext/xds/xds_listener.cc +25 -20
- data/src/core/ext/xds/xds_listener.h +3 -4
- data/src/core/ext/xds/xds_resource_type.h +11 -8
- data/src/core/ext/xds/xds_route_config.cc +15 -16
- data/src/core/ext/xds/xds_route_config.h +3 -3
- data/src/core/ext/xds/xds_server_config_fetcher.cc +7 -5
- data/src/core/ext/xds/xds_transport_grpc.cc +15 -7
- data/src/core/lib/backoff/backoff.cc +2 -4
- data/src/core/lib/channel/call_finalization.h +1 -3
- data/src/core/lib/channel/channel_args.h +114 -14
- data/src/core/lib/channel/channel_trace.cc +3 -4
- data/src/core/lib/channel/promise_based_filter.cc +18 -19
- data/src/core/lib/channel/status_util.cc +27 -0
- data/src/core/lib/channel/status_util.h +10 -0
- data/src/core/lib/config/core_configuration.cc +5 -1
- data/src/core/lib/config/core_configuration.h +33 -0
- data/src/core/lib/debug/stats.cc +26 -30
- data/src/core/lib/debug/stats.h +2 -12
- data/src/core/lib/debug/stats_data.cc +118 -614
- data/src/core/lib/debug/stats_data.h +67 -465
- data/src/core/lib/debug/trace.cc +0 -2
- data/src/core/lib/event_engine/channel_args_endpoint_config.cc +12 -20
- data/src/core/lib/event_engine/channel_args_endpoint_config.h +13 -7
- data/src/core/lib/event_engine/forkable.cc +19 -16
- data/src/core/lib/event_engine/poller.h +14 -12
- data/src/core/lib/event_engine/posix_engine/timer_manager.cc +53 -32
- data/src/core/lib/event_engine/posix_engine/timer_manager.h +23 -1
- data/src/core/lib/event_engine/thread_pool.cc +131 -94
- data/src/core/lib/event_engine/thread_pool.h +56 -23
- data/src/core/lib/event_engine/time_util.cc +30 -0
- data/src/core/lib/event_engine/time_util.h +32 -0
- data/src/core/lib/event_engine/utils.cc +0 -5
- data/src/core/lib/event_engine/utils.h +0 -4
- data/src/core/lib/event_engine/windows/iocp.cc +13 -7
- data/src/core/lib/event_engine/windows/iocp.h +2 -1
- data/src/core/lib/event_engine/windows/win_socket.cc +1 -1
- data/src/core/lib/experiments/config.cc +146 -0
- data/src/core/lib/experiments/config.h +43 -0
- data/src/core/lib/experiments/experiments.cc +75 -0
- data/src/core/lib/experiments/experiments.h +56 -0
- data/src/core/lib/gpr/alloc.cc +1 -9
- data/src/core/lib/gpr/log_windows.cc +0 -1
- data/src/core/lib/gpr/string_util_windows.cc +3 -30
- data/src/core/lib/gpr/sync_abseil.cc +0 -14
- data/src/core/lib/gpr/sync_posix.cc +0 -14
- data/src/core/lib/gpr/time_posix.cc +0 -6
- data/src/core/lib/gpr/time_precise.h +1 -1
- data/src/core/lib/gpr/tmpfile_windows.cc +5 -7
- data/src/core/lib/gpr/useful.h +11 -0
- data/src/core/lib/{gpr → gprpp}/env.h +25 -12
- data/src/core/lib/{gpr → gprpp}/env_linux.cc +20 -15
- data/src/core/lib/{gpr → gprpp}/env_posix.cc +11 -10
- data/src/core/lib/gprpp/env_windows.cc +56 -0
- data/src/core/lib/gprpp/fork.cc +14 -22
- data/src/core/lib/gprpp/fork.h +0 -8
- data/src/core/lib/gprpp/global_config_env.cc +7 -6
- data/src/core/lib/gprpp/notification.h +67 -0
- data/src/core/lib/gprpp/packed_table.h +40 -0
- data/src/core/lib/gprpp/ref_counted_ptr.h +20 -33
- data/src/core/lib/gprpp/sorted_pack.h +98 -0
- data/src/core/lib/gprpp/status_helper.h +6 -0
- data/src/core/lib/gprpp/table.h +9 -1
- data/src/core/lib/gprpp/tchar.cc +49 -0
- data/src/core/lib/gprpp/tchar.h +33 -0
- data/src/core/lib/gprpp/time.cc +21 -0
- data/src/core/lib/gprpp/time.h +55 -0
- data/src/core/lib/gprpp/validation_errors.cc +61 -0
- data/src/core/lib/gprpp/validation_errors.h +110 -0
- data/src/core/{ext/filters/client_channel → lib/handshaker}/proxy_mapper.h +3 -3
- data/src/core/{ext/filters/client_channel → lib/handshaker}/proxy_mapper_registry.cc +14 -36
- data/src/core/lib/handshaker/proxy_mapper_registry.h +75 -0
- data/src/core/lib/iomgr/call_combiner.cc +0 -8
- data/src/core/lib/iomgr/closure.h +0 -1
- data/src/core/lib/iomgr/endpoint_pair_posix.cc +14 -10
- data/src/core/lib/iomgr/endpoint_pair_windows.cc +2 -2
- data/src/core/lib/iomgr/ev_epoll1_linux.cc +1 -38
- data/src/core/lib/iomgr/ev_poll_posix.cc +2 -17
- data/src/core/lib/iomgr/exec_ctx.cc +0 -10
- data/src/core/lib/iomgr/exec_ctx.h +7 -31
- data/src/core/lib/iomgr/iocp_windows.cc +1 -2
- data/src/core/lib/iomgr/iomgr.cc +6 -8
- data/src/core/lib/iomgr/iomgr_fwd.h +1 -0
- data/src/core/lib/iomgr/pollset.h +1 -1
- data/src/core/lib/iomgr/pollset_set.h +0 -1
- data/src/core/lib/iomgr/resolve_address.h +1 -0
- data/src/core/lib/iomgr/resolve_address_impl.h +1 -0
- data/src/core/lib/iomgr/resolve_address_posix.cc +5 -0
- data/src/core/lib/iomgr/resolve_address_windows.cc +5 -0
- data/src/core/lib/iomgr/sockaddr_utils_posix.cc +2 -1
- data/src/core/lib/iomgr/socket_utils_common_posix.cc +12 -34
- data/src/core/lib/iomgr/socket_utils_posix.cc +83 -1
- data/src/core/lib/iomgr/socket_utils_posix.h +98 -6
- data/src/core/lib/iomgr/tcp_client.cc +6 -7
- data/src/core/lib/iomgr/tcp_client.h +11 -11
- data/src/core/lib/iomgr/tcp_client_cfstream.cc +6 -6
- data/src/core/lib/iomgr/tcp_client_posix.cc +33 -29
- data/src/core/lib/iomgr/tcp_client_posix.h +12 -9
- data/src/core/lib/iomgr/tcp_client_windows.cc +6 -6
- data/src/core/lib/iomgr/tcp_posix.cc +131 -114
- data/src/core/lib/iomgr/tcp_posix.h +3 -1
- data/src/core/lib/iomgr/tcp_server.cc +5 -4
- data/src/core/lib/iomgr/tcp_server.h +9 -6
- data/src/core/lib/iomgr/tcp_server_posix.cc +17 -28
- data/src/core/lib/iomgr/tcp_server_utils_posix.h +2 -2
- data/src/core/lib/iomgr/tcp_server_utils_posix_common.cc +3 -3
- data/src/core/lib/iomgr/tcp_server_windows.cc +6 -7
- data/src/core/lib/iomgr/tcp_windows.cc +0 -1
- data/src/core/lib/iomgr/tcp_windows.h +0 -1
- data/src/core/lib/iomgr/timer_generic.cc +4 -4
- data/src/core/lib/iomgr/timer_manager.cc +1 -2
- data/src/core/lib/iomgr/wakeup_fd_eventfd.cc +0 -2
- data/src/core/lib/json/json_object_loader.cc +21 -52
- data/src/core/lib/json/json_object_loader.h +56 -76
- data/src/core/lib/json/json_util.cc +2 -1
- data/src/core/lib/load_balancing/lb_policy.h +5 -5
- data/src/core/lib/load_balancing/lb_policy_registry.cc +29 -55
- data/src/core/lib/load_balancing/lb_policy_registry.h +23 -11
- data/src/core/lib/promise/activity.h +2 -3
- data/src/core/lib/promise/context.h +1 -1
- data/src/core/lib/promise/sleep.cc +16 -4
- data/src/core/lib/promise/sleep.h +8 -2
- data/src/core/lib/resolver/resolver.h +13 -3
- data/src/core/lib/resource_quota/api.cc +9 -0
- data/src/core/lib/resource_quota/api.h +6 -0
- data/src/core/lib/resource_quota/arena.cc +1 -3
- data/src/core/lib/resource_quota/memory_quota.cc +8 -24
- data/src/core/lib/resource_quota/memory_quota.h +6 -19
- data/src/core/lib/resource_quota/periodic_update.cc +2 -3
- data/src/core/{ext/xds → lib/security/certificate_provider}/certificate_provider_factory.h +3 -3
- data/src/core/lib/security/certificate_provider/certificate_provider_registry.cc +60 -0
- data/src/core/lib/security/certificate_provider/certificate_provider_registry.h +70 -0
- data/src/core/lib/security/credentials/channel_creds_registry_init.cc +1 -0
- data/src/core/lib/security/credentials/external/aws_external_account_credentials.cc +15 -16
- data/src/core/lib/security/credentials/external/external_account_credentials.cc +2 -1
- data/src/core/lib/security/credentials/google_default/credentials_generic.cc +5 -8
- data/src/core/lib/security/credentials/google_default/google_default_credentials.cc +6 -6
- data/src/core/lib/security/credentials/jwt/jwt_verifier.cc +3 -2
- data/src/core/lib/security/credentials/jwt/jwt_verifier.h +1 -1
- data/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +1 -2
- data/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.cc +4 -3
- data/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h +4 -2
- data/src/core/lib/security/credentials/tls/tls_utils.cc +3 -1
- data/src/core/lib/security/transport/client_auth_filter.cc +12 -1
- data/src/core/lib/security/transport/secure_endpoint.cc +0 -4
- data/src/core/lib/surface/call.cc +1 -11
- data/src/core/lib/surface/channel.cc +3 -2
- data/src/core/lib/surface/completion_queue.cc +16 -28
- data/src/core/lib/surface/completion_queue.h +1 -1
- data/src/core/lib/surface/completion_queue_factory.cc +5 -0
- data/src/core/lib/surface/init.cc +16 -11
- data/src/core/lib/surface/init_internally.cc +24 -0
- data/src/core/lib/surface/init_internally.h +28 -0
- data/src/core/lib/surface/server.cc +1 -7
- data/src/core/lib/surface/server.h +4 -6
- data/src/core/lib/surface/version.cc +2 -2
- data/src/core/lib/transport/bdp_estimator.cc +1 -3
- data/src/core/lib/transport/metadata_batch.cc +2 -3
- data/src/core/lib/transport/metadata_batch.h +9 -7
- data/src/core/lib/transport/parsed_metadata.h +4 -2
- data/src/core/lib/transport/status_conversion.cc +1 -3
- data/src/core/lib/transport/tcp_connect_handshaker.cc +9 -5
- data/src/core/lib/transport/transport.h +0 -1
- data/src/core/lib/transport/transport_impl.h +0 -1
- data/src/core/plugin_registry/grpc_plugin_registry.cc +23 -46
- data/src/core/plugin_registry/grpc_plugin_registry_extra.cc +13 -25
- data/src/ruby/ext/grpc/extconf.rb +1 -1
- 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/src/ruby/spec/channel_spec.rb +5 -0
- data/src/ruby/spec/generic/server_interceptors_spec.rb +1 -1
- data/src/ruby/spec/user_agent_spec.rb +1 -1
- metadata +32 -19
- data/src/core/ext/filters/client_channel/proxy_mapper_registry.h +0 -56
- data/src/core/ext/xds/certificate_provider_registry.cc +0 -103
- data/src/core/ext/xds/certificate_provider_registry.h +0 -59
- data/src/core/lib/event_engine/promise.h +0 -78
- data/src/core/lib/gpr/env_windows.cc +0 -74
- data/src/core/lib/gpr/string_windows.h +0 -32
- data/src/core/lib/profiling/basic_timers.cc +0 -295
- data/src/core/lib/profiling/stap_timers.cc +0 -50
- data/src/core/lib/profiling/timers.h +0 -94
- data/src/ruby/lib/grpc/2.5/grpc_c.so +0 -0
@@ -24,7 +24,6 @@
|
|
24
24
|
#include <algorithm>
|
25
25
|
#include <atomic>
|
26
26
|
#include <cmath>
|
27
|
-
#include <map>
|
28
27
|
#include <memory>
|
29
28
|
#include <string>
|
30
29
|
#include <utility>
|
@@ -38,7 +37,6 @@
|
|
38
37
|
#include "absl/status/statusor.h"
|
39
38
|
#include "absl/strings/numbers.h"
|
40
39
|
#include "absl/strings/str_cat.h"
|
41
|
-
#include "absl/strings/str_join.h"
|
42
40
|
#include "absl/strings/string_view.h"
|
43
41
|
#include "absl/types/optional.h"
|
44
42
|
|
@@ -52,11 +50,10 @@
|
|
52
50
|
#include "src/core/ext/filters/client_channel/lb_policy/subchannel_list.h"
|
53
51
|
#include "src/core/lib/address_utils/sockaddr_utils.h"
|
54
52
|
#include "src/core/lib/channel/channel_args.h"
|
53
|
+
#include "src/core/lib/config/core_configuration.h"
|
55
54
|
#include "src/core/lib/debug/trace.h"
|
56
|
-
#include "src/core/lib/gpr/string.h"
|
57
55
|
#include "src/core/lib/gprpp/debug_location.h"
|
58
56
|
#include "src/core/lib/gprpp/orphanable.h"
|
59
|
-
#include "src/core/lib/gprpp/ref_counted.h"
|
60
57
|
#include "src/core/lib/gprpp/ref_counted_ptr.h"
|
61
58
|
#include "src/core/lib/gprpp/sync.h"
|
62
59
|
#include "src/core/lib/gprpp/unique_type_name.h"
|
@@ -82,49 +79,35 @@ UniqueTypeName RequestHashAttributeName() {
|
|
82
79
|
}
|
83
80
|
|
84
81
|
// Helper Parser method
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
82
|
+
|
83
|
+
const JsonLoaderInterface* RingHashConfig::JsonLoader(const JsonArgs&) {
|
84
|
+
static const auto* loader =
|
85
|
+
JsonObjectLoader<RingHashConfig>()
|
86
|
+
.OptionalField("min_ring_size", &RingHashConfig::min_ring_size)
|
87
|
+
.OptionalField("max_ring_size", &RingHashConfig::max_ring_size)
|
88
|
+
.Finish();
|
89
|
+
return loader;
|
90
|
+
}
|
91
|
+
|
92
|
+
void RingHashConfig::JsonPostLoad(const Json&, const JsonArgs&,
|
93
|
+
ValidationErrors* errors) {
|
94
|
+
{
|
95
|
+
ValidationErrors::ScopedField field(errors, ".min_ring_size");
|
96
|
+
if (!errors->FieldHasErrors() &&
|
97
|
+
(min_ring_size == 0 || min_ring_size > 8388608)) {
|
98
|
+
errors->AddError("must be in the range [1, 8388608]");
|
101
99
|
}
|
102
100
|
}
|
103
|
-
|
104
|
-
|
105
|
-
if (
|
106
|
-
|
107
|
-
|
108
|
-
} else {
|
109
|
-
config.max_ring_size = gpr_parse_nonnegative_int(
|
110
|
-
ring_hash_it->second.string_value().c_str());
|
101
|
+
{
|
102
|
+
ValidationErrors::ScopedField field(errors, ".max_ring_size");
|
103
|
+
if (!errors->FieldHasErrors() &&
|
104
|
+
(max_ring_size == 0 || max_ring_size > 8388608)) {
|
105
|
+
errors->AddError("must be in the range [1, 8388608]");
|
111
106
|
}
|
112
107
|
}
|
113
|
-
if (
|
114
|
-
|
115
|
-
config.min_ring_size > config.max_ring_size) {
|
116
|
-
errors.emplace_back(
|
117
|
-
"field:max_ring_size and or min_ring_size error: "
|
118
|
-
"values need to be in the range of 1 to 8388608 "
|
119
|
-
"and max_ring_size cannot be smaller than "
|
120
|
-
"min_ring_size");
|
108
|
+
if (min_ring_size > max_ring_size) {
|
109
|
+
errors->AddError("max_ring_size cannot be smaller than min_ring_size");
|
121
110
|
}
|
122
|
-
if (!errors.empty()) {
|
123
|
-
return absl::InvalidArgumentError(
|
124
|
-
absl::StrCat("errors parsing ring hash LB config: [",
|
125
|
-
absl::StrJoin(errors, "; "), "]"));
|
126
|
-
}
|
127
|
-
return config;
|
128
111
|
}
|
129
112
|
|
130
113
|
namespace {
|
@@ -154,15 +137,14 @@ class RingHash : public LoadBalancingPolicy {
|
|
154
137
|
|
155
138
|
absl::string_view name() const override { return kRingHash; }
|
156
139
|
|
157
|
-
|
140
|
+
absl::Status UpdateLocked(UpdateArgs args) override;
|
158
141
|
void ResetBackoffLocked() override;
|
159
142
|
|
160
143
|
private:
|
161
144
|
~RingHash() override;
|
162
145
|
|
163
|
-
// Forward
|
146
|
+
// Forward declaration.
|
164
147
|
class RingHashSubchannelList;
|
165
|
-
class Ring;
|
166
148
|
|
167
149
|
// Data for a particular subchannel in a subchannel list.
|
168
150
|
// This subclass adds the following functionality:
|
@@ -211,32 +193,25 @@ class RingHash : public LoadBalancingPolicy {
|
|
211
193
|
absl::Status connectivity_status_ ABSL_GUARDED_BY(&mu_);
|
212
194
|
};
|
213
195
|
|
214
|
-
// A list of subchannels.
|
196
|
+
// A list of subchannels and the ring containing those subchannels.
|
215
197
|
class RingHashSubchannelList
|
216
198
|
: public SubchannelList<RingHashSubchannelList, RingHashSubchannelData> {
|
217
199
|
public:
|
200
|
+
struct RingEntry {
|
201
|
+
uint64_t hash;
|
202
|
+
RingHashSubchannelData* subchannel;
|
203
|
+
};
|
204
|
+
|
218
205
|
RingHashSubchannelList(RingHash* policy, ServerAddressList addresses,
|
219
|
-
const ChannelArgs& args)
|
220
|
-
: SubchannelList(policy,
|
221
|
-
(GRPC_TRACE_FLAG_ENABLED(grpc_lb_ring_hash_trace)
|
222
|
-
? "RingHashSubchannelList"
|
223
|
-
: nullptr),
|
224
|
-
std::move(addresses), policy->channel_control_helper(),
|
225
|
-
args),
|
226
|
-
num_idle_(num_subchannels()),
|
227
|
-
ring_(MakeRefCounted<Ring>(policy, Ref(DEBUG_LOCATION, "Ring"))) {
|
228
|
-
// Need to maintain a ref to the LB policy as long as we maintain
|
229
|
-
// any references to subchannels, since the subchannels'
|
230
|
-
// pollset_sets will include the LB policy's pollset_set.
|
231
|
-
policy->Ref(DEBUG_LOCATION, "subchannel_list").release();
|
232
|
-
}
|
206
|
+
const ChannelArgs& args);
|
233
207
|
|
234
208
|
~RingHashSubchannelList() override {
|
235
|
-
ring_.reset(DEBUG_LOCATION, "~RingHashSubchannelList");
|
236
209
|
RingHash* p = static_cast<RingHash*>(policy());
|
237
210
|
p->Unref(DEBUG_LOCATION, "subchannel_list");
|
238
211
|
}
|
239
212
|
|
213
|
+
const std::vector<RingEntry>& ring() const { return ring_; }
|
214
|
+
|
240
215
|
// Updates the counters of subchannels in each state when a
|
241
216
|
// subchannel transitions from old_state to new_state.
|
242
217
|
void UpdateStateCountersLocked(grpc_connectivity_state old_state,
|
@@ -261,17 +236,12 @@ class RingHash : public LoadBalancingPolicy {
|
|
261
236
|
return true;
|
262
237
|
}
|
263
238
|
|
264
|
-
void ShutdownLocked() override {
|
265
|
-
ring_.reset(DEBUG_LOCATION, "RingHashSubchannelList::ShutdownLocked()");
|
266
|
-
SubchannelList::ShutdownLocked();
|
267
|
-
}
|
268
|
-
|
269
239
|
size_t num_idle_;
|
270
240
|
size_t num_ready_ = 0;
|
271
241
|
size_t num_connecting_ = 0;
|
272
242
|
size_t num_transient_failure_ = 0;
|
273
243
|
|
274
|
-
|
244
|
+
std::vector<RingEntry> ring_;
|
275
245
|
|
276
246
|
// The index of the subchannel currently doing an internally
|
277
247
|
// triggered connection attempt, if any.
|
@@ -284,73 +254,83 @@ class RingHash : public LoadBalancingPolicy {
|
|
284
254
|
absl::Status last_failure_;
|
285
255
|
};
|
286
256
|
|
287
|
-
class Ring : public RefCounted<Ring> {
|
288
|
-
public:
|
289
|
-
struct Entry {
|
290
|
-
uint64_t hash;
|
291
|
-
RingHashSubchannelData* subchannel;
|
292
|
-
};
|
293
|
-
|
294
|
-
Ring(RingHash* parent,
|
295
|
-
RefCountedPtr<RingHashSubchannelList> subchannel_list);
|
296
|
-
|
297
|
-
const std::vector<Entry>& ring() const { return ring_; }
|
298
|
-
|
299
|
-
private:
|
300
|
-
RefCountedPtr<RingHashSubchannelList> subchannel_list_;
|
301
|
-
std::vector<Entry> ring_;
|
302
|
-
};
|
303
|
-
|
304
257
|
class Picker : public SubchannelPicker {
|
305
258
|
public:
|
306
|
-
Picker(RefCountedPtr<
|
307
|
-
:
|
259
|
+
explicit Picker(RefCountedPtr<RingHashSubchannelList> subchannel_list)
|
260
|
+
: subchannel_list_(std::move(subchannel_list)) {}
|
261
|
+
|
262
|
+
~Picker() override {
|
263
|
+
// Hop into WorkSerializer to unref the subchannel list, since that may
|
264
|
+
// trigger the unreffing of the underlying subchannels.
|
265
|
+
MakeOrphanable<WorkSerializerRunner>(std::move(subchannel_list_));
|
266
|
+
}
|
308
267
|
|
309
268
|
PickResult Pick(PickArgs args) override;
|
310
269
|
|
311
270
|
private:
|
312
|
-
//
|
313
|
-
|
314
|
-
class SubchannelConnectionAttempter : public Orphanable {
|
271
|
+
// An interface for running a callback in the control plane WorkSerializer.
|
272
|
+
class WorkSerializerRunner : public Orphanable {
|
315
273
|
public:
|
316
|
-
explicit
|
317
|
-
RefCountedPtr<
|
318
|
-
:
|
274
|
+
explicit WorkSerializerRunner(
|
275
|
+
RefCountedPtr<RingHashSubchannelList> subchannel_list)
|
276
|
+
: subchannel_list_(std::move(subchannel_list)) {
|
319
277
|
GRPC_CLOSURE_INIT(&closure_, RunInExecCtx, this, nullptr);
|
320
278
|
}
|
321
279
|
|
322
|
-
void AddSubchannel(RefCountedPtr<SubchannelInterface> subchannel) {
|
323
|
-
subchannels_.push_back(std::move(subchannel));
|
324
|
-
}
|
325
|
-
|
326
280
|
void Orphan() override {
|
327
281
|
// Hop into ExecCtx, so that we're not holding the data plane mutex
|
328
282
|
// while we run control-plane code.
|
329
283
|
ExecCtx::Run(DEBUG_LOCATION, &closure_, GRPC_ERROR_NONE);
|
330
284
|
}
|
331
285
|
|
286
|
+
// Will be invoked inside of the WorkSerializer.
|
287
|
+
virtual void Run() {}
|
288
|
+
|
289
|
+
protected:
|
290
|
+
RingHash* ring_hash_lb() const {
|
291
|
+
return static_cast<RingHash*>(subchannel_list_->policy());
|
292
|
+
}
|
293
|
+
|
332
294
|
private:
|
333
295
|
static void RunInExecCtx(void* arg, grpc_error_handle /*error*/) {
|
334
296
|
auto* self = static_cast<SubchannelConnectionAttempter*>(arg);
|
335
|
-
self->
|
297
|
+
self->ring_hash_lb()->work_serializer()->Run(
|
336
298
|
[self]() {
|
337
|
-
|
338
|
-
for (auto& subchannel : self->subchannels_) {
|
339
|
-
subchannel->RequestConnection();
|
340
|
-
}
|
341
|
-
}
|
299
|
+
self->Run();
|
342
300
|
delete self;
|
343
301
|
},
|
344
302
|
DEBUG_LOCATION);
|
345
303
|
}
|
346
304
|
|
347
|
-
RefCountedPtr<
|
305
|
+
RefCountedPtr<RingHashSubchannelList> subchannel_list_;
|
348
306
|
grpc_closure closure_;
|
307
|
+
};
|
308
|
+
|
309
|
+
// A fire-and-forget class that schedules subchannel connection attempts
|
310
|
+
// on the control plane WorkSerializer.
|
311
|
+
class SubchannelConnectionAttempter : public WorkSerializerRunner {
|
312
|
+
public:
|
313
|
+
explicit SubchannelConnectionAttempter(
|
314
|
+
RefCountedPtr<RingHashSubchannelList> subchannel_list)
|
315
|
+
: WorkSerializerRunner(std::move(subchannel_list)) {}
|
316
|
+
|
317
|
+
void AddSubchannel(RefCountedPtr<SubchannelInterface> subchannel) {
|
318
|
+
subchannels_.push_back(std::move(subchannel));
|
319
|
+
}
|
320
|
+
|
321
|
+
void Run() override {
|
322
|
+
if (!ring_hash_lb()->shutdown_) {
|
323
|
+
for (auto& subchannel : subchannels_) {
|
324
|
+
subchannel->RequestConnection();
|
325
|
+
}
|
326
|
+
}
|
327
|
+
}
|
328
|
+
|
329
|
+
private:
|
349
330
|
std::vector<RefCountedPtr<SubchannelInterface>> subchannels_;
|
350
331
|
};
|
351
332
|
|
352
|
-
RefCountedPtr<
|
353
|
-
RefCountedPtr<Ring> ring_;
|
333
|
+
RefCountedPtr<RingHashSubchannelList> subchannel_list_;
|
354
334
|
};
|
355
335
|
|
356
336
|
void ShutdownLocked() override;
|
@@ -359,117 +339,12 @@ class RingHash : public LoadBalancingPolicy {
|
|
359
339
|
RefCountedPtr<RingHashLbConfig> config_;
|
360
340
|
|
361
341
|
// list of subchannels.
|
362
|
-
|
363
|
-
|
342
|
+
RefCountedPtr<RingHashSubchannelList> subchannel_list_;
|
343
|
+
RefCountedPtr<RingHashSubchannelList> latest_pending_subchannel_list_;
|
364
344
|
// indicating if we are shutting down.
|
365
345
|
bool shutdown_ = false;
|
366
346
|
};
|
367
347
|
|
368
|
-
//
|
369
|
-
// RingHash::Ring
|
370
|
-
//
|
371
|
-
|
372
|
-
RingHash::Ring::Ring(RingHash* parent,
|
373
|
-
RefCountedPtr<RingHashSubchannelList> subchannel_list)
|
374
|
-
: subchannel_list_(std::move(subchannel_list)) {
|
375
|
-
size_t num_subchannels = subchannel_list_->num_subchannels();
|
376
|
-
// Store the weights while finding the sum.
|
377
|
-
struct AddressWeight {
|
378
|
-
std::string address;
|
379
|
-
// Default weight is 1 for the cases where a weight is not provided,
|
380
|
-
// each occurrence of the address will be counted a weight value of 1.
|
381
|
-
uint32_t weight = 1;
|
382
|
-
double normalized_weight;
|
383
|
-
};
|
384
|
-
std::vector<AddressWeight> address_weights;
|
385
|
-
size_t sum = 0;
|
386
|
-
address_weights.reserve(num_subchannels);
|
387
|
-
for (size_t i = 0; i < num_subchannels; ++i) {
|
388
|
-
RingHashSubchannelData* sd = subchannel_list_->subchannel(i);
|
389
|
-
const ServerAddressWeightAttribute* weight_attribute = static_cast<
|
390
|
-
const ServerAddressWeightAttribute*>(sd->address().GetAttribute(
|
391
|
-
ServerAddressWeightAttribute::kServerAddressWeightAttributeKey));
|
392
|
-
AddressWeight address_weight;
|
393
|
-
address_weight.address =
|
394
|
-
grpc_sockaddr_to_string(&sd->address().address(), false).value();
|
395
|
-
// Weight should never be zero, but ignore it just in case, since
|
396
|
-
// that value would screw up the ring-building algorithm.
|
397
|
-
if (weight_attribute != nullptr && weight_attribute->weight() > 0) {
|
398
|
-
address_weight.weight = weight_attribute->weight();
|
399
|
-
}
|
400
|
-
sum += address_weight.weight;
|
401
|
-
address_weights.push_back(std::move(address_weight));
|
402
|
-
}
|
403
|
-
// Calculating normalized weights and find min and max.
|
404
|
-
double min_normalized_weight = 1.0;
|
405
|
-
double max_normalized_weight = 0.0;
|
406
|
-
for (auto& address : address_weights) {
|
407
|
-
address.normalized_weight = static_cast<double>(address.weight) / sum;
|
408
|
-
min_normalized_weight =
|
409
|
-
std::min(address.normalized_weight, min_normalized_weight);
|
410
|
-
max_normalized_weight =
|
411
|
-
std::max(address.normalized_weight, max_normalized_weight);
|
412
|
-
}
|
413
|
-
// Scale up the number of hashes per host such that the least-weighted host
|
414
|
-
// gets a whole number of hashes on the ring. Other hosts might not end up
|
415
|
-
// with whole numbers, and that's fine (the ring-building algorithm below can
|
416
|
-
// handle this). This preserves the original implementation's behavior: when
|
417
|
-
// weights aren't provided, all hosts should get an equal number of hashes. In
|
418
|
-
// the case where this number exceeds the max_ring_size, it's scaled back down
|
419
|
-
// to fit.
|
420
|
-
const size_t min_ring_size = parent->config_->min_ring_size();
|
421
|
-
const size_t max_ring_size = parent->config_->max_ring_size();
|
422
|
-
const double scale = std::min(
|
423
|
-
std::ceil(min_normalized_weight * min_ring_size) / min_normalized_weight,
|
424
|
-
static_cast<double>(max_ring_size));
|
425
|
-
// Reserve memory for the entire ring up front.
|
426
|
-
const size_t ring_size = std::ceil(scale);
|
427
|
-
ring_.reserve(ring_size);
|
428
|
-
// Populate the hash ring by walking through the (host, weight) pairs in
|
429
|
-
// normalized_host_weights, and generating (scale * weight) hashes for each
|
430
|
-
// host. Since these aren't necessarily whole numbers, we maintain running
|
431
|
-
// sums -- current_hashes and target_hashes -- which allows us to populate the
|
432
|
-
// ring in a mostly stable way.
|
433
|
-
absl::InlinedVector<char, 196> hash_key_buffer;
|
434
|
-
double current_hashes = 0.0;
|
435
|
-
double target_hashes = 0.0;
|
436
|
-
uint64_t min_hashes_per_host = ring_size;
|
437
|
-
uint64_t max_hashes_per_host = 0;
|
438
|
-
for (size_t i = 0; i < num_subchannels; ++i) {
|
439
|
-
const std::string& address_string = address_weights[i].address;
|
440
|
-
hash_key_buffer.assign(address_string.begin(), address_string.end());
|
441
|
-
hash_key_buffer.emplace_back('_');
|
442
|
-
auto offset_start = hash_key_buffer.end();
|
443
|
-
target_hashes += scale * address_weights[i].normalized_weight;
|
444
|
-
size_t count = 0;
|
445
|
-
while (current_hashes < target_hashes) {
|
446
|
-
const std::string count_str = absl::StrCat(count);
|
447
|
-
hash_key_buffer.insert(offset_start, count_str.begin(), count_str.end());
|
448
|
-
absl::string_view hash_key(hash_key_buffer.data(),
|
449
|
-
hash_key_buffer.size());
|
450
|
-
const uint64_t hash = XXH64(hash_key.data(), hash_key.size(), 0);
|
451
|
-
ring_.push_back({hash, subchannel_list_->subchannel(i)});
|
452
|
-
++count;
|
453
|
-
++current_hashes;
|
454
|
-
hash_key_buffer.erase(offset_start, hash_key_buffer.end());
|
455
|
-
}
|
456
|
-
min_hashes_per_host =
|
457
|
-
std::min(static_cast<uint64_t>(i), min_hashes_per_host);
|
458
|
-
max_hashes_per_host =
|
459
|
-
std::max(static_cast<uint64_t>(i), max_hashes_per_host);
|
460
|
-
}
|
461
|
-
std::sort(ring_.begin(), ring_.end(),
|
462
|
-
[](const Entry& lhs, const Entry& rhs) -> bool {
|
463
|
-
return lhs.hash < rhs.hash;
|
464
|
-
});
|
465
|
-
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_ring_hash_trace)) {
|
466
|
-
gpr_log(GPR_INFO,
|
467
|
-
"[RH %p picker %p] created ring from subchannel_list=%p "
|
468
|
-
"with %" PRIuPTR " ring entries",
|
469
|
-
parent, this, subchannel_list_.get(), ring_.size());
|
470
|
-
}
|
471
|
-
}
|
472
|
-
|
473
348
|
//
|
474
349
|
// RingHash::Picker
|
475
350
|
//
|
@@ -483,7 +358,7 @@ RingHash::PickResult RingHash::Picker::Pick(PickArgs args) {
|
|
483
358
|
return PickResult::Fail(
|
484
359
|
absl::InternalError("ring hash value is not a number"));
|
485
360
|
}
|
486
|
-
const
|
361
|
+
const auto& ring = subchannel_list_->ring();
|
487
362
|
// Ported from https://github.com/RJ/ketama/blob/master/libketama/ketama.c
|
488
363
|
// (ketama_get_server) NOTE: The algorithm depends on using signed integers
|
489
364
|
// for lowp, highp, and first_index. Do not change them!
|
@@ -516,7 +391,9 @@ RingHash::PickResult RingHash::Picker::Pick(PickArgs args) {
|
|
516
391
|
[&](RefCountedPtr<SubchannelInterface> subchannel) {
|
517
392
|
if (subchannel_connection_attempter == nullptr) {
|
518
393
|
subchannel_connection_attempter =
|
519
|
-
MakeOrphanable<SubchannelConnectionAttempter>(
|
394
|
+
MakeOrphanable<SubchannelConnectionAttempter>(
|
395
|
+
subchannel_list_->Ref(DEBUG_LOCATION,
|
396
|
+
"SubchannelConnectionAttempter"));
|
520
397
|
}
|
521
398
|
subchannel_connection_attempter->AddSubchannel(std::move(subchannel));
|
522
399
|
};
|
@@ -541,7 +418,7 @@ RingHash::PickResult RingHash::Picker::Pick(PickArgs args) {
|
|
541
418
|
bool found_second_subchannel = false;
|
542
419
|
bool found_first_non_failed = false;
|
543
420
|
for (size_t i = 1; i < ring.size(); ++i) {
|
544
|
-
const
|
421
|
+
const auto& entry = ring[(first_index + i) % ring.size()];
|
545
422
|
if (entry.subchannel == ring[first_index].subchannel) {
|
546
423
|
continue;
|
547
424
|
}
|
@@ -585,6 +462,117 @@ RingHash::PickResult RingHash::Picker::Pick(PickArgs args) {
|
|
585
462
|
// RingHash::RingHashSubchannelList
|
586
463
|
//
|
587
464
|
|
465
|
+
RingHash::RingHashSubchannelList::RingHashSubchannelList(
|
466
|
+
RingHash* policy, ServerAddressList addresses, const ChannelArgs& args)
|
467
|
+
: SubchannelList(policy,
|
468
|
+
(GRPC_TRACE_FLAG_ENABLED(grpc_lb_ring_hash_trace)
|
469
|
+
? "RingHashSubchannelList"
|
470
|
+
: nullptr),
|
471
|
+
std::move(addresses), policy->channel_control_helper(),
|
472
|
+
args),
|
473
|
+
num_idle_(num_subchannels()) {
|
474
|
+
// Need to maintain a ref to the LB policy as long as we maintain
|
475
|
+
// any references to subchannels, since the subchannels'
|
476
|
+
// pollset_sets will include the LB policy's pollset_set.
|
477
|
+
policy->Ref(DEBUG_LOCATION, "subchannel_list").release();
|
478
|
+
// Construct the ring.
|
479
|
+
// Store the weights while finding the sum.
|
480
|
+
struct AddressWeight {
|
481
|
+
std::string address;
|
482
|
+
// Default weight is 1 for the cases where a weight is not provided,
|
483
|
+
// each occurrence of the address will be counted a weight value of 1.
|
484
|
+
uint32_t weight = 1;
|
485
|
+
double normalized_weight;
|
486
|
+
};
|
487
|
+
std::vector<AddressWeight> address_weights;
|
488
|
+
size_t sum = 0;
|
489
|
+
address_weights.reserve(num_subchannels());
|
490
|
+
for (size_t i = 0; i < num_subchannels(); ++i) {
|
491
|
+
RingHashSubchannelData* sd = subchannel(i);
|
492
|
+
const ServerAddressWeightAttribute* weight_attribute = static_cast<
|
493
|
+
const ServerAddressWeightAttribute*>(sd->address().GetAttribute(
|
494
|
+
ServerAddressWeightAttribute::kServerAddressWeightAttributeKey));
|
495
|
+
AddressWeight address_weight;
|
496
|
+
address_weight.address =
|
497
|
+
grpc_sockaddr_to_string(&sd->address().address(), false).value();
|
498
|
+
// Weight should never be zero, but ignore it just in case, since
|
499
|
+
// that value would screw up the ring-building algorithm.
|
500
|
+
if (weight_attribute != nullptr && weight_attribute->weight() > 0) {
|
501
|
+
address_weight.weight = weight_attribute->weight();
|
502
|
+
}
|
503
|
+
sum += address_weight.weight;
|
504
|
+
address_weights.push_back(std::move(address_weight));
|
505
|
+
}
|
506
|
+
// Calculating normalized weights and find min and max.
|
507
|
+
double min_normalized_weight = 1.0;
|
508
|
+
double max_normalized_weight = 0.0;
|
509
|
+
for (auto& address : address_weights) {
|
510
|
+
address.normalized_weight = static_cast<double>(address.weight) / sum;
|
511
|
+
min_normalized_weight =
|
512
|
+
std::min(address.normalized_weight, min_normalized_weight);
|
513
|
+
max_normalized_weight =
|
514
|
+
std::max(address.normalized_weight, max_normalized_weight);
|
515
|
+
}
|
516
|
+
// Scale up the number of hashes per host such that the least-weighted host
|
517
|
+
// gets a whole number of hashes on the ring. Other hosts might not end up
|
518
|
+
// with whole numbers, and that's fine (the ring-building algorithm below can
|
519
|
+
// handle this). This preserves the original implementation's behavior: when
|
520
|
+
// weights aren't provided, all hosts should get an equal number of hashes. In
|
521
|
+
// the case where this number exceeds the max_ring_size, it's scaled back down
|
522
|
+
// to fit.
|
523
|
+
const size_t min_ring_size = policy->config_->min_ring_size();
|
524
|
+
const size_t max_ring_size = policy->config_->max_ring_size();
|
525
|
+
const double scale = std::min(
|
526
|
+
std::ceil(min_normalized_weight * min_ring_size) / min_normalized_weight,
|
527
|
+
static_cast<double>(max_ring_size));
|
528
|
+
// Reserve memory for the entire ring up front.
|
529
|
+
const size_t ring_size = std::ceil(scale);
|
530
|
+
ring_.reserve(ring_size);
|
531
|
+
// Populate the hash ring by walking through the (host, weight) pairs in
|
532
|
+
// normalized_host_weights, and generating (scale * weight) hashes for each
|
533
|
+
// host. Since these aren't necessarily whole numbers, we maintain running
|
534
|
+
// sums -- current_hashes and target_hashes -- which allows us to populate the
|
535
|
+
// ring in a mostly stable way.
|
536
|
+
absl::InlinedVector<char, 196> hash_key_buffer;
|
537
|
+
double current_hashes = 0.0;
|
538
|
+
double target_hashes = 0.0;
|
539
|
+
uint64_t min_hashes_per_host = ring_size;
|
540
|
+
uint64_t max_hashes_per_host = 0;
|
541
|
+
for (size_t i = 0; i < num_subchannels(); ++i) {
|
542
|
+
const std::string& address_string = address_weights[i].address;
|
543
|
+
hash_key_buffer.assign(address_string.begin(), address_string.end());
|
544
|
+
hash_key_buffer.emplace_back('_');
|
545
|
+
auto offset_start = hash_key_buffer.end();
|
546
|
+
target_hashes += scale * address_weights[i].normalized_weight;
|
547
|
+
size_t count = 0;
|
548
|
+
while (current_hashes < target_hashes) {
|
549
|
+
const std::string count_str = absl::StrCat(count);
|
550
|
+
hash_key_buffer.insert(offset_start, count_str.begin(), count_str.end());
|
551
|
+
absl::string_view hash_key(hash_key_buffer.data(),
|
552
|
+
hash_key_buffer.size());
|
553
|
+
const uint64_t hash = XXH64(hash_key.data(), hash_key.size(), 0);
|
554
|
+
ring_.push_back({hash, subchannel(i)});
|
555
|
+
++count;
|
556
|
+
++current_hashes;
|
557
|
+
hash_key_buffer.erase(offset_start, hash_key_buffer.end());
|
558
|
+
}
|
559
|
+
min_hashes_per_host =
|
560
|
+
std::min(static_cast<uint64_t>(i), min_hashes_per_host);
|
561
|
+
max_hashes_per_host =
|
562
|
+
std::max(static_cast<uint64_t>(i), max_hashes_per_host);
|
563
|
+
}
|
564
|
+
std::sort(ring_.begin(), ring_.end(),
|
565
|
+
[](const RingHashSubchannelList::RingEntry& lhs,
|
566
|
+
const RingHashSubchannelList::RingEntry& rhs) -> bool {
|
567
|
+
return lhs.hash < rhs.hash;
|
568
|
+
});
|
569
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_ring_hash_trace)) {
|
570
|
+
gpr_log(GPR_INFO,
|
571
|
+
"[RH %p] created subchannel list %p with %" PRIuPTR " ring entries",
|
572
|
+
policy, this, ring_.size());
|
573
|
+
}
|
574
|
+
}
|
575
|
+
|
588
576
|
void RingHash::RingHashSubchannelList::UpdateStateCountersLocked(
|
589
577
|
grpc_connectivity_state old_state, grpc_connectivity_state new_state) {
|
590
578
|
if (old_state == GRPC_CHANNEL_IDLE) {
|
@@ -673,8 +661,7 @@ void RingHash::RingHashSubchannelList::UpdateRingHashConnectivityStateLocked(
|
|
673
661
|
// Note that we use our own picker regardless of connectivity state.
|
674
662
|
p->channel_control_helper()->UpdateState(
|
675
663
|
state, status,
|
676
|
-
absl::make_unique<Picker>(
|
677
|
-
ring_));
|
664
|
+
absl::make_unique<Picker>(Ref(DEBUG_LOCATION, "RingHashPicker")));
|
678
665
|
// While the ring_hash policy is reporting TRANSIENT_FAILURE, it will
|
679
666
|
// not be getting any pick requests from the priority policy.
|
680
667
|
// However, because the ring_hash policy does not attempt to
|
@@ -813,7 +800,7 @@ void RingHash::ResetBackoffLocked() {
|
|
813
800
|
}
|
814
801
|
}
|
815
802
|
|
816
|
-
|
803
|
+
absl::Status RingHash::UpdateLocked(UpdateArgs args) {
|
817
804
|
config_ = std::move(args.config);
|
818
805
|
ServerAddressList addresses;
|
819
806
|
if (args.addresses.ok()) {
|
@@ -827,16 +814,16 @@ void RingHash::UpdateLocked(UpdateArgs args) {
|
|
827
814
|
gpr_log(GPR_INFO, "[RH %p] received update with addresses error: %s",
|
828
815
|
this, args.addresses.status().ToString().c_str());
|
829
816
|
}
|
830
|
-
// If we already have a subchannel list, then
|
831
|
-
//
|
832
|
-
if (subchannel_list_ != nullptr) return;
|
817
|
+
// If we already have a subchannel list, then keep using the existing
|
818
|
+
// list, but still report back that the update was not accepted.
|
819
|
+
if (subchannel_list_ != nullptr) return args.addresses.status();
|
833
820
|
}
|
834
821
|
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_ring_hash_trace) &&
|
835
822
|
latest_pending_subchannel_list_ != nullptr) {
|
836
823
|
gpr_log(GPR_INFO, "[RH %p] replacing latest pending subchannel list %p",
|
837
824
|
this, latest_pending_subchannel_list_.get());
|
838
825
|
}
|
839
|
-
latest_pending_subchannel_list_ =
|
826
|
+
latest_pending_subchannel_list_ = MakeRefCounted<RingHashSubchannelList>(
|
840
827
|
this, std::move(addresses), args.args);
|
841
828
|
latest_pending_subchannel_list_->StartWatchingLocked();
|
842
829
|
// If we have no existing list or the new list is empty, immediately
|
@@ -862,12 +849,13 @@ void RingHash::UpdateLocked(UpdateArgs args) {
|
|
862
849
|
channel_control_helper()->UpdateState(
|
863
850
|
GRPC_CHANNEL_TRANSIENT_FAILURE, status,
|
864
851
|
absl::make_unique<TransientFailurePicker>(status));
|
865
|
-
|
866
|
-
// Otherwise, report IDLE.
|
867
|
-
subchannel_list_->UpdateRingHashConnectivityStateLocked(
|
868
|
-
/*index=*/0, /*connection_attempt_complete=*/false, absl::OkStatus());
|
852
|
+
return status;
|
869
853
|
}
|
854
|
+
// Otherwise, report IDLE.
|
855
|
+
subchannel_list_->UpdateRingHashConnectivityStateLocked(
|
856
|
+
/*index=*/0, /*connection_attempt_complete=*/false, absl::OkStatus());
|
870
857
|
}
|
858
|
+
return absl::OkStatus();
|
871
859
|
}
|
872
860
|
|
873
861
|
//
|
@@ -885,7 +873,8 @@ class RingHashFactory : public LoadBalancingPolicyFactory {
|
|
885
873
|
|
886
874
|
absl::StatusOr<RefCountedPtr<LoadBalancingPolicy::Config>>
|
887
875
|
ParseLoadBalancingConfig(const Json& json) const override {
|
888
|
-
auto config =
|
876
|
+
auto config = LoadFromJson<RingHashConfig>(
|
877
|
+
json, JsonArgs(), "errors validating ring_hash LB policy config");
|
889
878
|
if (!config.ok()) return config.status();
|
890
879
|
return MakeRefCounted<RingHashLbConfig>(config->min_ring_size,
|
891
880
|
config->max_ring_size);
|
@@ -894,11 +883,9 @@ class RingHashFactory : public LoadBalancingPolicyFactory {
|
|
894
883
|
|
895
884
|
} // namespace
|
896
885
|
|
897
|
-
void
|
898
|
-
|
886
|
+
void RegisterRingHashLbPolicy(CoreConfiguration::Builder* builder) {
|
887
|
+
builder->lb_policy_registry()->RegisterLoadBalancingPolicyFactory(
|
899
888
|
absl::make_unique<RingHashFactory>());
|
900
889
|
}
|
901
890
|
|
902
|
-
void GrpcLbPolicyRingHashShutdown() {}
|
903
|
-
|
904
891
|
} // namespace grpc_core
|
@@ -19,12 +19,13 @@
|
|
19
19
|
|
20
20
|
#include <grpc/support/port_platform.h>
|
21
21
|
|
22
|
-
#include <
|
23
|
-
|
24
|
-
#include "absl/status/statusor.h"
|
22
|
+
#include <stdint.h>
|
25
23
|
|
26
24
|
#include "src/core/lib/gprpp/unique_type_name.h"
|
25
|
+
#include "src/core/lib/gprpp/validation_errors.h"
|
27
26
|
#include "src/core/lib/json/json.h"
|
27
|
+
#include "src/core/lib/json/json_args.h"
|
28
|
+
#include "src/core/lib/json/json_object_loader.h"
|
28
29
|
|
29
30
|
namespace grpc_core {
|
30
31
|
|
@@ -33,10 +34,13 @@ UniqueTypeName RequestHashAttributeName();
|
|
33
34
|
// Helper Parsing method to parse ring hash policy configs; for example, ring
|
34
35
|
// hash size validity.
|
35
36
|
struct RingHashConfig {
|
36
|
-
|
37
|
-
|
37
|
+
uint64_t min_ring_size = 1024;
|
38
|
+
uint64_t max_ring_size = 8388608;
|
39
|
+
|
40
|
+
static const JsonLoaderInterface* JsonLoader(const JsonArgs&);
|
41
|
+
void JsonPostLoad(const Json& json, const JsonArgs&,
|
42
|
+
ValidationErrors* errors);
|
38
43
|
};
|
39
|
-
absl::StatusOr<RingHashConfig> ParseRingHashLbConfig(const Json& json);
|
40
44
|
|
41
45
|
} // namespace grpc_core
|
42
46
|
|