grpc 1.18.0 → 1.22.0
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 +4731 -7404
- data/etc/roots.pem +146 -0
- data/include/grpc/grpc.h +11 -6
- data/include/grpc/grpc_security.h +297 -4
- data/include/grpc/grpc_security_constants.h +1 -1
- data/include/grpc/impl/codegen/byte_buffer.h +13 -0
- data/include/grpc/impl/codegen/gpr_types.h +1 -1
- data/include/grpc/impl/codegen/grpc_types.h +30 -7
- data/include/grpc/impl/codegen/port_platform.h +88 -7
- data/include/grpc/impl/codegen/slice.h +2 -22
- data/include/grpc/impl/codegen/status.h +2 -1
- data/include/grpc/impl/codegen/sync_posix.h +18 -0
- data/include/grpc/slice.h +3 -3
- data/src/core/ext/filters/client_channel/backup_poller.cc +21 -16
- data/src/core/ext/filters/client_channel/backup_poller.h +8 -2
- data/src/core/ext/filters/client_channel/channel_connectivity.cc +3 -1
- data/src/core/ext/filters/client_channel/client_channel.cc +2435 -1557
- data/src/core/ext/filters/client_channel/client_channel.h +2 -10
- data/src/core/ext/filters/client_channel/client_channel_channelz.cc +6 -89
- data/src/core/ext/filters/client_channel/client_channel_channelz.h +8 -33
- data/src/core/ext/filters/client_channel/client_channel_factory.cc +22 -34
- data/src/core/ext/filters/client_channel/client_channel_factory.h +19 -38
- data/src/core/ext/filters/client_channel/client_channel_plugin.cc +9 -11
- data/src/core/ext/filters/client_channel/global_subchannel_pool.cc +179 -0
- data/src/core/ext/filters/client_channel/global_subchannel_pool.h +68 -0
- data/src/core/ext/filters/client_channel/health/health_check_client.cc +59 -55
- data/src/core/ext/filters/client_channel/health/health_check_client.h +20 -9
- data/src/core/ext/filters/client_channel/http_connect_handshaker.cc +146 -157
- data/src/core/ext/filters/client_channel/http_connect_handshaker.h +1 -1
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.cc +29 -32
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +844 -859
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h +3 -1
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel_secure.cc +2 -6
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.cc +6 -2
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.h +14 -12
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.cc +16 -12
- data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h +3 -3
- data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +185 -312
- data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +143 -375
- data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +192 -245
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc +1554 -955
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds_channel_secure.cc +0 -43
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.cc +14 -10
- data/src/core/ext/filters/client_channel/lb_policy/xds/xds_load_balancer_api.h +2 -2
- data/src/core/ext/filters/client_channel/lb_policy.cc +115 -22
- data/src/core/ext/filters/client_channel/lb_policy.h +260 -129
- data/src/core/ext/filters/client_channel/lb_policy_factory.h +5 -2
- data/src/core/ext/filters/client_channel/lb_policy_registry.cc +107 -4
- data/src/core/ext/filters/client_channel/lb_policy_registry.h +10 -3
- data/src/core/ext/filters/client_channel/local_subchannel_pool.cc +96 -0
- data/src/core/ext/filters/client_channel/local_subchannel_pool.h +56 -0
- data/src/core/ext/filters/client_channel/parse_address.cc +24 -5
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +121 -122
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc +84 -2
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h +3 -0
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_libuv.cc +179 -0
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc +24 -10
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc +111 -47
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h +7 -13
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc +2 -2
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_libuv.cc +39 -0
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc +0 -6
- data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc +2 -64
- data/src/core/ext/filters/client_channel/resolver/dns/dns_resolver_selection.cc +28 -0
- data/src/core/{lib/iomgr/network_status_tracker.cc → ext/filters/client_channel/resolver/dns/dns_resolver_selection.h} +8 -15
- data/src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc +36 -82
- data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +111 -72
- data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h +13 -8
- data/src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc +28 -63
- data/src/core/ext/filters/client_channel/resolver.cc +54 -1
- data/src/core/ext/filters/client_channel/resolver.h +52 -23
- data/src/core/ext/filters/client_channel/resolver_factory.h +3 -1
- data/src/core/ext/filters/client_channel/resolver_registry.cc +5 -2
- data/src/core/ext/filters/client_channel/resolver_registry.h +5 -4
- data/src/core/ext/filters/client_channel/resolver_result_parsing.cc +368 -241
- data/src/core/ext/filters/client_channel/resolver_result_parsing.h +58 -76
- data/src/core/ext/filters/client_channel/resolving_lb_policy.cc +543 -0
- data/src/core/ext/filters/client_channel/resolving_lb_policy.h +139 -0
- data/src/core/ext/filters/client_channel/server_address.cc +4 -54
- data/src/core/ext/filters/client_channel/server_address.h +1 -13
- data/src/core/ext/filters/client_channel/service_config.cc +329 -0
- data/src/core/ext/filters/client_channel/service_config.h +205 -0
- data/src/core/ext/filters/client_channel/subchannel.cc +803 -838
- data/src/core/ext/filters/client_channel/subchannel.h +295 -128
- data/src/core/ext/filters/client_channel/subchannel_interface.h +113 -0
- data/src/core/ext/filters/client_channel/subchannel_pool_interface.cc +97 -0
- data/src/core/ext/filters/client_channel/subchannel_pool_interface.h +94 -0
- data/src/core/ext/filters/deadline/deadline_filter.cc +3 -4
- data/src/core/ext/filters/deadline/deadline_filter.h +3 -2
- data/src/core/ext/filters/http/client/http_client_filter.cc +7 -5
- data/src/core/ext/filters/http/client/http_client_filter.h +1 -1
- data/src/core/ext/filters/http/client_authority_filter.cc +6 -3
- data/src/core/ext/filters/http/message_compress/message_compress_filter.cc +4 -3
- data/src/core/ext/filters/http/server/http_server_filter.cc +18 -12
- data/src/core/ext/filters/max_age/max_age_filter.cc +5 -2
- data/src/core/ext/filters/message_size/message_size_filter.cc +119 -77
- data/src/core/ext/filters/message_size/message_size_filter.h +33 -0
- data/src/core/ext/transport/chttp2/alpn/alpn.h +1 -1
- data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +13 -12
- data/src/core/ext/transport/chttp2/client/insecure/channel_create.cc +45 -47
- data/src/core/ext/transport/chttp2/client/secure/secure_channel_create.cc +134 -143
- data/src/core/ext/transport/chttp2/server/chttp2_server.cc +68 -21
- data/src/core/ext/transport/chttp2/transport/bin_decoder.cc +4 -4
- data/src/core/ext/transport/chttp2/transport/bin_decoder.h +4 -4
- data/src/core/ext/transport/chttp2/transport/bin_encoder.cc +7 -6
- data/src/core/ext/transport/chttp2/transport/bin_encoder.h +4 -3
- data/src/core/ext/transport/chttp2/transport/chttp2_plugin.cc +9 -7
- data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +156 -94
- data/src/core/ext/transport/chttp2/transport/flow_control.cc +2 -2
- data/src/core/ext/transport/chttp2/transport/flow_control.h +1 -1
- data/src/core/ext/transport/chttp2/transport/frame_data.cc +33 -37
- data/src/core/ext/transport/chttp2/transport/frame_data.h +1 -1
- data/src/core/ext/transport/chttp2/transport/frame_goaway.cc +6 -5
- data/src/core/ext/transport/chttp2/transport/frame_goaway.h +3 -2
- data/src/core/ext/transport/chttp2/transport/frame_ping.cc +5 -4
- data/src/core/ext/transport/chttp2/transport/frame_ping.h +1 -1
- data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +8 -6
- data/src/core/ext/transport/chttp2/transport/frame_rst_stream.h +2 -1
- data/src/core/ext/transport/chttp2/transport/frame_settings.cc +6 -4
- data/src/core/ext/transport/chttp2/transport/frame_settings.h +2 -1
- data/src/core/ext/transport/chttp2/transport/frame_window_update.cc +7 -6
- data/src/core/ext/transport/chttp2/transport/frame_window_update.h +1 -1
- data/src/core/ext/transport/chttp2/transport/hpack_encoder.cc +74 -55
- data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +33 -11
- data/src/core/ext/transport/chttp2/transport/hpack_parser.h +3 -2
- data/src/core/ext/transport/chttp2/transport/hpack_table.cc +7 -14
- data/src/core/ext/transport/chttp2/transport/hpack_table.h +10 -1
- data/src/core/ext/transport/chttp2/transport/incoming_metadata.cc +9 -5
- data/src/core/ext/transport/chttp2/transport/incoming_metadata.h +9 -3
- data/src/core/ext/transport/chttp2/transport/internal.h +43 -30
- data/src/core/ext/transport/chttp2/transport/parsing.cc +52 -70
- data/src/core/ext/transport/chttp2/transport/stream_lists.cc +3 -3
- data/src/core/ext/transport/chttp2/transport/writing.cc +70 -33
- data/src/core/ext/transport/inproc/inproc_transport.cc +26 -18
- data/src/core/lib/channel/channel_args.cc +2 -101
- data/src/core/lib/channel/channel_args.h +3 -37
- data/src/core/lib/channel/channel_stack.h +10 -6
- data/src/core/lib/channel/channel_trace.cc +4 -4
- data/src/core/lib/channel/channel_trace.h +4 -4
- data/src/core/lib/channel/channelz.cc +168 -38
- data/src/core/lib/channel/channelz.h +40 -44
- data/src/core/lib/channel/channelz_registry.cc +75 -107
- data/src/core/lib/channel/channelz_registry.h +10 -28
- data/src/core/lib/channel/connected_channel.cc +2 -2
- data/src/core/lib/channel/context.h +2 -2
- data/src/core/lib/channel/handshaker.cc +151 -218
- data/src/core/lib/channel/handshaker.h +110 -101
- data/src/core/lib/channel/handshaker_factory.h +11 -19
- data/src/core/lib/channel/handshaker_registry.cc +67 -51
- data/src/core/lib/channel/handshaker_registry.h +21 -16
- data/src/core/lib/compression/algorithm_metadata.h +3 -3
- data/src/core/lib/compression/compression.cc +14 -9
- data/src/core/lib/compression/compression_args.cc +127 -0
- data/src/core/lib/compression/compression_args.h +55 -0
- data/src/core/lib/compression/compression_internal.cc +16 -12
- data/src/core/lib/compression/compression_internal.h +1 -1
- data/src/core/lib/compression/stream_compression.cc +3 -2
- data/src/core/lib/compression/stream_compression.h +2 -2
- data/src/core/lib/compression/stream_compression_gzip.cc +9 -9
- data/src/core/lib/debug/trace.cc +13 -7
- data/src/core/lib/debug/trace.h +14 -1
- data/src/core/lib/gpr/arena.h +13 -9
- data/src/core/lib/gpr/cpu_posix.cc +5 -3
- data/src/core/lib/gpr/env.h +3 -6
- data/src/core/lib/gpr/env_linux.cc +6 -1
- data/src/core/lib/gpr/env_posix.cc +5 -0
- data/src/core/lib/gpr/env_windows.cc +7 -5
- data/src/core/lib/gpr/log.cc +9 -13
- data/src/core/lib/gpr/log_posix.cc +2 -1
- data/src/core/lib/gpr/string.cc +20 -7
- data/src/core/lib/gpr/string.h +10 -3
- data/src/core/lib/gpr/sync_posix.cc +65 -4
- data/src/core/lib/gpr/time.cc +8 -0
- data/src/core/lib/gpr/time_posix.cc +21 -2
- data/src/core/lib/gprpp/arena.cc +103 -0
- data/src/core/lib/gprpp/arena.h +121 -0
- data/src/core/lib/gprpp/atomic.h +75 -5
- data/src/core/lib/gprpp/fork.cc +13 -32
- data/src/core/lib/gprpp/fork.h +5 -1
- data/src/core/lib/gprpp/global_config.h +96 -0
- data/src/core/lib/gprpp/global_config_custom.h +29 -0
- data/src/core/lib/gprpp/global_config_env.cc +135 -0
- data/src/core/lib/gprpp/global_config_env.h +131 -0
- data/src/core/lib/gprpp/global_config_generic.h +44 -0
- data/src/core/lib/gprpp/inlined_vector.h +8 -0
- data/src/core/lib/gprpp/map.h +436 -0
- data/src/core/lib/gprpp/memory.h +2 -2
- data/src/core/lib/gprpp/optional.h +48 -0
- data/src/core/lib/gprpp/orphanable.h +6 -5
- data/src/core/lib/gprpp/{mutex_lock.h → pair.h} +15 -19
- data/src/core/lib/gprpp/ref_counted.h +36 -17
- data/src/core/lib/gprpp/sync.h +126 -0
- data/src/core/lib/gprpp/thd.h +42 -7
- data/src/core/lib/gprpp/thd_posix.cc +31 -13
- data/src/core/lib/gprpp/thd_windows.cc +47 -34
- data/src/core/lib/http/httpcli.cc +6 -5
- data/src/core/lib/http/httpcli_security_connector.cc +13 -15
- data/src/core/lib/http/parser.cc +3 -2
- data/src/core/lib/http/parser.h +2 -1
- data/src/core/lib/iomgr/buffer_list.cc +182 -24
- data/src/core/lib/iomgr/buffer_list.h +72 -10
- data/src/core/lib/iomgr/call_combiner.cc +84 -90
- data/src/core/lib/iomgr/call_combiner.h +75 -82
- data/src/core/lib/iomgr/cfstream_handle.cc +203 -0
- data/src/core/lib/iomgr/cfstream_handle.h +86 -0
- data/src/core/lib/iomgr/combiner.cc +11 -3
- data/src/core/lib/iomgr/combiner.h +1 -1
- data/src/core/lib/iomgr/endpoint.cc +2 -2
- data/src/core/lib/iomgr/endpoint.h +3 -2
- data/src/core/lib/iomgr/endpoint_cfstream.cc +375 -0
- data/src/core/lib/iomgr/endpoint_cfstream.h +49 -0
- data/src/core/lib/iomgr/endpoint_pair_windows.cc +2 -2
- data/src/core/lib/iomgr/error.cc +21 -17
- data/src/core/lib/iomgr/error.h +36 -6
- data/src/core/lib/iomgr/error_cfstream.cc +52 -0
- data/src/core/lib/iomgr/error_cfstream.h +31 -0
- data/src/core/lib/iomgr/error_internal.h +1 -1
- data/src/core/lib/iomgr/ev_epoll1_linux.cc +44 -28
- data/src/core/lib/iomgr/ev_epollex_linux.cc +173 -194
- data/src/core/lib/iomgr/ev_poll_posix.cc +16 -487
- data/src/core/lib/iomgr/ev_posix.cc +29 -19
- data/src/core/lib/iomgr/ev_posix.h +19 -3
- data/src/core/lib/iomgr/ev_windows.cc +2 -2
- data/src/core/lib/iomgr/exec_ctx.cc +1 -0
- data/src/core/lib/iomgr/exec_ctx.h +137 -8
- data/src/core/lib/iomgr/executor.cc +147 -95
- data/src/core/lib/iomgr/executor.h +55 -49
- data/src/core/lib/iomgr/fork_posix.cc +6 -5
- data/src/core/lib/{gprpp/atomic_with_std.h → iomgr/grpc_if_nametoindex.h} +8 -13
- data/src/core/lib/iomgr/grpc_if_nametoindex_posix.cc +42 -0
- data/src/core/lib/iomgr/{network_status_tracker.h → grpc_if_nametoindex_unsupported.cc} +15 -9
- data/src/core/lib/iomgr/internal_errqueue.cc +3 -5
- data/src/core/lib/iomgr/internal_errqueue.h +105 -3
- data/src/core/lib/iomgr/iomgr.cc +20 -13
- data/src/core/lib/iomgr/iomgr.h +15 -0
- data/src/core/lib/iomgr/iomgr_custom.cc +17 -3
- data/src/core/lib/iomgr/iomgr_custom.h +2 -0
- data/src/core/lib/iomgr/iomgr_internal.cc +10 -0
- data/src/core/lib/iomgr/iomgr_internal.h +12 -0
- data/src/core/lib/iomgr/iomgr_posix.cc +19 -2
- data/src/core/lib/iomgr/iomgr_posix_cfstream.cc +93 -0
- data/src/core/lib/iomgr/iomgr_windows.cc +18 -2
- data/src/core/lib/iomgr/lockfree_event.cc +4 -4
- data/src/core/lib/iomgr/port.h +35 -0
- data/src/core/lib/iomgr/resolve_address_posix.cc +4 -3
- data/src/core/lib/iomgr/resolve_address_windows.cc +2 -1
- data/src/core/lib/iomgr/resource_quota.cc +40 -37
- data/src/core/lib/iomgr/socket_utils_common_posix.cc +6 -2
- data/src/core/lib/iomgr/socket_windows.cc +19 -0
- data/src/core/lib/iomgr/socket_windows.h +8 -0
- data/src/core/lib/iomgr/tcp_client_cfstream.cc +216 -0
- data/src/core/lib/iomgr/tcp_client_custom.cc +2 -2
- data/src/core/lib/iomgr/tcp_client_posix.cc +3 -3
- data/src/core/lib/iomgr/tcp_client_windows.cc +7 -5
- data/src/core/lib/iomgr/tcp_custom.cc +10 -14
- data/src/core/lib/iomgr/tcp_posix.cc +256 -140
- data/src/core/lib/iomgr/tcp_server.cc +5 -0
- data/src/core/lib/iomgr/tcp_server.h +24 -0
- data/src/core/lib/iomgr/tcp_server_custom.cc +14 -12
- data/src/core/lib/iomgr/tcp_server_posix.cc +86 -12
- data/src/core/lib/iomgr/tcp_server_utils_posix.h +3 -0
- data/src/core/lib/iomgr/tcp_server_windows.cc +13 -11
- data/src/core/lib/iomgr/tcp_uv.cc +5 -7
- data/src/core/lib/iomgr/tcp_windows.cc +8 -14
- data/src/core/lib/iomgr/timer.h +2 -1
- data/src/core/lib/iomgr/timer_generic.cc +16 -16
- data/src/core/lib/iomgr/timer_manager.cc +20 -11
- data/src/core/lib/iomgr/udp_server.cc +8 -6
- data/src/core/lib/iomgr/wakeup_fd_posix.cc +1 -19
- data/src/core/lib/json/json.cc +1 -4
- data/src/core/lib/profiling/basic_timers.cc +10 -4
- data/src/core/lib/security/context/security_context.cc +6 -7
- data/src/core/lib/security/context/security_context.h +3 -4
- data/src/core/lib/security/credentials/alts/alts_credentials.cc +1 -1
- data/src/core/lib/security/credentials/alts/check_gcp_environment_no_op.cc +2 -2
- data/src/core/lib/security/credentials/composite/composite_credentials.h +4 -0
- data/src/core/lib/security/credentials/credentials.h +9 -1
- data/src/core/lib/security/credentials/google_default/google_default_credentials.cc +15 -3
- data/src/core/lib/security/credentials/google_default/google_default_credentials.h +2 -0
- data/src/core/lib/security/credentials/jwt/json_token.cc +1 -1
- data/src/core/lib/security/credentials/jwt/jwt_credentials.cc +2 -1
- data/src/core/lib/security/credentials/jwt/jwt_verifier.cc +10 -6
- data/src/core/lib/security/credentials/jwt/jwt_verifier.h +2 -1
- data/src/core/lib/security/credentials/oauth2/oauth2_credentials.cc +3 -3
- data/src/core/lib/security/credentials/plugin/plugin_credentials.cc +9 -8
- data/src/core/lib/security/credentials/ssl/ssl_credentials.cc +20 -2
- data/src/core/lib/security/credentials/ssl/ssl_credentials.h +2 -2
- data/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc +192 -0
- data/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h +210 -0
- data/src/core/lib/security/credentials/tls/spiffe_credentials.cc +129 -0
- data/src/core/lib/security/credentials/tls/spiffe_credentials.h +62 -0
- data/src/core/lib/security/security_connector/alts/alts_security_connector.cc +10 -8
- data/src/core/lib/security/security_connector/fake/fake_security_connector.cc +13 -12
- data/src/core/lib/security/security_connector/load_system_roots_linux.cc +7 -5
- data/src/core/lib/security/security_connector/local/local_security_connector.cc +10 -8
- data/src/core/lib/security/security_connector/security_connector.cc +0 -1
- data/src/core/lib/security/security_connector/security_connector.h +3 -3
- data/src/core/lib/security/security_connector/ssl/ssl_security_connector.cc +39 -38
- data/src/core/lib/security/security_connector/ssl_utils.cc +164 -26
- data/src/core/lib/security/security_connector/ssl_utils.h +70 -1
- data/src/core/lib/security/security_connector/tls/spiffe_security_connector.cc +426 -0
- data/src/core/lib/security/security_connector/tls/spiffe_security_connector.h +122 -0
- data/src/core/lib/security/transport/auth_filters.h +5 -2
- data/src/core/lib/security/transport/client_auth_filter.cc +55 -50
- data/src/core/lib/security/transport/secure_endpoint.cc +6 -6
- data/src/core/lib/security/transport/security_handshaker.cc +271 -303
- data/src/core/lib/security/transport/security_handshaker.h +11 -2
- data/src/core/lib/security/transport/server_auth_filter.cc +3 -3
- data/src/core/lib/slice/b64.h +2 -2
- data/src/core/lib/slice/percent_encoding.cc +3 -3
- data/src/core/lib/slice/percent_encoding.h +3 -3
- data/src/core/lib/slice/slice.cc +174 -122
- data/src/core/lib/slice/slice_buffer.cc +54 -21
- data/src/core/lib/slice/slice_hash_table.h +4 -4
- data/src/core/lib/slice/slice_intern.cc +49 -107
- data/src/core/lib/slice/slice_internal.h +264 -3
- data/src/core/lib/slice/slice_string_helpers.cc +10 -1
- data/src/core/lib/slice/slice_string_helpers.h +3 -1
- data/src/core/lib/slice/slice_utils.h +50 -0
- data/src/core/lib/slice/slice_weak_hash_table.h +6 -6
- data/src/core/lib/surface/api_trace.h +1 -1
- data/src/core/lib/surface/byte_buffer_reader.cc +17 -0
- data/src/core/lib/surface/call.cc +67 -46
- data/src/core/lib/surface/call.h +7 -2
- data/src/core/lib/surface/call_details.cc +0 -1
- data/src/core/lib/surface/channel.cc +89 -97
- data/src/core/lib/surface/channel.h +60 -6
- data/src/core/lib/surface/channel_init.h +5 -0
- data/src/core/lib/surface/completion_queue.cc +221 -216
- data/src/core/lib/surface/completion_queue.h +2 -1
- data/src/core/lib/surface/init.cc +82 -33
- data/src/core/lib/surface/init.h +1 -0
- data/src/core/lib/surface/init_secure.cc +1 -1
- data/src/core/lib/surface/lame_client.cc +5 -7
- data/src/core/lib/surface/server.cc +42 -47
- data/src/core/lib/surface/validate_metadata.cc +14 -8
- data/src/core/lib/surface/validate_metadata.h +13 -2
- data/src/core/lib/surface/version.cc +1 -1
- data/src/core/lib/transport/bdp_estimator.cc +3 -3
- data/src/core/lib/transport/bdp_estimator.h +2 -2
- data/src/core/lib/transport/connectivity_state.cc +10 -40
- data/src/core/lib/transport/connectivity_state.h +0 -8
- data/src/core/lib/transport/error_utils.cc +12 -0
- data/src/core/lib/transport/metadata.cc +258 -267
- data/src/core/lib/transport/metadata.h +227 -16
- data/src/core/lib/transport/metadata_batch.cc +1 -1
- data/src/core/lib/transport/metadata_batch.h +1 -1
- data/src/core/lib/transport/static_metadata.cc +477 -399
- data/src/core/lib/transport/static_metadata.h +273 -182
- data/src/core/lib/transport/status_metadata.cc +3 -3
- data/src/core/lib/transport/timeout_encoding.cc +1 -1
- data/src/core/lib/transport/timeout_encoding.h +1 -1
- data/src/core/lib/transport/transport.cc +39 -72
- data/src/core/lib/transport/transport.h +59 -24
- data/src/core/lib/transport/transport_impl.h +1 -1
- data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +3 -3
- data/src/core/tsi/alts/handshaker/alts_handshaker_client.h +1 -1
- data/src/core/tsi/alts/handshaker/alts_shared_resource.h +1 -1
- data/src/core/tsi/alts/handshaker/transport_security_common_api.cc +4 -3
- data/src/core/tsi/alts/handshaker/transport_security_common_api.h +1 -1
- data/src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc +1 -1
- data/src/core/tsi/fake_transport_security.cc +4 -4
- data/src/core/tsi/ssl/session_cache/ssl_session_cache.cc +1 -1
- data/src/core/tsi/ssl_transport_security.cc +12 -10
- data/src/core/tsi/ssl_transport_security.h +24 -4
- data/src/ruby/bin/math_pb.rb +18 -16
- data/src/ruby/ext/grpc/extconf.rb +12 -4
- data/src/ruby/ext/grpc/rb_call_credentials.c +8 -5
- data/src/ruby/ext/grpc/rb_channel.c +14 -10
- data/src/ruby/ext/grpc/rb_channel_credentials.c +8 -4
- data/src/ruby/ext/grpc/rb_compression_options.c +9 -7
- data/src/ruby/ext/grpc/rb_event_thread.c +2 -0
- data/src/ruby/ext/grpc/rb_grpc.c +23 -24
- data/src/ruby/ext/grpc/rb_grpc.h +4 -2
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +24 -0
- data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +36 -0
- data/src/ruby/ext/grpc/rb_server.c +8 -4
- data/src/ruby/lib/grpc/errors.rb +22 -3
- data/src/ruby/lib/grpc/generic/bidi_call.rb +1 -1
- data/src/ruby/lib/grpc/generic/rpc_server.rb +2 -2
- data/src/ruby/lib/grpc/version.rb +1 -1
- data/src/ruby/pb/README.md +1 -1
- data/src/ruby/pb/grpc/health/v1/health_pb.rb +13 -10
- data/src/ruby/pb/grpc/health/v1/health_services_pb.rb +18 -0
- data/src/ruby/pb/src/proto/grpc/testing/empty_pb.rb +3 -1
- data/src/ruby/pb/src/proto/grpc/testing/messages_pb.rb +58 -56
- data/src/ruby/pb/src/proto/grpc/testing/test_pb.rb +2 -0
- data/src/ruby/spec/errors_spec.rb +141 -0
- data/third_party/cares/cares/ares.h +12 -0
- data/third_party/cares/cares/ares_create_query.c +5 -1
- data/third_party/cares/cares/ares_data.c +74 -73
- data/third_party/cares/cares/ares_destroy.c +6 -1
- data/third_party/cares/cares/ares_gethostbyaddr.c +5 -5
- data/third_party/cares/cares/ares_gethostbyname.c +15 -4
- data/third_party/cares/cares/ares_getnameinfo.c +11 -0
- data/third_party/cares/cares/ares_init.c +274 -173
- data/third_party/cares/cares/ares_library_init.c +21 -3
- data/third_party/cares/cares/ares_options.c +6 -2
- data/third_party/cares/cares/ares_parse_naptr_reply.c +7 -6
- data/third_party/cares/cares/ares_parse_ptr_reply.c +4 -2
- data/third_party/cares/cares/ares_platform.c +7 -0
- data/third_party/cares/cares/ares_private.h +19 -11
- data/third_party/cares/cares/ares_process.c +27 -2
- data/third_party/cares/cares/ares_rules.h +1 -1
- data/third_party/cares/cares/ares_search.c +7 -0
- data/third_party/cares/cares/ares_send.c +6 -0
- data/third_party/cares/cares/ares_strsplit.c +174 -0
- data/third_party/cares/cares/ares_strsplit.h +43 -0
- data/third_party/cares/cares/ares_version.h +4 -4
- data/third_party/cares/cares/config-win32.h +1 -1
- data/third_party/cares/cares/inet_ntop.c +2 -3
- data/third_party/cares/config_darwin/ares_config.h +3 -0
- data/third_party/cares/config_freebsd/ares_config.h +3 -0
- data/third_party/cares/config_linux/ares_config.h +3 -0
- data/third_party/cares/config_openbsd/ares_config.h +3 -0
- metadata +83 -48
- data/src/core/ext/filters/client_channel/request_routing.cc +0 -936
- data/src/core/ext/filters/client_channel/request_routing.h +0 -177
- data/src/core/ext/filters/client_channel/subchannel_index.cc +0 -248
- data/src/core/ext/filters/client_channel/subchannel_index.h +0 -76
- data/src/core/lib/channel/handshaker_factory.cc +0 -42
- data/src/core/lib/gpr/arena.cc +0 -192
- data/src/core/lib/gprpp/atomic_with_atm.h +0 -57
- data/src/core/lib/iomgr/wakeup_fd_cv.cc +0 -107
- data/src/core/lib/iomgr/wakeup_fd_cv.h +0 -69
- data/src/core/lib/transport/service_config.cc +0 -106
- data/src/core/lib/transport/service_config.h +0 -249
@@ -26,30 +26,27 @@
|
|
26
26
|
/// channel that uses pick_first to select from the list of balancer
|
27
27
|
/// addresses.
|
28
28
|
///
|
29
|
-
///
|
30
|
-
/// the
|
31
|
-
///
|
32
|
-
///
|
33
|
-
///
|
34
|
-
///
|
35
|
-
///
|
36
|
-
/// will be made immediately; otherwise, we apply back-off delays between
|
37
|
-
/// attempts.
|
29
|
+
/// When we get our initial update, we instantiate the internal *streaming*
|
30
|
+
/// call to the LB server (whichever address pick_first chose). The call
|
31
|
+
/// will be complete when either the balancer sends status or when we cancel
|
32
|
+
/// the call (e.g., because we are shutting down). In needed, we retry the
|
33
|
+
/// call. If we received at least one valid message from the server, a new
|
34
|
+
/// call attempt will be made immediately; otherwise, we apply back-off
|
35
|
+
/// delays between attempts.
|
38
36
|
///
|
39
37
|
/// We maintain an internal round_robin policy instance for distributing
|
40
38
|
/// requests across backends. Whenever we receive a new serverlist from
|
41
39
|
/// the balancer, we update the round_robin policy with the new list of
|
42
40
|
/// addresses. If we cannot communicate with the balancer on startup,
|
43
41
|
/// however, we may enter fallback mode, in which case we will populate
|
44
|
-
/// the
|
42
|
+
/// the child policy's addresses from the backend addresses returned by the
|
45
43
|
/// resolver.
|
46
44
|
///
|
47
|
-
/// Once
|
45
|
+
/// Once a child policy instance is in place (and getting updated as described),
|
48
46
|
/// calls for a pick, a ping, or a cancellation will be serviced right
|
49
|
-
/// away by forwarding them to the
|
50
|
-
/// policy available (i.e., right after the creation of the gRPCLB
|
51
|
-
/// pick
|
52
|
-
/// to be flushed and serviced when the RR policy instance becomes available.
|
47
|
+
/// away by forwarding them to the child policy instance. Any time there's no
|
48
|
+
/// child policy available (i.e., right after the creation of the gRPCLB
|
49
|
+
/// policy), pick requests are queued.
|
53
50
|
///
|
54
51
|
/// \see https://github.com/grpc/grpc/blob/master/doc/load-balancing.md for the
|
55
52
|
/// high level design and details.
|
@@ -74,7 +71,6 @@
|
|
74
71
|
#include <grpc/support/time.h>
|
75
72
|
|
76
73
|
#include "src/core/ext/filters/client_channel/client_channel.h"
|
77
|
-
#include "src/core/ext/filters/client_channel/client_channel_factory.h"
|
78
74
|
#include "src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.h"
|
79
75
|
#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.h"
|
80
76
|
#include "src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_channel.h"
|
@@ -85,7 +81,6 @@
|
|
85
81
|
#include "src/core/ext/filters/client_channel/parse_address.h"
|
86
82
|
#include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h"
|
87
83
|
#include "src/core/ext/filters/client_channel/server_address.h"
|
88
|
-
#include "src/core/ext/filters/client_channel/subchannel_index.h"
|
89
84
|
#include "src/core/lib/backoff/backoff.h"
|
90
85
|
#include "src/core/lib/channel/channel_args.h"
|
91
86
|
#include "src/core/lib/channel/channel_stack.h"
|
@@ -93,7 +88,6 @@
|
|
93
88
|
#include "src/core/lib/gpr/string.h"
|
94
89
|
#include "src/core/lib/gprpp/manual_constructor.h"
|
95
90
|
#include "src/core/lib/gprpp/memory.h"
|
96
|
-
#include "src/core/lib/gprpp/mutex_lock.h"
|
97
91
|
#include "src/core/lib/gprpp/orphanable.h"
|
98
92
|
#include "src/core/lib/gprpp/ref_counted_ptr.h"
|
99
93
|
#include "src/core/lib/iomgr/combiner.h"
|
@@ -124,56 +118,31 @@ namespace {
|
|
124
118
|
|
125
119
|
constexpr char kGrpclb[] = "grpclb";
|
126
120
|
|
121
|
+
class ParsedGrpcLbConfig : public LoadBalancingPolicy::Config {
|
122
|
+
public:
|
123
|
+
explicit ParsedGrpcLbConfig(
|
124
|
+
RefCountedPtr<LoadBalancingPolicy::Config> child_policy)
|
125
|
+
: child_policy_(std::move(child_policy)) {}
|
126
|
+
const char* name() const override { return kGrpclb; }
|
127
|
+
|
128
|
+
RefCountedPtr<LoadBalancingPolicy::Config> child_policy() const {
|
129
|
+
return child_policy_;
|
130
|
+
}
|
131
|
+
|
132
|
+
private:
|
133
|
+
RefCountedPtr<LoadBalancingPolicy::Config> child_policy_;
|
134
|
+
};
|
135
|
+
|
127
136
|
class GrpcLb : public LoadBalancingPolicy {
|
128
137
|
public:
|
129
|
-
explicit GrpcLb(
|
138
|
+
explicit GrpcLb(Args args);
|
130
139
|
|
131
140
|
const char* name() const override { return kGrpclb; }
|
132
141
|
|
133
|
-
void UpdateLocked(
|
134
|
-
grpc_json* lb_config) override;
|
135
|
-
bool PickLocked(PickState* pick, grpc_error** error) override;
|
136
|
-
void CancelPickLocked(PickState* pick, grpc_error* error) override;
|
137
|
-
void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask,
|
138
|
-
uint32_t initial_metadata_flags_eq,
|
139
|
-
grpc_error* error) override;
|
140
|
-
void NotifyOnStateChangeLocked(grpc_connectivity_state* state,
|
141
|
-
grpc_closure* closure) override;
|
142
|
-
grpc_connectivity_state CheckConnectivityLocked(
|
143
|
-
grpc_error** connectivity_error) override;
|
144
|
-
void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) override;
|
145
|
-
void ExitIdleLocked() override;
|
142
|
+
void UpdateLocked(UpdateArgs args) override;
|
146
143
|
void ResetBackoffLocked() override;
|
147
|
-
void FillChildRefsForChannelz(
|
148
|
-
channelz::ChildRefsList* child_subchannels,
|
149
|
-
channelz::ChildRefsList* child_channels) override;
|
150
144
|
|
151
145
|
private:
|
152
|
-
/// Linked list of pending pick requests. It stores all information needed to
|
153
|
-
/// eventually call (Round Robin's) pick() on them. They mainly stay pending
|
154
|
-
/// waiting for the RR policy to be created.
|
155
|
-
///
|
156
|
-
/// Note that when a pick is sent to the RR policy, we inject our own
|
157
|
-
/// on_complete callback, so that we can intercept the result before
|
158
|
-
/// invoking the original on_complete callback. This allows us to set the
|
159
|
-
/// LB token metadata and add client_stats to the call context.
|
160
|
-
/// See \a pending_pick_complete() for details.
|
161
|
-
struct PendingPick {
|
162
|
-
// The grpclb instance that created the wrapping. This instance is not
|
163
|
-
// owned; reference counts are untouched. It's used only for logging
|
164
|
-
// purposes.
|
165
|
-
GrpcLb* grpclb_policy;
|
166
|
-
// The original pick.
|
167
|
-
PickState* pick;
|
168
|
-
// Our on_complete closure and the original one.
|
169
|
-
grpc_closure on_complete;
|
170
|
-
grpc_closure* original_on_complete;
|
171
|
-
// Stats for client-side load reporting.
|
172
|
-
RefCountedPtr<GrpcLbClientStats> client_stats;
|
173
|
-
// Next pending pick.
|
174
|
-
PendingPick* next = nullptr;
|
175
|
-
};
|
176
|
-
|
177
146
|
/// Contains a call to the LB server and all the data related to the call.
|
178
147
|
class BalancerCallState : public InternallyRefCounted<BalancerCallState> {
|
179
148
|
public:
|
@@ -189,6 +158,7 @@ class GrpcLb : public LoadBalancingPolicy {
|
|
189
158
|
GrpcLbClientStats* client_stats() const { return client_stats_.get(); }
|
190
159
|
|
191
160
|
bool seen_initial_response() const { return seen_initial_response_; }
|
161
|
+
bool seen_serverlist() const { return seen_serverlist_; }
|
192
162
|
|
193
163
|
private:
|
194
164
|
// So Delete() can access our private dtor.
|
@@ -229,6 +199,7 @@ class GrpcLb : public LoadBalancingPolicy {
|
|
229
199
|
grpc_byte_buffer* recv_message_payload_ = nullptr;
|
230
200
|
grpc_closure lb_on_balancer_message_received_;
|
231
201
|
bool seen_initial_response_ = false;
|
202
|
+
bool seen_serverlist_ = false;
|
232
203
|
|
233
204
|
// recv_trailing_metadata
|
234
205
|
grpc_closure lb_on_balancer_status_received_;
|
@@ -249,40 +220,121 @@ class GrpcLb : public LoadBalancingPolicy {
|
|
249
220
|
grpc_closure client_load_report_closure_;
|
250
221
|
};
|
251
222
|
|
223
|
+
class Serverlist : public RefCounted<Serverlist> {
|
224
|
+
public:
|
225
|
+
// Takes ownership of serverlist.
|
226
|
+
explicit Serverlist(grpc_grpclb_serverlist* serverlist)
|
227
|
+
: serverlist_(serverlist) {}
|
228
|
+
|
229
|
+
~Serverlist() { grpc_grpclb_destroy_serverlist(serverlist_); }
|
230
|
+
|
231
|
+
bool operator==(const Serverlist& other) const;
|
232
|
+
|
233
|
+
const grpc_grpclb_serverlist* serverlist() const { return serverlist_; }
|
234
|
+
|
235
|
+
// Returns a text representation suitable for logging.
|
236
|
+
UniquePtr<char> AsText() const;
|
237
|
+
|
238
|
+
// Extracts all non-drop entries into a ServerAddressList.
|
239
|
+
ServerAddressList GetServerAddressList(
|
240
|
+
GrpcLbClientStats* client_stats) const;
|
241
|
+
|
242
|
+
// Returns true if the serverlist contains at least one drop entry and
|
243
|
+
// no backend address entries.
|
244
|
+
bool ContainsAllDropEntries() const;
|
245
|
+
|
246
|
+
// Returns the LB token to use for a drop, or null if the call
|
247
|
+
// should not be dropped.
|
248
|
+
//
|
249
|
+
// Note: This is called from the picker, so it will be invoked in
|
250
|
+
// the channel's data plane combiner, NOT the control plane
|
251
|
+
// combiner. It should not be accessed by any other part of the LB
|
252
|
+
// policy.
|
253
|
+
const char* ShouldDrop();
|
254
|
+
|
255
|
+
private:
|
256
|
+
grpc_grpclb_serverlist* serverlist_;
|
257
|
+
|
258
|
+
// Guarded by the channel's data plane combiner, NOT the control
|
259
|
+
// plane combiner. It should not be accessed by anything but the
|
260
|
+
// picker via the ShouldDrop() method.
|
261
|
+
size_t drop_index_ = 0;
|
262
|
+
};
|
263
|
+
|
264
|
+
class Picker : public SubchannelPicker {
|
265
|
+
public:
|
266
|
+
Picker(GrpcLb* parent, RefCountedPtr<Serverlist> serverlist,
|
267
|
+
UniquePtr<SubchannelPicker> child_picker,
|
268
|
+
RefCountedPtr<GrpcLbClientStats> client_stats)
|
269
|
+
: parent_(parent),
|
270
|
+
serverlist_(std::move(serverlist)),
|
271
|
+
child_picker_(std::move(child_picker)),
|
272
|
+
client_stats_(std::move(client_stats)) {}
|
273
|
+
|
274
|
+
PickResult Pick(PickArgs args) override;
|
275
|
+
|
276
|
+
private:
|
277
|
+
// Storing the address for logging, but not holding a ref.
|
278
|
+
// DO NOT DEFERENCE!
|
279
|
+
GrpcLb* parent_;
|
280
|
+
|
281
|
+
// Serverlist to be used for determining drops.
|
282
|
+
RefCountedPtr<Serverlist> serverlist_;
|
283
|
+
|
284
|
+
UniquePtr<SubchannelPicker> child_picker_;
|
285
|
+
RefCountedPtr<GrpcLbClientStats> client_stats_;
|
286
|
+
};
|
287
|
+
|
288
|
+
class Helper : public ChannelControlHelper {
|
289
|
+
public:
|
290
|
+
explicit Helper(RefCountedPtr<GrpcLb> parent)
|
291
|
+
: parent_(std::move(parent)) {}
|
292
|
+
|
293
|
+
RefCountedPtr<SubchannelInterface> CreateSubchannel(
|
294
|
+
const grpc_channel_args& args) override;
|
295
|
+
grpc_channel* CreateChannel(const char* target,
|
296
|
+
const grpc_channel_args& args) override;
|
297
|
+
void UpdateState(grpc_connectivity_state state,
|
298
|
+
UniquePtr<SubchannelPicker> picker) override;
|
299
|
+
void RequestReresolution() override;
|
300
|
+
void AddTraceEvent(TraceSeverity severity, const char* message) override;
|
301
|
+
|
302
|
+
void set_child(LoadBalancingPolicy* child) { child_ = child; }
|
303
|
+
|
304
|
+
private:
|
305
|
+
bool CalledByPendingChild() const;
|
306
|
+
bool CalledByCurrentChild() const;
|
307
|
+
|
308
|
+
RefCountedPtr<GrpcLb> parent_;
|
309
|
+
LoadBalancingPolicy* child_ = nullptr;
|
310
|
+
};
|
311
|
+
|
252
312
|
~GrpcLb();
|
253
313
|
|
254
314
|
void ShutdownLocked() override;
|
255
315
|
|
256
|
-
// Helper
|
257
|
-
void
|
316
|
+
// Helper functions used in UpdateLocked().
|
317
|
+
void ProcessAddressesAndChannelArgsLocked(const ServerAddressList& addresses,
|
318
|
+
const grpc_channel_args& args);
|
319
|
+
static void OnBalancerChannelConnectivityChangedLocked(void* arg,
|
320
|
+
grpc_error* error);
|
321
|
+
void CancelBalancerChannelConnectivityWatchLocked();
|
258
322
|
|
259
|
-
// Methods for dealing with
|
260
|
-
void
|
261
|
-
void StartBalancerCallLocked();
|
323
|
+
// Methods for dealing with fallback state.
|
324
|
+
void MaybeEnterFallbackModeAfterStartup();
|
262
325
|
static void OnFallbackTimerLocked(void* arg, grpc_error* error);
|
326
|
+
|
327
|
+
// Methods for dealing with the balancer call.
|
328
|
+
void StartBalancerCallLocked();
|
263
329
|
void StartBalancerCallRetryTimerLocked();
|
264
330
|
static void OnBalancerCallRetryTimerLocked(void* arg, grpc_error* error);
|
265
|
-
static void OnBalancerChannelConnectivityChangedLocked(void* arg,
|
266
|
-
grpc_error* error);
|
267
331
|
|
268
|
-
//
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
// Methods for dealing with the RR policy.
|
275
|
-
void CreateOrUpdateRoundRobinPolicyLocked();
|
276
|
-
grpc_channel_args* CreateRoundRobinPolicyArgsLocked();
|
277
|
-
void CreateRoundRobinPolicyLocked(const Args& args);
|
278
|
-
bool PickFromRoundRobinPolicyLocked(bool force_async, PendingPick* pp,
|
279
|
-
grpc_error** error);
|
280
|
-
void UpdateConnectivityStateFromRoundRobinPolicyLocked(
|
281
|
-
grpc_error* rr_state_error);
|
282
|
-
static void OnRoundRobinConnectivityChangedLocked(void* arg,
|
283
|
-
grpc_error* error);
|
284
|
-
static void OnRoundRobinRequestReresolutionLocked(void* arg,
|
285
|
-
grpc_error* error);
|
332
|
+
// Methods for dealing with the child policy.
|
333
|
+
grpc_channel_args* CreateChildPolicyArgsLocked(
|
334
|
+
bool is_backend_from_grpclb_load_balancer);
|
335
|
+
OrphanablePtr<LoadBalancingPolicy> CreateChildPolicyLocked(
|
336
|
+
const char* name, const grpc_channel_args* args);
|
337
|
+
void CreateOrUpdateChildPolicyLocked();
|
286
338
|
|
287
339
|
// Who the client is trying to communicate with.
|
288
340
|
const char* server_name_ = nullptr;
|
@@ -291,19 +343,10 @@ class GrpcLb : public LoadBalancingPolicy {
|
|
291
343
|
grpc_channel_args* args_ = nullptr;
|
292
344
|
|
293
345
|
// Internal state.
|
294
|
-
bool started_picking_ = false;
|
295
346
|
bool shutting_down_ = false;
|
296
|
-
grpc_connectivity_state_tracker state_tracker_;
|
297
347
|
|
298
348
|
// The channel for communicating with the LB server.
|
299
349
|
grpc_channel* lb_channel_ = nullptr;
|
300
|
-
// Mutex to protect the channel to the LB server. This is used when
|
301
|
-
// processing a channelz request.
|
302
|
-
gpr_mu lb_channel_mu_;
|
303
|
-
grpc_connectivity_state lb_channel_connectivity_;
|
304
|
-
grpc_closure lb_channel_on_connectivity_changed_;
|
305
|
-
// Are we already watching the LB channel's connectivity?
|
306
|
-
bool watching_lb_channel_ = false;
|
307
350
|
// Response generator to inject address updates into lb_channel_.
|
308
351
|
RefCountedPtr<FakeResolverResponseGenerator> response_generator_;
|
309
352
|
|
@@ -323,36 +366,88 @@ class GrpcLb : public LoadBalancingPolicy {
|
|
323
366
|
|
324
367
|
// The deserialized response from the balancer. May be nullptr until one
|
325
368
|
// such response has arrived.
|
326
|
-
|
327
|
-
|
328
|
-
//
|
329
|
-
|
330
|
-
size_t serverlist_index_ = 0;
|
331
|
-
|
332
|
-
// Timeout in milliseconds for before using fallback backend addresses.
|
333
|
-
// 0 means not using fallback.
|
334
|
-
int lb_fallback_timeout_ms_ = 0;
|
369
|
+
RefCountedPtr<Serverlist> serverlist_;
|
370
|
+
|
371
|
+
// Whether we're in fallback mode.
|
372
|
+
bool fallback_mode_ = false;
|
335
373
|
// The backend addresses from the resolver.
|
336
|
-
|
337
|
-
//
|
338
|
-
|
374
|
+
ServerAddressList fallback_backend_addresses_;
|
375
|
+
// State for fallback-at-startup checks.
|
376
|
+
// Timeout after startup after which we will go into fallback mode if
|
377
|
+
// we have not received a serverlist from the balancer.
|
378
|
+
int fallback_at_startup_timeout_ = 0;
|
379
|
+
bool fallback_at_startup_checks_pending_ = false;
|
339
380
|
grpc_timer lb_fallback_timer_;
|
340
381
|
grpc_closure lb_on_fallback_;
|
382
|
+
grpc_connectivity_state lb_channel_connectivity_ = GRPC_CHANNEL_IDLE;
|
383
|
+
grpc_closure lb_channel_on_connectivity_changed_;
|
341
384
|
|
342
|
-
//
|
343
|
-
|
344
|
-
|
345
|
-
//
|
346
|
-
OrphanablePtr<LoadBalancingPolicy>
|
347
|
-
|
348
|
-
|
349
|
-
|
385
|
+
// The child policy to use for the backends.
|
386
|
+
OrphanablePtr<LoadBalancingPolicy> child_policy_;
|
387
|
+
// When switching child policies, the new policy will be stored here
|
388
|
+
// until it reports READY, at which point it will be moved to child_policy_.
|
389
|
+
OrphanablePtr<LoadBalancingPolicy> pending_child_policy_;
|
390
|
+
// The child policy config.
|
391
|
+
RefCountedPtr<LoadBalancingPolicy::Config> child_policy_config_;
|
392
|
+
// Child policy in state READY.
|
393
|
+
bool child_policy_ready_ = false;
|
350
394
|
};
|
351
395
|
|
352
396
|
//
|
353
|
-
//
|
397
|
+
// GrpcLb::Serverlist
|
354
398
|
//
|
355
399
|
|
400
|
+
bool GrpcLb::Serverlist::operator==(const Serverlist& other) const {
|
401
|
+
return grpc_grpclb_serverlist_equals(serverlist_, other.serverlist_);
|
402
|
+
}
|
403
|
+
|
404
|
+
void ParseServer(const grpc_grpclb_server* server,
|
405
|
+
grpc_resolved_address* addr) {
|
406
|
+
memset(addr, 0, sizeof(*addr));
|
407
|
+
if (server->drop) return;
|
408
|
+
const uint16_t netorder_port = grpc_htons((uint16_t)server->port);
|
409
|
+
/* the addresses are given in binary format (a in(6)_addr struct) in
|
410
|
+
* server->ip_address.bytes. */
|
411
|
+
const grpc_grpclb_ip_address* ip = &server->ip_address;
|
412
|
+
if (ip->size == 4) {
|
413
|
+
addr->len = static_cast<socklen_t>(sizeof(grpc_sockaddr_in));
|
414
|
+
grpc_sockaddr_in* addr4 = reinterpret_cast<grpc_sockaddr_in*>(&addr->addr);
|
415
|
+
addr4->sin_family = GRPC_AF_INET;
|
416
|
+
memcpy(&addr4->sin_addr, ip->bytes, ip->size);
|
417
|
+
addr4->sin_port = netorder_port;
|
418
|
+
} else if (ip->size == 16) {
|
419
|
+
addr->len = static_cast<socklen_t>(sizeof(grpc_sockaddr_in6));
|
420
|
+
grpc_sockaddr_in6* addr6 = (grpc_sockaddr_in6*)&addr->addr;
|
421
|
+
addr6->sin6_family = GRPC_AF_INET6;
|
422
|
+
memcpy(&addr6->sin6_addr, ip->bytes, ip->size);
|
423
|
+
addr6->sin6_port = netorder_port;
|
424
|
+
}
|
425
|
+
}
|
426
|
+
|
427
|
+
UniquePtr<char> GrpcLb::Serverlist::AsText() const {
|
428
|
+
gpr_strvec entries;
|
429
|
+
gpr_strvec_init(&entries);
|
430
|
+
for (size_t i = 0; i < serverlist_->num_servers; ++i) {
|
431
|
+
const auto* server = serverlist_->servers[i];
|
432
|
+
char* ipport;
|
433
|
+
if (server->drop) {
|
434
|
+
ipport = gpr_strdup("(drop)");
|
435
|
+
} else {
|
436
|
+
grpc_resolved_address addr;
|
437
|
+
ParseServer(server, &addr);
|
438
|
+
grpc_sockaddr_to_string(&ipport, &addr, false);
|
439
|
+
}
|
440
|
+
char* entry;
|
441
|
+
gpr_asprintf(&entry, " %" PRIuPTR ": %s token=%s\n", i, ipport,
|
442
|
+
server->load_balance_token);
|
443
|
+
gpr_free(ipport);
|
444
|
+
gpr_strvec_add(&entries, entry);
|
445
|
+
}
|
446
|
+
UniquePtr<char> result(gpr_strvec_flatten(&entries, nullptr));
|
447
|
+
gpr_strvec_destroy(&entries);
|
448
|
+
return result;
|
449
|
+
}
|
450
|
+
|
356
451
|
// vtable for LB token channel arg.
|
357
452
|
void* lb_token_copy(void* token) {
|
358
453
|
return token == nullptr
|
@@ -395,35 +490,13 @@ bool IsServerValid(const grpc_grpclb_server* server, size_t idx, bool log) {
|
|
395
490
|
return true;
|
396
491
|
}
|
397
492
|
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
if (server->drop) return;
|
402
|
-
const uint16_t netorder_port = grpc_htons((uint16_t)server->port);
|
403
|
-
/* the addresses are given in binary format (a in(6)_addr struct) in
|
404
|
-
* server->ip_address.bytes. */
|
405
|
-
const grpc_grpclb_ip_address* ip = &server->ip_address;
|
406
|
-
if (ip->size == 4) {
|
407
|
-
addr->len = static_cast<socklen_t>(sizeof(grpc_sockaddr_in));
|
408
|
-
grpc_sockaddr_in* addr4 = reinterpret_cast<grpc_sockaddr_in*>(&addr->addr);
|
409
|
-
addr4->sin_family = GRPC_AF_INET;
|
410
|
-
memcpy(&addr4->sin_addr, ip->bytes, ip->size);
|
411
|
-
addr4->sin_port = netorder_port;
|
412
|
-
} else if (ip->size == 16) {
|
413
|
-
addr->len = static_cast<socklen_t>(sizeof(grpc_sockaddr_in6));
|
414
|
-
grpc_sockaddr_in6* addr6 = (grpc_sockaddr_in6*)&addr->addr;
|
415
|
-
addr6->sin6_family = GRPC_AF_INET6;
|
416
|
-
memcpy(&addr6->sin6_addr, ip->bytes, ip->size);
|
417
|
-
addr6->sin6_port = netorder_port;
|
418
|
-
}
|
419
|
-
}
|
420
|
-
|
421
|
-
// Returns addresses extracted from \a serverlist.
|
422
|
-
ServerAddressList ProcessServerlist(const grpc_grpclb_serverlist* serverlist) {
|
493
|
+
// Returns addresses extracted from the serverlist.
|
494
|
+
ServerAddressList GrpcLb::Serverlist::GetServerAddressList(
|
495
|
+
GrpcLbClientStats* client_stats) const {
|
423
496
|
ServerAddressList addresses;
|
424
|
-
for (size_t i = 0; i <
|
425
|
-
const grpc_grpclb_server* server =
|
426
|
-
if (!IsServerValid(
|
497
|
+
for (size_t i = 0; i < serverlist_->num_servers; ++i) {
|
498
|
+
const grpc_grpclb_server* server = serverlist_->servers[i];
|
499
|
+
if (!IsServerValid(serverlist_->servers[i], i, false)) continue;
|
427
500
|
// Address processing.
|
428
501
|
grpc_resolved_address addr;
|
429
502
|
ParseServer(server, &addr);
|
@@ -437,6 +510,11 @@ ServerAddressList ProcessServerlist(const grpc_grpclb_serverlist* serverlist) {
|
|
437
510
|
grpc_slice lb_token_mdstr = grpc_slice_from_copied_buffer(
|
438
511
|
server->load_balance_token, lb_token_length);
|
439
512
|
lb_token = grpc_mdelem_from_slices(GRPC_MDSTR_LB_TOKEN, lb_token_mdstr);
|
513
|
+
if (client_stats != nullptr) {
|
514
|
+
GPR_ASSERT(grpc_mdelem_set_user_data(
|
515
|
+
lb_token, GrpcLbClientStats::Destroy,
|
516
|
+
client_stats->Ref().release()) == client_stats);
|
517
|
+
}
|
440
518
|
} else {
|
441
519
|
char* uri = grpc_sockaddr_to_uri(&addr);
|
442
520
|
gpr_log(GPR_INFO,
|
@@ -458,6 +536,206 @@ ServerAddressList ProcessServerlist(const grpc_grpclb_serverlist* serverlist) {
|
|
458
536
|
return addresses;
|
459
537
|
}
|
460
538
|
|
539
|
+
bool GrpcLb::Serverlist::ContainsAllDropEntries() const {
|
540
|
+
if (serverlist_->num_servers == 0) return false;
|
541
|
+
for (size_t i = 0; i < serverlist_->num_servers; ++i) {
|
542
|
+
if (!serverlist_->servers[i]->drop) return false;
|
543
|
+
}
|
544
|
+
return true;
|
545
|
+
}
|
546
|
+
|
547
|
+
const char* GrpcLb::Serverlist::ShouldDrop() {
|
548
|
+
if (serverlist_->num_servers == 0) return nullptr;
|
549
|
+
grpc_grpclb_server* server = serverlist_->servers[drop_index_];
|
550
|
+
drop_index_ = (drop_index_ + 1) % serverlist_->num_servers;
|
551
|
+
return server->drop ? server->load_balance_token : nullptr;
|
552
|
+
}
|
553
|
+
|
554
|
+
//
|
555
|
+
// GrpcLb::Picker
|
556
|
+
//
|
557
|
+
|
558
|
+
GrpcLb::PickResult GrpcLb::Picker::Pick(PickArgs args) {
|
559
|
+
PickResult result;
|
560
|
+
// Check if we should drop the call.
|
561
|
+
const char* drop_token = serverlist_->ShouldDrop();
|
562
|
+
if (drop_token != nullptr) {
|
563
|
+
// Update client load reporting stats to indicate the number of
|
564
|
+
// dropped calls. Note that we have to do this here instead of in
|
565
|
+
// the client_load_reporting filter, because we do not create a
|
566
|
+
// subchannel call (and therefore no client_load_reporting filter)
|
567
|
+
// for dropped calls.
|
568
|
+
if (client_stats_ != nullptr) {
|
569
|
+
client_stats_->AddCallDropped(drop_token);
|
570
|
+
}
|
571
|
+
result.type = PickResult::PICK_COMPLETE;
|
572
|
+
return result;
|
573
|
+
}
|
574
|
+
// Forward pick to child policy.
|
575
|
+
result = child_picker_->Pick(args);
|
576
|
+
// If pick succeeded, add LB token to initial metadata.
|
577
|
+
if (result.type == PickResult::PICK_COMPLETE &&
|
578
|
+
result.connected_subchannel != nullptr) {
|
579
|
+
const grpc_arg* arg = grpc_channel_args_find(
|
580
|
+
result.connected_subchannel->args(), GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN);
|
581
|
+
if (arg == nullptr) {
|
582
|
+
gpr_log(GPR_ERROR,
|
583
|
+
"[grpclb %p picker %p] No LB token for connected subchannel %p",
|
584
|
+
parent_, this, result.connected_subchannel.get());
|
585
|
+
abort();
|
586
|
+
}
|
587
|
+
grpc_mdelem lb_token = {reinterpret_cast<uintptr_t>(arg->value.pointer.p)};
|
588
|
+
GPR_ASSERT(!GRPC_MDISNULL(lb_token));
|
589
|
+
grpc_linked_mdelem* mdelem_storage = static_cast<grpc_linked_mdelem*>(
|
590
|
+
args.call_state->Alloc(sizeof(grpc_linked_mdelem)));
|
591
|
+
GPR_ASSERT(grpc_metadata_batch_add_tail(
|
592
|
+
args.initial_metadata, mdelem_storage,
|
593
|
+
GRPC_MDELEM_REF(lb_token)) == GRPC_ERROR_NONE);
|
594
|
+
GrpcLbClientStats* client_stats = static_cast<GrpcLbClientStats*>(
|
595
|
+
grpc_mdelem_get_user_data(lb_token, GrpcLbClientStats::Destroy));
|
596
|
+
if (client_stats != nullptr) {
|
597
|
+
client_stats->AddCallStarted();
|
598
|
+
}
|
599
|
+
}
|
600
|
+
return result;
|
601
|
+
}
|
602
|
+
|
603
|
+
//
|
604
|
+
// GrpcLb::Helper
|
605
|
+
//
|
606
|
+
|
607
|
+
bool GrpcLb::Helper::CalledByPendingChild() const {
|
608
|
+
GPR_ASSERT(child_ != nullptr);
|
609
|
+
return child_ == parent_->pending_child_policy_.get();
|
610
|
+
}
|
611
|
+
|
612
|
+
bool GrpcLb::Helper::CalledByCurrentChild() const {
|
613
|
+
GPR_ASSERT(child_ != nullptr);
|
614
|
+
return child_ == parent_->child_policy_.get();
|
615
|
+
}
|
616
|
+
|
617
|
+
RefCountedPtr<SubchannelInterface> GrpcLb::Helper::CreateSubchannel(
|
618
|
+
const grpc_channel_args& args) {
|
619
|
+
if (parent_->shutting_down_ ||
|
620
|
+
(!CalledByPendingChild() && !CalledByCurrentChild())) {
|
621
|
+
return nullptr;
|
622
|
+
}
|
623
|
+
return parent_->channel_control_helper()->CreateSubchannel(args);
|
624
|
+
}
|
625
|
+
|
626
|
+
grpc_channel* GrpcLb::Helper::CreateChannel(const char* target,
|
627
|
+
const grpc_channel_args& args) {
|
628
|
+
if (parent_->shutting_down_ ||
|
629
|
+
(!CalledByPendingChild() && !CalledByCurrentChild())) {
|
630
|
+
return nullptr;
|
631
|
+
}
|
632
|
+
return parent_->channel_control_helper()->CreateChannel(target, args);
|
633
|
+
}
|
634
|
+
|
635
|
+
void GrpcLb::Helper::UpdateState(grpc_connectivity_state state,
|
636
|
+
UniquePtr<SubchannelPicker> picker) {
|
637
|
+
if (parent_->shutting_down_) return;
|
638
|
+
// If this request is from the pending child policy, ignore it until
|
639
|
+
// it reports READY, at which point we swap it into place.
|
640
|
+
if (CalledByPendingChild()) {
|
641
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) {
|
642
|
+
gpr_log(GPR_INFO,
|
643
|
+
"[grpclb %p helper %p] pending child policy %p reports state=%s",
|
644
|
+
parent_.get(), this, parent_->pending_child_policy_.get(),
|
645
|
+
grpc_connectivity_state_name(state));
|
646
|
+
}
|
647
|
+
if (state != GRPC_CHANNEL_READY) return;
|
648
|
+
grpc_pollset_set_del_pollset_set(
|
649
|
+
parent_->child_policy_->interested_parties(),
|
650
|
+
parent_->interested_parties());
|
651
|
+
parent_->child_policy_ = std::move(parent_->pending_child_policy_);
|
652
|
+
} else if (!CalledByCurrentChild()) {
|
653
|
+
// This request is from an outdated child, so ignore it.
|
654
|
+
return;
|
655
|
+
}
|
656
|
+
// Record whether child policy reports READY.
|
657
|
+
parent_->child_policy_ready_ = state == GRPC_CHANNEL_READY;
|
658
|
+
// Enter fallback mode if needed.
|
659
|
+
parent_->MaybeEnterFallbackModeAfterStartup();
|
660
|
+
// There are three cases to consider here:
|
661
|
+
// 1. We're in fallback mode. In this case, we're always going to use
|
662
|
+
// the child policy's result, so we pass its picker through as-is.
|
663
|
+
// 2. The serverlist contains only drop entries. In this case, we
|
664
|
+
// want to use our own picker so that we can return the drops.
|
665
|
+
// 3. Not in fallback mode and serverlist is not all drops (i.e., it
|
666
|
+
// may be empty or contain at least one backend address). There are
|
667
|
+
// two sub-cases:
|
668
|
+
// a. The child policy is reporting state READY. In this case, we wrap
|
669
|
+
// the child's picker in our own, so that we can handle drops and LB
|
670
|
+
// token metadata for each pick.
|
671
|
+
// b. The child policy is reporting a state other than READY. In this
|
672
|
+
// case, we don't want to use our own picker, because we don't want
|
673
|
+
// to process drops for picks that yield a QUEUE result; this would
|
674
|
+
// result in dropping too many calls, since we will see the
|
675
|
+
// queued picks multiple times, and we'd consider each one a
|
676
|
+
// separate call for the drop calculation.
|
677
|
+
//
|
678
|
+
// Cases 1 and 3b: return picker from the child policy as-is.
|
679
|
+
if (parent_->serverlist_ == nullptr ||
|
680
|
+
(!parent_->serverlist_->ContainsAllDropEntries() &&
|
681
|
+
state != GRPC_CHANNEL_READY)) {
|
682
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) {
|
683
|
+
gpr_log(GPR_INFO,
|
684
|
+
"[grpclb %p helper %p] state=%s passing child picker %p as-is",
|
685
|
+
parent_.get(), this, grpc_connectivity_state_name(state),
|
686
|
+
picker.get());
|
687
|
+
}
|
688
|
+
parent_->channel_control_helper()->UpdateState(state, std::move(picker));
|
689
|
+
return;
|
690
|
+
}
|
691
|
+
// Cases 2 and 3a: wrap picker from the child in our own picker.
|
692
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) {
|
693
|
+
gpr_log(GPR_INFO, "[grpclb %p helper %p] state=%s wrapping child picker %p",
|
694
|
+
parent_.get(), this, grpc_connectivity_state_name(state),
|
695
|
+
picker.get());
|
696
|
+
}
|
697
|
+
RefCountedPtr<GrpcLbClientStats> client_stats;
|
698
|
+
if (parent_->lb_calld_ != nullptr &&
|
699
|
+
parent_->lb_calld_->client_stats() != nullptr) {
|
700
|
+
client_stats = parent_->lb_calld_->client_stats()->Ref();
|
701
|
+
}
|
702
|
+
parent_->channel_control_helper()->UpdateState(
|
703
|
+
state, UniquePtr<SubchannelPicker>(
|
704
|
+
New<Picker>(parent_.get(), parent_->serverlist_,
|
705
|
+
std::move(picker), std::move(client_stats))));
|
706
|
+
}
|
707
|
+
|
708
|
+
void GrpcLb::Helper::RequestReresolution() {
|
709
|
+
if (parent_->shutting_down_) return;
|
710
|
+
const LoadBalancingPolicy* latest_child_policy =
|
711
|
+
parent_->pending_child_policy_ != nullptr
|
712
|
+
? parent_->pending_child_policy_.get()
|
713
|
+
: parent_->child_policy_.get();
|
714
|
+
if (child_ != latest_child_policy) return;
|
715
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) {
|
716
|
+
gpr_log(GPR_INFO,
|
717
|
+
"[grpclb %p] Re-resolution requested from %schild policy (%p).",
|
718
|
+
parent_.get(), CalledByPendingChild() ? "pending " : "", child_);
|
719
|
+
}
|
720
|
+
// If we are talking to a balancer, we expect to get updated addresses
|
721
|
+
// from the balancer, so we can ignore the re-resolution request from
|
722
|
+
// the child policy. Otherwise, pass the re-resolution request up to the
|
723
|
+
// channel.
|
724
|
+
if (parent_->lb_calld_ == nullptr ||
|
725
|
+
!parent_->lb_calld_->seen_initial_response()) {
|
726
|
+
parent_->channel_control_helper()->RequestReresolution();
|
727
|
+
}
|
728
|
+
}
|
729
|
+
|
730
|
+
void GrpcLb::Helper::AddTraceEvent(TraceSeverity severity,
|
731
|
+
const char* message) {
|
732
|
+
if (parent_->shutting_down_ ||
|
733
|
+
(!CalledByPendingChild() && !CalledByCurrentChild())) {
|
734
|
+
return;
|
735
|
+
}
|
736
|
+
parent_->channel_control_helper()->AddTraceEvent(severity, message);
|
737
|
+
}
|
738
|
+
|
461
739
|
//
|
462
740
|
// GrpcLb::BalancerCallState
|
463
741
|
//
|
@@ -530,7 +808,7 @@ void GrpcLb::BalancerCallState::Orphan() {
|
|
530
808
|
|
531
809
|
void GrpcLb::BalancerCallState::StartQuery() {
|
532
810
|
GPR_ASSERT(lb_call_ != nullptr);
|
533
|
-
if (grpc_lb_glb_trace
|
811
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) {
|
534
812
|
gpr_log(GPR_INFO, "[grpclb %p] lb_calld=%p: Starting LB call %p",
|
535
813
|
grpclb_policy_.get(), this, lb_call_);
|
536
814
|
}
|
@@ -542,7 +820,8 @@ void GrpcLb::BalancerCallState::StartQuery() {
|
|
542
820
|
grpc_op* op = ops;
|
543
821
|
op->op = GRPC_OP_SEND_INITIAL_METADATA;
|
544
822
|
op->data.send_initial_metadata.count = 0;
|
545
|
-
op->flags =
|
823
|
+
op->flags = GRPC_INITIAL_METADATA_WAIT_FOR_READY |
|
824
|
+
GRPC_INITIAL_METADATA_WAIT_FOR_READY_EXPLICITLY_SET;
|
546
825
|
op->reserved = nullptr;
|
547
826
|
op++;
|
548
827
|
// Op: send request message.
|
@@ -598,7 +877,7 @@ void GrpcLb::BalancerCallState::StartQuery() {
|
|
598
877
|
call_error = grpc_call_start_batch_and_execute(
|
599
878
|
lb_call_, ops, (size_t)(op - ops), &lb_on_balancer_status_received_);
|
600
879
|
GPR_ASSERT(GRPC_CALL_OK == call_error);
|
601
|
-
}
|
880
|
+
}
|
602
881
|
|
603
882
|
void GrpcLb::BalancerCallState::ScheduleNextClientLoadReportLocked() {
|
604
883
|
const grpc_millis next_client_load_report_time =
|
@@ -647,7 +926,7 @@ void GrpcLb::BalancerCallState::SendClientLoadReportLocked() {
|
|
647
926
|
// Construct message payload.
|
648
927
|
GPR_ASSERT(send_message_payload_ == nullptr);
|
649
928
|
grpc_grpclb_request* request =
|
650
|
-
|
929
|
+
grpc_grpclb_load_report_request_create(client_stats_.get());
|
651
930
|
// Skip client load report if the counters were all zero in the last
|
652
931
|
// report and they are still zero in this one.
|
653
932
|
if (LoadReportCountersAreZero(request)) {
|
@@ -736,7 +1015,7 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked(
|
|
736
1015
|
lb_calld->client_stats_report_interval_ = GPR_MAX(
|
737
1016
|
GPR_MS_PER_SEC, grpc_grpclb_duration_to_millis(
|
738
1017
|
&initial_response->client_stats_report_interval));
|
739
|
-
if (grpc_lb_glb_trace
|
1018
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) {
|
740
1019
|
gpr_log(GPR_INFO,
|
741
1020
|
"[grpclb %p] lb_calld=%p: Received initial LB response "
|
742
1021
|
"message; client load reporting interval = %" PRId64
|
@@ -744,7 +1023,7 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked(
|
|
744
1023
|
grpclb_policy, lb_calld,
|
745
1024
|
lb_calld->client_stats_report_interval_);
|
746
1025
|
}
|
747
|
-
} else if (grpc_lb_glb_trace
|
1026
|
+
} else if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) {
|
748
1027
|
gpr_log(GPR_INFO,
|
749
1028
|
"[grpclb %p] lb_calld=%p: Received initial LB response message; "
|
750
1029
|
"client load reporting NOT enabled",
|
@@ -756,60 +1035,71 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked(
|
|
756
1035
|
response_slice)) != nullptr) {
|
757
1036
|
// Have seen initial response, look for serverlist.
|
758
1037
|
GPR_ASSERT(lb_calld->lb_call_ != nullptr);
|
759
|
-
|
1038
|
+
auto serverlist_wrapper = MakeRefCounted<Serverlist>(serverlist);
|
1039
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) {
|
1040
|
+
UniquePtr<char> serverlist_text = serverlist_wrapper->AsText();
|
760
1041
|
gpr_log(GPR_INFO,
|
761
1042
|
"[grpclb %p] lb_calld=%p: Serverlist with %" PRIuPTR
|
762
|
-
" servers received",
|
763
|
-
grpclb_policy, lb_calld, serverlist->num_servers
|
764
|
-
|
765
|
-
grpc_resolved_address addr;
|
766
|
-
ParseServer(serverlist->servers[i], &addr);
|
767
|
-
char* ipport;
|
768
|
-
grpc_sockaddr_to_string(&ipport, &addr, false);
|
769
|
-
gpr_log(GPR_INFO,
|
770
|
-
"[grpclb %p] lb_calld=%p: Serverlist[%" PRIuPTR "]: %s",
|
771
|
-
grpclb_policy, lb_calld, i, ipport);
|
772
|
-
gpr_free(ipport);
|
773
|
-
}
|
1043
|
+
" servers received:\n%s",
|
1044
|
+
grpclb_policy, lb_calld, serverlist->num_servers,
|
1045
|
+
serverlist_text.get());
|
774
1046
|
}
|
1047
|
+
lb_calld->seen_serverlist_ = true;
|
775
1048
|
// Start sending client load report only after we start using the
|
776
1049
|
// serverlist returned from the current LB call.
|
777
1050
|
if (lb_calld->client_stats_report_interval_ > 0 &&
|
778
1051
|
lb_calld->client_stats_ == nullptr) {
|
779
|
-
lb_calld->client_stats_
|
780
|
-
//
|
781
|
-
|
782
|
-
// with the callback.
|
783
|
-
auto self = lb_calld->Ref(DEBUG_LOCATION, "client_load_report");
|
784
|
-
self.release();
|
1052
|
+
lb_calld->client_stats_ = MakeRefCounted<GrpcLbClientStats>();
|
1053
|
+
// Ref held by callback.
|
1054
|
+
lb_calld->Ref(DEBUG_LOCATION, "client_load_report").release();
|
785
1055
|
lb_calld->ScheduleNextClientLoadReportLocked();
|
786
1056
|
}
|
787
1057
|
// Check if the serverlist differs from the previous one.
|
788
|
-
if (
|
789
|
-
|
1058
|
+
if (grpclb_policy->serverlist_ != nullptr &&
|
1059
|
+
*grpclb_policy->serverlist_ == *serverlist_wrapper) {
|
1060
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) {
|
790
1061
|
gpr_log(GPR_INFO,
|
791
1062
|
"[grpclb %p] lb_calld=%p: Incoming server list identical to "
|
792
1063
|
"current, ignoring.",
|
793
1064
|
grpclb_policy, lb_calld);
|
794
1065
|
}
|
795
|
-
grpc_grpclb_destroy_serverlist(serverlist);
|
796
1066
|
} else { // New serverlist.
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
1067
|
+
// Dispose of the fallback.
|
1068
|
+
// TODO(roth): Ideally, we should stay in fallback mode until we
|
1069
|
+
// know that we can reach at least one of the backends in the new
|
1070
|
+
// serverlist. Unfortunately, we can't do that, since we need to
|
1071
|
+
// send the new addresses to the child policy in order to determine
|
1072
|
+
// if they are reachable, and if we don't exit fallback mode now,
|
1073
|
+
// CreateOrUpdateChildPolicyLocked() will use the fallback
|
1074
|
+
// addresses instead of the addresses from the new serverlist.
|
1075
|
+
// However, if we can't reach any of the servers in the new
|
1076
|
+
// serverlist, then the child policy will never switch away from
|
1077
|
+
// the fallback addresses, but the grpclb policy will still think
|
1078
|
+
// that we're not in fallback mode, which means that we won't send
|
1079
|
+
// updates to the child policy when the fallback addresses are
|
1080
|
+
// updated by the resolver. This is sub-optimal, but the only way
|
1081
|
+
// to fix it is to maintain a completely separate child policy for
|
1082
|
+
// fallback mode, and that's more work than we want to put into
|
1083
|
+
// the grpclb implementation at this point, since we're deprecating
|
1084
|
+
// it in favor of the xds policy. We will implement this the
|
1085
|
+
// right way in the xds policy instead.
|
1086
|
+
if (grpclb_policy->fallback_mode_) {
|
1087
|
+
gpr_log(GPR_INFO,
|
1088
|
+
"[grpclb %p] Received response from balancer; exiting "
|
1089
|
+
"fallback mode",
|
1090
|
+
grpclb_policy);
|
1091
|
+
grpclb_policy->fallback_mode_ = false;
|
1092
|
+
}
|
1093
|
+
if (grpclb_policy->fallback_at_startup_checks_pending_) {
|
1094
|
+
grpclb_policy->fallback_at_startup_checks_pending_ = false;
|
1095
|
+
grpc_timer_cancel(&grpclb_policy->lb_fallback_timer_);
|
1096
|
+
grpclb_policy->CancelBalancerChannelConnectivityWatchLocked();
|
806
1097
|
}
|
807
1098
|
// Update the serverlist in the GrpcLb instance. This serverlist
|
808
1099
|
// instance will be destroyed either upon the next update or when the
|
809
1100
|
// GrpcLb instance is destroyed.
|
810
|
-
grpclb_policy->serverlist_ =
|
811
|
-
grpclb_policy->
|
812
|
-
grpclb_policy->CreateOrUpdateRoundRobinPolicyLocked();
|
1101
|
+
grpclb_policy->serverlist_ = std::move(serverlist_wrapper);
|
1102
|
+
grpclb_policy->CreateOrUpdateChildPolicyLocked();
|
813
1103
|
}
|
814
1104
|
} else {
|
815
1105
|
// No valid initial response or serverlist found.
|
@@ -845,7 +1135,7 @@ void GrpcLb::BalancerCallState::OnBalancerStatusReceivedLocked(
|
|
845
1135
|
BalancerCallState* lb_calld = static_cast<BalancerCallState*>(arg);
|
846
1136
|
GrpcLb* grpclb_policy = lb_calld->grpclb_policy();
|
847
1137
|
GPR_ASSERT(lb_calld->lb_call_ != nullptr);
|
848
|
-
if (grpc_lb_glb_trace
|
1138
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) {
|
849
1139
|
char* status_details =
|
850
1140
|
grpc_slice_to_c_string(lb_calld->lb_call_status_details_);
|
851
1141
|
gpr_log(GPR_INFO,
|
@@ -855,13 +1145,31 @@ void GrpcLb::BalancerCallState::OnBalancerStatusReceivedLocked(
|
|
855
1145
|
lb_calld->lb_call_, grpc_error_string(error));
|
856
1146
|
gpr_free(status_details);
|
857
1147
|
}
|
858
|
-
grpclb_policy->TryReresolutionLocked(&grpc_lb_glb_trace, GRPC_ERROR_NONE);
|
859
1148
|
// If this lb_calld is still in use, this call ended because of a failure so
|
860
1149
|
// we want to retry connecting. Otherwise, we have deliberately ended this
|
861
1150
|
// call and no further action is required.
|
862
1151
|
if (lb_calld == grpclb_policy->lb_calld_.get()) {
|
1152
|
+
// If the fallback-at-startup checks are pending, go into fallback mode
|
1153
|
+
// immediately. This short-circuits the timeout for the fallback-at-startup
|
1154
|
+
// case.
|
1155
|
+
if (grpclb_policy->fallback_at_startup_checks_pending_) {
|
1156
|
+
GPR_ASSERT(!lb_calld->seen_serverlist_);
|
1157
|
+
gpr_log(GPR_INFO,
|
1158
|
+
"[grpclb %p] Balancer call finished without receiving "
|
1159
|
+
"serverlist; entering fallback mode",
|
1160
|
+
grpclb_policy);
|
1161
|
+
grpclb_policy->fallback_at_startup_checks_pending_ = false;
|
1162
|
+
grpc_timer_cancel(&grpclb_policy->lb_fallback_timer_);
|
1163
|
+
grpclb_policy->CancelBalancerChannelConnectivityWatchLocked();
|
1164
|
+
grpclb_policy->fallback_mode_ = true;
|
1165
|
+
grpclb_policy->CreateOrUpdateChildPolicyLocked();
|
1166
|
+
} else {
|
1167
|
+
// This handles the fallback-after-startup case.
|
1168
|
+
grpclb_policy->MaybeEnterFallbackModeAfterStartup();
|
1169
|
+
}
|
863
1170
|
grpclb_policy->lb_calld_.reset();
|
864
1171
|
GPR_ASSERT(!grpclb_policy->shutting_down_);
|
1172
|
+
grpclb_policy->channel_control_helper()->RequestReresolution();
|
865
1173
|
if (lb_calld->seen_initial_response_) {
|
866
1174
|
// If we lose connection to the LB server, reset the backoff and restart
|
867
1175
|
// the LB call immediately.
|
@@ -913,25 +1221,18 @@ grpc_channel_args* BuildBalancerChannelArgs(
|
|
913
1221
|
const ServerAddressList& addresses,
|
914
1222
|
FakeResolverResponseGenerator* response_generator,
|
915
1223
|
const grpc_channel_args* args) {
|
916
|
-
ServerAddressList balancer_addresses = ExtractBalancerAddresses(addresses);
|
917
1224
|
// Channel args to remove.
|
918
1225
|
static const char* args_to_remove[] = {
|
919
1226
|
// LB policy name, since we want to use the default (pick_first) in
|
920
1227
|
// the LB channel.
|
921
1228
|
GRPC_ARG_LB_POLICY_NAME,
|
1229
|
+
// Strip out the service config, since we don't want the LB policy
|
1230
|
+
// config specified for the parent channel to affect the LB channel.
|
1231
|
+
GRPC_ARG_SERVICE_CONFIG,
|
922
1232
|
// The channel arg for the server URI, since that will be different for
|
923
1233
|
// the LB channel than for the parent channel. The client channel
|
924
1234
|
// factory will re-add this arg with the right value.
|
925
1235
|
GRPC_ARG_SERVER_URI,
|
926
|
-
// The resolved addresses, which will be generated by the name resolver
|
927
|
-
// used in the LB channel. Note that the LB channel will use the fake
|
928
|
-
// resolver, so this won't actually generate a query to DNS (or some
|
929
|
-
// other name service). However, the addresses returned by the fake
|
930
|
-
// resolver will have is_balancer=false, whereas our own addresses have
|
931
|
-
// is_balancer=true. We need the LB channel to return addresses with
|
932
|
-
// is_balancer=false so that it does not wind up recursively using the
|
933
|
-
// grpclb LB policy, as per the special case logic in client_channel.c.
|
934
|
-
GRPC_ARG_SERVER_ADDRESS_LIST,
|
935
1236
|
// The fake resolver response generator, because we are replacing it
|
936
1237
|
// with the one from the grpclb policy, used to propagate updates to
|
937
1238
|
// the LB channel.
|
@@ -944,39 +1245,44 @@ grpc_channel_args* BuildBalancerChannelArgs(
|
|
944
1245
|
// treated as a stand-alone channel and not inherit this argument from the
|
945
1246
|
// args of the parent channel.
|
946
1247
|
GRPC_SSL_TARGET_NAME_OVERRIDE_ARG,
|
1248
|
+
// Don't want to pass down channelz node from parent; the balancer
|
1249
|
+
// channel will get its own.
|
1250
|
+
GRPC_ARG_CHANNELZ_CHANNEL_NODE,
|
947
1251
|
};
|
948
1252
|
// Channel args to add.
|
949
|
-
|
950
|
-
|
951
|
-
|
952
|
-
|
953
|
-
CreateServerAddressListChannelArg(&balancer_addresses),
|
954
|
-
// The fake resolver response generator, which we use to inject
|
955
|
-
// address updates into the LB channel.
|
1253
|
+
InlinedVector<grpc_arg, 3> args_to_add;
|
1254
|
+
// The fake resolver response generator, which we use to inject
|
1255
|
+
// address updates into the LB channel.
|
1256
|
+
args_to_add.emplace_back(
|
956
1257
|
grpc_core::FakeResolverResponseGenerator::MakeChannelArg(
|
957
|
-
response_generator)
|
958
|
-
|
959
|
-
|
960
|
-
|
961
|
-
|
962
|
-
|
963
|
-
|
964
|
-
|
965
|
-
|
1258
|
+
response_generator));
|
1259
|
+
// A channel arg indicating the target is a grpclb load balancer.
|
1260
|
+
args_to_add.emplace_back(grpc_channel_arg_integer_create(
|
1261
|
+
const_cast<char*>(GRPC_ARG_ADDRESS_IS_GRPCLB_LOAD_BALANCER), 1));
|
1262
|
+
// The parent channel's channelz uuid.
|
1263
|
+
channelz::ChannelNode* channelz_node = nullptr;
|
1264
|
+
const grpc_arg* arg =
|
1265
|
+
grpc_channel_args_find(args, GRPC_ARG_CHANNELZ_CHANNEL_NODE);
|
1266
|
+
if (arg != nullptr && arg->type == GRPC_ARG_POINTER &&
|
1267
|
+
arg->value.pointer.p != nullptr) {
|
1268
|
+
channelz_node = static_cast<channelz::ChannelNode*>(arg->value.pointer.p);
|
1269
|
+
args_to_add.emplace_back(
|
1270
|
+
channelz::MakeParentUuidArg(channelz_node->uuid()));
|
1271
|
+
}
|
966
1272
|
// Construct channel args.
|
967
1273
|
grpc_channel_args* new_args = grpc_channel_args_copy_and_add_and_remove(
|
968
|
-
args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), args_to_add,
|
969
|
-
|
1274
|
+
args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), args_to_add.data(),
|
1275
|
+
args_to_add.size());
|
970
1276
|
// Make any necessary modifications for security.
|
971
|
-
return grpc_lb_policy_grpclb_modify_lb_channel_args(new_args);
|
1277
|
+
return grpc_lb_policy_grpclb_modify_lb_channel_args(addresses, new_args);
|
972
1278
|
}
|
973
1279
|
|
974
1280
|
//
|
975
1281
|
// ctor and dtor
|
976
1282
|
//
|
977
1283
|
|
978
|
-
GrpcLb::GrpcLb(
|
979
|
-
: LoadBalancingPolicy(args),
|
1284
|
+
GrpcLb::GrpcLb(Args args)
|
1285
|
+
: LoadBalancingPolicy(std::move(args)),
|
980
1286
|
response_generator_(MakeRefCounted<FakeResolverResponseGenerator>()),
|
981
1287
|
lb_call_backoff_(
|
982
1288
|
BackOff::Options()
|
@@ -987,18 +1293,11 @@ GrpcLb::GrpcLb(const LoadBalancingPolicy::Args& args)
|
|
987
1293
|
.set_max_backoff(GRPC_GRPCLB_RECONNECT_MAX_BACKOFF_SECONDS *
|
988
1294
|
1000)) {
|
989
1295
|
// Initialization.
|
990
|
-
|
991
|
-
|
1296
|
+
GRPC_CLOSURE_INIT(&lb_on_fallback_, &GrpcLb::OnFallbackTimerLocked, this,
|
1297
|
+
grpc_combiner_scheduler(combiner()));
|
992
1298
|
GRPC_CLOSURE_INIT(&lb_channel_on_connectivity_changed_,
|
993
1299
|
&GrpcLb::OnBalancerChannelConnectivityChangedLocked, this,
|
994
1300
|
grpc_combiner_scheduler(args.combiner));
|
995
|
-
GRPC_CLOSURE_INIT(&on_rr_connectivity_changed_,
|
996
|
-
&GrpcLb::OnRoundRobinConnectivityChangedLocked, this,
|
997
|
-
grpc_combiner_scheduler(args.combiner));
|
998
|
-
GRPC_CLOSURE_INIT(&on_rr_request_reresolution_,
|
999
|
-
&GrpcLb::OnRoundRobinRequestReresolutionLocked, this,
|
1000
|
-
grpc_combiner_scheduler(args.combiner));
|
1001
|
-
grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE, "grpclb");
|
1002
1301
|
// Record server name.
|
1003
1302
|
const grpc_arg* arg = grpc_channel_args_find(args.args, GRPC_ARG_SERVER_URI);
|
1004
1303
|
const char* server_uri = grpc_channel_arg_get_string(arg);
|
@@ -1006,7 +1305,7 @@ GrpcLb::GrpcLb(const LoadBalancingPolicy::Args& args)
|
|
1006
1305
|
grpc_uri* uri = grpc_uri_parse(server_uri, true);
|
1007
1306
|
GPR_ASSERT(uri->path[0] != '\0');
|
1008
1307
|
server_name_ = gpr_strdup(uri->path[0] == '/' ? uri->path + 1 : uri->path);
|
1009
|
-
if (grpc_lb_glb_trace
|
1308
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) {
|
1010
1309
|
gpr_log(GPR_INFO,
|
1011
1310
|
"[grpclb %p] Will use '%s' as the server name for LB request.",
|
1012
1311
|
this, server_name_);
|
@@ -1015,234 +1314,115 @@ GrpcLb::GrpcLb(const LoadBalancingPolicy::Args& args)
|
|
1015
1314
|
// Record LB call timeout.
|
1016
1315
|
arg = grpc_channel_args_find(args.args, GRPC_ARG_GRPCLB_CALL_TIMEOUT_MS);
|
1017
1316
|
lb_call_timeout_ms_ = grpc_channel_arg_get_integer(arg, {0, 0, INT_MAX});
|
1018
|
-
// Record fallback timeout.
|
1317
|
+
// Record fallback-at-startup timeout.
|
1019
1318
|
arg = grpc_channel_args_find(args.args, GRPC_ARG_GRPCLB_FALLBACK_TIMEOUT_MS);
|
1020
|
-
|
1319
|
+
fallback_at_startup_timeout_ = grpc_channel_arg_get_integer(
|
1021
1320
|
arg, {GRPC_GRPCLB_DEFAULT_FALLBACK_TIMEOUT_MS, 0, INT_MAX});
|
1022
|
-
// Process channel args.
|
1023
|
-
ProcessChannelArgsLocked(*args.args);
|
1024
1321
|
}
|
1025
1322
|
|
1026
1323
|
GrpcLb::~GrpcLb() {
|
1027
|
-
GPR_ASSERT(pending_picks_ == nullptr);
|
1028
|
-
gpr_mu_destroy(&lb_channel_mu_);
|
1029
1324
|
gpr_free((void*)server_name_);
|
1030
1325
|
grpc_channel_args_destroy(args_);
|
1031
|
-
grpc_connectivity_state_destroy(&state_tracker_);
|
1032
|
-
if (serverlist_ != nullptr) {
|
1033
|
-
grpc_grpclb_destroy_serverlist(serverlist_);
|
1034
|
-
}
|
1035
|
-
grpc_subchannel_index_unref();
|
1036
1326
|
}
|
1037
1327
|
|
1038
1328
|
void GrpcLb::ShutdownLocked() {
|
1039
|
-
grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel shutdown");
|
1040
1329
|
shutting_down_ = true;
|
1041
1330
|
lb_calld_.reset();
|
1042
1331
|
if (retry_timer_callback_pending_) {
|
1043
1332
|
grpc_timer_cancel(&lb_call_retry_timer_);
|
1044
1333
|
}
|
1045
|
-
if (
|
1334
|
+
if (fallback_at_startup_checks_pending_) {
|
1046
1335
|
grpc_timer_cancel(&lb_fallback_timer_);
|
1336
|
+
CancelBalancerChannelConnectivityWatchLocked();
|
1337
|
+
}
|
1338
|
+
if (child_policy_ != nullptr) {
|
1339
|
+
grpc_pollset_set_del_pollset_set(child_policy_->interested_parties(),
|
1340
|
+
interested_parties());
|
1341
|
+
}
|
1342
|
+
if (pending_child_policy_ != nullptr) {
|
1343
|
+
grpc_pollset_set_del_pollset_set(
|
1344
|
+
pending_child_policy_->interested_parties(), interested_parties());
|
1047
1345
|
}
|
1048
|
-
|
1049
|
-
|
1346
|
+
child_policy_.reset();
|
1347
|
+
pending_child_policy_.reset();
|
1050
1348
|
// We destroy the LB channel here instead of in our destructor because
|
1051
1349
|
// destroying the channel triggers a last callback to
|
1052
1350
|
// OnBalancerChannelConnectivityChangedLocked(), and we need to be
|
1053
1351
|
// alive when that callback is invoked.
|
1054
1352
|
if (lb_channel_ != nullptr) {
|
1055
|
-
gpr_mu_lock(&lb_channel_mu_);
|
1056
1353
|
grpc_channel_destroy(lb_channel_);
|
1057
1354
|
lb_channel_ = nullptr;
|
1058
|
-
gpr_mu_unlock(&lb_channel_mu_);
|
1059
1355
|
}
|
1060
|
-
grpc_connectivity_state_set(&state_tracker_, GRPC_CHANNEL_SHUTDOWN,
|
1061
|
-
GRPC_ERROR_REF(error), "grpclb_shutdown");
|
1062
|
-
// Clear pending picks.
|
1063
|
-
PendingPick* pp;
|
1064
|
-
while ((pp = pending_picks_) != nullptr) {
|
1065
|
-
pending_picks_ = pp->next;
|
1066
|
-
pp->pick->connected_subchannel.reset();
|
1067
|
-
// Note: pp is deleted in this callback.
|
1068
|
-
GRPC_CLOSURE_SCHED(&pp->on_complete, GRPC_ERROR_REF(error));
|
1069
|
-
}
|
1070
|
-
GRPC_ERROR_UNREF(error);
|
1071
1356
|
}
|
1072
1357
|
|
1073
1358
|
//
|
1074
1359
|
// public methods
|
1075
1360
|
//
|
1076
1361
|
|
1077
|
-
void GrpcLb::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) {
|
1078
|
-
PendingPick* pp;
|
1079
|
-
while ((pp = pending_picks_) != nullptr) {
|
1080
|
-
pending_picks_ = pp->next;
|
1081
|
-
pp->pick->on_complete = pp->original_on_complete;
|
1082
|
-
grpc_error* error = GRPC_ERROR_NONE;
|
1083
|
-
if (new_policy->PickLocked(pp->pick, &error)) {
|
1084
|
-
// Synchronous return; schedule closure.
|
1085
|
-
GRPC_CLOSURE_SCHED(pp->pick->on_complete, error);
|
1086
|
-
}
|
1087
|
-
Delete(pp);
|
1088
|
-
}
|
1089
|
-
}
|
1090
|
-
|
1091
|
-
// Cancel a specific pending pick.
|
1092
|
-
//
|
1093
|
-
// A grpclb pick progresses as follows:
|
1094
|
-
// - If there's a Round Robin policy (rr_policy_) available, it'll be
|
1095
|
-
// handed over to the RR policy (in CreateRoundRobinPolicyLocked()). From
|
1096
|
-
// that point onwards, it'll be RR's responsibility. For cancellations, that
|
1097
|
-
// implies the pick needs also be cancelled by the RR instance.
|
1098
|
-
// - Otherwise, without an RR instance, picks stay pending at this policy's
|
1099
|
-
// level (grpclb), inside the pending_picks_ list. To cancel these,
|
1100
|
-
// we invoke the completion closure and set the pick's connected
|
1101
|
-
// subchannel to nullptr right here.
|
1102
|
-
void GrpcLb::CancelPickLocked(PickState* pick, grpc_error* error) {
|
1103
|
-
PendingPick* pp = pending_picks_;
|
1104
|
-
pending_picks_ = nullptr;
|
1105
|
-
while (pp != nullptr) {
|
1106
|
-
PendingPick* next = pp->next;
|
1107
|
-
if (pp->pick == pick) {
|
1108
|
-
pick->connected_subchannel.reset();
|
1109
|
-
// Note: pp is deleted in this callback.
|
1110
|
-
GRPC_CLOSURE_SCHED(&pp->on_complete,
|
1111
|
-
GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
|
1112
|
-
"Pick Cancelled", &error, 1));
|
1113
|
-
} else {
|
1114
|
-
pp->next = pending_picks_;
|
1115
|
-
pending_picks_ = pp;
|
1116
|
-
}
|
1117
|
-
pp = next;
|
1118
|
-
}
|
1119
|
-
if (rr_policy_ != nullptr) {
|
1120
|
-
rr_policy_->CancelPickLocked(pick, GRPC_ERROR_REF(error));
|
1121
|
-
}
|
1122
|
-
GRPC_ERROR_UNREF(error);
|
1123
|
-
}
|
1124
|
-
|
1125
|
-
// Cancel all pending picks.
|
1126
|
-
//
|
1127
|
-
// A grpclb pick progresses as follows:
|
1128
|
-
// - If there's a Round Robin policy (rr_policy_) available, it'll be
|
1129
|
-
// handed over to the RR policy (in CreateRoundRobinPolicyLocked()). From
|
1130
|
-
// that point onwards, it'll be RR's responsibility. For cancellations, that
|
1131
|
-
// implies the pick needs also be cancelled by the RR instance.
|
1132
|
-
// - Otherwise, without an RR instance, picks stay pending at this policy's
|
1133
|
-
// level (grpclb), inside the pending_picks_ list. To cancel these,
|
1134
|
-
// we invoke the completion closure and set the pick's connected
|
1135
|
-
// subchannel to nullptr right here.
|
1136
|
-
void GrpcLb::CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask,
|
1137
|
-
uint32_t initial_metadata_flags_eq,
|
1138
|
-
grpc_error* error) {
|
1139
|
-
PendingPick* pp = pending_picks_;
|
1140
|
-
pending_picks_ = nullptr;
|
1141
|
-
while (pp != nullptr) {
|
1142
|
-
PendingPick* next = pp->next;
|
1143
|
-
if ((*pp->pick->initial_metadata_flags & initial_metadata_flags_mask) ==
|
1144
|
-
initial_metadata_flags_eq) {
|
1145
|
-
// Note: pp is deleted in this callback.
|
1146
|
-
GRPC_CLOSURE_SCHED(&pp->on_complete,
|
1147
|
-
GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
|
1148
|
-
"Pick Cancelled", &error, 1));
|
1149
|
-
} else {
|
1150
|
-
pp->next = pending_picks_;
|
1151
|
-
pending_picks_ = pp;
|
1152
|
-
}
|
1153
|
-
pp = next;
|
1154
|
-
}
|
1155
|
-
if (rr_policy_ != nullptr) {
|
1156
|
-
rr_policy_->CancelMatchingPicksLocked(initial_metadata_flags_mask,
|
1157
|
-
initial_metadata_flags_eq,
|
1158
|
-
GRPC_ERROR_REF(error));
|
1159
|
-
}
|
1160
|
-
GRPC_ERROR_UNREF(error);
|
1161
|
-
}
|
1162
|
-
|
1163
|
-
void GrpcLb::ExitIdleLocked() {
|
1164
|
-
if (!started_picking_) {
|
1165
|
-
StartPickingLocked();
|
1166
|
-
}
|
1167
|
-
}
|
1168
|
-
|
1169
1362
|
void GrpcLb::ResetBackoffLocked() {
|
1170
1363
|
if (lb_channel_ != nullptr) {
|
1171
1364
|
grpc_channel_reset_connect_backoff(lb_channel_);
|
1172
1365
|
}
|
1173
|
-
if (
|
1174
|
-
|
1366
|
+
if (child_policy_ != nullptr) {
|
1367
|
+
child_policy_->ResetBackoffLocked();
|
1175
1368
|
}
|
1176
|
-
|
1177
|
-
|
1178
|
-
bool GrpcLb::PickLocked(PickState* pick, grpc_error** error) {
|
1179
|
-
PendingPick* pp = PendingPickCreate(pick);
|
1180
|
-
bool pick_done = false;
|
1181
|
-
if (rr_policy_ != nullptr) {
|
1182
|
-
if (grpc_lb_glb_trace.enabled()) {
|
1183
|
-
gpr_log(GPR_INFO, "[grpclb %p] about to PICK from RR %p", this,
|
1184
|
-
rr_policy_.get());
|
1185
|
-
}
|
1186
|
-
pick_done =
|
1187
|
-
PickFromRoundRobinPolicyLocked(false /* force_async */, pp, error);
|
1188
|
-
} else { // rr_policy_ == NULL
|
1189
|
-
if (pick->on_complete == nullptr) {
|
1190
|
-
*error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
1191
|
-
"No pick result available but synchronous result required.");
|
1192
|
-
pick_done = true;
|
1193
|
-
} else {
|
1194
|
-
if (grpc_lb_glb_trace.enabled()) {
|
1195
|
-
gpr_log(GPR_INFO,
|
1196
|
-
"[grpclb %p] No RR policy. Adding to grpclb's pending picks",
|
1197
|
-
this);
|
1198
|
-
}
|
1199
|
-
AddPendingPick(pp);
|
1200
|
-
if (!started_picking_) {
|
1201
|
-
StartPickingLocked();
|
1202
|
-
}
|
1203
|
-
pick_done = false;
|
1204
|
-
}
|
1369
|
+
if (pending_child_policy_ != nullptr) {
|
1370
|
+
pending_child_policy_->ResetBackoffLocked();
|
1205
1371
|
}
|
1206
|
-
return pick_done;
|
1207
1372
|
}
|
1208
1373
|
|
1209
|
-
void GrpcLb::
|
1210
|
-
|
1211
|
-
|
1212
|
-
|
1213
|
-
|
1214
|
-
|
1215
|
-
|
1216
|
-
|
1217
|
-
|
1218
|
-
|
1219
|
-
|
1220
|
-
|
1374
|
+
void GrpcLb::UpdateLocked(UpdateArgs args) {
|
1375
|
+
const bool is_initial_update = lb_channel_ == nullptr;
|
1376
|
+
auto* grpclb_config =
|
1377
|
+
static_cast<const ParsedGrpcLbConfig*>(args.config.get());
|
1378
|
+
if (grpclb_config != nullptr) {
|
1379
|
+
child_policy_config_ = grpclb_config->child_policy();
|
1380
|
+
} else {
|
1381
|
+
child_policy_config_ = nullptr;
|
1382
|
+
}
|
1383
|
+
ProcessAddressesAndChannelArgsLocked(args.addresses, *args.args);
|
1384
|
+
// Update the existing child policy.
|
1385
|
+
if (child_policy_ != nullptr) CreateOrUpdateChildPolicyLocked();
|
1386
|
+
// If this is the initial update, start the fallback-at-startup checks
|
1387
|
+
// and the balancer call.
|
1388
|
+
if (is_initial_update) {
|
1389
|
+
fallback_at_startup_checks_pending_ = true;
|
1390
|
+
// Start timer.
|
1391
|
+
grpc_millis deadline = ExecCtx::Get()->Now() + fallback_at_startup_timeout_;
|
1392
|
+
Ref(DEBUG_LOCATION, "on_fallback_timer").release(); // Ref for callback
|
1393
|
+
grpc_timer_init(&lb_fallback_timer_, deadline, &lb_on_fallback_);
|
1394
|
+
// Start watching the channel's connectivity state. If the channel
|
1395
|
+
// goes into state TRANSIENT_FAILURE before the timer fires, we go into
|
1396
|
+
// fallback mode even if the fallback timeout has not elapsed.
|
1397
|
+
grpc_channel_element* client_channel_elem = grpc_channel_stack_last_element(
|
1398
|
+
grpc_channel_get_channel_stack(lb_channel_));
|
1399
|
+
GPR_ASSERT(client_channel_elem->filter == &grpc_client_channel_filter);
|
1400
|
+
// Ref held by callback.
|
1401
|
+
Ref(DEBUG_LOCATION, "watch_lb_channel_connectivity").release();
|
1402
|
+
grpc_client_channel_watch_connectivity_state(
|
1403
|
+
client_channel_elem,
|
1404
|
+
grpc_polling_entity_create_from_pollset_set(interested_parties()),
|
1405
|
+
&lb_channel_connectivity_, &lb_channel_on_connectivity_changed_,
|
1406
|
+
nullptr);
|
1407
|
+
// Start balancer call.
|
1408
|
+
StartBalancerCallLocked();
|
1221
1409
|
}
|
1222
1410
|
}
|
1223
1411
|
|
1224
|
-
|
1225
|
-
|
1226
|
-
|
1227
|
-
}
|
1228
|
-
|
1229
|
-
void GrpcLb::NotifyOnStateChangeLocked(grpc_connectivity_state* current,
|
1230
|
-
grpc_closure* notify) {
|
1231
|
-
grpc_connectivity_state_notify_on_state_change(&state_tracker_, current,
|
1232
|
-
notify);
|
1233
|
-
}
|
1412
|
+
//
|
1413
|
+
// helpers for UpdateLocked()
|
1414
|
+
//
|
1234
1415
|
|
1235
1416
|
// Returns the backend addresses extracted from the given addresses.
|
1236
|
-
|
1237
|
-
const ServerAddressList& addresses) {
|
1417
|
+
ServerAddressList ExtractBackendAddresses(const ServerAddressList& addresses) {
|
1238
1418
|
void* lb_token = (void*)GRPC_MDELEM_LB_TOKEN_EMPTY.payload;
|
1239
1419
|
grpc_arg arg = grpc_channel_arg_pointer_create(
|
1240
1420
|
const_cast<char*>(GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN), lb_token,
|
1241
1421
|
&lb_token_arg_vtable);
|
1242
|
-
|
1422
|
+
ServerAddressList backend_addresses;
|
1243
1423
|
for (size_t i = 0; i < addresses.size(); ++i) {
|
1244
1424
|
if (!addresses[i].IsBalancer()) {
|
1245
|
-
backend_addresses
|
1425
|
+
backend_addresses.emplace_back(
|
1246
1426
|
addresses[i].address(),
|
1247
1427
|
grpc_channel_args_copy_and_add(addresses[i].args(), &arg, 1));
|
1248
1428
|
}
|
@@ -1250,18 +1430,10 @@ UniquePtr<ServerAddressList> ExtractBackendAddresses(
|
|
1250
1430
|
return backend_addresses;
|
1251
1431
|
}
|
1252
1432
|
|
1253
|
-
void GrpcLb::
|
1254
|
-
|
1255
|
-
if (addresses == nullptr) {
|
1256
|
-
// Ignore this update.
|
1257
|
-
gpr_log(
|
1258
|
-
GPR_ERROR,
|
1259
|
-
"[grpclb %p] No valid LB addresses channel arg in update, ignoring.",
|
1260
|
-
this);
|
1261
|
-
return;
|
1262
|
-
}
|
1433
|
+
void GrpcLb::ProcessAddressesAndChannelArgsLocked(
|
1434
|
+
const ServerAddressList& addresses, const grpc_channel_args& args) {
|
1263
1435
|
// Update fallback address list.
|
1264
|
-
fallback_backend_addresses_ = ExtractBackendAddresses(
|
1436
|
+
fallback_backend_addresses_ = ExtractBackendAddresses(addresses);
|
1265
1437
|
// Make sure that GRPC_ARG_LB_POLICY_NAME is set in channel args,
|
1266
1438
|
// since we use this to trigger the client_load_reporting filter.
|
1267
1439
|
static const char* args_to_remove[] = {GRPC_ARG_LB_POLICY_NAME};
|
@@ -1271,82 +1443,80 @@ void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) {
|
|
1271
1443
|
args_ = grpc_channel_args_copy_and_add_and_remove(
|
1272
1444
|
&args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove), &new_arg, 1);
|
1273
1445
|
// Construct args for balancer channel.
|
1274
|
-
|
1275
|
-
|
1446
|
+
ServerAddressList balancer_addresses = ExtractBalancerAddresses(addresses);
|
1447
|
+
grpc_channel_args* lb_channel_args = BuildBalancerChannelArgs(
|
1448
|
+
balancer_addresses, response_generator_.get(), &args);
|
1276
1449
|
// Create balancer channel if needed.
|
1277
1450
|
if (lb_channel_ == nullptr) {
|
1278
1451
|
char* uri_str;
|
1279
1452
|
gpr_asprintf(&uri_str, "fake:///%s", server_name_);
|
1280
|
-
|
1281
|
-
|
1282
|
-
client_channel_factory(), uri_str,
|
1283
|
-
GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, lb_channel_args);
|
1284
|
-
gpr_mu_unlock(&lb_channel_mu_);
|
1453
|
+
lb_channel_ =
|
1454
|
+
channel_control_helper()->CreateChannel(uri_str, *lb_channel_args);
|
1285
1455
|
GPR_ASSERT(lb_channel_ != nullptr);
|
1286
1456
|
gpr_free(uri_str);
|
1287
1457
|
}
|
1288
1458
|
// Propagate updates to the LB channel (pick_first) through the fake
|
1289
1459
|
// resolver.
|
1290
|
-
|
1291
|
-
|
1460
|
+
Resolver::Result result;
|
1461
|
+
result.addresses = std::move(balancer_addresses);
|
1462
|
+
result.args = lb_channel_args;
|
1463
|
+
response_generator_->SetResponse(std::move(result));
|
1292
1464
|
}
|
1293
1465
|
|
1294
|
-
void GrpcLb::
|
1295
|
-
|
1296
|
-
|
1297
|
-
if (
|
1298
|
-
|
1299
|
-
|
1300
|
-
|
1301
|
-
|
1302
|
-
|
1303
|
-
|
1304
|
-
|
1305
|
-
|
1306
|
-
|
1307
|
-
|
1308
|
-
|
1309
|
-
|
1310
|
-
|
1311
|
-
|
1312
|
-
|
1313
|
-
|
1314
|
-
|
1315
|
-
|
1316
|
-
|
1466
|
+
void GrpcLb::OnBalancerChannelConnectivityChangedLocked(void* arg,
|
1467
|
+
grpc_error* error) {
|
1468
|
+
GrpcLb* self = static_cast<GrpcLb*>(arg);
|
1469
|
+
if (!self->shutting_down_ && self->fallback_at_startup_checks_pending_) {
|
1470
|
+
if (self->lb_channel_connectivity_ != GRPC_CHANNEL_TRANSIENT_FAILURE) {
|
1471
|
+
// Not in TRANSIENT_FAILURE. Renew connectivity watch.
|
1472
|
+
grpc_channel_element* client_channel_elem =
|
1473
|
+
grpc_channel_stack_last_element(
|
1474
|
+
grpc_channel_get_channel_stack(self->lb_channel_));
|
1475
|
+
GPR_ASSERT(client_channel_elem->filter == &grpc_client_channel_filter);
|
1476
|
+
grpc_client_channel_watch_connectivity_state(
|
1477
|
+
client_channel_elem,
|
1478
|
+
grpc_polling_entity_create_from_pollset_set(
|
1479
|
+
self->interested_parties()),
|
1480
|
+
&self->lb_channel_connectivity_,
|
1481
|
+
&self->lb_channel_on_connectivity_changed_, nullptr);
|
1482
|
+
return; // Early out so we don't drop the ref below.
|
1483
|
+
}
|
1484
|
+
// In TRANSIENT_FAILURE. Cancel the fallback timer and go into
|
1485
|
+
// fallback mode immediately.
|
1486
|
+
gpr_log(GPR_INFO,
|
1487
|
+
"[grpclb %p] balancer channel in state TRANSIENT_FAILURE; "
|
1488
|
+
"entering fallback mode",
|
1489
|
+
self);
|
1490
|
+
self->fallback_at_startup_checks_pending_ = false;
|
1491
|
+
grpc_timer_cancel(&self->lb_fallback_timer_);
|
1492
|
+
self->fallback_mode_ = true;
|
1493
|
+
self->CreateOrUpdateChildPolicyLocked();
|
1317
1494
|
}
|
1495
|
+
// Done watching connectivity state, so drop ref.
|
1496
|
+
self->Unref(DEBUG_LOCATION, "watch_lb_channel_connectivity");
|
1497
|
+
}
|
1498
|
+
|
1499
|
+
void GrpcLb::CancelBalancerChannelConnectivityWatchLocked() {
|
1500
|
+
grpc_channel_element* client_channel_elem = grpc_channel_stack_last_element(
|
1501
|
+
grpc_channel_get_channel_stack(lb_channel_));
|
1502
|
+
GPR_ASSERT(client_channel_elem->filter == &grpc_client_channel_filter);
|
1503
|
+
grpc_client_channel_watch_connectivity_state(
|
1504
|
+
client_channel_elem,
|
1505
|
+
grpc_polling_entity_create_from_pollset_set(interested_parties()),
|
1506
|
+
nullptr, &lb_channel_on_connectivity_changed_, nullptr);
|
1318
1507
|
}
|
1319
1508
|
|
1320
1509
|
//
|
1321
1510
|
// code for balancer channel and call
|
1322
1511
|
//
|
1323
1512
|
|
1324
|
-
void GrpcLb::StartPickingLocked() {
|
1325
|
-
// Start a timer to fall back.
|
1326
|
-
if (lb_fallback_timeout_ms_ > 0 && serverlist_ == nullptr &&
|
1327
|
-
!fallback_timer_callback_pending_) {
|
1328
|
-
grpc_millis deadline = ExecCtx::Get()->Now() + lb_fallback_timeout_ms_;
|
1329
|
-
// TODO(roth): We currently track this ref manually. Once the
|
1330
|
-
// ClosureRef API is ready, we should pass the RefCountedPtr<> along
|
1331
|
-
// with the callback.
|
1332
|
-
auto self = Ref(DEBUG_LOCATION, "on_fallback_timer");
|
1333
|
-
self.release();
|
1334
|
-
GRPC_CLOSURE_INIT(&lb_on_fallback_, &GrpcLb::OnFallbackTimerLocked, this,
|
1335
|
-
grpc_combiner_scheduler(combiner()));
|
1336
|
-
fallback_timer_callback_pending_ = true;
|
1337
|
-
grpc_timer_init(&lb_fallback_timer_, deadline, &lb_on_fallback_);
|
1338
|
-
}
|
1339
|
-
started_picking_ = true;
|
1340
|
-
StartBalancerCallLocked();
|
1341
|
-
}
|
1342
|
-
|
1343
1513
|
void GrpcLb::StartBalancerCallLocked() {
|
1344
1514
|
GPR_ASSERT(lb_channel_ != nullptr);
|
1345
1515
|
if (shutting_down_) return;
|
1346
1516
|
// Init the LB call data.
|
1347
1517
|
GPR_ASSERT(lb_calld_ == nullptr);
|
1348
1518
|
lb_calld_ = MakeOrphanable<BalancerCallState>(Ref());
|
1349
|
-
if (grpc_lb_glb_trace
|
1519
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) {
|
1350
1520
|
gpr_log(GPR_INFO,
|
1351
1521
|
"[grpclb %p] Query for backends (lb_channel: %p, lb_calld: %p)",
|
1352
1522
|
this, lb_channel_, lb_calld_.get());
|
@@ -1354,27 +1524,9 @@ void GrpcLb::StartBalancerCallLocked() {
|
|
1354
1524
|
lb_calld_->StartQuery();
|
1355
1525
|
}
|
1356
1526
|
|
1357
|
-
void GrpcLb::OnFallbackTimerLocked(void* arg, grpc_error* error) {
|
1358
|
-
GrpcLb* grpclb_policy = static_cast<GrpcLb*>(arg);
|
1359
|
-
grpclb_policy->fallback_timer_callback_pending_ = false;
|
1360
|
-
// If we receive a serverlist after the timer fires but before this callback
|
1361
|
-
// actually runs, don't fall back.
|
1362
|
-
if (grpclb_policy->serverlist_ == nullptr && !grpclb_policy->shutting_down_ &&
|
1363
|
-
error == GRPC_ERROR_NONE) {
|
1364
|
-
if (grpc_lb_glb_trace.enabled()) {
|
1365
|
-
gpr_log(GPR_INFO,
|
1366
|
-
"[grpclb %p] Falling back to use backends from resolver",
|
1367
|
-
grpclb_policy);
|
1368
|
-
}
|
1369
|
-
GPR_ASSERT(grpclb_policy->fallback_backend_addresses_ != nullptr);
|
1370
|
-
grpclb_policy->CreateOrUpdateRoundRobinPolicyLocked();
|
1371
|
-
}
|
1372
|
-
grpclb_policy->Unref(DEBUG_LOCATION, "on_fallback_timer");
|
1373
|
-
}
|
1374
|
-
|
1375
1527
|
void GrpcLb::StartBalancerCallRetryTimerLocked() {
|
1376
1528
|
grpc_millis next_try = lb_call_backoff_.NextAttemptTime();
|
1377
|
-
if (grpc_lb_glb_trace
|
1529
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) {
|
1378
1530
|
gpr_log(GPR_INFO, "[grpclb %p] Connection to LB server lost...", this);
|
1379
1531
|
grpc_millis timeout = next_try - ExecCtx::Get()->Now();
|
1380
1532
|
if (timeout > 0) {
|
@@ -1401,7 +1553,7 @@ void GrpcLb::OnBalancerCallRetryTimerLocked(void* arg, grpc_error* error) {
|
|
1401
1553
|
grpclb_policy->retry_timer_callback_pending_ = false;
|
1402
1554
|
if (!grpclb_policy->shutting_down_ && error == GRPC_ERROR_NONE &&
|
1403
1555
|
grpclb_policy->lb_calld_ == nullptr) {
|
1404
|
-
if (grpc_lb_glb_trace
|
1556
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) {
|
1405
1557
|
gpr_log(GPR_INFO, "[grpclb %p] Restarting call to LB server",
|
1406
1558
|
grpclb_policy);
|
1407
1559
|
}
|
@@ -1410,394 +1562,205 @@ void GrpcLb::OnBalancerCallRetryTimerLocked(void* arg, grpc_error* error) {
|
|
1410
1562
|
grpclb_policy->Unref(DEBUG_LOCATION, "on_balancer_call_retry_timer");
|
1411
1563
|
}
|
1412
1564
|
|
1413
|
-
// Invoked as part of the update process. It continues watching the LB channel
|
1414
|
-
// until it shuts down or becomes READY. It's invoked even if the LB channel
|
1415
|
-
// stayed READY throughout the update (for example if the update is identical).
|
1416
|
-
void GrpcLb::OnBalancerChannelConnectivityChangedLocked(void* arg,
|
1417
|
-
grpc_error* error) {
|
1418
|
-
GrpcLb* grpclb_policy = static_cast<GrpcLb*>(arg);
|
1419
|
-
if (grpclb_policy->shutting_down_) goto done;
|
1420
|
-
// Re-initialize the lb_call. This should also take care of updating the
|
1421
|
-
// embedded RR policy. Note that the current RR policy, if any, will stay in
|
1422
|
-
// effect until an update from the new lb_call is received.
|
1423
|
-
switch (grpclb_policy->lb_channel_connectivity_) {
|
1424
|
-
case GRPC_CHANNEL_CONNECTING:
|
1425
|
-
case GRPC_CHANNEL_TRANSIENT_FAILURE: {
|
1426
|
-
// Keep watching the LB channel.
|
1427
|
-
grpc_channel_element* client_channel_elem =
|
1428
|
-
grpc_channel_stack_last_element(
|
1429
|
-
grpc_channel_get_channel_stack(grpclb_policy->lb_channel_));
|
1430
|
-
GPR_ASSERT(client_channel_elem->filter == &grpc_client_channel_filter);
|
1431
|
-
grpc_client_channel_watch_connectivity_state(
|
1432
|
-
client_channel_elem,
|
1433
|
-
grpc_polling_entity_create_from_pollset_set(
|
1434
|
-
grpclb_policy->interested_parties()),
|
1435
|
-
&grpclb_policy->lb_channel_connectivity_,
|
1436
|
-
&grpclb_policy->lb_channel_on_connectivity_changed_, nullptr);
|
1437
|
-
break;
|
1438
|
-
}
|
1439
|
-
// The LB channel may be IDLE because it's shut down before the update.
|
1440
|
-
// Restart the LB call to kick the LB channel into gear.
|
1441
|
-
case GRPC_CHANNEL_IDLE:
|
1442
|
-
case GRPC_CHANNEL_READY:
|
1443
|
-
grpclb_policy->lb_calld_.reset();
|
1444
|
-
if (grpclb_policy->started_picking_) {
|
1445
|
-
if (grpclb_policy->retry_timer_callback_pending_) {
|
1446
|
-
grpc_timer_cancel(&grpclb_policy->lb_call_retry_timer_);
|
1447
|
-
}
|
1448
|
-
grpclb_policy->lb_call_backoff_.Reset();
|
1449
|
-
grpclb_policy->StartBalancerCallLocked();
|
1450
|
-
}
|
1451
|
-
// fallthrough
|
1452
|
-
case GRPC_CHANNEL_SHUTDOWN:
|
1453
|
-
done:
|
1454
|
-
grpclb_policy->watching_lb_channel_ = false;
|
1455
|
-
grpclb_policy->Unref(DEBUG_LOCATION,
|
1456
|
-
"watch_lb_channel_connectivity_cb_shutdown");
|
1457
|
-
}
|
1458
|
-
}
|
1459
|
-
|
1460
1565
|
//
|
1461
|
-
//
|
1566
|
+
// code for handling fallback mode
|
1462
1567
|
//
|
1463
1568
|
|
1464
|
-
|
1465
|
-
//
|
1466
|
-
|
1467
|
-
|
1468
|
-
|
1469
|
-
|
1470
|
-
|
1471
|
-
|
1472
|
-
|
1473
|
-
|
1474
|
-
|
1475
|
-
|
1476
|
-
|
1477
|
-
|
1478
|
-
|
1479
|
-
|
1480
|
-
void GrpcLb::PendingPickSetMetadataAndContext(PendingPick* pp) {
|
1481
|
-
// If connected_subchannel is nullptr, no pick has been made by the RR
|
1482
|
-
// policy (e.g., all addresses failed to connect). There won't be any
|
1483
|
-
// LB token available.
|
1484
|
-
if (pp->pick->connected_subchannel != nullptr) {
|
1485
|
-
const grpc_arg* arg =
|
1486
|
-
grpc_channel_args_find(pp->pick->connected_subchannel->args(),
|
1487
|
-
GRPC_ARG_GRPCLB_ADDRESS_LB_TOKEN);
|
1488
|
-
if (arg != nullptr) {
|
1489
|
-
grpc_mdelem lb_token = {
|
1490
|
-
reinterpret_cast<uintptr_t>(arg->value.pointer.p)};
|
1491
|
-
AddLbTokenToInitialMetadata(GRPC_MDELEM_REF(lb_token),
|
1492
|
-
&pp->pick->lb_token_mdelem_storage,
|
1493
|
-
pp->pick->initial_metadata);
|
1494
|
-
} else {
|
1495
|
-
gpr_log(GPR_ERROR,
|
1496
|
-
"[grpclb %p] No LB token for connected subchannel pick %p",
|
1497
|
-
pp->grpclb_policy, pp->pick);
|
1498
|
-
abort();
|
1499
|
-
}
|
1500
|
-
// Pass on client stats via context. Passes ownership of the reference.
|
1501
|
-
if (pp->client_stats != nullptr) {
|
1502
|
-
pp->pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].value =
|
1503
|
-
pp->client_stats.release();
|
1504
|
-
pp->pick->subchannel_call_context[GRPC_GRPCLB_CLIENT_STATS].destroy =
|
1505
|
-
DestroyClientStats;
|
1506
|
-
}
|
1507
|
-
} else {
|
1508
|
-
pp->client_stats.reset();
|
1569
|
+
void GrpcLb::MaybeEnterFallbackModeAfterStartup() {
|
1570
|
+
// Enter fallback mode if all of the following are true:
|
1571
|
+
// - We are not currently in fallback mode.
|
1572
|
+
// - We are not currently waiting for the initial fallback timeout.
|
1573
|
+
// - We are not currently in contact with the balancer.
|
1574
|
+
// - The child policy is not in state READY.
|
1575
|
+
if (!fallback_mode_ && !fallback_at_startup_checks_pending_ &&
|
1576
|
+
(lb_calld_ == nullptr || !lb_calld_->seen_serverlist()) &&
|
1577
|
+
!child_policy_ready_) {
|
1578
|
+
gpr_log(GPR_INFO,
|
1579
|
+
"[grpclb %p] lost contact with balancer and backends from "
|
1580
|
+
"most recent serverlist; entering fallback mode",
|
1581
|
+
this);
|
1582
|
+
fallback_mode_ = true;
|
1583
|
+
CreateOrUpdateChildPolicyLocked();
|
1509
1584
|
}
|
1510
1585
|
}
|
1511
1586
|
|
1512
|
-
|
1513
|
-
|
1514
|
-
|
1515
|
-
|
1516
|
-
|
1517
|
-
|
1518
|
-
|
1519
|
-
|
1520
|
-
|
1521
|
-
|
1522
|
-
|
1523
|
-
|
1524
|
-
|
1525
|
-
|
1526
|
-
|
1527
|
-
|
1528
|
-
pp->original_on_complete = pick->on_complete;
|
1529
|
-
pick->on_complete = &pp->on_complete;
|
1530
|
-
return pp;
|
1531
|
-
}
|
1532
|
-
|
1533
|
-
void GrpcLb::AddPendingPick(PendingPick* pp) {
|
1534
|
-
pp->next = pending_picks_;
|
1535
|
-
pending_picks_ = pp;
|
1587
|
+
void GrpcLb::OnFallbackTimerLocked(void* arg, grpc_error* error) {
|
1588
|
+
GrpcLb* grpclb_policy = static_cast<GrpcLb*>(arg);
|
1589
|
+
// If we receive a serverlist after the timer fires but before this callback
|
1590
|
+
// actually runs, don't fall back.
|
1591
|
+
if (grpclb_policy->fallback_at_startup_checks_pending_ &&
|
1592
|
+
!grpclb_policy->shutting_down_ && error == GRPC_ERROR_NONE) {
|
1593
|
+
gpr_log(GPR_INFO,
|
1594
|
+
"[grpclb %p] No response from balancer after fallback timeout; "
|
1595
|
+
"entering fallback mode",
|
1596
|
+
grpclb_policy);
|
1597
|
+
grpclb_policy->fallback_at_startup_checks_pending_ = false;
|
1598
|
+
grpclb_policy->CancelBalancerChannelConnectivityWatchLocked();
|
1599
|
+
grpclb_policy->fallback_mode_ = true;
|
1600
|
+
grpclb_policy->CreateOrUpdateChildPolicyLocked();
|
1601
|
+
}
|
1602
|
+
grpclb_policy->Unref(DEBUG_LOCATION, "on_fallback_timer");
|
1536
1603
|
}
|
1537
1604
|
|
1538
1605
|
//
|
1539
|
-
// code for interacting with the
|
1606
|
+
// code for interacting with the child policy
|
1540
1607
|
//
|
1541
1608
|
|
1542
|
-
|
1543
|
-
|
1544
|
-
|
1545
|
-
|
1546
|
-
|
1547
|
-
|
1548
|
-
|
1549
|
-
|
1550
|
-
|
1551
|
-
// Look at the index into the serverlist to see if we should drop this call.
|
1552
|
-
grpc_grpclb_server* server = serverlist_->servers[serverlist_index_++];
|
1553
|
-
if (serverlist_index_ == serverlist_->num_servers) {
|
1554
|
-
serverlist_index_ = 0; // Wrap-around.
|
1555
|
-
}
|
1556
|
-
if (server->drop) {
|
1557
|
-
// Update client load reporting stats to indicate the number of
|
1558
|
-
// dropped calls. Note that we have to do this here instead of in
|
1559
|
-
// the client_load_reporting filter, because we do not create a
|
1560
|
-
// subchannel call (and therefore no client_load_reporting filter)
|
1561
|
-
// for dropped calls.
|
1562
|
-
if (lb_calld_ != nullptr && lb_calld_->client_stats() != nullptr) {
|
1563
|
-
lb_calld_->client_stats()->AddCallDroppedLocked(
|
1564
|
-
server->load_balance_token);
|
1565
|
-
}
|
1566
|
-
if (force_async) {
|
1567
|
-
GRPC_CLOSURE_SCHED(pp->original_on_complete, GRPC_ERROR_NONE);
|
1568
|
-
Delete(pp);
|
1569
|
-
return false;
|
1570
|
-
}
|
1571
|
-
Delete(pp);
|
1572
|
-
return true;
|
1573
|
-
}
|
1574
|
-
}
|
1575
|
-
// Set client_stats.
|
1576
|
-
if (lb_calld_ != nullptr && lb_calld_->client_stats() != nullptr) {
|
1577
|
-
pp->client_stats = lb_calld_->client_stats()->Ref();
|
1578
|
-
}
|
1579
|
-
// Pick via the RR policy.
|
1580
|
-
bool pick_done = rr_policy_->PickLocked(pp->pick, error);
|
1581
|
-
if (pick_done) {
|
1582
|
-
PendingPickSetMetadataAndContext(pp);
|
1583
|
-
if (force_async) {
|
1584
|
-
GRPC_CLOSURE_SCHED(pp->original_on_complete, *error);
|
1585
|
-
*error = GRPC_ERROR_NONE;
|
1586
|
-
pick_done = false;
|
1587
|
-
}
|
1588
|
-
Delete(pp);
|
1609
|
+
grpc_channel_args* GrpcLb::CreateChildPolicyArgsLocked(
|
1610
|
+
bool is_backend_from_grpclb_load_balancer) {
|
1611
|
+
InlinedVector<grpc_arg, 2> args_to_add;
|
1612
|
+
args_to_add.emplace_back(grpc_channel_arg_integer_create(
|
1613
|
+
const_cast<char*>(GRPC_ARG_ADDRESS_IS_BACKEND_FROM_GRPCLB_LOAD_BALANCER),
|
1614
|
+
is_backend_from_grpclb_load_balancer));
|
1615
|
+
if (is_backend_from_grpclb_load_balancer) {
|
1616
|
+
args_to_add.emplace_back(grpc_channel_arg_integer_create(
|
1617
|
+
const_cast<char*>(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1));
|
1589
1618
|
}
|
1590
|
-
|
1591
|
-
|
1592
|
-
// OnPendingPickComplete() will be called, which will (among other
|
1593
|
-
// things) add the LB token to the call's initial metadata.
|
1594
|
-
return pick_done;
|
1619
|
+
return grpc_channel_args_copy_and_add(args_, args_to_add.data(),
|
1620
|
+
args_to_add.size());
|
1595
1621
|
}
|
1596
1622
|
|
1597
|
-
|
1598
|
-
|
1599
|
-
|
1600
|
-
|
1601
|
-
|
1602
|
-
|
1603
|
-
|
1604
|
-
|
1623
|
+
OrphanablePtr<LoadBalancingPolicy> GrpcLb::CreateChildPolicyLocked(
|
1624
|
+
const char* name, const grpc_channel_args* args) {
|
1625
|
+
Helper* helper = New<Helper>(Ref());
|
1626
|
+
LoadBalancingPolicy::Args lb_policy_args;
|
1627
|
+
lb_policy_args.combiner = combiner();
|
1628
|
+
lb_policy_args.args = args;
|
1629
|
+
lb_policy_args.channel_control_helper =
|
1630
|
+
UniquePtr<ChannelControlHelper>(helper);
|
1631
|
+
OrphanablePtr<LoadBalancingPolicy> lb_policy =
|
1632
|
+
LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy(
|
1633
|
+
name, std::move(lb_policy_args));
|
1634
|
+
if (GPR_UNLIKELY(lb_policy == nullptr)) {
|
1635
|
+
gpr_log(GPR_ERROR, "[grpclb %p] Failure creating child policy %s", this,
|
1636
|
+
name);
|
1637
|
+
return nullptr;
|
1605
1638
|
}
|
1606
|
-
|
1607
|
-
|
1608
|
-
|
1639
|
+
helper->set_child(lb_policy.get());
|
1640
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) {
|
1641
|
+
gpr_log(GPR_INFO, "[grpclb %p] Created new child policy %s (%p)", this,
|
1642
|
+
name, lb_policy.get());
|
1609
1643
|
}
|
1610
|
-
// TODO(roth): We currently track this ref manually. Once the new
|
1611
|
-
// ClosureRef API is done, pass the RefCountedPtr<> along with the closure.
|
1612
|
-
auto self = Ref(DEBUG_LOCATION, "on_rr_reresolution_requested");
|
1613
|
-
self.release();
|
1614
|
-
rr_policy_->SetReresolutionClosureLocked(&on_rr_request_reresolution_);
|
1615
|
-
grpc_error* rr_state_error = nullptr;
|
1616
|
-
rr_connectivity_state_ = rr_policy_->CheckConnectivityLocked(&rr_state_error);
|
1617
|
-
// Connectivity state is a function of the RR policy updated/created.
|
1618
|
-
UpdateConnectivityStateFromRoundRobinPolicyLocked(rr_state_error);
|
1619
1644
|
// Add the gRPC LB's interested_parties pollset_set to that of the newly
|
1620
|
-
// created
|
1621
|
-
// gRPC LB, which in turn is tied to the application's call.
|
1622
|
-
grpc_pollset_set_add_pollset_set(
|
1645
|
+
// created child policy. This will make the child policy progress upon
|
1646
|
+
// activity on gRPC LB, which in turn is tied to the application's call.
|
1647
|
+
grpc_pollset_set_add_pollset_set(lb_policy->interested_parties(),
|
1623
1648
|
interested_parties());
|
1624
|
-
|
1625
|
-
// TODO(roth): We currently track this ref manually. Once the new
|
1626
|
-
// ClosureRef API is done, pass the RefCountedPtr<> along with the closure.
|
1627
|
-
self = Ref(DEBUG_LOCATION, "on_rr_connectivity_changed");
|
1628
|
-
self.release();
|
1629
|
-
rr_policy_->NotifyOnStateChangeLocked(&rr_connectivity_state_,
|
1630
|
-
&on_rr_connectivity_changed_);
|
1631
|
-
rr_policy_->ExitIdleLocked();
|
1632
|
-
// Send pending picks to RR policy.
|
1633
|
-
PendingPick* pp;
|
1634
|
-
while ((pp = pending_picks_)) {
|
1635
|
-
pending_picks_ = pp->next;
|
1636
|
-
if (grpc_lb_glb_trace.enabled()) {
|
1637
|
-
gpr_log(GPR_INFO,
|
1638
|
-
"[grpclb %p] Pending pick about to (async) PICK from RR %p", this,
|
1639
|
-
rr_policy_.get());
|
1640
|
-
}
|
1641
|
-
grpc_error* error = GRPC_ERROR_NONE;
|
1642
|
-
PickFromRoundRobinPolicyLocked(true /* force_async */, pp, &error);
|
1643
|
-
}
|
1649
|
+
return lb_policy;
|
1644
1650
|
}
|
1645
1651
|
|
1646
|
-
|
1647
|
-
|
1648
|
-
|
1652
|
+
void GrpcLb::CreateOrUpdateChildPolicyLocked() {
|
1653
|
+
if (shutting_down_) return;
|
1654
|
+
// Construct update args.
|
1655
|
+
UpdateArgs update_args;
|
1649
1656
|
bool is_backend_from_grpclb_load_balancer = false;
|
1650
|
-
if (
|
1651
|
-
|
1652
|
-
is_backend_from_grpclb_load_balancer = true;
|
1653
|
-
} else {
|
1654
|
-
// If CreateOrUpdateRoundRobinPolicyLocked() is invoked when we haven't
|
1657
|
+
if (fallback_mode_) {
|
1658
|
+
// If CreateOrUpdateChildPolicyLocked() is invoked when we haven't
|
1655
1659
|
// received any serverlist from the balancer, we use the fallback backends
|
1656
1660
|
// returned by the resolver. Note that the fallback backend list may be
|
1657
1661
|
// empty, in which case the new round_robin policy will keep the requested
|
1658
1662
|
// picks pending.
|
1659
|
-
|
1660
|
-
|
1661
|
-
|
1662
|
-
|
1663
|
-
|
1664
|
-
// the subchannel.
|
1665
|
-
static const char* keys_to_remove[] = {GRPC_ARG_SERVER_ADDRESS_LIST};
|
1666
|
-
grpc_arg args_to_add[3] = {
|
1667
|
-
CreateServerAddressListChannelArg(addresses),
|
1668
|
-
// A channel arg indicating if the target is a backend inferred from a
|
1669
|
-
// grpclb load balancer.
|
1670
|
-
grpc_channel_arg_integer_create(
|
1671
|
-
const_cast<char*>(
|
1672
|
-
GRPC_ARG_ADDRESS_IS_BACKEND_FROM_GRPCLB_LOAD_BALANCER),
|
1673
|
-
is_backend_from_grpclb_load_balancer),
|
1674
|
-
};
|
1675
|
-
size_t num_args_to_add = 2;
|
1676
|
-
if (is_backend_from_grpclb_load_balancer) {
|
1677
|
-
args_to_add[2] = grpc_channel_arg_integer_create(
|
1678
|
-
const_cast<char*>(GRPC_ARG_INHIBIT_HEALTH_CHECKING), 1);
|
1679
|
-
++num_args_to_add;
|
1663
|
+
update_args.addresses = fallback_backend_addresses_;
|
1664
|
+
} else {
|
1665
|
+
update_args.addresses = serverlist_->GetServerAddressList(
|
1666
|
+
lb_calld_ == nullptr ? nullptr : lb_calld_->client_stats());
|
1667
|
+
is_backend_from_grpclb_load_balancer = true;
|
1680
1668
|
}
|
1681
|
-
|
1682
|
-
|
1683
|
-
|
1684
|
-
|
1685
|
-
|
1686
|
-
|
1687
|
-
|
1688
|
-
|
1689
|
-
|
1690
|
-
|
1691
|
-
|
1692
|
-
|
1693
|
-
|
1694
|
-
|
1669
|
+
update_args.args =
|
1670
|
+
CreateChildPolicyArgsLocked(is_backend_from_grpclb_load_balancer);
|
1671
|
+
GPR_ASSERT(update_args.args != nullptr);
|
1672
|
+
update_args.config = child_policy_config_;
|
1673
|
+
// If the child policy name changes, we need to create a new child
|
1674
|
+
// policy. When this happens, we leave child_policy_ as-is and store
|
1675
|
+
// the new child policy in pending_child_policy_. Once the new child
|
1676
|
+
// policy transitions into state READY, we swap it into child_policy_,
|
1677
|
+
// replacing the original child policy. So pending_child_policy_ is
|
1678
|
+
// non-null only between when we apply an update that changes the child
|
1679
|
+
// policy name and when the new child reports state READY.
|
1680
|
+
//
|
1681
|
+
// Updates can arrive at any point during this transition. We always
|
1682
|
+
// apply updates relative to the most recently created child policy,
|
1683
|
+
// even if the most recent one is still in pending_child_policy_. This
|
1684
|
+
// is true both when applying the updates to an existing child policy
|
1685
|
+
// and when determining whether we need to create a new policy.
|
1686
|
+
//
|
1687
|
+
// As a result of this, there are several cases to consider here:
|
1688
|
+
//
|
1689
|
+
// 1. We have no existing child policy (i.e., we have started up but
|
1690
|
+
// have not yet received a serverlist from the balancer or gone
|
1691
|
+
// into fallback mode; in this case, both child_policy_ and
|
1692
|
+
// pending_child_policy_ are null). In this case, we create a
|
1693
|
+
// new child policy and store it in child_policy_.
|
1694
|
+
//
|
1695
|
+
// 2. We have an existing child policy and have no pending child policy
|
1696
|
+
// from a previous update (i.e., either there has not been a
|
1697
|
+
// previous update that changed the policy name, or we have already
|
1698
|
+
// finished swapping in the new policy; in this case, child_policy_
|
1699
|
+
// is non-null but pending_child_policy_ is null). In this case:
|
1700
|
+
// a. If child_policy_->name() equals child_policy_name, then we
|
1701
|
+
// update the existing child policy.
|
1702
|
+
// b. If child_policy_->name() does not equal child_policy_name,
|
1703
|
+
// we create a new policy. The policy will be stored in
|
1704
|
+
// pending_child_policy_ and will later be swapped into
|
1705
|
+
// child_policy_ by the helper when the new child transitions
|
1706
|
+
// into state READY.
|
1707
|
+
//
|
1708
|
+
// 3. We have an existing child policy and have a pending child policy
|
1709
|
+
// from a previous update (i.e., a previous update set
|
1710
|
+
// pending_child_policy_ as per case 2b above and that policy has
|
1711
|
+
// not yet transitioned into state READY and been swapped into
|
1712
|
+
// child_policy_; in this case, both child_policy_ and
|
1713
|
+
// pending_child_policy_ are non-null). In this case:
|
1714
|
+
// a. If pending_child_policy_->name() equals child_policy_name,
|
1715
|
+
// then we update the existing pending child policy.
|
1716
|
+
// b. If pending_child_policy->name() does not equal
|
1717
|
+
// child_policy_name, then we create a new policy. The new
|
1718
|
+
// policy is stored in pending_child_policy_ (replacing the one
|
1719
|
+
// that was there before, which will be immediately shut down)
|
1720
|
+
// and will later be swapped into child_policy_ by the helper
|
1721
|
+
// when the new child transitions into state READY.
|
1722
|
+
const char* child_policy_name = child_policy_config_ == nullptr
|
1723
|
+
? "round_robin"
|
1724
|
+
: child_policy_config_->name();
|
1725
|
+
const bool create_policy =
|
1726
|
+
// case 1
|
1727
|
+
child_policy_ == nullptr ||
|
1728
|
+
// case 2b
|
1729
|
+
(pending_child_policy_ == nullptr &&
|
1730
|
+
strcmp(child_policy_->name(), child_policy_name) != 0) ||
|
1731
|
+
// case 3b
|
1732
|
+
(pending_child_policy_ != nullptr &&
|
1733
|
+
strcmp(pending_child_policy_->name(), child_policy_name) != 0);
|
1734
|
+
LoadBalancingPolicy* policy_to_update = nullptr;
|
1735
|
+
if (create_policy) {
|
1736
|
+
// Cases 1, 2b, and 3b: create a new child policy.
|
1737
|
+
// If child_policy_ is null, we set it (case 1), else we set
|
1738
|
+
// pending_child_policy_ (cases 2b and 3b).
|
1739
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) {
|
1740
|
+
gpr_log(GPR_INFO, "[grpclb %p] Creating new %schild policy %s", this,
|
1741
|
+
child_policy_ == nullptr ? "" : "pending ", child_policy_name);
|
1695
1742
|
}
|
1696
|
-
|
1743
|
+
// Swap the policy into place.
|
1744
|
+
auto& lb_policy =
|
1745
|
+
child_policy_ == nullptr ? child_policy_ : pending_child_policy_;
|
1746
|
+
lb_policy = CreateChildPolicyLocked(child_policy_name, update_args.args);
|
1747
|
+
policy_to_update = lb_policy.get();
|
1697
1748
|
} else {
|
1698
|
-
|
1699
|
-
|
1700
|
-
|
1701
|
-
|
1702
|
-
|
1703
|
-
|
1704
|
-
grpc_channel_args_destroy(args);
|
1705
|
-
}
|
1706
|
-
|
1707
|
-
void GrpcLb::OnRoundRobinRequestReresolutionLocked(void* arg,
|
1708
|
-
grpc_error* error) {
|
1709
|
-
GrpcLb* grpclb_policy = static_cast<GrpcLb*>(arg);
|
1710
|
-
if (grpclb_policy->shutting_down_ || error != GRPC_ERROR_NONE) {
|
1711
|
-
grpclb_policy->Unref(DEBUG_LOCATION, "on_rr_reresolution_requested");
|
1712
|
-
return;
|
1713
|
-
}
|
1714
|
-
if (grpc_lb_glb_trace.enabled()) {
|
1715
|
-
gpr_log(
|
1716
|
-
GPR_INFO,
|
1717
|
-
"[grpclb %p] Re-resolution requested from the internal RR policy (%p).",
|
1718
|
-
grpclb_policy, grpclb_policy->rr_policy_.get());
|
1719
|
-
}
|
1720
|
-
// If we are talking to a balancer, we expect to get updated addresses form
|
1721
|
-
// the balancer, so we can ignore the re-resolution request from the RR
|
1722
|
-
// policy. Otherwise, handle the re-resolution request using the
|
1723
|
-
// grpclb policy's original re-resolution closure.
|
1724
|
-
if (grpclb_policy->lb_calld_ == nullptr ||
|
1725
|
-
!grpclb_policy->lb_calld_->seen_initial_response()) {
|
1726
|
-
grpclb_policy->TryReresolutionLocked(&grpc_lb_glb_trace, GRPC_ERROR_NONE);
|
1727
|
-
}
|
1728
|
-
// Give back the wrapper closure to the RR policy.
|
1729
|
-
grpclb_policy->rr_policy_->SetReresolutionClosureLocked(
|
1730
|
-
&grpclb_policy->on_rr_request_reresolution_);
|
1731
|
-
}
|
1732
|
-
|
1733
|
-
void GrpcLb::UpdateConnectivityStateFromRoundRobinPolicyLocked(
|
1734
|
-
grpc_error* rr_state_error) {
|
1735
|
-
const grpc_connectivity_state curr_glb_state =
|
1736
|
-
grpc_connectivity_state_check(&state_tracker_);
|
1737
|
-
/* The new connectivity status is a function of the previous one and the new
|
1738
|
-
* input coming from the status of the RR policy.
|
1739
|
-
*
|
1740
|
-
* current state (grpclb's)
|
1741
|
-
* |
|
1742
|
-
* v || I | C | R | TF | SD | <- new state (RR's)
|
1743
|
-
* ===++====+=====+=====+======+======+
|
1744
|
-
* I || I | C | R | [I] | [I] |
|
1745
|
-
* ---++----+-----+-----+------+------+
|
1746
|
-
* C || I | C | R | [C] | [C] |
|
1747
|
-
* ---++----+-----+-----+------+------+
|
1748
|
-
* R || I | C | R | [R] | [R] |
|
1749
|
-
* ---++----+-----+-----+------+------+
|
1750
|
-
* TF || I | C | R | [TF] | [TF] |
|
1751
|
-
* ---++----+-----+-----+------+------+
|
1752
|
-
* SD || NA | NA | NA | NA | NA | (*)
|
1753
|
-
* ---++----+-----+-----+------+------+
|
1754
|
-
*
|
1755
|
-
* A [STATE] indicates that the old RR policy is kept. In those cases, STATE
|
1756
|
-
* is the current state of grpclb, which is left untouched.
|
1757
|
-
*
|
1758
|
-
* In summary, if the new state is TRANSIENT_FAILURE or SHUTDOWN, stick to
|
1759
|
-
* the previous RR instance.
|
1760
|
-
*
|
1761
|
-
* Note that the status is never updated to SHUTDOWN as a result of calling
|
1762
|
-
* this function. Only glb_shutdown() has the power to set that state.
|
1763
|
-
*
|
1764
|
-
* (*) This function mustn't be called during shutting down. */
|
1765
|
-
GPR_ASSERT(curr_glb_state != GRPC_CHANNEL_SHUTDOWN);
|
1766
|
-
switch (rr_connectivity_state_) {
|
1767
|
-
case GRPC_CHANNEL_TRANSIENT_FAILURE:
|
1768
|
-
case GRPC_CHANNEL_SHUTDOWN:
|
1769
|
-
GPR_ASSERT(rr_state_error != GRPC_ERROR_NONE);
|
1770
|
-
break;
|
1771
|
-
case GRPC_CHANNEL_IDLE:
|
1772
|
-
case GRPC_CHANNEL_CONNECTING:
|
1773
|
-
case GRPC_CHANNEL_READY:
|
1774
|
-
GPR_ASSERT(rr_state_error == GRPC_ERROR_NONE);
|
1749
|
+
// Cases 2a and 3a: update an existing policy.
|
1750
|
+
// If we have a pending child policy, send the update to the pending
|
1751
|
+
// policy (case 3a), else send it to the current policy (case 2a).
|
1752
|
+
policy_to_update = pending_child_policy_ != nullptr
|
1753
|
+
? pending_child_policy_.get()
|
1754
|
+
: child_policy_.get();
|
1775
1755
|
}
|
1776
|
-
|
1777
|
-
|
1778
|
-
|
1779
|
-
|
1780
|
-
|
1781
|
-
|
1782
|
-
}
|
1783
|
-
grpc_connectivity_state_set(&state_tracker_, rr_connectivity_state_,
|
1784
|
-
rr_state_error,
|
1785
|
-
"update_lb_connectivity_status_locked");
|
1786
|
-
}
|
1787
|
-
|
1788
|
-
void GrpcLb::OnRoundRobinConnectivityChangedLocked(void* arg,
|
1789
|
-
grpc_error* error) {
|
1790
|
-
GrpcLb* grpclb_policy = static_cast<GrpcLb*>(arg);
|
1791
|
-
if (grpclb_policy->shutting_down_) {
|
1792
|
-
grpclb_policy->Unref(DEBUG_LOCATION, "on_rr_connectivity_changed");
|
1793
|
-
return;
|
1756
|
+
GPR_ASSERT(policy_to_update != nullptr);
|
1757
|
+
// Update the policy.
|
1758
|
+
if (GRPC_TRACE_FLAG_ENABLED(grpc_lb_glb_trace)) {
|
1759
|
+
gpr_log(GPR_INFO, "[grpclb %p] Updating %schild policy %p", this,
|
1760
|
+
policy_to_update == pending_child_policy_.get() ? "pending " : "",
|
1761
|
+
policy_to_update);
|
1794
1762
|
}
|
1795
|
-
|
1796
|
-
GRPC_ERROR_REF(error));
|
1797
|
-
// Resubscribe. Reuse the "on_rr_connectivity_changed" ref.
|
1798
|
-
grpclb_policy->rr_policy_->NotifyOnStateChangeLocked(
|
1799
|
-
&grpclb_policy->rr_connectivity_state_,
|
1800
|
-
&grpclb_policy->on_rr_connectivity_changed_);
|
1763
|
+
policy_to_update->UpdateLocked(std::move(update_args));
|
1801
1764
|
}
|
1802
1765
|
|
1803
1766
|
//
|
@@ -1807,23 +1770,45 @@ void GrpcLb::OnRoundRobinConnectivityChangedLocked(void* arg,
|
|
1807
1770
|
class GrpcLbFactory : public LoadBalancingPolicyFactory {
|
1808
1771
|
public:
|
1809
1772
|
OrphanablePtr<LoadBalancingPolicy> CreateLoadBalancingPolicy(
|
1810
|
-
|
1811
|
-
|
1812
|
-
const ServerAddressList* addresses =
|
1813
|
-
FindServerAddressListChannelArg(args.args);
|
1814
|
-
if (addresses == nullptr) return nullptr;
|
1815
|
-
bool found_balancer = false;
|
1816
|
-
for (size_t i = 0; i < addresses->size(); ++i) {
|
1817
|
-
if ((*addresses)[i].IsBalancer()) {
|
1818
|
-
found_balancer = true;
|
1819
|
-
break;
|
1820
|
-
}
|
1821
|
-
}
|
1822
|
-
if (!found_balancer) return nullptr;
|
1823
|
-
return OrphanablePtr<LoadBalancingPolicy>(New<GrpcLb>(args));
|
1773
|
+
LoadBalancingPolicy::Args args) const override {
|
1774
|
+
return OrphanablePtr<LoadBalancingPolicy>(New<GrpcLb>(std::move(args)));
|
1824
1775
|
}
|
1825
1776
|
|
1826
1777
|
const char* name() const override { return kGrpclb; }
|
1778
|
+
|
1779
|
+
RefCountedPtr<LoadBalancingPolicy::Config> ParseLoadBalancingConfig(
|
1780
|
+
const grpc_json* json, grpc_error** error) const override {
|
1781
|
+
GPR_DEBUG_ASSERT(error != nullptr && *error == GRPC_ERROR_NONE);
|
1782
|
+
if (json == nullptr) {
|
1783
|
+
return RefCountedPtr<LoadBalancingPolicy::Config>(
|
1784
|
+
New<ParsedGrpcLbConfig>(nullptr));
|
1785
|
+
}
|
1786
|
+
InlinedVector<grpc_error*, 2> error_list;
|
1787
|
+
RefCountedPtr<LoadBalancingPolicy::Config> child_policy;
|
1788
|
+
for (const grpc_json* field = json->child; field != nullptr;
|
1789
|
+
field = field->next) {
|
1790
|
+
if (field->key == nullptr) continue;
|
1791
|
+
if (strcmp(field->key, "childPolicy") == 0) {
|
1792
|
+
if (child_policy != nullptr) {
|
1793
|
+
error_list.push_back(GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
1794
|
+
"field:childPolicy error:Duplicate entry"));
|
1795
|
+
}
|
1796
|
+
grpc_error* parse_error = GRPC_ERROR_NONE;
|
1797
|
+
child_policy = LoadBalancingPolicyRegistry::ParseLoadBalancingConfig(
|
1798
|
+
field, &parse_error);
|
1799
|
+
if (parse_error != GRPC_ERROR_NONE) {
|
1800
|
+
error_list.push_back(parse_error);
|
1801
|
+
}
|
1802
|
+
}
|
1803
|
+
}
|
1804
|
+
if (error_list.empty()) {
|
1805
|
+
return RefCountedPtr<LoadBalancingPolicy::Config>(
|
1806
|
+
New<ParsedGrpcLbConfig>(std::move(child_policy)));
|
1807
|
+
} else {
|
1808
|
+
*error = GRPC_ERROR_CREATE_FROM_VECTOR("GrpcLb Parser", &error_list);
|
1809
|
+
return nullptr;
|
1810
|
+
}
|
1811
|
+
}
|
1827
1812
|
};
|
1828
1813
|
|
1829
1814
|
} // namespace
|