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
@@ -33,7 +33,8 @@
|
|
33
33
|
#include "src/core/ext/filters/client_channel/health/health_check_client.h"
|
34
34
|
#include "src/core/ext/filters/client_channel/parse_address.h"
|
35
35
|
#include "src/core/ext/filters/client_channel/proxy_mapper_registry.h"
|
36
|
-
#include "src/core/ext/filters/client_channel/
|
36
|
+
#include "src/core/ext/filters/client_channel/service_config.h"
|
37
|
+
#include "src/core/ext/filters/client_channel/subchannel_pool_interface.h"
|
37
38
|
#include "src/core/lib/backoff/backoff.h"
|
38
39
|
#include "src/core/lib/channel/channel_args.h"
|
39
40
|
#include "src/core/lib/channel/connected_channel.h"
|
@@ -41,249 +42,312 @@
|
|
41
42
|
#include "src/core/lib/gpr/alloc.h"
|
42
43
|
#include "src/core/lib/gprpp/debug_location.h"
|
43
44
|
#include "src/core/lib/gprpp/manual_constructor.h"
|
44
|
-
#include "src/core/lib/gprpp/mutex_lock.h"
|
45
45
|
#include "src/core/lib/gprpp/ref_counted_ptr.h"
|
46
|
+
#include "src/core/lib/gprpp/sync.h"
|
46
47
|
#include "src/core/lib/iomgr/sockaddr_utils.h"
|
47
|
-
#include "src/core/lib/iomgr/timer.h"
|
48
48
|
#include "src/core/lib/profiling/timers.h"
|
49
49
|
#include "src/core/lib/slice/slice_internal.h"
|
50
50
|
#include "src/core/lib/surface/channel.h"
|
51
51
|
#include "src/core/lib/surface/channel_init.h"
|
52
52
|
#include "src/core/lib/transport/connectivity_state.h"
|
53
53
|
#include "src/core/lib/transport/error_utils.h"
|
54
|
-
#include "src/core/lib/transport/service_config.h"
|
55
54
|
#include "src/core/lib/transport/status_metadata.h"
|
56
55
|
#include "src/core/lib/uri/uri_parser.h"
|
57
56
|
|
57
|
+
// Strong and weak refs.
|
58
58
|
#define INTERNAL_REF_BITS 16
|
59
59
|
#define STRONG_REF_MASK (~(gpr_atm)((1 << INTERNAL_REF_BITS) - 1))
|
60
60
|
|
61
|
+
// Backoff parameters.
|
61
62
|
#define GRPC_SUBCHANNEL_INITIAL_CONNECT_BACKOFF_SECONDS 1
|
62
63
|
#define GRPC_SUBCHANNEL_RECONNECT_BACKOFF_MULTIPLIER 1.6
|
63
64
|
#define GRPC_SUBCHANNEL_RECONNECT_MIN_TIMEOUT_SECONDS 20
|
64
65
|
#define GRPC_SUBCHANNEL_RECONNECT_MAX_BACKOFF_SECONDS 120
|
65
66
|
#define GRPC_SUBCHANNEL_RECONNECT_JITTER 0.2
|
66
67
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
grpc_closure health_check_closure;
|
75
|
-
grpc_connectivity_state health_state;
|
76
|
-
};
|
77
|
-
} // namespace
|
78
|
-
|
79
|
-
typedef struct external_state_watcher {
|
80
|
-
grpc_subchannel* subchannel;
|
81
|
-
grpc_pollset_set* pollset_set;
|
82
|
-
grpc_closure* notify;
|
83
|
-
grpc_closure closure;
|
84
|
-
struct external_state_watcher* next;
|
85
|
-
struct external_state_watcher* prev;
|
86
|
-
} external_state_watcher;
|
68
|
+
// Conversion between subchannel call and call stack.
|
69
|
+
#define SUBCHANNEL_CALL_TO_CALL_STACK(call) \
|
70
|
+
(grpc_call_stack*)((char*)(call) + \
|
71
|
+
GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(SubchannelCall)))
|
72
|
+
#define CALL_STACK_TO_SUBCHANNEL_CALL(callstack) \
|
73
|
+
(SubchannelCall*)(((char*)(call_stack)) - \
|
74
|
+
GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(SubchannelCall)))
|
87
75
|
|
88
76
|
namespace grpc_core {
|
89
77
|
|
90
|
-
|
78
|
+
TraceFlag grpc_trace_subchannel(false, "subchannel");
|
79
|
+
DebugOnlyTraceFlag grpc_trace_subchannel_refcount(false, "subchannel_refcount");
|
91
80
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
grpc_connector* connector;
|
81
|
+
//
|
82
|
+
// ConnectedSubchannel
|
83
|
+
//
|
96
84
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
85
|
+
ConnectedSubchannel::ConnectedSubchannel(
|
86
|
+
grpc_channel_stack* channel_stack, const grpc_channel_args* args,
|
87
|
+
RefCountedPtr<channelz::SubchannelNode> channelz_subchannel,
|
88
|
+
intptr_t socket_uuid)
|
89
|
+
: ConnectedSubchannelInterface(&grpc_trace_subchannel_refcount),
|
90
|
+
channel_stack_(channel_stack),
|
91
|
+
args_(grpc_channel_args_copy(args)),
|
92
|
+
channelz_subchannel_(std::move(channelz_subchannel)),
|
93
|
+
socket_uuid_(socket_uuid) {}
|
103
94
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
grpc_channel_args* args;
|
95
|
+
ConnectedSubchannel::~ConnectedSubchannel() {
|
96
|
+
grpc_channel_args_destroy(args_);
|
97
|
+
GRPC_CHANNEL_STACK_UNREF(channel_stack_, "connected_subchannel_dtor");
|
98
|
+
}
|
109
99
|
|
110
|
-
|
100
|
+
void ConnectedSubchannel::NotifyOnStateChange(
|
101
|
+
grpc_pollset_set* interested_parties, grpc_connectivity_state* state,
|
102
|
+
grpc_closure* closure) {
|
103
|
+
grpc_transport_op* op = grpc_make_transport_op(nullptr);
|
104
|
+
grpc_channel_element* elem;
|
105
|
+
op->connectivity_state = state;
|
106
|
+
op->on_connectivity_state_change = closure;
|
107
|
+
op->bind_pollset_set = interested_parties;
|
108
|
+
elem = grpc_channel_stack_element(channel_stack_, 0);
|
109
|
+
elem->filter->start_transport_op(elem, op);
|
110
|
+
}
|
111
111
|
|
112
|
-
|
113
|
-
|
112
|
+
void ConnectedSubchannel::Ping(grpc_closure* on_initiate,
|
113
|
+
grpc_closure* on_ack) {
|
114
|
+
grpc_transport_op* op = grpc_make_transport_op(nullptr);
|
115
|
+
grpc_channel_element* elem;
|
116
|
+
op->send_ping.on_initiate = on_initiate;
|
117
|
+
op->send_ping.on_ack = on_ack;
|
118
|
+
elem = grpc_channel_stack_element(channel_stack_, 0);
|
119
|
+
elem->filter->start_transport_op(elem, op);
|
120
|
+
}
|
114
121
|
|
115
|
-
|
116
|
-
|
122
|
+
RefCountedPtr<SubchannelCall> ConnectedSubchannel::CreateCall(
|
123
|
+
const CallArgs& args, grpc_error** error) {
|
124
|
+
const size_t allocation_size =
|
125
|
+
GetInitialCallSizeEstimate(args.parent_data_size);
|
126
|
+
RefCountedPtr<SubchannelCall> call(
|
127
|
+
new (args.arena->Alloc(allocation_size))
|
128
|
+
SubchannelCall(Ref(DEBUG_LOCATION, "subchannel_call"), args));
|
129
|
+
grpc_call_stack* callstk = SUBCHANNEL_CALL_TO_CALL_STACK(call.get());
|
130
|
+
const grpc_call_element_args call_args = {
|
131
|
+
callstk, /* call_stack */
|
132
|
+
nullptr, /* server_transport_data */
|
133
|
+
args.context, /* context */
|
134
|
+
args.path, /* path */
|
135
|
+
args.start_time, /* start_time */
|
136
|
+
args.deadline, /* deadline */
|
137
|
+
args.arena, /* arena */
|
138
|
+
args.call_combiner /* call_combiner */
|
139
|
+
};
|
140
|
+
*error = grpc_call_stack_init(channel_stack_, 1, SubchannelCall::Destroy,
|
141
|
+
call.get(), &call_args);
|
142
|
+
if (GPR_UNLIKELY(*error != GRPC_ERROR_NONE)) {
|
143
|
+
const char* error_string = grpc_error_string(*error);
|
144
|
+
gpr_log(GPR_ERROR, "error: %s", error_string);
|
145
|
+
return call;
|
146
|
+
}
|
147
|
+
grpc_call_stack_set_pollset_or_pollset_set(callstk, args.pollent);
|
148
|
+
if (channelz_subchannel_ != nullptr) {
|
149
|
+
channelz_subchannel_->RecordCallStarted();
|
150
|
+
}
|
151
|
+
return call;
|
152
|
+
}
|
117
153
|
|
118
|
-
|
119
|
-
|
154
|
+
size_t ConnectedSubchannel::GetInitialCallSizeEstimate(
|
155
|
+
size_t parent_data_size) const {
|
156
|
+
size_t allocation_size =
|
157
|
+
GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(SubchannelCall));
|
158
|
+
if (parent_data_size > 0) {
|
159
|
+
allocation_size +=
|
160
|
+
GPR_ROUND_UP_TO_ALIGNMENT_SIZE(channel_stack_->call_stack_size) +
|
161
|
+
parent_data_size;
|
162
|
+
} else {
|
163
|
+
allocation_size += channel_stack_->call_stack_size;
|
164
|
+
}
|
165
|
+
return allocation_size;
|
166
|
+
}
|
120
167
|
|
121
|
-
|
122
|
-
|
123
|
-
|
168
|
+
//
|
169
|
+
// SubchannelCall
|
170
|
+
//
|
124
171
|
|
125
|
-
|
172
|
+
void SubchannelCall::StartTransportStreamOpBatch(
|
173
|
+
grpc_transport_stream_op_batch* batch) {
|
174
|
+
GPR_TIMER_SCOPE("subchannel_call_process_op", 0);
|
175
|
+
MaybeInterceptRecvTrailingMetadata(batch);
|
176
|
+
grpc_call_stack* call_stack = SUBCHANNEL_CALL_TO_CALL_STACK(this);
|
177
|
+
grpc_call_element* top_elem = grpc_call_stack_element(call_stack, 0);
|
178
|
+
GRPC_CALL_LOG_OP(GPR_INFO, top_elem, batch);
|
179
|
+
top_elem->filter->start_transport_stream_op_batch(top_elem, batch);
|
180
|
+
}
|
126
181
|
|
127
|
-
|
128
|
-
|
182
|
+
void* SubchannelCall::GetParentData() {
|
183
|
+
grpc_channel_stack* chanstk = connected_subchannel_->channel_stack();
|
184
|
+
return (char*)this + GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(SubchannelCall)) +
|
185
|
+
GPR_ROUND_UP_TO_ALIGNMENT_SIZE(chanstk->call_stack_size);
|
186
|
+
}
|
129
187
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
connected_subchannel_watcher;
|
188
|
+
grpc_call_stack* SubchannelCall::GetCallStack() {
|
189
|
+
return SUBCHANNEL_CALL_TO_CALL_STACK(this);
|
190
|
+
}
|
134
191
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
192
|
+
void SubchannelCall::SetAfterCallStackDestroy(grpc_closure* closure) {
|
193
|
+
GPR_ASSERT(after_call_stack_destroy_ == nullptr);
|
194
|
+
GPR_ASSERT(closure != nullptr);
|
195
|
+
after_call_stack_destroy_ = closure;
|
196
|
+
}
|
139
197
|
|
140
|
-
|
141
|
-
|
142
|
-
|
198
|
+
RefCountedPtr<SubchannelCall> SubchannelCall::Ref() {
|
199
|
+
IncrementRefCount();
|
200
|
+
return RefCountedPtr<SubchannelCall>(this);
|
201
|
+
}
|
143
202
|
|
144
|
-
|
203
|
+
RefCountedPtr<SubchannelCall> SubchannelCall::Ref(
|
204
|
+
const grpc_core::DebugLocation& location, const char* reason) {
|
205
|
+
IncrementRefCount(location, reason);
|
206
|
+
return RefCountedPtr<SubchannelCall>(this);
|
207
|
+
}
|
145
208
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
grpc_millis min_connect_timeout_ms;
|
209
|
+
void SubchannelCall::Unref() {
|
210
|
+
GRPC_CALL_STACK_UNREF(SUBCHANNEL_CALL_TO_CALL_STACK(this), "");
|
211
|
+
}
|
150
212
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
bool backoff_begun;
|
155
|
-
// reset_backoff() was called while alarm was pending
|
156
|
-
bool retry_immediately;
|
157
|
-
/** our alarm */
|
158
|
-
grpc_timer alarm;
|
213
|
+
void SubchannelCall::Unref(const DebugLocation& location, const char* reason) {
|
214
|
+
GRPC_CALL_STACK_UNREF(SUBCHANNEL_CALL_TO_CALL_STACK(this), reason);
|
215
|
+
}
|
159
216
|
|
160
|
-
|
161
|
-
|
162
|
-
|
217
|
+
void SubchannelCall::Destroy(void* arg, grpc_error* error) {
|
218
|
+
GPR_TIMER_SCOPE("subchannel_call_destroy", 0);
|
219
|
+
SubchannelCall* self = static_cast<SubchannelCall*>(arg);
|
220
|
+
// Keep some members before destroying the subchannel call.
|
221
|
+
grpc_closure* after_call_stack_destroy = self->after_call_stack_destroy_;
|
222
|
+
RefCountedPtr<ConnectedSubchannel> connected_subchannel =
|
223
|
+
std::move(self->connected_subchannel_);
|
224
|
+
// Destroy the subchannel call.
|
225
|
+
self->~SubchannelCall();
|
226
|
+
// Destroy the call stack. This should be after destroying the subchannel
|
227
|
+
// call, because call->after_call_stack_destroy(), if not null, will free the
|
228
|
+
// call arena.
|
229
|
+
grpc_call_stack_destroy(SUBCHANNEL_CALL_TO_CALL_STACK(self), nullptr,
|
230
|
+
after_call_stack_destroy);
|
231
|
+
// Automatically reset connected_subchannel. This should be after destroying
|
232
|
+
// the call stack, because destroying call stack needs access to the channel
|
233
|
+
// stack.
|
234
|
+
}
|
163
235
|
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
236
|
+
void SubchannelCall::MaybeInterceptRecvTrailingMetadata(
|
237
|
+
grpc_transport_stream_op_batch* batch) {
|
238
|
+
// only intercept payloads with recv trailing.
|
239
|
+
if (!batch->recv_trailing_metadata) {
|
240
|
+
return;
|
241
|
+
}
|
242
|
+
// only add interceptor is channelz is enabled.
|
243
|
+
if (connected_subchannel_->channelz_subchannel() == nullptr) {
|
244
|
+
return;
|
245
|
+
}
|
246
|
+
GRPC_CLOSURE_INIT(&recv_trailing_metadata_ready_, RecvTrailingMetadataReady,
|
247
|
+
this, grpc_schedule_on_exec_ctx);
|
248
|
+
// save some state needed for the interception callback.
|
249
|
+
GPR_ASSERT(recv_trailing_metadata_ == nullptr);
|
250
|
+
recv_trailing_metadata_ =
|
251
|
+
batch->payload->recv_trailing_metadata.recv_trailing_metadata;
|
252
|
+
original_recv_trailing_metadata_ =
|
253
|
+
batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready;
|
254
|
+
batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready =
|
255
|
+
&recv_trailing_metadata_ready_;
|
256
|
+
}
|
177
257
|
|
178
|
-
|
258
|
+
namespace {
|
179
259
|
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
return "Subchannel state change to SHUTDOWN";
|
260
|
+
// Sets *status based on the rest of the parameters.
|
261
|
+
void GetCallStatus(grpc_status_code* status, grpc_millis deadline,
|
262
|
+
grpc_metadata_batch* md_batch, grpc_error* error) {
|
263
|
+
if (error != GRPC_ERROR_NONE) {
|
264
|
+
grpc_error_get_status(error, deadline, status, nullptr, nullptr, nullptr);
|
265
|
+
} else {
|
266
|
+
if (md_batch->idx.named.grpc_status != nullptr) {
|
267
|
+
*status = grpc_get_status_code_from_metadata(
|
268
|
+
md_batch->idx.named.grpc_status->md);
|
269
|
+
} else {
|
270
|
+
*status = GRPC_STATUS_UNKNOWN;
|
271
|
+
}
|
193
272
|
}
|
194
|
-
|
273
|
+
GRPC_ERROR_UNREF(error);
|
195
274
|
}
|
196
275
|
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
276
|
+
} // namespace
|
277
|
+
|
278
|
+
void SubchannelCall::RecvTrailingMetadataReady(void* arg, grpc_error* error) {
|
279
|
+
SubchannelCall* call = static_cast<SubchannelCall*>(arg);
|
280
|
+
GPR_ASSERT(call->recv_trailing_metadata_ != nullptr);
|
281
|
+
grpc_status_code status = GRPC_STATUS_OK;
|
282
|
+
GetCallStatus(&status, call->deadline_, call->recv_trailing_metadata_,
|
283
|
+
GRPC_ERROR_REF(error));
|
284
|
+
channelz::SubchannelNode* channelz_subchannel =
|
285
|
+
call->connected_subchannel_->channelz_subchannel();
|
286
|
+
GPR_ASSERT(channelz_subchannel != nullptr);
|
287
|
+
if (status == GRPC_STATUS_OK) {
|
288
|
+
channelz_subchannel->RecordCallSucceeded();
|
289
|
+
} else {
|
290
|
+
channelz_subchannel->RecordCallFailed();
|
205
291
|
}
|
206
|
-
|
292
|
+
GRPC_CLOSURE_RUN(call->original_recv_trailing_metadata_,
|
293
|
+
GRPC_ERROR_REF(error));
|
207
294
|
}
|
208
295
|
|
209
|
-
|
296
|
+
void SubchannelCall::IncrementRefCount() {
|
297
|
+
GRPC_CALL_STACK_REF(SUBCHANNEL_CALL_TO_CALL_STACK(this), "");
|
298
|
+
}
|
299
|
+
|
300
|
+
void SubchannelCall::IncrementRefCount(const grpc_core::DebugLocation& location,
|
301
|
+
const char* reason) {
|
302
|
+
GRPC_CALL_STACK_REF(SUBCHANNEL_CALL_TO_CALL_STACK(this), reason);
|
303
|
+
}
|
210
304
|
|
211
|
-
|
212
|
-
|
305
|
+
//
|
306
|
+
// Subchannel::ConnectedSubchannelStateWatcher
|
307
|
+
//
|
308
|
+
|
309
|
+
class Subchannel::ConnectedSubchannelStateWatcher {
|
213
310
|
public:
|
214
311
|
// Must be instantiated while holding c->mu.
|
215
|
-
explicit ConnectedSubchannelStateWatcher(
|
216
|
-
: subchannel_(c) {
|
312
|
+
explicit ConnectedSubchannelStateWatcher(Subchannel* c) : subchannel_(c) {
|
217
313
|
// Steal subchannel ref for connecting.
|
218
314
|
GRPC_SUBCHANNEL_WEAK_REF(subchannel_, "state_watcher");
|
219
315
|
GRPC_SUBCHANNEL_WEAK_UNREF(subchannel_, "connecting");
|
220
316
|
// Start watching for connectivity state changes.
|
221
|
-
// Callback uses initial ref to this.
|
222
317
|
GRPC_CLOSURE_INIT(&on_connectivity_changed_, OnConnectivityChanged, this,
|
223
318
|
grpc_schedule_on_exec_ctx);
|
224
|
-
c->
|
225
|
-
|
226
|
-
|
227
|
-
// Start health check if needed.
|
228
|
-
grpc_connectivity_state health_state = GRPC_CHANNEL_READY;
|
229
|
-
if (c->health_check_service_name != nullptr) {
|
230
|
-
health_check_client_ = grpc_core::MakeOrphanable<HealthCheckClient>(
|
231
|
-
c->health_check_service_name.get(), c->connected_subchannel,
|
232
|
-
c->pollset_set, c->channelz_subchannel);
|
233
|
-
GRPC_CLOSURE_INIT(&on_health_changed_, OnHealthChanged, this,
|
234
|
-
grpc_schedule_on_exec_ctx);
|
235
|
-
Ref().release(); // Ref for health callback tracked manually.
|
236
|
-
health_check_client_->NotifyOnHealthChange(&health_state_,
|
237
|
-
&on_health_changed_);
|
238
|
-
health_state = GRPC_CHANNEL_CONNECTING;
|
239
|
-
}
|
240
|
-
// Report initial state.
|
241
|
-
set_subchannel_connectivity_state_locked(
|
242
|
-
c, GRPC_CHANNEL_READY, GRPC_ERROR_NONE, "subchannel_connected");
|
243
|
-
grpc_connectivity_state_set(&c->state_and_health_tracker, health_state,
|
244
|
-
GRPC_ERROR_NONE, "subchannel_connected");
|
319
|
+
c->connected_subchannel_->NotifyOnStateChange(c->pollset_set_,
|
320
|
+
&pending_connectivity_state_,
|
321
|
+
&on_connectivity_changed_);
|
245
322
|
}
|
246
323
|
|
247
324
|
~ConnectedSubchannelStateWatcher() {
|
248
325
|
GRPC_SUBCHANNEL_WEAK_UNREF(subchannel_, "state_watcher");
|
249
326
|
}
|
250
327
|
|
251
|
-
void Orphan() override { health_check_client_.reset(); }
|
252
|
-
|
253
328
|
private:
|
254
329
|
static void OnConnectivityChanged(void* arg, grpc_error* error) {
|
255
330
|
auto* self = static_cast<ConnectedSubchannelStateWatcher*>(arg);
|
256
|
-
|
331
|
+
Subchannel* c = self->subchannel_;
|
257
332
|
{
|
258
|
-
MutexLock lock(&c->
|
333
|
+
MutexLock lock(&c->mu_);
|
259
334
|
switch (self->pending_connectivity_state_) {
|
260
335
|
case GRPC_CHANNEL_TRANSIENT_FAILURE:
|
261
336
|
case GRPC_CHANNEL_SHUTDOWN: {
|
262
|
-
if (!c->
|
263
|
-
if (
|
337
|
+
if (!c->disconnected_ && c->connected_subchannel_ != nullptr) {
|
338
|
+
if (grpc_trace_subchannel.enabled()) {
|
264
339
|
gpr_log(GPR_INFO,
|
265
340
|
"Connected subchannel %p of subchannel %p has gone into "
|
266
341
|
"%s. Attempting to reconnect.",
|
267
|
-
c->
|
342
|
+
c->connected_subchannel_.get(), c,
|
268
343
|
grpc_connectivity_state_name(
|
269
344
|
self->pending_connectivity_state_));
|
270
345
|
}
|
271
|
-
c->
|
272
|
-
c->
|
273
|
-
|
274
|
-
|
275
|
-
c, GRPC_CHANNEL_TRANSIENT_FAILURE, GRPC_ERROR_REF(error),
|
276
|
-
"reflect_child");
|
277
|
-
grpc_connectivity_state_set(&c->state_and_health_tracker,
|
278
|
-
GRPC_CHANNEL_TRANSIENT_FAILURE,
|
279
|
-
GRPC_ERROR_REF(error), "reflect_child");
|
280
|
-
c->backoff_begun = false;
|
281
|
-
c->backoff->Reset();
|
282
|
-
maybe_start_connecting_locked(c);
|
283
|
-
} else {
|
284
|
-
self->last_connectivity_state_ = GRPC_CHANNEL_SHUTDOWN;
|
346
|
+
c->connected_subchannel_.reset();
|
347
|
+
c->SetConnectivityStateLocked(GRPC_CHANNEL_TRANSIENT_FAILURE);
|
348
|
+
c->backoff_begun_ = false;
|
349
|
+
c->backoff_.Reset();
|
285
350
|
}
|
286
|
-
self->health_check_client_.reset();
|
287
351
|
break;
|
288
352
|
}
|
289
353
|
default: {
|
@@ -291,197 +355,239 @@ class ConnectedSubchannelStateWatcher
|
|
291
355
|
// a callback for READY, because that was the state we started
|
292
356
|
// this watch from. And a connected subchannel should never go
|
293
357
|
// from READY to CONNECTING or IDLE.
|
294
|
-
|
295
|
-
|
296
|
-
c, self->pending_connectivity_state_, GRPC_ERROR_REF(error),
|
297
|
-
"reflect_child");
|
298
|
-
if (self->pending_connectivity_state_ != GRPC_CHANNEL_READY) {
|
299
|
-
grpc_connectivity_state_set(&c->state_and_health_tracker,
|
300
|
-
self->pending_connectivity_state_,
|
301
|
-
GRPC_ERROR_REF(error), "reflect_child");
|
302
|
-
}
|
303
|
-
c->connected_subchannel->NotifyOnStateChange(
|
358
|
+
c->SetConnectivityStateLocked(self->pending_connectivity_state_);
|
359
|
+
c->connected_subchannel_->NotifyOnStateChange(
|
304
360
|
nullptr, &self->pending_connectivity_state_,
|
305
361
|
&self->on_connectivity_changed_);
|
306
|
-
|
362
|
+
return; // So we don't delete ourself below.
|
307
363
|
}
|
308
364
|
}
|
309
365
|
}
|
310
|
-
// Don't
|
366
|
+
// Don't delete until we've released the lock, because this might
|
311
367
|
// cause the subchannel (which contains the lock) to be destroyed.
|
312
|
-
|
313
|
-
}
|
314
|
-
|
315
|
-
static void OnHealthChanged(void* arg, grpc_error* error) {
|
316
|
-
auto* self = static_cast<ConnectedSubchannelStateWatcher*>(arg);
|
317
|
-
if (self->health_state_ == GRPC_CHANNEL_SHUTDOWN) {
|
318
|
-
self->Unref();
|
319
|
-
return;
|
320
|
-
}
|
321
|
-
grpc_subchannel* c = self->subchannel_;
|
322
|
-
MutexLock lock(&c->mu);
|
323
|
-
if (self->last_connectivity_state_ == GRPC_CHANNEL_READY) {
|
324
|
-
grpc_connectivity_state_set(&c->state_and_health_tracker,
|
325
|
-
self->health_state_, GRPC_ERROR_REF(error),
|
326
|
-
"health_changed");
|
327
|
-
}
|
328
|
-
self->health_check_client_->NotifyOnHealthChange(&self->health_state_,
|
329
|
-
&self->on_health_changed_);
|
368
|
+
Delete(self);
|
330
369
|
}
|
331
370
|
|
332
|
-
|
371
|
+
Subchannel* subchannel_;
|
333
372
|
grpc_closure on_connectivity_changed_;
|
334
373
|
grpc_connectivity_state pending_connectivity_state_ = GRPC_CHANNEL_READY;
|
335
|
-
grpc_connectivity_state last_connectivity_state_ = GRPC_CHANNEL_READY;
|
336
|
-
grpc_core::OrphanablePtr<grpc_core::HealthCheckClient> health_check_client_;
|
337
|
-
grpc_closure on_health_changed_;
|
338
|
-
grpc_connectivity_state health_state_ = GRPC_CHANNEL_CONNECTING;
|
339
374
|
};
|
340
375
|
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
(grpc_call_stack*)((char*)(call) + GPR_ROUND_UP_TO_ALIGNMENT_SIZE( \
|
345
|
-
sizeof(grpc_subchannel_call)))
|
346
|
-
#define CALLSTACK_TO_SUBCHANNEL_CALL(callstack) \
|
347
|
-
(grpc_subchannel_call*)(((char*)(call_stack)) - \
|
348
|
-
GPR_ROUND_UP_TO_ALIGNMENT_SIZE( \
|
349
|
-
sizeof(grpc_subchannel_call)))
|
376
|
+
//
|
377
|
+
// Subchannel::ConnectivityStateWatcherList
|
378
|
+
//
|
350
379
|
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
#define REF_MUTATE_EXTRA_ARGS \
|
356
|
-
GRPC_SUBCHANNEL_REF_EXTRA_ARGS, const char* purpose
|
357
|
-
#define REF_MUTATE_PURPOSE(x) , file, line, reason, x
|
358
|
-
#else
|
359
|
-
#define REF_REASON ""
|
360
|
-
#define REF_MUTATE_EXTRA_ARGS
|
361
|
-
#define REF_MUTATE_PURPOSE(x)
|
362
|
-
#endif
|
380
|
+
void Subchannel::ConnectivityStateWatcherList::AddWatcherLocked(
|
381
|
+
UniquePtr<ConnectivityStateWatcher> watcher) {
|
382
|
+
watchers_.insert(MakePair(watcher.get(), std::move(watcher)));
|
383
|
+
}
|
363
384
|
|
364
|
-
|
365
|
-
|
366
|
-
|
385
|
+
void Subchannel::ConnectivityStateWatcherList::RemoveWatcherLocked(
|
386
|
+
ConnectivityStateWatcher* watcher) {
|
387
|
+
watchers_.erase(watcher);
|
388
|
+
}
|
367
389
|
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
390
|
+
void Subchannel::ConnectivityStateWatcherList::NotifyLocked(
|
391
|
+
Subchannel* subchannel, grpc_connectivity_state state) {
|
392
|
+
for (const auto& p : watchers_) {
|
393
|
+
RefCountedPtr<ConnectedSubchannel> connected_subchannel;
|
394
|
+
if (state == GRPC_CHANNEL_READY) {
|
395
|
+
connected_subchannel = subchannel->connected_subchannel_;
|
396
|
+
}
|
397
|
+
// TODO(roth): In principle, it seems wrong to send this notification
|
398
|
+
// to the watcher while holding the subchannel's mutex, since it could
|
399
|
+
// lead to a deadlock if the watcher calls back into the subchannel
|
400
|
+
// before returning back to us. In practice, this doesn't happen,
|
401
|
+
// because the LB policy code that watches subchannels always bounces
|
402
|
+
// the notification into the client_channel control-plane combiner
|
403
|
+
// before processing it. But if we ever have any other callers here,
|
404
|
+
// we will probably need to change this.
|
405
|
+
p.second->OnConnectivityStateChange(state, std::move(connected_subchannel));
|
406
|
+
}
|
372
407
|
}
|
373
408
|
|
374
|
-
|
375
|
-
|
376
|
-
|
409
|
+
//
|
410
|
+
// Subchannel::HealthWatcherMap::HealthWatcher
|
411
|
+
//
|
377
412
|
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
413
|
+
// State needed for tracking the connectivity state with a particular
|
414
|
+
// health check service name.
|
415
|
+
class Subchannel::HealthWatcherMap::HealthWatcher
|
416
|
+
: public InternallyRefCounted<HealthWatcher> {
|
417
|
+
public:
|
418
|
+
HealthWatcher(Subchannel* c, UniquePtr<char> health_check_service_name,
|
419
|
+
grpc_connectivity_state subchannel_state)
|
420
|
+
: subchannel_(c),
|
421
|
+
health_check_service_name_(std::move(health_check_service_name)),
|
422
|
+
state_(subchannel_state == GRPC_CHANNEL_READY ? GRPC_CHANNEL_CONNECTING
|
423
|
+
: subchannel_state) {
|
424
|
+
GRPC_SUBCHANNEL_WEAK_REF(subchannel_, "health_watcher");
|
425
|
+
GRPC_CLOSURE_INIT(&on_health_changed_, OnHealthChanged, this,
|
426
|
+
grpc_schedule_on_exec_ctx);
|
427
|
+
// If the subchannel is already connected, start health checking.
|
428
|
+
if (subchannel_state == GRPC_CHANNEL_READY) StartHealthCheckingLocked();
|
386
429
|
}
|
387
|
-
gpr_free((void*)c->filters);
|
388
|
-
c->health_check_service_name.reset();
|
389
|
-
grpc_channel_args_destroy(c->args);
|
390
|
-
grpc_connectivity_state_destroy(&c->state_tracker);
|
391
|
-
grpc_connectivity_state_destroy(&c->state_and_health_tracker);
|
392
|
-
grpc_connector_unref(c->connector);
|
393
|
-
grpc_pollset_set_destroy(c->pollset_set);
|
394
|
-
grpc_subchannel_key_destroy(c->key);
|
395
|
-
gpr_mu_destroy(&c->mu);
|
396
|
-
gpr_free(c);
|
397
|
-
}
|
398
430
|
|
399
|
-
|
400
|
-
|
401
|
-
gpr_atm old_val = barrier ? gpr_atm_full_fetch_add(&c->ref_pair, delta)
|
402
|
-
: gpr_atm_no_barrier_fetch_add(&c->ref_pair, delta);
|
403
|
-
#ifndef NDEBUG
|
404
|
-
if (grpc_trace_stream_refcount.enabled()) {
|
405
|
-
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
|
406
|
-
"SUBCHANNEL: %p %12s 0x%" PRIxPTR " -> 0x%" PRIxPTR " [%s]", c,
|
407
|
-
purpose, old_val, old_val + delta, reason);
|
431
|
+
~HealthWatcher() {
|
432
|
+
GRPC_SUBCHANNEL_WEAK_UNREF(subchannel_, "health_watcher");
|
408
433
|
}
|
409
|
-
#endif
|
410
|
-
return old_val;
|
411
|
-
}
|
412
434
|
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
old_refs = ref_mutate(c, (1 << INTERNAL_REF_BITS),
|
417
|
-
0 REF_MUTATE_PURPOSE("STRONG_REF"));
|
418
|
-
GPR_ASSERT((old_refs & STRONG_REF_MASK) != 0);
|
419
|
-
return c;
|
420
|
-
}
|
435
|
+
const char* health_check_service_name() const {
|
436
|
+
return health_check_service_name_.get();
|
437
|
+
}
|
421
438
|
|
422
|
-
|
423
|
-
grpc_subchannel* c GRPC_SUBCHANNEL_REF_EXTRA_ARGS) {
|
424
|
-
gpr_atm old_refs;
|
425
|
-
old_refs = ref_mutate(c, 1, 0 REF_MUTATE_PURPOSE("WEAK_REF"));
|
426
|
-
GPR_ASSERT(old_refs != 0);
|
427
|
-
return c;
|
428
|
-
}
|
439
|
+
grpc_connectivity_state state() const { return state_; }
|
429
440
|
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
441
|
+
void AddWatcherLocked(grpc_connectivity_state initial_state,
|
442
|
+
UniquePtr<ConnectivityStateWatcher> watcher) {
|
443
|
+
if (state_ != initial_state) {
|
444
|
+
RefCountedPtr<ConnectedSubchannel> connected_subchannel;
|
445
|
+
if (state_ == GRPC_CHANNEL_READY) {
|
446
|
+
connected_subchannel = subchannel_->connected_subchannel_;
|
447
|
+
}
|
448
|
+
watcher->OnConnectivityStateChange(state_,
|
449
|
+
std::move(connected_subchannel));
|
450
|
+
}
|
451
|
+
watcher_list_.AddWatcherLocked(std::move(watcher));
|
452
|
+
}
|
453
|
+
|
454
|
+
void RemoveWatcherLocked(ConnectivityStateWatcher* watcher) {
|
455
|
+
watcher_list_.RemoveWatcherLocked(watcher);
|
456
|
+
}
|
457
|
+
|
458
|
+
bool HasWatchers() const { return !watcher_list_.empty(); }
|
459
|
+
|
460
|
+
void NotifyLocked(grpc_connectivity_state state) {
|
461
|
+
if (state == GRPC_CHANNEL_READY) {
|
462
|
+
// If we had not already notified for CONNECTING state, do so now.
|
463
|
+
// (We may have missed this earlier, because if the transition
|
464
|
+
// from IDLE to CONNECTING to READY was too quick, the connected
|
465
|
+
// subchannel may not have sent us a notification for CONNECTING.)
|
466
|
+
if (state_ != GRPC_CHANNEL_CONNECTING) {
|
467
|
+
state_ = GRPC_CHANNEL_CONNECTING;
|
468
|
+
watcher_list_.NotifyLocked(subchannel_, state_);
|
439
469
|
}
|
470
|
+
// If we've become connected, start health checking.
|
471
|
+
StartHealthCheckingLocked();
|
440
472
|
} else {
|
441
|
-
|
473
|
+
state_ = state;
|
474
|
+
watcher_list_.NotifyLocked(subchannel_, state_);
|
475
|
+
// We're not connected, so stop health checking.
|
476
|
+
health_check_client_.reset();
|
477
|
+
}
|
478
|
+
}
|
479
|
+
|
480
|
+
void Orphan() override {
|
481
|
+
watcher_list_.Clear();
|
482
|
+
health_check_client_.reset();
|
483
|
+
Unref();
|
484
|
+
}
|
485
|
+
|
486
|
+
private:
|
487
|
+
void StartHealthCheckingLocked() {
|
488
|
+
GPR_ASSERT(health_check_client_ == nullptr);
|
489
|
+
health_check_client_ = MakeOrphanable<HealthCheckClient>(
|
490
|
+
health_check_service_name_.get(), subchannel_->connected_subchannel_,
|
491
|
+
subchannel_->pollset_set_, subchannel_->channelz_node_);
|
492
|
+
Ref().release(); // Ref for health callback tracked manually.
|
493
|
+
health_check_client_->NotifyOnHealthChange(&state_, &on_health_changed_);
|
494
|
+
}
|
495
|
+
|
496
|
+
static void OnHealthChanged(void* arg, grpc_error* error) {
|
497
|
+
auto* self = static_cast<HealthWatcher*>(arg);
|
498
|
+
Subchannel* c = self->subchannel_;
|
499
|
+
{
|
500
|
+
MutexLock lock(&c->mu_);
|
501
|
+
if (self->state_ != GRPC_CHANNEL_SHUTDOWN &&
|
502
|
+
self->health_check_client_ != nullptr) {
|
503
|
+
self->watcher_list_.NotifyLocked(c, self->state_);
|
504
|
+
// Renew watch.
|
505
|
+
self->health_check_client_->NotifyOnHealthChange(
|
506
|
+
&self->state_, &self->on_health_changed_);
|
507
|
+
return; // So we don't unref below.
|
508
|
+
}
|
442
509
|
}
|
510
|
+
// Don't unref until we've released the lock, because this might
|
511
|
+
// cause the subchannel (which contains the lock) to be destroyed.
|
512
|
+
self->Unref();
|
443
513
|
}
|
514
|
+
|
515
|
+
Subchannel* subchannel_;
|
516
|
+
UniquePtr<char> health_check_service_name_;
|
517
|
+
OrphanablePtr<HealthCheckClient> health_check_client_;
|
518
|
+
grpc_closure on_health_changed_;
|
519
|
+
grpc_connectivity_state state_;
|
520
|
+
ConnectivityStateWatcherList watcher_list_;
|
521
|
+
};
|
522
|
+
|
523
|
+
//
|
524
|
+
// Subchannel::HealthWatcherMap
|
525
|
+
//
|
526
|
+
|
527
|
+
void Subchannel::HealthWatcherMap::AddWatcherLocked(
|
528
|
+
Subchannel* subchannel, grpc_connectivity_state initial_state,
|
529
|
+
UniquePtr<char> health_check_service_name,
|
530
|
+
UniquePtr<ConnectivityStateWatcher> watcher) {
|
531
|
+
// If the health check service name is not already present in the map,
|
532
|
+
// add it.
|
533
|
+
auto it = map_.find(health_check_service_name.get());
|
534
|
+
HealthWatcher* health_watcher;
|
535
|
+
if (it == map_.end()) {
|
536
|
+
const char* key = health_check_service_name.get();
|
537
|
+
auto w = MakeOrphanable<HealthWatcher>(
|
538
|
+
subchannel, std::move(health_check_service_name), subchannel->state_);
|
539
|
+
health_watcher = w.get();
|
540
|
+
map_[key] = std::move(w);
|
541
|
+
} else {
|
542
|
+
health_watcher = it->second.get();
|
543
|
+
}
|
544
|
+
// Add the watcher to the entry.
|
545
|
+
health_watcher->AddWatcherLocked(initial_state, std::move(watcher));
|
444
546
|
}
|
445
547
|
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
GPR_ASSERT(
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
c->connected_subchannel_watcher.reset();
|
455
|
-
gpr_mu_unlock(&c->mu);
|
548
|
+
void Subchannel::HealthWatcherMap::RemoveWatcherLocked(
|
549
|
+
const char* health_check_service_name, ConnectivityStateWatcher* watcher) {
|
550
|
+
auto it = map_.find(health_check_service_name);
|
551
|
+
GPR_ASSERT(it != map_.end());
|
552
|
+
it->second->RemoveWatcherLocked(watcher);
|
553
|
+
// If we just removed the last watcher for this service name, remove
|
554
|
+
// the map entry.
|
555
|
+
if (!it->second->HasWatchers()) map_.erase(it);
|
456
556
|
}
|
457
557
|
|
458
|
-
void
|
459
|
-
|
460
|
-
|
461
|
-
old_refs = ref_mutate(
|
462
|
-
c, static_cast<gpr_atm>(1) - static_cast<gpr_atm>(1 << INTERNAL_REF_BITS),
|
463
|
-
1 REF_MUTATE_PURPOSE("STRONG_UNREF"));
|
464
|
-
if ((old_refs & STRONG_REF_MASK) == (1 << INTERNAL_REF_BITS)) {
|
465
|
-
disconnect(c);
|
558
|
+
void Subchannel::HealthWatcherMap::NotifyLocked(grpc_connectivity_state state) {
|
559
|
+
for (const auto& p : map_) {
|
560
|
+
p.second->NotifyLocked(state);
|
466
561
|
}
|
467
|
-
GRPC_SUBCHANNEL_WEAK_UNREF(c, "strong-unref");
|
468
562
|
}
|
469
563
|
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
564
|
+
grpc_connectivity_state
|
565
|
+
Subchannel::HealthWatcherMap::CheckConnectivityStateLocked(
|
566
|
+
Subchannel* subchannel, const char* health_check_service_name) {
|
567
|
+
auto it = map_.find(health_check_service_name);
|
568
|
+
if (it == map_.end()) {
|
569
|
+
// If the health check service name is not found in the map, we're
|
570
|
+
// not currently doing a health check for that service name. If the
|
571
|
+
// subchannel's state without health checking is READY, report
|
572
|
+
// CONNECTING, since that's what we'd be in as soon as we do start a
|
573
|
+
// watch. Otherwise, report the channel's state without health checking.
|
574
|
+
return subchannel->state_ == GRPC_CHANNEL_READY ? GRPC_CHANNEL_CONNECTING
|
575
|
+
: subchannel->state_;
|
479
576
|
}
|
577
|
+
HealthWatcher* health_watcher = it->second.get();
|
578
|
+
return health_watcher->state();
|
480
579
|
}
|
481
580
|
|
482
|
-
|
483
|
-
|
484
|
-
|
581
|
+
void Subchannel::HealthWatcherMap::ShutdownLocked() { map_.clear(); }
|
582
|
+
|
583
|
+
//
|
584
|
+
// Subchannel
|
585
|
+
//
|
586
|
+
|
587
|
+
namespace {
|
588
|
+
|
589
|
+
BackOff::Options ParseArgsForBackoffValues(
|
590
|
+
const grpc_channel_args* args, grpc_millis* min_connect_timeout_ms) {
|
485
591
|
grpc_millis initial_backoff_ms =
|
486
592
|
GRPC_SUBCHANNEL_INITIAL_CONNECT_BACKOFF_SECONDS * 1000;
|
487
593
|
*min_connect_timeout_ms =
|
@@ -518,7 +624,8 @@ static void parse_args_for_backoff_values(
|
|
518
624
|
}
|
519
625
|
}
|
520
626
|
}
|
521
|
-
|
627
|
+
return BackOff::Options()
|
628
|
+
.set_initial_backoff(initial_backoff_ms)
|
522
629
|
.set_multiplier(fixed_reconnect_backoff
|
523
630
|
? 1.0
|
524
631
|
: GRPC_SUBCHANNEL_RECONNECT_BACKOFF_MULTIPLIER)
|
@@ -527,630 +634,488 @@ static void parse_args_for_backoff_values(
|
|
527
634
|
.set_max_backoff(max_backoff_ms);
|
528
635
|
}
|
529
636
|
|
530
|
-
namespace grpc_core {
|
531
|
-
namespace {
|
532
|
-
|
533
|
-
struct HealthCheckParams {
|
534
|
-
UniquePtr<char> service_name;
|
535
|
-
|
536
|
-
static void Parse(const grpc_json* field, HealthCheckParams* params) {
|
537
|
-
if (strcmp(field->key, "healthCheckConfig") == 0) {
|
538
|
-
if (field->type != GRPC_JSON_OBJECT) return;
|
539
|
-
for (grpc_json* sub_field = field->child; sub_field != nullptr;
|
540
|
-
sub_field = sub_field->next) {
|
541
|
-
if (sub_field->key == nullptr) return;
|
542
|
-
if (strcmp(sub_field->key, "serviceName") == 0) {
|
543
|
-
if (params->service_name != nullptr) return; // Duplicate.
|
544
|
-
if (sub_field->type != GRPC_JSON_STRING) return;
|
545
|
-
params->service_name.reset(gpr_strdup(sub_field->value));
|
546
|
-
}
|
547
|
-
}
|
548
|
-
}
|
549
|
-
}
|
550
|
-
};
|
551
|
-
|
552
637
|
} // namespace
|
553
|
-
} // namespace grpc_core
|
554
|
-
|
555
|
-
grpc_subchannel* grpc_subchannel_create(grpc_connector* connector,
|
556
|
-
const grpc_subchannel_args* args) {
|
557
|
-
grpc_subchannel_key* key = grpc_subchannel_key_create(args);
|
558
|
-
grpc_subchannel* c = grpc_subchannel_index_find(key);
|
559
|
-
if (c) {
|
560
|
-
grpc_subchannel_key_destroy(key);
|
561
|
-
return c;
|
562
|
-
}
|
563
638
|
|
639
|
+
Subchannel::Subchannel(SubchannelKey* key, grpc_connector* connector,
|
640
|
+
const grpc_channel_args* args)
|
641
|
+
: key_(key),
|
642
|
+
connector_(connector),
|
643
|
+
backoff_(ParseArgsForBackoffValues(args, &min_connect_timeout_ms_)) {
|
564
644
|
GRPC_STATS_INC_CLIENT_SUBCHANNELS_CREATED();
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
c->connector = connector;
|
569
|
-
grpc_connector_ref(c->connector);
|
570
|
-
c->num_filters = args->filter_count;
|
571
|
-
if (c->num_filters > 0) {
|
572
|
-
c->filters = static_cast<const grpc_channel_filter**>(
|
573
|
-
gpr_malloc(sizeof(grpc_channel_filter*) * c->num_filters));
|
574
|
-
memcpy((void*)c->filters, args->filters,
|
575
|
-
sizeof(grpc_channel_filter*) * c->num_filters);
|
576
|
-
} else {
|
577
|
-
c->filters = nullptr;
|
578
|
-
}
|
579
|
-
c->pollset_set = grpc_pollset_set_create();
|
645
|
+
gpr_atm_no_barrier_store(&ref_pair_, 1 << INTERNAL_REF_BITS);
|
646
|
+
grpc_connector_ref(connector_);
|
647
|
+
pollset_set_ = grpc_pollset_set_create();
|
580
648
|
grpc_resolved_address* addr =
|
581
649
|
static_cast<grpc_resolved_address*>(gpr_malloc(sizeof(*addr)));
|
582
|
-
|
650
|
+
GetAddressFromSubchannelAddressArg(args, addr);
|
583
651
|
grpc_resolved_address* new_address = nullptr;
|
584
652
|
grpc_channel_args* new_args = nullptr;
|
585
|
-
if (grpc_proxy_mappers_map_address(addr, args
|
586
|
-
&new_args)) {
|
653
|
+
if (grpc_proxy_mappers_map_address(addr, args, &new_address, &new_args)) {
|
587
654
|
GPR_ASSERT(new_address != nullptr);
|
588
655
|
gpr_free(addr);
|
589
656
|
addr = new_address;
|
590
657
|
}
|
591
658
|
static const char* keys_to_remove[] = {GRPC_ARG_SUBCHANNEL_ADDRESS};
|
592
|
-
grpc_arg new_arg =
|
659
|
+
grpc_arg new_arg = CreateSubchannelAddressArg(addr);
|
593
660
|
gpr_free(addr);
|
594
|
-
|
595
|
-
new_args != nullptr ? new_args : args
|
661
|
+
args_ = grpc_channel_args_copy_and_add_and_remove(
|
662
|
+
new_args != nullptr ? new_args : args, keys_to_remove,
|
596
663
|
GPR_ARRAY_SIZE(keys_to_remove), &new_arg, 1);
|
597
664
|
gpr_free(new_arg.value.string);
|
598
665
|
if (new_args != nullptr) grpc_channel_args_destroy(new_args);
|
599
|
-
|
600
|
-
&c->root_external_state_watcher;
|
601
|
-
GRPC_CLOSURE_INIT(&c->on_connected, on_subchannel_connected, c,
|
666
|
+
GRPC_CLOSURE_INIT(&on_connecting_finished_, OnConnectingFinished, this,
|
602
667
|
grpc_schedule_on_exec_ctx);
|
603
|
-
|
604
|
-
|
605
|
-
grpc_connectivity_state_init(&c->state_and_health_tracker, GRPC_CHANNEL_IDLE,
|
606
|
-
"subchannel");
|
607
|
-
grpc_core::BackOff::Options backoff_options;
|
608
|
-
parse_args_for_backoff_values(args->args, &backoff_options,
|
609
|
-
&c->min_connect_timeout_ms);
|
610
|
-
c->backoff.Init(backoff_options);
|
611
|
-
gpr_mu_init(&c->mu);
|
612
|
-
|
613
|
-
// Check whether we should enable health checking.
|
614
|
-
const char* service_config_json = grpc_channel_arg_get_string(
|
615
|
-
grpc_channel_args_find(c->args, GRPC_ARG_SERVICE_CONFIG));
|
616
|
-
if (service_config_json != nullptr) {
|
617
|
-
grpc_core::UniquePtr<grpc_core::ServiceConfig> service_config =
|
618
|
-
grpc_core::ServiceConfig::Create(service_config_json);
|
619
|
-
if (service_config != nullptr) {
|
620
|
-
grpc_core::HealthCheckParams params;
|
621
|
-
service_config->ParseGlobalParams(grpc_core::HealthCheckParams::Parse,
|
622
|
-
¶ms);
|
623
|
-
c->health_check_service_name = std::move(params.service_name);
|
624
|
-
}
|
625
|
-
}
|
626
|
-
|
627
|
-
const grpc_arg* arg =
|
628
|
-
grpc_channel_args_find(c->args, GRPC_ARG_ENABLE_CHANNELZ);
|
629
|
-
bool channelz_enabled =
|
668
|
+
const grpc_arg* arg = grpc_channel_args_find(args_, GRPC_ARG_ENABLE_CHANNELZ);
|
669
|
+
const bool channelz_enabled =
|
630
670
|
grpc_channel_arg_get_bool(arg, GRPC_ENABLE_CHANNELZ_DEFAULT);
|
631
671
|
arg = grpc_channel_args_find(
|
632
|
-
|
672
|
+
args_, GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE);
|
633
673
|
const grpc_integer_options options = {
|
634
674
|
GRPC_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE_DEFAULT, 0, INT_MAX};
|
635
675
|
size_t channel_tracer_max_memory =
|
636
676
|
(size_t)grpc_channel_arg_get_integer(arg, options);
|
637
677
|
if (channelz_enabled) {
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
grpc_slice_from_static_string("Subchannel created"));
|
678
|
+
channelz_node_ = MakeRefCounted<channelz::SubchannelNode>(
|
679
|
+
this, channel_tracer_max_memory);
|
680
|
+
channelz_node_->AddTraceEvent(
|
681
|
+
channelz::ChannelTrace::Severity::Info,
|
682
|
+
grpc_slice_from_static_string("subchannel created"));
|
644
683
|
}
|
645
|
-
|
646
|
-
return grpc_subchannel_index_register(key, c);
|
647
684
|
}
|
648
685
|
|
649
|
-
|
650
|
-
|
651
|
-
|
686
|
+
Subchannel::~Subchannel() {
|
687
|
+
if (channelz_node_ != nullptr) {
|
688
|
+
channelz_node_->AddTraceEvent(
|
689
|
+
channelz::ChannelTrace::Severity::Info,
|
690
|
+
grpc_slice_from_static_string("Subchannel destroyed"));
|
691
|
+
channelz_node_->MarkSubchannelDestroyed();
|
692
|
+
}
|
693
|
+
grpc_channel_args_destroy(args_);
|
694
|
+
grpc_connector_unref(connector_);
|
695
|
+
grpc_pollset_set_destroy(pollset_set_);
|
696
|
+
Delete(key_);
|
652
697
|
}
|
653
698
|
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
699
|
+
Subchannel* Subchannel::Create(grpc_connector* connector,
|
700
|
+
const grpc_channel_args* args) {
|
701
|
+
SubchannelKey* key = New<SubchannelKey>(args);
|
702
|
+
SubchannelPoolInterface* subchannel_pool =
|
703
|
+
SubchannelPoolInterface::GetSubchannelPoolFromChannelArgs(args);
|
704
|
+
GPR_ASSERT(subchannel_pool != nullptr);
|
705
|
+
Subchannel* c = subchannel_pool->FindSubchannel(key);
|
706
|
+
if (c != nullptr) {
|
707
|
+
Delete(key);
|
708
|
+
return c;
|
659
709
|
}
|
710
|
+
c = New<Subchannel>(key, connector, args);
|
711
|
+
// Try to register the subchannel before setting the subchannel pool.
|
712
|
+
// Otherwise, in case of a registration race, unreffing c in
|
713
|
+
// RegisterSubchannel() will cause c to be tried to be unregistered, while
|
714
|
+
// its key maps to a different subchannel.
|
715
|
+
Subchannel* registered = subchannel_pool->RegisterSubchannel(key, c);
|
716
|
+
if (registered == c) c->subchannel_pool_ = subchannel_pool->Ref();
|
717
|
+
return registered;
|
660
718
|
}
|
661
719
|
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
args.deadline = std::max(c->next_attempt_deadline, min_deadline);
|
669
|
-
args.channel_args = c->args;
|
670
|
-
set_subchannel_connectivity_state_locked(c, GRPC_CHANNEL_CONNECTING,
|
671
|
-
GRPC_ERROR_NONE, "connecting");
|
672
|
-
grpc_connectivity_state_set(&c->state_and_health_tracker,
|
673
|
-
GRPC_CHANNEL_CONNECTING, GRPC_ERROR_NONE,
|
674
|
-
"connecting");
|
675
|
-
grpc_connector_connect(c->connector, &args, &c->connecting_result,
|
676
|
-
&c->on_connected);
|
720
|
+
Subchannel* Subchannel::Ref(GRPC_SUBCHANNEL_REF_EXTRA_ARGS) {
|
721
|
+
gpr_atm old_refs;
|
722
|
+
old_refs = RefMutate((1 << INTERNAL_REF_BITS),
|
723
|
+
0 GRPC_SUBCHANNEL_REF_MUTATE_PURPOSE("STRONG_REF"));
|
724
|
+
GPR_ASSERT((old_refs & STRONG_REF_MASK) != 0);
|
725
|
+
return this;
|
677
726
|
}
|
678
727
|
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
|
728
|
+
void Subchannel::Unref(GRPC_SUBCHANNEL_REF_EXTRA_ARGS) {
|
729
|
+
gpr_atm old_refs;
|
730
|
+
// add a weak ref and subtract a strong ref (atomically)
|
731
|
+
old_refs = RefMutate(
|
732
|
+
static_cast<gpr_atm>(1) - static_cast<gpr_atm>(1 << INTERNAL_REF_BITS),
|
733
|
+
1 GRPC_SUBCHANNEL_REF_MUTATE_PURPOSE("STRONG_UNREF"));
|
734
|
+
if ((old_refs & STRONG_REF_MASK) == (1 << INTERNAL_REF_BITS)) {
|
735
|
+
Disconnect();
|
736
|
+
}
|
737
|
+
GRPC_SUBCHANNEL_WEAK_UNREF(this, "strong-unref");
|
687
738
|
}
|
688
739
|
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
w->pollset_set);
|
695
|
-
}
|
696
|
-
gpr_mu_lock(&w->subchannel->mu);
|
697
|
-
w->next->prev = w->prev;
|
698
|
-
w->prev->next = w->next;
|
699
|
-
gpr_mu_unlock(&w->subchannel->mu);
|
700
|
-
GRPC_SUBCHANNEL_WEAK_UNREF(w->subchannel, "external_state_watcher");
|
701
|
-
gpr_free(w);
|
702
|
-
GRPC_CLOSURE_SCHED(follow_up, GRPC_ERROR_REF(error));
|
740
|
+
Subchannel* Subchannel::WeakRef(GRPC_SUBCHANNEL_REF_EXTRA_ARGS) {
|
741
|
+
gpr_atm old_refs;
|
742
|
+
old_refs = RefMutate(1, 0 GRPC_SUBCHANNEL_REF_MUTATE_PURPOSE("WEAK_REF"));
|
743
|
+
GPR_ASSERT(old_refs != 0);
|
744
|
+
return this;
|
703
745
|
}
|
704
746
|
|
705
|
-
|
706
|
-
grpc_subchannel* c = static_cast<grpc_subchannel*>(arg);
|
707
|
-
gpr_mu_lock(&c->mu);
|
708
|
-
c->have_alarm = false;
|
709
|
-
if (c->disconnected) {
|
710
|
-
error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING("Disconnected",
|
711
|
-
&error, 1);
|
712
|
-
} else if (c->retry_immediately) {
|
713
|
-
c->retry_immediately = false;
|
714
|
-
error = GRPC_ERROR_NONE;
|
715
|
-
} else {
|
716
|
-
GRPC_ERROR_REF(error);
|
717
|
-
}
|
718
|
-
if (error == GRPC_ERROR_NONE) {
|
719
|
-
gpr_log(GPR_INFO, "Failed to connect to channel, retrying");
|
720
|
-
continue_connect_locked(c);
|
721
|
-
gpr_mu_unlock(&c->mu);
|
722
|
-
} else {
|
723
|
-
gpr_mu_unlock(&c->mu);
|
724
|
-
GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting");
|
725
|
-
}
|
726
|
-
GRPC_ERROR_UNREF(error);
|
727
|
-
}
|
728
|
-
|
729
|
-
static void maybe_start_connecting_locked(grpc_subchannel* c) {
|
730
|
-
if (c->disconnected) {
|
731
|
-
/* Don't try to connect if we're already disconnected */
|
732
|
-
return;
|
733
|
-
}
|
734
|
-
if (c->connecting) {
|
735
|
-
/* Already connecting: don't restart */
|
736
|
-
return;
|
737
|
-
}
|
738
|
-
if (c->connected_subchannel != nullptr) {
|
739
|
-
/* Already connected: don't restart */
|
740
|
-
return;
|
741
|
-
}
|
742
|
-
if (!grpc_connectivity_state_has_watchers(&c->state_tracker) &&
|
743
|
-
!grpc_connectivity_state_has_watchers(&c->state_and_health_tracker)) {
|
744
|
-
/* Nobody is interested in connecting: so don't just yet */
|
745
|
-
return;
|
746
|
-
}
|
747
|
-
c->connecting = true;
|
748
|
-
GRPC_SUBCHANNEL_WEAK_REF(c, "connecting");
|
749
|
-
if (!c->backoff_begun) {
|
750
|
-
c->backoff_begun = true;
|
751
|
-
continue_connect_locked(c);
|
752
|
-
} else {
|
753
|
-
GPR_ASSERT(!c->have_alarm);
|
754
|
-
c->have_alarm = true;
|
755
|
-
const grpc_millis time_til_next =
|
756
|
-
c->next_attempt_deadline - grpc_core::ExecCtx::Get()->Now();
|
757
|
-
if (time_til_next <= 0) {
|
758
|
-
gpr_log(GPR_INFO, "Subchannel %p: Retry immediately", c);
|
759
|
-
} else {
|
760
|
-
gpr_log(GPR_INFO, "Subchannel %p: Retry in %" PRId64 " milliseconds", c,
|
761
|
-
time_til_next);
|
762
|
-
}
|
763
|
-
GRPC_CLOSURE_INIT(&c->on_alarm, on_alarm, c, grpc_schedule_on_exec_ctx);
|
764
|
-
grpc_timer_init(&c->alarm, c->next_attempt_deadline, &c->on_alarm);
|
765
|
-
}
|
766
|
-
}
|
747
|
+
namespace {
|
767
748
|
|
768
|
-
void
|
769
|
-
|
770
|
-
|
771
|
-
bool inhibit_health_checks) {
|
772
|
-
grpc_connectivity_state_tracker* tracker =
|
773
|
-
inhibit_health_checks ? &c->state_tracker : &c->state_and_health_tracker;
|
774
|
-
external_state_watcher* w;
|
775
|
-
if (state == nullptr) {
|
776
|
-
gpr_mu_lock(&c->mu);
|
777
|
-
for (w = c->root_external_state_watcher.next;
|
778
|
-
w != &c->root_external_state_watcher; w = w->next) {
|
779
|
-
if (w->notify == notify) {
|
780
|
-
grpc_connectivity_state_notify_on_state_change(tracker, nullptr,
|
781
|
-
&w->closure);
|
782
|
-
}
|
783
|
-
}
|
784
|
-
gpr_mu_unlock(&c->mu);
|
785
|
-
} else {
|
786
|
-
w = static_cast<external_state_watcher*>(gpr_malloc(sizeof(*w)));
|
787
|
-
w->subchannel = c;
|
788
|
-
w->pollset_set = interested_parties;
|
789
|
-
w->notify = notify;
|
790
|
-
GRPC_CLOSURE_INIT(&w->closure, on_external_state_watcher_done, w,
|
791
|
-
grpc_schedule_on_exec_ctx);
|
792
|
-
if (interested_parties != nullptr) {
|
793
|
-
grpc_pollset_set_add_pollset_set(c->pollset_set, interested_parties);
|
794
|
-
}
|
795
|
-
GRPC_SUBCHANNEL_WEAK_REF(c, "external_state_watcher");
|
796
|
-
gpr_mu_lock(&c->mu);
|
797
|
-
w->next = &c->root_external_state_watcher;
|
798
|
-
w->prev = w->next->prev;
|
799
|
-
w->next->prev = w->prev->next = w;
|
800
|
-
grpc_connectivity_state_notify_on_state_change(tracker, state, &w->closure);
|
801
|
-
maybe_start_connecting_locked(c);
|
802
|
-
gpr_mu_unlock(&c->mu);
|
803
|
-
}
|
749
|
+
void subchannel_destroy(void* arg, grpc_error* error) {
|
750
|
+
Subchannel* self = static_cast<Subchannel*>(arg);
|
751
|
+
Delete(self);
|
804
752
|
}
|
805
753
|
|
806
|
-
|
807
|
-
/* construct channel stack */
|
808
|
-
grpc_channel_stack_builder* builder = grpc_channel_stack_builder_create();
|
809
|
-
grpc_channel_stack_builder_set_channel_arguments(
|
810
|
-
builder, c->connecting_result.channel_args);
|
811
|
-
grpc_channel_stack_builder_set_transport(builder,
|
812
|
-
c->connecting_result.transport);
|
813
|
-
|
814
|
-
if (!grpc_channel_init_create_stack(builder, GRPC_CLIENT_SUBCHANNEL)) {
|
815
|
-
grpc_channel_stack_builder_destroy(builder);
|
816
|
-
return false;
|
817
|
-
}
|
818
|
-
grpc_channel_stack* stk;
|
819
|
-
grpc_error* error = grpc_channel_stack_builder_finish(
|
820
|
-
builder, 0, 1, connection_destroy, nullptr,
|
821
|
-
reinterpret_cast<void**>(&stk));
|
822
|
-
if (error != GRPC_ERROR_NONE) {
|
823
|
-
grpc_transport_destroy(c->connecting_result.transport);
|
824
|
-
gpr_log(GPR_ERROR, "error initializing subchannel stack: %s",
|
825
|
-
grpc_error_string(error));
|
826
|
-
GRPC_ERROR_UNREF(error);
|
827
|
-
return false;
|
828
|
-
}
|
829
|
-
intptr_t socket_uuid = c->connecting_result.socket_uuid;
|
830
|
-
memset(&c->connecting_result, 0, sizeof(c->connecting_result));
|
754
|
+
} // namespace
|
831
755
|
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
756
|
+
void Subchannel::WeakUnref(GRPC_SUBCHANNEL_REF_EXTRA_ARGS) {
|
757
|
+
gpr_atm old_refs;
|
758
|
+
old_refs = RefMutate(-static_cast<gpr_atm>(1),
|
759
|
+
1 GRPC_SUBCHANNEL_REF_MUTATE_PURPOSE("WEAK_UNREF"));
|
760
|
+
if (old_refs == 1) {
|
761
|
+
GRPC_CLOSURE_SCHED(GRPC_CLOSURE_CREATE(subchannel_destroy, this,
|
762
|
+
grpc_schedule_on_exec_ctx),
|
763
|
+
GRPC_ERROR_NONE);
|
836
764
|
}
|
837
|
-
|
838
|
-
/* publish */
|
839
|
-
c->connected_subchannel.reset(grpc_core::New<grpc_core::ConnectedSubchannel>(
|
840
|
-
stk, c->args, c->channelz_subchannel, socket_uuid));
|
841
|
-
gpr_log(GPR_INFO, "New connected subchannel at %p for subchannel %p",
|
842
|
-
c->connected_subchannel.get(), c);
|
843
|
-
|
844
|
-
// Instantiate state watcher. Will clean itself up.
|
845
|
-
c->connected_subchannel_watcher =
|
846
|
-
grpc_core::MakeOrphanable<grpc_core::ConnectedSubchannelStateWatcher>(c);
|
847
|
-
|
848
|
-
return true;
|
849
765
|
}
|
850
766
|
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
860
|
-
|
861
|
-
|
862
|
-
GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting");
|
863
|
-
} else {
|
864
|
-
set_subchannel_connectivity_state_locked(
|
865
|
-
c, GRPC_CHANNEL_TRANSIENT_FAILURE,
|
866
|
-
grpc_error_set_int(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
|
867
|
-
"Connect Failed", &error, 1),
|
868
|
-
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE),
|
869
|
-
"connect_failed");
|
870
|
-
grpc_connectivity_state_set(
|
871
|
-
&c->state_and_health_tracker, GRPC_CHANNEL_TRANSIENT_FAILURE,
|
872
|
-
grpc_error_set_int(GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING(
|
873
|
-
"Connect Failed", &error, 1),
|
874
|
-
GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_UNAVAILABLE),
|
875
|
-
"connect_failed");
|
876
|
-
|
877
|
-
const char* errmsg = grpc_error_string(error);
|
878
|
-
gpr_log(GPR_INFO, "Connect failed: %s", errmsg);
|
879
|
-
|
880
|
-
maybe_start_connecting_locked(c);
|
881
|
-
GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting");
|
767
|
+
Subchannel* Subchannel::RefFromWeakRef(GRPC_SUBCHANNEL_REF_EXTRA_ARGS) {
|
768
|
+
for (;;) {
|
769
|
+
gpr_atm old_refs = gpr_atm_acq_load(&ref_pair_);
|
770
|
+
if (old_refs >= (1 << INTERNAL_REF_BITS)) {
|
771
|
+
gpr_atm new_refs = old_refs + (1 << INTERNAL_REF_BITS);
|
772
|
+
if (gpr_atm_rel_cas(&ref_pair_, old_refs, new_refs)) {
|
773
|
+
return this;
|
774
|
+
}
|
775
|
+
} else {
|
776
|
+
return nullptr;
|
777
|
+
}
|
882
778
|
}
|
883
|
-
gpr_mu_unlock(&c->mu);
|
884
|
-
GRPC_SUBCHANNEL_WEAK_UNREF(c, "connected");
|
885
|
-
grpc_channel_args_destroy(delete_channel_args);
|
886
779
|
}
|
887
780
|
|
888
|
-
|
889
|
-
|
890
|
-
|
891
|
-
if (subchannel->have_alarm) {
|
892
|
-
subchannel->retry_immediately = true;
|
893
|
-
grpc_timer_cancel(&subchannel->alarm);
|
781
|
+
intptr_t Subchannel::GetChildSocketUuid() {
|
782
|
+
if (connected_subchannel_ != nullptr) {
|
783
|
+
return connected_subchannel_->socket_uuid();
|
894
784
|
} else {
|
895
|
-
|
896
|
-
maybe_start_connecting_locked(subchannel);
|
785
|
+
return 0;
|
897
786
|
}
|
898
|
-
gpr_mu_unlock(&subchannel->mu);
|
899
|
-
}
|
900
|
-
|
901
|
-
/*
|
902
|
-
* grpc_subchannel_call implementation
|
903
|
-
*/
|
904
|
-
|
905
|
-
static void subchannel_call_destroy(void* call, grpc_error* error) {
|
906
|
-
GPR_TIMER_SCOPE("grpc_subchannel_call_unref.destroy", 0);
|
907
|
-
grpc_subchannel_call* c = static_cast<grpc_subchannel_call*>(call);
|
908
|
-
grpc_core::ConnectedSubchannel* connection = c->connection;
|
909
|
-
grpc_call_stack_destroy(SUBCHANNEL_CALL_TO_CALL_STACK(c), nullptr,
|
910
|
-
c->schedule_closure_after_destroy);
|
911
|
-
connection->Unref(DEBUG_LOCATION, "subchannel_call");
|
912
|
-
c->~grpc_subchannel_call();
|
913
|
-
}
|
914
|
-
|
915
|
-
void grpc_subchannel_call_set_cleanup_closure(grpc_subchannel_call* call,
|
916
|
-
grpc_closure* closure) {
|
917
|
-
GPR_ASSERT(call->schedule_closure_after_destroy == nullptr);
|
918
|
-
GPR_ASSERT(closure != nullptr);
|
919
|
-
call->schedule_closure_after_destroy = closure;
|
920
787
|
}
|
921
788
|
|
922
|
-
|
923
|
-
|
924
|
-
|
925
|
-
|
789
|
+
const char* Subchannel::GetTargetAddress() {
|
790
|
+
const grpc_arg* addr_arg =
|
791
|
+
grpc_channel_args_find(args_, GRPC_ARG_SUBCHANNEL_ADDRESS);
|
792
|
+
const char* addr_str = grpc_channel_arg_get_string(addr_arg);
|
793
|
+
GPR_ASSERT(addr_str != nullptr); // Should have been set by LB policy.
|
794
|
+
return addr_str;
|
926
795
|
}
|
927
796
|
|
928
|
-
|
929
|
-
|
930
|
-
GRPC_CALL_STACK_UNREF(SUBCHANNEL_CALL_TO_CALL_STACK(c), REF_REASON);
|
797
|
+
channelz::SubchannelNode* Subchannel::channelz_node() {
|
798
|
+
return channelz_node_.get();
|
931
799
|
}
|
932
800
|
|
933
|
-
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
|
938
|
-
|
939
|
-
|
801
|
+
grpc_connectivity_state Subchannel::CheckConnectivityState(
|
802
|
+
const char* health_check_service_name,
|
803
|
+
RefCountedPtr<ConnectedSubchannel>* connected_subchannel) {
|
804
|
+
MutexLock lock(&mu_);
|
805
|
+
grpc_connectivity_state state;
|
806
|
+
if (health_check_service_name == nullptr) {
|
807
|
+
state = state_;
|
940
808
|
} else {
|
941
|
-
|
942
|
-
|
943
|
-
md_batch->idx.named.grpc_status->md);
|
944
|
-
} else {
|
945
|
-
*status = GRPC_STATUS_UNKNOWN;
|
946
|
-
}
|
809
|
+
state = health_watcher_map_.CheckConnectivityStateLocked(
|
810
|
+
this, health_check_service_name);
|
947
811
|
}
|
948
|
-
|
812
|
+
if (connected_subchannel != nullptr && state == GRPC_CHANNEL_READY) {
|
813
|
+
*connected_subchannel = connected_subchannel_;
|
814
|
+
}
|
815
|
+
return state;
|
949
816
|
}
|
950
817
|
|
951
|
-
|
952
|
-
|
953
|
-
|
954
|
-
|
955
|
-
|
956
|
-
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
if (
|
961
|
-
|
818
|
+
void Subchannel::WatchConnectivityState(
|
819
|
+
grpc_connectivity_state initial_state,
|
820
|
+
UniquePtr<char> health_check_service_name,
|
821
|
+
UniquePtr<ConnectivityStateWatcher> watcher) {
|
822
|
+
MutexLock lock(&mu_);
|
823
|
+
grpc_pollset_set* interested_parties = watcher->interested_parties();
|
824
|
+
if (interested_parties != nullptr) {
|
825
|
+
grpc_pollset_set_add_pollset_set(pollset_set_, interested_parties);
|
826
|
+
}
|
827
|
+
if (health_check_service_name == nullptr) {
|
828
|
+
if (state_ != initial_state) {
|
829
|
+
watcher->OnConnectivityStateChange(state_, connected_subchannel_);
|
830
|
+
}
|
831
|
+
watcher_list_.AddWatcherLocked(std::move(watcher));
|
962
832
|
} else {
|
963
|
-
|
833
|
+
health_watcher_map_.AddWatcherLocked(this, initial_state,
|
834
|
+
std::move(health_check_service_name),
|
835
|
+
std::move(watcher));
|
964
836
|
}
|
965
|
-
GRPC_CLOSURE_RUN(call->original_recv_trailing_metadata,
|
966
|
-
GRPC_ERROR_REF(error));
|
967
837
|
}
|
968
838
|
|
969
|
-
|
970
|
-
|
971
|
-
|
972
|
-
|
973
|
-
|
974
|
-
|
975
|
-
return;
|
839
|
+
void Subchannel::CancelConnectivityStateWatch(
|
840
|
+
const char* health_check_service_name, ConnectivityStateWatcher* watcher) {
|
841
|
+
MutexLock lock(&mu_);
|
842
|
+
grpc_pollset_set* interested_parties = watcher->interested_parties();
|
843
|
+
if (interested_parties != nullptr) {
|
844
|
+
grpc_pollset_set_del_pollset_set(pollset_set_, interested_parties);
|
976
845
|
}
|
977
|
-
|
978
|
-
|
979
|
-
|
846
|
+
if (health_check_service_name == nullptr) {
|
847
|
+
watcher_list_.RemoveWatcherLocked(watcher);
|
848
|
+
} else {
|
849
|
+
health_watcher_map_.RemoveWatcherLocked(health_check_service_name, watcher);
|
980
850
|
}
|
981
|
-
GRPC_CLOSURE_INIT(&call->recv_trailing_metadata_ready,
|
982
|
-
recv_trailing_metadata_ready, call,
|
983
|
-
grpc_schedule_on_exec_ctx);
|
984
|
-
// save some state needed for the interception callback.
|
985
|
-
GPR_ASSERT(call->recv_trailing_metadata == nullptr);
|
986
|
-
call->recv_trailing_metadata =
|
987
|
-
batch->payload->recv_trailing_metadata.recv_trailing_metadata;
|
988
|
-
call->original_recv_trailing_metadata =
|
989
|
-
batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready;
|
990
|
-
batch->payload->recv_trailing_metadata.recv_trailing_metadata_ready =
|
991
|
-
&call->recv_trailing_metadata_ready;
|
992
851
|
}
|
993
852
|
|
994
|
-
void
|
995
|
-
|
996
|
-
|
997
|
-
maybe_intercept_recv_trailing_metadata(call, batch);
|
998
|
-
grpc_call_stack* call_stack = SUBCHANNEL_CALL_TO_CALL_STACK(call);
|
999
|
-
grpc_call_element* top_elem = grpc_call_stack_element(call_stack, 0);
|
1000
|
-
GRPC_CALL_LOG_OP(GPR_INFO, top_elem, batch);
|
1001
|
-
top_elem->filter->start_transport_stream_op_batch(top_elem, batch);
|
853
|
+
void Subchannel::AttemptToConnect() {
|
854
|
+
MutexLock lock(&mu_);
|
855
|
+
MaybeStartConnectingLocked();
|
1002
856
|
}
|
1003
857
|
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
1007
|
-
|
1008
|
-
|
1009
|
-
|
858
|
+
void Subchannel::ResetBackoff() {
|
859
|
+
MutexLock lock(&mu_);
|
860
|
+
backoff_.Reset();
|
861
|
+
if (have_retry_alarm_) {
|
862
|
+
retry_immediately_ = true;
|
863
|
+
grpc_timer_cancel(&retry_alarm_);
|
864
|
+
} else {
|
865
|
+
backoff_begun_ = false;
|
866
|
+
MaybeStartConnectingLocked();
|
867
|
+
}
|
1010
868
|
}
|
1011
869
|
|
1012
|
-
|
1013
|
-
const
|
1014
|
-
return
|
870
|
+
grpc_arg Subchannel::CreateSubchannelAddressArg(
|
871
|
+
const grpc_resolved_address* addr) {
|
872
|
+
return grpc_channel_arg_string_create(
|
873
|
+
(char*)GRPC_ARG_SUBCHANNEL_ADDRESS,
|
874
|
+
addr->len > 0 ? grpc_sockaddr_to_uri(addr) : gpr_strdup(""));
|
1015
875
|
}
|
1016
876
|
|
1017
|
-
|
1018
|
-
|
1019
|
-
|
1020
|
-
|
1021
|
-
|
877
|
+
const char* Subchannel::GetUriFromSubchannelAddressArg(
|
878
|
+
const grpc_channel_args* args) {
|
879
|
+
const grpc_arg* addr_arg =
|
880
|
+
grpc_channel_args_find(args, GRPC_ARG_SUBCHANNEL_ADDRESS);
|
881
|
+
const char* addr_str = grpc_channel_arg_get_string(addr_arg);
|
882
|
+
GPR_ASSERT(addr_str != nullptr); // Should have been set by LB policy.
|
883
|
+
return addr_str;
|
1022
884
|
}
|
1023
885
|
|
1024
|
-
|
1025
|
-
grpc_subchannel_call* subchannel_call) {
|
1026
|
-
return SUBCHANNEL_CALL_TO_CALL_STACK(subchannel_call);
|
1027
|
-
}
|
886
|
+
namespace {
|
1028
887
|
|
1029
|
-
|
1030
|
-
grpc_resolved_address* addr) {
|
888
|
+
void UriToSockaddr(const char* uri_str, grpc_resolved_address* addr) {
|
1031
889
|
grpc_uri* uri = grpc_uri_parse(uri_str, 0 /* suppress_errors */);
|
1032
890
|
GPR_ASSERT(uri != nullptr);
|
1033
891
|
if (!grpc_parse_uri(uri, addr)) memset(addr, 0, sizeof(*addr));
|
1034
892
|
grpc_uri_destroy(uri);
|
1035
893
|
}
|
1036
894
|
|
1037
|
-
|
1038
|
-
|
1039
|
-
|
895
|
+
} // namespace
|
896
|
+
|
897
|
+
void Subchannel::GetAddressFromSubchannelAddressArg(
|
898
|
+
const grpc_channel_args* args, grpc_resolved_address* addr) {
|
899
|
+
const char* addr_uri_str = GetUriFromSubchannelAddressArg(args);
|
1040
900
|
memset(addr, 0, sizeof(*addr));
|
1041
901
|
if (*addr_uri_str != '\0') {
|
1042
|
-
|
902
|
+
UriToSockaddr(addr_uri_str, addr);
|
1043
903
|
}
|
1044
904
|
}
|
1045
905
|
|
1046
|
-
|
1047
|
-
const grpc_arg* addr_arg =
|
1048
|
-
grpc_channel_args_find(subchannel->args, GRPC_ARG_SUBCHANNEL_ADDRESS);
|
1049
|
-
const char* addr_str = grpc_channel_arg_get_string(addr_arg);
|
1050
|
-
GPR_ASSERT(addr_str != nullptr); // Should have been set by LB policy.
|
1051
|
-
return addr_str;
|
1052
|
-
}
|
906
|
+
namespace {
|
1053
907
|
|
1054
|
-
|
1055
|
-
|
1056
|
-
|
1057
|
-
|
1058
|
-
|
1059
|
-
|
908
|
+
// Returns a string indicating the subchannel's connectivity state change to
|
909
|
+
// \a state.
|
910
|
+
const char* SubchannelConnectivityStateChangeString(
|
911
|
+
grpc_connectivity_state state) {
|
912
|
+
switch (state) {
|
913
|
+
case GRPC_CHANNEL_IDLE:
|
914
|
+
return "Subchannel state change to IDLE";
|
915
|
+
case GRPC_CHANNEL_CONNECTING:
|
916
|
+
return "Subchannel state change to CONNECTING";
|
917
|
+
case GRPC_CHANNEL_READY:
|
918
|
+
return "Subchannel state change to READY";
|
919
|
+
case GRPC_CHANNEL_TRANSIENT_FAILURE:
|
920
|
+
return "Subchannel state change to TRANSIENT_FAILURE";
|
921
|
+
case GRPC_CHANNEL_SHUTDOWN:
|
922
|
+
return "Subchannel state change to SHUTDOWN";
|
923
|
+
}
|
924
|
+
GPR_UNREACHABLE_CODE(return "UNKNOWN");
|
1060
925
|
}
|
1061
926
|
|
1062
|
-
|
1063
|
-
|
1064
|
-
|
1065
|
-
|
927
|
+
} // namespace
|
928
|
+
|
929
|
+
// Note: Must be called with a state that is different from the current state.
|
930
|
+
void Subchannel::SetConnectivityStateLocked(grpc_connectivity_state state) {
|
931
|
+
state_ = state;
|
932
|
+
if (channelz_node_ != nullptr) {
|
933
|
+
channelz_node_->AddTraceEvent(
|
934
|
+
channelz::ChannelTrace::Severity::Info,
|
935
|
+
grpc_slice_from_static_string(
|
936
|
+
SubchannelConnectivityStateChangeString(state)));
|
937
|
+
}
|
938
|
+
// Notify non-health watchers.
|
939
|
+
watcher_list_.NotifyLocked(this, state);
|
940
|
+
// Notify health watchers.
|
941
|
+
health_watcher_map_.NotifyLocked(state);
|
1066
942
|
}
|
1067
943
|
|
1068
|
-
|
944
|
+
void Subchannel::MaybeStartConnectingLocked() {
|
945
|
+
if (disconnected_) {
|
946
|
+
// Don't try to connect if we're already disconnected.
|
947
|
+
return;
|
948
|
+
}
|
949
|
+
if (connecting_) {
|
950
|
+
// Already connecting: don't restart.
|
951
|
+
return;
|
952
|
+
}
|
953
|
+
if (connected_subchannel_ != nullptr) {
|
954
|
+
// Already connected: don't restart.
|
955
|
+
return;
|
956
|
+
}
|
957
|
+
connecting_ = true;
|
958
|
+
GRPC_SUBCHANNEL_WEAK_REF(this, "connecting");
|
959
|
+
if (!backoff_begun_) {
|
960
|
+
backoff_begun_ = true;
|
961
|
+
ContinueConnectingLocked();
|
962
|
+
} else {
|
963
|
+
GPR_ASSERT(!have_retry_alarm_);
|
964
|
+
have_retry_alarm_ = true;
|
965
|
+
const grpc_millis time_til_next =
|
966
|
+
next_attempt_deadline_ - ExecCtx::Get()->Now();
|
967
|
+
if (time_til_next <= 0) {
|
968
|
+
gpr_log(GPR_INFO, "Subchannel %p: Retry immediately", this);
|
969
|
+
} else {
|
970
|
+
gpr_log(GPR_INFO, "Subchannel %p: Retry in %" PRId64 " milliseconds",
|
971
|
+
this, time_til_next);
|
972
|
+
}
|
973
|
+
GRPC_CLOSURE_INIT(&on_retry_alarm_, OnRetryAlarm, this,
|
974
|
+
grpc_schedule_on_exec_ctx);
|
975
|
+
grpc_timer_init(&retry_alarm_, next_attempt_deadline_, &on_retry_alarm_);
|
976
|
+
}
|
977
|
+
}
|
1069
978
|
|
1070
|
-
|
1071
|
-
|
1072
|
-
|
1073
|
-
|
1074
|
-
|
1075
|
-
|
1076
|
-
|
1077
|
-
|
1078
|
-
|
1079
|
-
|
979
|
+
void Subchannel::OnRetryAlarm(void* arg, grpc_error* error) {
|
980
|
+
Subchannel* c = static_cast<Subchannel*>(arg);
|
981
|
+
// TODO(soheilhy): Once subchannel refcounting is simplified, we can get use
|
982
|
+
// MutexLock instead of ReleasableMutexLock, here.
|
983
|
+
ReleasableMutexLock lock(&c->mu_);
|
984
|
+
c->have_retry_alarm_ = false;
|
985
|
+
if (c->disconnected_) {
|
986
|
+
error = GRPC_ERROR_CREATE_REFERENCING_FROM_STATIC_STRING("Disconnected",
|
987
|
+
&error, 1);
|
988
|
+
} else if (c->retry_immediately_) {
|
989
|
+
c->retry_immediately_ = false;
|
990
|
+
error = GRPC_ERROR_NONE;
|
991
|
+
} else {
|
992
|
+
GRPC_ERROR_REF(error);
|
993
|
+
}
|
994
|
+
if (error == GRPC_ERROR_NONE) {
|
995
|
+
gpr_log(GPR_INFO, "Failed to connect to channel, retrying");
|
996
|
+
c->ContinueConnectingLocked();
|
997
|
+
lock.Unlock();
|
998
|
+
} else {
|
999
|
+
lock.Unlock();
|
1000
|
+
GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting");
|
1001
|
+
}
|
1002
|
+
GRPC_ERROR_UNREF(error);
|
1003
|
+
}
|
1080
1004
|
|
1081
|
-
|
1082
|
-
|
1083
|
-
|
1005
|
+
void Subchannel::ContinueConnectingLocked() {
|
1006
|
+
grpc_connect_in_args args;
|
1007
|
+
args.interested_parties = pollset_set_;
|
1008
|
+
const grpc_millis min_deadline =
|
1009
|
+
min_connect_timeout_ms_ + ExecCtx::Get()->Now();
|
1010
|
+
next_attempt_deadline_ = backoff_.NextAttemptTime();
|
1011
|
+
args.deadline = std::max(next_attempt_deadline_, min_deadline);
|
1012
|
+
args.channel_args = args_;
|
1013
|
+
SetConnectivityStateLocked(GRPC_CHANNEL_CONNECTING);
|
1014
|
+
grpc_connector_connect(connector_, &args, &connecting_result_,
|
1015
|
+
&on_connecting_finished_);
|
1084
1016
|
}
|
1085
1017
|
|
1086
|
-
void
|
1087
|
-
|
1088
|
-
|
1089
|
-
|
1090
|
-
|
1091
|
-
|
1092
|
-
|
1093
|
-
|
1094
|
-
|
1095
|
-
|
1018
|
+
void Subchannel::OnConnectingFinished(void* arg, grpc_error* error) {
|
1019
|
+
auto* c = static_cast<Subchannel*>(arg);
|
1020
|
+
grpc_channel_args* delete_channel_args = c->connecting_result_.channel_args;
|
1021
|
+
GRPC_SUBCHANNEL_WEAK_REF(c, "on_connecting_finished");
|
1022
|
+
{
|
1023
|
+
MutexLock lock(&c->mu_);
|
1024
|
+
c->connecting_ = false;
|
1025
|
+
if (c->connecting_result_.transport != nullptr &&
|
1026
|
+
c->PublishTransportLocked()) {
|
1027
|
+
// Do nothing, transport was published.
|
1028
|
+
} else if (c->disconnected_) {
|
1029
|
+
GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting");
|
1030
|
+
} else {
|
1031
|
+
gpr_log(GPR_INFO, "Connect failed: %s", grpc_error_string(error));
|
1032
|
+
c->SetConnectivityStateLocked(GRPC_CHANNEL_TRANSIENT_FAILURE);
|
1033
|
+
GRPC_SUBCHANNEL_WEAK_UNREF(c, "connecting");
|
1034
|
+
}
|
1035
|
+
}
|
1036
|
+
GRPC_SUBCHANNEL_WEAK_UNREF(c, "on_connecting_finished");
|
1037
|
+
grpc_channel_args_destroy(delete_channel_args);
|
1096
1038
|
}
|
1097
1039
|
|
1098
|
-
|
1099
|
-
|
1100
|
-
|
1101
|
-
|
1102
|
-
|
1103
|
-
|
1104
|
-
elem = grpc_channel_stack_element(channel_stack_, 0);
|
1105
|
-
elem->filter->start_transport_op(elem, op);
|
1040
|
+
namespace {
|
1041
|
+
|
1042
|
+
void ConnectionDestroy(void* arg, grpc_error* error) {
|
1043
|
+
grpc_channel_stack* stk = static_cast<grpc_channel_stack*>(arg);
|
1044
|
+
grpc_channel_stack_destroy(stk);
|
1045
|
+
gpr_free(stk);
|
1106
1046
|
}
|
1107
1047
|
|
1108
|
-
|
1109
|
-
|
1110
|
-
|
1111
|
-
|
1112
|
-
*
|
1113
|
-
|
1114
|
-
|
1115
|
-
|
1116
|
-
|
1117
|
-
|
1118
|
-
|
1119
|
-
|
1120
|
-
nullptr, /* server_transport_data */
|
1121
|
-
args.context, /* context */
|
1122
|
-
args.path, /* path */
|
1123
|
-
args.start_time, /* start_time */
|
1124
|
-
args.deadline, /* deadline */
|
1125
|
-
args.arena, /* arena */
|
1126
|
-
args.call_combiner /* call_combiner */
|
1127
|
-
};
|
1128
|
-
grpc_error* error = grpc_call_stack_init(
|
1129
|
-
channel_stack_, 1, subchannel_call_destroy, *call, &call_args);
|
1130
|
-
if (GPR_UNLIKELY(error != GRPC_ERROR_NONE)) {
|
1131
|
-
const char* error_string = grpc_error_string(error);
|
1132
|
-
gpr_log(GPR_ERROR, "error: %s", error_string);
|
1133
|
-
return error;
|
1048
|
+
} // namespace
|
1049
|
+
|
1050
|
+
bool Subchannel::PublishTransportLocked() {
|
1051
|
+
// Construct channel stack.
|
1052
|
+
grpc_channel_stack_builder* builder = grpc_channel_stack_builder_create();
|
1053
|
+
grpc_channel_stack_builder_set_channel_arguments(
|
1054
|
+
builder, connecting_result_.channel_args);
|
1055
|
+
grpc_channel_stack_builder_set_transport(builder,
|
1056
|
+
connecting_result_.transport);
|
1057
|
+
if (!grpc_channel_init_create_stack(builder, GRPC_CLIENT_SUBCHANNEL)) {
|
1058
|
+
grpc_channel_stack_builder_destroy(builder);
|
1059
|
+
return false;
|
1134
1060
|
}
|
1135
|
-
|
1136
|
-
|
1137
|
-
|
1061
|
+
grpc_channel_stack* stk;
|
1062
|
+
grpc_error* error = grpc_channel_stack_builder_finish(
|
1063
|
+
builder, 0, 1, ConnectionDestroy, nullptr,
|
1064
|
+
reinterpret_cast<void**>(&stk));
|
1065
|
+
if (error != GRPC_ERROR_NONE) {
|
1066
|
+
grpc_transport_destroy(connecting_result_.transport);
|
1067
|
+
gpr_log(GPR_ERROR, "error initializing subchannel stack: %s",
|
1068
|
+
grpc_error_string(error));
|
1069
|
+
GRPC_ERROR_UNREF(error);
|
1070
|
+
return false;
|
1071
|
+
}
|
1072
|
+
intptr_t socket_uuid = connecting_result_.socket_uuid;
|
1073
|
+
memset(&connecting_result_, 0, sizeof(connecting_result_));
|
1074
|
+
if (disconnected_) {
|
1075
|
+
grpc_channel_stack_destroy(stk);
|
1076
|
+
gpr_free(stk);
|
1077
|
+
return false;
|
1138
1078
|
}
|
1139
|
-
|
1079
|
+
// Publish.
|
1080
|
+
connected_subchannel_.reset(
|
1081
|
+
New<ConnectedSubchannel>(stk, args_, channelz_node_, socket_uuid));
|
1082
|
+
gpr_log(GPR_INFO, "New connected subchannel at %p for subchannel %p",
|
1083
|
+
connected_subchannel_.get(), this);
|
1084
|
+
// Instantiate state watcher. Will clean itself up.
|
1085
|
+
New<ConnectedSubchannelStateWatcher>(this);
|
1086
|
+
// Report initial state.
|
1087
|
+
SetConnectivityStateLocked(GRPC_CHANNEL_READY);
|
1088
|
+
return true;
|
1140
1089
|
}
|
1141
1090
|
|
1142
|
-
|
1143
|
-
|
1144
|
-
|
1145
|
-
|
1146
|
-
|
1147
|
-
|
1148
|
-
GPR_ROUND_UP_TO_ALIGNMENT_SIZE(channel_stack_->call_stack_size) +
|
1149
|
-
parent_data_size;
|
1150
|
-
} else {
|
1151
|
-
allocation_size += channel_stack_->call_stack_size;
|
1091
|
+
void Subchannel::Disconnect() {
|
1092
|
+
// The subchannel_pool is only used once here in this subchannel, so the
|
1093
|
+
// access can be outside of the lock.
|
1094
|
+
if (subchannel_pool_ != nullptr) {
|
1095
|
+
subchannel_pool_->UnregisterSubchannel(key_);
|
1096
|
+
subchannel_pool_.reset();
|
1152
1097
|
}
|
1153
|
-
|
1098
|
+
MutexLock lock(&mu_);
|
1099
|
+
GPR_ASSERT(!disconnected_);
|
1100
|
+
disconnected_ = true;
|
1101
|
+
grpc_connector_shutdown(connector_, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
|
1102
|
+
"Subchannel disconnected"));
|
1103
|
+
connected_subchannel_.reset();
|
1104
|
+
health_watcher_map_.ShutdownLocked();
|
1105
|
+
}
|
1106
|
+
|
1107
|
+
gpr_atm Subchannel::RefMutate(
|
1108
|
+
gpr_atm delta, int barrier GRPC_SUBCHANNEL_REF_MUTATE_EXTRA_ARGS) {
|
1109
|
+
gpr_atm old_val = barrier ? gpr_atm_full_fetch_add(&ref_pair_, delta)
|
1110
|
+
: gpr_atm_no_barrier_fetch_add(&ref_pair_, delta);
|
1111
|
+
#ifndef NDEBUG
|
1112
|
+
if (grpc_trace_subchannel_refcount.enabled()) {
|
1113
|
+
gpr_log(file, line, GPR_LOG_SEVERITY_DEBUG,
|
1114
|
+
"SUBCHANNEL: %p %12s 0x%" PRIxPTR " -> 0x%" PRIxPTR " [%s]", this,
|
1115
|
+
purpose, old_val, old_val + delta, reason);
|
1116
|
+
}
|
1117
|
+
#endif
|
1118
|
+
return old_val;
|
1154
1119
|
}
|
1155
1120
|
|
1156
1121
|
} // namespace grpc_core
|