aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.gitmodules12
-rw-r--r--AUTHORS1
-rw-r--r--BUILD15
-rw-r--r--CMakeLists.txt62
-rw-r--r--CONTRIBUTING.md2
-rw-r--r--Makefile87
-rw-r--r--README.md20
-rw-r--r--WORKSPACE43
-rw-r--r--bazel/grpc_build_system.bzl4
-rw-r--r--bazel/grpc_deps.bzl12
-rw-r--r--build.yaml26
-rw-r--r--config.m47
-rw-r--r--config.w324
-rw-r--r--doc/g_stands_for.md3
-rw-r--r--doc/grpc_release_schedule.md22
-rw-r--r--doc/python/sphinx/conf.py3
-rw-r--r--doc/python/sphinx/grpc.rst (renamed from doc/python/sphinx/api.rst)62
-rw-r--r--doc/python/sphinx/grpc_channelz.rst12
-rw-r--r--doc/python/sphinx/index.rst3
-rw-r--r--examples/objective-c/helloworld_macos/HelloWorld.podspec66
-rw-r--r--examples/objective-c/helloworld_macos/HelloWorld.xcodeproj/project.pbxproj399
-rw-r--r--examples/objective-c/helloworld_macos/HelloWorld/AppDelegate.h25
-rw-r--r--examples/objective-c/helloworld_macos/HelloWorld/AppDelegate.m (renamed from src/core/tsi/alts_transport_security.cc)28
-rw-r--r--examples/objective-c/helloworld_macos/HelloWorld/Assets.xcassets/AppIcon.appiconset/Contents.json58
-rw-r--r--examples/objective-c/helloworld_macos/HelloWorld/Assets.xcassets/Contents.json6
-rw-r--r--examples/objective-c/helloworld_macos/HelloWorld/Base.lproj/Main.storyboard717
-rw-r--r--examples/objective-c/helloworld_macos/HelloWorld/HelloWorld.entitlements5
-rw-r--r--examples/objective-c/helloworld_macos/HelloWorld/Info.plist32
-rw-r--r--examples/objective-c/helloworld_macos/HelloWorld/ViewController.h25
-rw-r--r--examples/objective-c/helloworld_macos/HelloWorld/ViewController.m (renamed from src/core/tsi/alts_transport_security.h)29
-rw-r--r--examples/objective-c/helloworld_macos/Podfile9
-rw-r--r--examples/objective-c/helloworld_macos/README.md6
-rw-r--r--examples/objective-c/helloworld_macos/main.m43
-rw-r--r--gRPC-C++.podspec10
-rw-r--r--gRPC-Core.podspec14
-rw-r--r--gRPC-ProtoRPC.podspec2
-rw-r--r--gRPC-RxLibrary.podspec2
-rw-r--r--gRPC.podspec2
-rw-r--r--grpc.gemspec8
-rw-r--r--grpc.gyp13
-rw-r--r--include/grpc/impl/codegen/atm_gcc_sync.h2
-rw-r--r--include/grpc/impl/codegen/atm_windows.h2
-rw-r--r--include/grpc/impl/codegen/grpc_types.h2
-rw-r--r--include/grpcpp/channel.h8
-rw-r--r--include/grpcpp/create_channel.h4
-rw-r--r--include/grpcpp/impl/codegen/client_unary_call.h18
-rw-r--r--include/grpcpp/impl/codegen/completion_queue.h3
-rw-r--r--include/grpcpp/impl/codegen/metadata_map.h19
-rw-r--r--include/grpcpp/security/credentials.h12
-rw-r--r--include/grpcpp/server.h4
-rw-r--r--package.xml12
-rw-r--r--requirements.bazel.txt4
-rw-r--r--src/compiler/csharp_generator.cc37
-rw-r--r--src/core/ext/filters/client_channel/client_channel.cc173
-rw-r--r--src/core/ext/filters/client_channel/lb_policy.h9
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc98
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc8
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc8
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/xds/xds.cc420
-rw-r--r--src/core/ext/filters/client_channel/lb_policy_registry.cc5
-rw-r--r--src/core/ext/filters/client_channel/lb_policy_registry.h4
-rw-r--r--src/core/ext/filters/client_channel/method_params.cc178
-rw-r--r--src/core/ext/filters/client_channel/method_params.h78
-rw-r--r--src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc34
-rw-r--r--src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc17
-rw-r--r--src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h4
-rw-r--r--src/core/ext/filters/client_channel/resolver_result_parsing.cc384
-rw-r--r--src/core/ext/filters/client_channel/resolver_result_parsing.h146
-rw-r--r--src/core/ext/transport/chttp2/transport/chttp2_transport.cc48
-rw-r--r--src/core/ext/transport/chttp2/transport/context_list.cc51
-rw-r--r--src/core/ext/transport/chttp2/transport/context_list.h72
-rw-r--r--src/core/ext/transport/chttp2/transport/internal.h33
-rw-r--r--src/core/ext/transport/chttp2/transport/writing.cc5
-rw-r--r--src/core/lib/gprpp/inlined_vector.h44
-rw-r--r--src/core/lib/gprpp/orphanable.h27
-rw-r--r--src/core/lib/gprpp/ref_counted.h128
-rw-r--r--src/core/lib/gprpp/ref_counted_ptr.h11
-rw-r--r--src/core/lib/iomgr/buffer_list.cc21
-rw-r--r--src/core/lib/iomgr/buffer_list.h13
-rw-r--r--src/core/lib/iomgr/endpoint.cc4
-rw-r--r--src/core/lib/iomgr/endpoint.h3
-rw-r--r--src/core/lib/iomgr/endpoint_cfstream.cc5
-rw-r--r--src/core/lib/iomgr/endpoint_pair_posix.cc4
-rw-r--r--src/core/lib/iomgr/ev_epoll1_linux.cc4
-rw-r--r--src/core/lib/iomgr/ev_epollex_linux.cc4
-rw-r--r--src/core/lib/iomgr/ev_poll_posix.cc4
-rw-r--r--src/core/lib/iomgr/ev_posix.cc22
-rw-r--r--src/core/lib/iomgr/ev_posix.h10
-rw-r--r--src/core/lib/iomgr/fork_posix.cc2
-rw-r--r--src/core/lib/iomgr/internal_errqueue.cc39
-rw-r--r--src/core/lib/iomgr/internal_errqueue.h8
-rw-r--r--src/core/lib/iomgr/iomgr.cc7
-rw-r--r--src/core/lib/iomgr/iomgr.h4
-rw-r--r--src/core/lib/iomgr/iomgr_custom.cc4
-rw-r--r--src/core/lib/iomgr/iomgr_internal.cc4
-rw-r--r--src/core/lib/iomgr/iomgr_internal.h4
-rw-r--r--src/core/lib/iomgr/iomgr_posix.cc7
-rw-r--r--src/core/lib/iomgr/iomgr_posix_cfstream.cc7
-rw-r--r--src/core/lib/iomgr/iomgr_windows.cc5
-rw-r--r--src/core/lib/iomgr/port.h3
-rw-r--r--src/core/lib/iomgr/tcp_client_posix.cc2
-rw-r--r--src/core/lib/iomgr/tcp_custom.cc5
-rw-r--r--src/core/lib/iomgr/tcp_posix.cc105
-rw-r--r--src/core/lib/iomgr/tcp_windows.cc5
-rw-r--r--src/core/lib/security/transport/secure_endpoint.cc8
-rw-r--r--src/core/lib/surface/call.cc4
-rw-r--r--src/core/lib/surface/call.h4
-rw-r--r--src/core/lib/surface/init.cc1
-rw-r--r--src/core/lib/surface/server.cc84
-rw-r--r--src/core/lib/surface/version.cc2
-rw-r--r--src/core/lib/transport/static_metadata.cc449
-rw-r--r--src/core/lib/transport/static_metadata.h146
-rw-r--r--src/core/lib/transport/transport.cc3
-rw-r--r--src/core/lib/transport/transport.h6
-rw-r--r--src/core/plugin_registry/grpc_cronet_plugin_registry.cc4
-rw-r--r--src/core/plugin_registry/grpc_plugin_registry.cc4
-rw-r--r--src/core/tsi/alts/handshaker/alts_handshaker_client.cc2
-rw-r--r--src/core/tsi/alts/handshaker/alts_shared_resource.cc28
-rw-r--r--src/core/tsi/alts/handshaker/alts_shared_resource.h5
-rw-r--r--src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc54
-rw-r--r--src/core/tsi/alts/handshaker/alts_tsi_handshaker.h1
-rw-r--r--src/core/tsi/transport_security.cc2
-rw-r--r--src/cpp/client/channel_cc.cc8
-rw-r--r--src/cpp/client/client_context.cc9
-rw-r--r--src/cpp/client/create_channel.cc36
-rw-r--r--src/cpp/client/create_channel_internal.cc4
-rw-r--r--src/cpp/client/create_channel_internal.h4
-rw-r--r--src/cpp/client/create_channel_posix.cc10
-rw-r--r--src/cpp/client/cronet_credentials.cc9
-rw-r--r--src/cpp/client/insecure_credentials.cc9
-rw-r--r--src/cpp/client/secure_credentials.cc9
-rw-r--r--src/cpp/client/secure_credentials.h4
-rw-r--r--src/cpp/common/version_cc.cc2
-rw-r--r--src/cpp/server/server_cc.cc48
-rw-r--r--src/cpp/server/server_context.cc4
-rw-r--r--src/csharp/Grpc.Core.Tests/Internal/AsyncCallServerTest.cs2
-rw-r--r--src/csharp/Grpc.Core.Tests/MarshallerTest.cs7
-rw-r--r--src/csharp/Grpc.Core/DeserializationContext.cs7
-rw-r--r--src/csharp/Grpc.Core/Internal/AsyncCall.cs2
-rw-r--r--src/csharp/Grpc.Core/Internal/AsyncCallBase.cs27
-rw-r--r--src/csharp/Grpc.Core/Internal/AsyncCallServer.cs2
-rw-r--r--src/csharp/Grpc.Core/Internal/DefaultDeserializationContext.cs66
-rw-r--r--src/csharp/Grpc.Core/Internal/DefaultSerializationContext.cs62
-rw-r--r--src/csharp/Grpc.Core/Internal/ServerCallHandler.cs16
-rw-r--r--src/csharp/Grpc.Core/Marshaller.cs67
-rw-r--r--src/csharp/Grpc.Core/SerializationContext.cs7
-rw-r--r--src/csharp/Grpc.Core/ServerServiceDefinition.cs8
-rw-r--r--src/csharp/Grpc.Core/ServiceBinderBase.cs101
-rwxr-xr-xsrc/csharp/Grpc.Core/Version.csproj.include2
-rw-r--r--src/csharp/Grpc.Core/VersionInfo.cs4
-rw-r--r--src/csharp/Grpc.Examples/MathGrpc.cs12
-rw-r--r--src/csharp/Grpc.HealthCheck/Health.cs20
-rw-r--r--src/csharp/Grpc.HealthCheck/HealthGrpc.cs135
-rw-r--r--src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs13
-rw-r--r--src/csharp/Grpc.IntegrationTesting/Control.cs144
-rw-r--r--src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs8
-rw-r--r--src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs10
-rw-r--r--src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs9
-rw-r--r--src/csharp/Grpc.IntegrationTesting/TestGrpc.cs35
-rw-r--r--src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs12
-rw-r--r--src/csharp/Grpc.Reflection/ReflectionGrpc.cs9
-rwxr-xr-xsrc/csharp/build_packages_dotnetcli.bat2
-rw-r--r--src/csharp/build_unitypackage.bat2
-rw-r--r--src/objective-c/!ProtoCompiler-gRPCPlugin.podspec2
-rw-r--r--src/objective-c/GRPCClient/private/version.h2
-rw-r--r--src/objective-c/tests/version.h2
-rw-r--r--src/php/composer.json2
-rw-r--r--src/php/ext/grpc/channel.c2
-rw-r--r--src/php/ext/grpc/channel.h3
-rwxr-xr-xsrc/php/ext/grpc/config.m42
-rw-r--r--src/php/ext/grpc/php_grpc.c122
-rw-r--r--src/php/ext/grpc/version.h2
-rw-r--r--src/proto/grpc/channelz/BUILD7
-rw-r--r--src/proto/grpc/health/v1/BUILD1
-rw-r--r--src/proto/grpc/testing/compiler_test.proto3
-rw-r--r--src/python/grpcio/grpc/BUILD.bazel1
-rw-r--r--src/python/grpcio/grpc/__init__.py41
-rw-r--r--src/python/grpcio/grpc/_channel.py1
-rw-r--r--src/python/grpcio/grpc/_common.py1
-rw-r--r--src/python/grpcio/grpc/_cython/BUILD.bazel1
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/channelz.pyx.pxi69
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi2
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi17
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/grpc_string.pyx.pxi1
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi1
-rw-r--r--src/python/grpcio/grpc/_cython/cygrpc.pyx1
-rw-r--r--src/python/grpcio/grpc/_grpcio_metadata.py2
-rw-r--r--src/python/grpcio/grpc/_interceptor.py8
-rw-r--r--src/python/grpcio/grpc/_plugin_wrapping.py1
-rw-r--r--src/python/grpcio/grpc/beta/BUILD.bazel58
-rw-r--r--src/python/grpcio/grpc/framework/foundation/callable_util.py1
-rw-r--r--src/python/grpcio/grpc/framework/foundation/logging_pool.py1
-rw-r--r--src/python/grpcio/grpc/framework/foundation/stream_util.py1
-rw-r--r--src/python/grpcio/grpc_core_dependencies.py4
-rw-r--r--src/python/grpcio/grpc_version.py2
-rw-r--r--src/python/grpcio_channelz/.gitignore6
-rw-r--r--src/python/grpcio_channelz/MANIFEST.in3
-rw-r--r--src/python/grpcio_channelz/README.rst9
-rw-r--r--src/python/grpcio_channelz/channelz_commands.py63
-rw-r--r--src/python/grpcio_channelz/grpc_channelz/__init__.py13
-rw-r--r--src/python/grpcio_channelz/grpc_channelz/v1/BUILD.bazel38
-rw-r--r--src/python/grpcio_channelz/grpc_channelz/v1/__init__.py13
-rw-r--r--src/python/grpcio_channelz/grpc_channelz/v1/channelz.py141
-rw-r--r--src/python/grpcio_channelz/grpc_version.py17
-rw-r--r--src/python/grpcio_channelz/setup.py96
-rw-r--r--src/python/grpcio_health_checking/grpc_version.py2
-rw-r--r--src/python/grpcio_reflection/grpc_version.py2
-rw-r--r--src/python/grpcio_testing/grpc_version.py2
-rw-r--r--src/python/grpcio_tests/commands.py7
-rw-r--r--src/python/grpcio_tests/grpc_version.py2
-rw-r--r--src/python/grpcio_tests/setup.py1
-rw-r--r--src/python/grpcio_tests/tests/channelz/BUILD.bazel15
-rw-r--r--src/python/grpcio_tests/tests/channelz/__init__.py13
-rw-r--r--src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py494
-rw-r--r--src/python/grpcio_tests/tests/interop/BUILD.bazel4
-rw-r--r--src/python/grpcio_tests/tests/interop/methods.py11
-rw-r--r--src/python/grpcio_tests/tests/tests.json1
-rw-r--r--src/python/grpcio_tests/tests/unit/_credentials_test.py11
-rw-r--r--src/python/grpcio_tests/tests/unit/_logging_test.py7
-rw-r--r--src/python/grpcio_tests/tests/unit/_server_ssl_cert_config_test.py51
-rw-r--r--src/python/grpcio_tests/tests/unit/beta/BUILD.bazel75
-rw-r--r--src/ruby/lib/grpc/generic/service.rb2
-rw-r--r--src/ruby/lib/grpc/version.rb2
-rw-r--r--src/ruby/spec/generic/rpc_server_spec.rb22
-rw-r--r--src/ruby/spec/support/services.rb1
-rw-r--r--src/ruby/tools/version.rb2
-rw-r--r--templates/Makefile.template2
-rw-r--r--templates/config.m4.template3
-rw-r--r--templates/gRPC-C++.podspec.template2
-rw-r--r--templates/src/python/grpcio_channelz/grpc_version.py.template19
-rw-r--r--templates/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile.template14
-rw-r--r--templates/tools/dockerfile/test/multilang_jessie_x64/Dockerfile.template41
-rw-r--r--templates/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile.template3
-rw-r--r--test/core/end2end/fuzzers/hpack.dictionary1
-rw-r--r--test/core/gpr/BUILD2
-rw-r--r--test/core/gprpp/inlined_vector_test.cc164
-rw-r--r--test/core/gprpp/ref_counted_test.cc47
-rw-r--r--test/core/iomgr/BUILD2
-rw-r--r--test/core/iomgr/buffer_list_test.cc4
-rw-r--r--test/core/transport/chttp2/BUILD16
-rw-r--r--test/core/transport/chttp2/context_list_test.cc102
-rw-r--r--test/core/util/mock_endpoint.cc25
-rw-r--r--test/core/util/passthru_endpoint.cc3
-rw-r--r--test/core/util/trickle_endpoint.cc5
-rw-r--r--test/cpp/end2end/client_callback_end2end_test.cc17
-rw-r--r--test/cpp/end2end/client_interceptors_end2end_test.cc108
-rw-r--r--test/cpp/end2end/client_lb_end2end_test.cc24
-rw-r--r--test/cpp/end2end/end2end_test.cc1
-rw-r--r--test/cpp/end2end/grpclb_end2end_test.cc8
-rw-r--r--test/cpp/end2end/interceptors_util.cc11
-rw-r--r--test/cpp/end2end/interceptors_util.h3
-rw-r--r--test/cpp/end2end/server_interceptors_end2end_test.cc3
-rw-r--r--test/cpp/interop/interop_client.cc4
-rw-r--r--test/cpp/interop/stress_interop_client.cc2
-rw-r--r--test/cpp/microbenchmarks/bm_call_create.cc3
-rw-r--r--test/cpp/microbenchmarks/bm_chttp2_transport.cc4
-rw-r--r--test/cpp/microbenchmarks/bm_cq_multiple_threads.cc1
-rw-r--r--test/cpp/microbenchmarks/fullstack_fixtures.h5
-rw-r--r--test/cpp/performance/writes_per_rpc_test.cc5
-rw-r--r--test/cpp/qps/BUILD2
-rw-r--r--test/cpp/qps/driver.cc36
-rw-r--r--test/cpp/qps/driver.h9
-rw-r--r--test/cpp/qps/inproc_sync_unary_ping_pong_test.cc2
-rw-r--r--test/cpp/qps/qps_json_driver.cc111
-rw-r--r--test/cpp/qps/qps_openloop_test.cc2
-rw-r--r--test/cpp/qps/secure_sync_unary_ping_pong_test.cc2
-rw-r--r--test/cpp/util/BUILD1
m---------third_party/data-plane-api0
m---------third_party/googleapis0
m---------third_party/protoc-gen-validate0
-rw-r--r--third_party/toolchains/BUILD51
-rw-r--r--third_party/toolchains/RBE_USE_MACHINE_TYPE_LARGE1
-rw-r--r--third_party/toolchains/machine_size/BUILD31
m---------third_party/upb0
-rw-r--r--tools/bazel.rc8
-rwxr-xr-xtools/codegen/core/gen_static_metadata.py1
-rwxr-xr-xtools/distrib/pylint_code.sh1
-rwxr-xr-xtools/distrib/python/docgen.py39
-rw-r--r--tools/distrib/python/grpcio_tools/grpc_version.py2
-rw-r--r--tools/dockerfile/interoptest/grpc_interop_python/Dockerfile33
-rwxr-xr-xtools/dockerfile/interoptest/grpc_interop_python/build_interop.sh4
-rw-r--r--tools/dockerfile/test/multilang_jessie_x64/Dockerfile170
-rw-r--r--tools/dockerfile/test/python_alpine_x64/Dockerfile8
-rw-r--r--tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile3
-rw-r--r--tools/doxygen/Doxyfile.c++3
-rw-r--r--tools/doxygen/Doxyfile.c++.internal3
-rw-r--r--tools/doxygen/Doxyfile.core1
-rw-r--r--tools/doxygen/Doxyfile.core.internal9
-rw-r--r--tools/internal_ci/helper_scripts/prepare_build_macos_rc11
-rw-r--r--tools/internal_ci/linux/grpc_bazel_on_foundry_dbg.sh2
-rw-r--r--tools/internal_ci/linux/grpc_bazel_on_foundry_opt.sh2
-rwxr-xr-xtools/internal_ci/linux/grpc_coverage.sh20
-rwxr-xr-xtools/internal_ci/linux/grpc_python_bazel_test_in_docker.sh2
-rw-r--r--tools/internal_ci/linux/pull_request/grpc_bazel_on_foundry_dbg.sh2
-rw-r--r--tools/internal_ci/linux/pull_request/grpc_bazel_on_foundry_opt.sh2
-rw-r--r--[-rwxr-xr-x]tools/internal_ci/linux/pull_request/grpc_msan_on_foundry.sh (renamed from tools/run_tests/helper_scripts/run_lcov.sh)19
-rw-r--r--tools/remote_build/README.md4
-rw-r--r--tools/remote_build/rbe_common.bazelrc19
-rw-r--r--tools/run_tests/artifacts/artifact_targets.py2
-rwxr-xr-xtools/run_tests/artifacts/build_artifact_python.sh8
-rwxr-xr-xtools/run_tests/dockerize/build_docker_and_run_tests.sh5
-rwxr-xr-xtools/run_tests/dockerize/build_interop_image.sh4
-rwxr-xr-xtools/run_tests/dockerize/docker_run_tests.sh12
-rw-r--r--tools/run_tests/generated/sources_and_headers.json29
-rw-r--r--tools/run_tests/generated/tests.json26
-rwxr-xr-xtools/run_tests/helper_scripts/build_python.sh23
-rwxr-xr-xtools/run_tests/run_interop_tests.py6
-rwxr-xr-xtools/run_tests/run_tests.py24
-rwxr-xr-xtools/run_tests/sanity/check_bazel_workspace.py1
-rwxr-xr-xtools/run_tests/sanity/check_submodules.sh4
-rwxr-xr-xtools/run_tests/sanity/core_banned_functions.py1
311 files changed, 6576 insertions, 2399 deletions
diff --git a/.gitmodules b/.gitmodules
index afde4d34f3..06f1394df6 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -42,3 +42,15 @@
path = third_party/libcxx
url = https://github.com/llvm-mirror/libcxx.git
branch = release_60
+[submodule "third_party/data-plane-api"]
+ path = third_party/data-plane-api
+ url = https://github.com/envoyproxy/data-plane-api.git
+[submodule "third_party/googleapis"]
+ path = third_party/googleapis
+ url = https://github.com/googleapis/googleapis.git
+[submodule "third_party/protoc-gen-validate"]
+ path = third_party/protoc-gen-validate
+ url = https://github.com/lyft/protoc-gen-validate.git
+[submodule "third_party/upb"]
+ path = third_party/upb
+ url = https://github.com/google/upb.git
diff --git a/AUTHORS b/AUTHORS
index 3e130afda2..0e8797391f 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,2 +1,3 @@
+Dropbox, Inc.
Google Inc.
WeWork Companies Inc.
diff --git a/BUILD b/BUILD
index e86e48c7e3..9a2c16c601 100644
--- a/BUILD
+++ b/BUILD
@@ -64,11 +64,11 @@ config_setting(
)
# This should be updated along with build.yaml
-g_stands_for = "gizmo"
+g_stands_for = "goose"
-core_version = "6.0.0-dev"
+core_version = "7.0.0-dev"
-version = "1.17.0-dev"
+version = "1.18.0-dev"
GPR_PUBLIC_HDRS = [
"include/grpc/support/alloc.h",
@@ -647,6 +647,7 @@ grpc_cc_library(
"debug_location",
"gpr_base",
"grpc_trace",
+ "ref_counted",
"ref_counted_ptr",
],
)
@@ -1048,12 +1049,12 @@ grpc_cc_library(
"src/core/ext/filters/client_channel/lb_policy.cc",
"src/core/ext/filters/client_channel/lb_policy_factory.cc",
"src/core/ext/filters/client_channel/lb_policy_registry.cc",
- "src/core/ext/filters/client_channel/method_params.cc",
"src/core/ext/filters/client_channel/parse_address.cc",
"src/core/ext/filters/client_channel/proxy_mapper.cc",
"src/core/ext/filters/client_channel/proxy_mapper_registry.cc",
"src/core/ext/filters/client_channel/resolver.cc",
"src/core/ext/filters/client_channel/resolver_registry.cc",
+ "src/core/ext/filters/client_channel/resolver_result_parsing.cc",
"src/core/ext/filters/client_channel/retry_throttle.cc",
"src/core/ext/filters/client_channel/subchannel.cc",
"src/core/ext/filters/client_channel/subchannel_index.cc",
@@ -1070,13 +1071,13 @@ grpc_cc_library(
"src/core/ext/filters/client_channel/lb_policy.h",
"src/core/ext/filters/client_channel/lb_policy_factory.h",
"src/core/ext/filters/client_channel/lb_policy_registry.h",
- "src/core/ext/filters/client_channel/method_params.h",
"src/core/ext/filters/client_channel/parse_address.h",
"src/core/ext/filters/client_channel/proxy_mapper.h",
"src/core/ext/filters/client_channel/proxy_mapper_registry.h",
"src/core/ext/filters/client_channel/resolver.h",
"src/core/ext/filters/client_channel/resolver_factory.h",
"src/core/ext/filters/client_channel/resolver_registry.h",
+ "src/core/ext/filters/client_channel/resolver_result_parsing.h",
"src/core/ext/filters/client_channel/retry_throttle.h",
"src/core/ext/filters/client_channel/subchannel.h",
"src/core/ext/filters/client_channel/subchannel_index.h",
@@ -1650,6 +1651,7 @@ grpc_cc_library(
"src/core/ext/transport/chttp2/transport/bin_encoder.cc",
"src/core/ext/transport/chttp2/transport/chttp2_plugin.cc",
"src/core/ext/transport/chttp2/transport/chttp2_transport.cc",
+ "src/core/ext/transport/chttp2/transport/context_list.cc",
"src/core/ext/transport/chttp2/transport/flow_control.cc",
"src/core/ext/transport/chttp2/transport/frame_data.cc",
"src/core/ext/transport/chttp2/transport/frame_goaway.cc",
@@ -1673,6 +1675,7 @@ grpc_cc_library(
"src/core/ext/transport/chttp2/transport/bin_decoder.h",
"src/core/ext/transport/chttp2/transport/bin_encoder.h",
"src/core/ext/transport/chttp2/transport/chttp2_transport.h",
+ "src/core/ext/transport/chttp2/transport/context_list.h",
"src/core/ext/transport/chttp2/transport/flow_control.h",
"src/core/ext/transport/chttp2/transport/frame.h",
"src/core/ext/transport/chttp2/transport/frame_data.h",
@@ -1962,7 +1965,6 @@ grpc_cc_library(
"src/core/tsi/alts/handshaker/alts_shared_resource.cc",
"src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc",
"src/core/tsi/alts/handshaker/alts_tsi_utils.cc",
- "src/core/tsi/alts_transport_security.cc",
"src/core/tsi/fake_transport_security.cc",
"src/core/tsi/local_transport_security.cc",
"src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc",
@@ -1977,7 +1979,6 @@ grpc_cc_library(
"src/core/tsi/alts/handshaker/alts_tsi_handshaker.h",
"src/core/tsi/alts/handshaker/alts_tsi_handshaker_private.h",
"src/core/tsi/alts/handshaker/alts_tsi_utils.h",
- "src/core/tsi/alts_transport_security.h",
"src/core/tsi/fake_transport_security.h",
"src/core/tsi/local_transport_security.h",
"src/core/tsi/ssl/session_cache/ssl_session.h",
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 56c9c6a02f..23b4bb77e7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -24,7 +24,7 @@
cmake_minimum_required(VERSION 2.8)
set(PACKAGE_NAME "grpc")
-set(PACKAGE_VERSION "1.17.0-dev")
+set(PACKAGE_VERSION "1.18.0-dev")
set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")
set(PACKAGE_TARNAME "${PACKAGE_NAME}-${PACKAGE_VERSION}")
set(PACKAGE_BUGREPORT "https://github.com/grpc/grpc/issues/")
@@ -588,6 +588,7 @@ add_dependencies(buildtests_cxx client_interceptors_end2end_test)
add_dependencies(buildtests_cxx client_lb_end2end_test)
add_dependencies(buildtests_cxx codegen_test_full)
add_dependencies(buildtests_cxx codegen_test_minimal)
+add_dependencies(buildtests_cxx context_list_test)
add_dependencies(buildtests_cxx credentials_test)
add_dependencies(buildtests_cxx cxx_byte_buffer_test)
add_dependencies(buildtests_cxx cxx_slice_test)
@@ -1132,6 +1133,7 @@ add_library(grpc
src/core/ext/transport/chttp2/transport/bin_encoder.cc
src/core/ext/transport/chttp2/transport/chttp2_plugin.cc
src/core/ext/transport/chttp2/transport/chttp2_transport.cc
+ src/core/ext/transport/chttp2/transport/context_list.cc
src/core/ext/transport/chttp2/transport/flow_control.cc
src/core/ext/transport/chttp2/transport/frame_data.cc
src/core/ext/transport/chttp2/transport/frame_goaway.cc
@@ -1240,18 +1242,17 @@ add_library(grpc
src/core/ext/filters/client_channel/lb_policy.cc
src/core/ext/filters/client_channel/lb_policy_factory.cc
src/core/ext/filters/client_channel/lb_policy_registry.cc
- src/core/ext/filters/client_channel/method_params.cc
src/core/ext/filters/client_channel/parse_address.cc
src/core/ext/filters/client_channel/proxy_mapper.cc
src/core/ext/filters/client_channel/proxy_mapper_registry.cc
src/core/ext/filters/client_channel/resolver.cc
src/core/ext/filters/client_channel/resolver_registry.cc
+ src/core/ext/filters/client_channel/resolver_result_parsing.cc
src/core/ext/filters/client_channel/retry_throttle.cc
src/core/ext/filters/client_channel/subchannel.cc
src/core/ext/filters/client_channel/subchannel_index.cc
src/core/ext/filters/deadline/deadline_filter.cc
src/core/ext/filters/client_channel/health/health.pb.c
- src/core/tsi/alts_transport_security.cc
src/core/tsi/fake_transport_security.cc
src/core/tsi/local_transport_security.cc
src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc
@@ -1556,6 +1557,7 @@ add_library(grpc_cronet
src/core/ext/transport/chttp2/transport/bin_encoder.cc
src/core/ext/transport/chttp2/transport/chttp2_plugin.cc
src/core/ext/transport/chttp2/transport/chttp2_transport.cc
+ src/core/ext/transport/chttp2/transport/context_list.cc
src/core/ext/transport/chttp2/transport/flow_control.cc
src/core/ext/transport/chttp2/transport/frame_data.cc
src/core/ext/transport/chttp2/transport/frame_goaway.cc
@@ -1592,12 +1594,12 @@ add_library(grpc_cronet
src/core/ext/filters/client_channel/lb_policy.cc
src/core/ext/filters/client_channel/lb_policy_factory.cc
src/core/ext/filters/client_channel/lb_policy_registry.cc
- src/core/ext/filters/client_channel/method_params.cc
src/core/ext/filters/client_channel/parse_address.cc
src/core/ext/filters/client_channel/proxy_mapper.cc
src/core/ext/filters/client_channel/proxy_mapper_registry.cc
src/core/ext/filters/client_channel/resolver.cc
src/core/ext/filters/client_channel/resolver_registry.cc
+ src/core/ext/filters/client_channel/resolver_result_parsing.cc
src/core/ext/filters/client_channel/retry_throttle.cc
src/core/ext/filters/client_channel/subchannel.cc
src/core/ext/filters/client_channel/subchannel_index.cc
@@ -1675,7 +1677,6 @@ add_library(grpc_cronet
src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc
src/core/ext/transport/chttp2/client/authority.cc
src/core/ext/transport/chttp2/client/chttp2_connector.cc
- src/core/tsi/alts_transport_security.cc
src/core/tsi/fake_transport_security.cc
src/core/tsi/local_transport_security.cc
src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc
@@ -1964,12 +1965,12 @@ add_library(grpc_test_util
src/core/ext/filters/client_channel/lb_policy.cc
src/core/ext/filters/client_channel/lb_policy_factory.cc
src/core/ext/filters/client_channel/lb_policy_registry.cc
- src/core/ext/filters/client_channel/method_params.cc
src/core/ext/filters/client_channel/parse_address.cc
src/core/ext/filters/client_channel/proxy_mapper.cc
src/core/ext/filters/client_channel/proxy_mapper_registry.cc
src/core/ext/filters/client_channel/resolver.cc
src/core/ext/filters/client_channel/resolver_registry.cc
+ src/core/ext/filters/client_channel/resolver_result_parsing.cc
src/core/ext/filters/client_channel/retry_throttle.cc
src/core/ext/filters/client_channel/subchannel.cc
src/core/ext/filters/client_channel/subchannel_index.cc
@@ -1982,6 +1983,7 @@ add_library(grpc_test_util
src/core/ext/transport/chttp2/transport/bin_encoder.cc
src/core/ext/transport/chttp2/transport/chttp2_plugin.cc
src/core/ext/transport/chttp2/transport/chttp2_transport.cc
+ src/core/ext/transport/chttp2/transport/context_list.cc
src/core/ext/transport/chttp2/transport/flow_control.cc
src/core/ext/transport/chttp2/transport/frame_data.cc
src/core/ext/transport/chttp2/transport/frame_goaway.cc
@@ -2283,12 +2285,12 @@ add_library(grpc_test_util_unsecure
src/core/ext/filters/client_channel/lb_policy.cc
src/core/ext/filters/client_channel/lb_policy_factory.cc
src/core/ext/filters/client_channel/lb_policy_registry.cc
- src/core/ext/filters/client_channel/method_params.cc
src/core/ext/filters/client_channel/parse_address.cc
src/core/ext/filters/client_channel/proxy_mapper.cc
src/core/ext/filters/client_channel/proxy_mapper_registry.cc
src/core/ext/filters/client_channel/resolver.cc
src/core/ext/filters/client_channel/resolver_registry.cc
+ src/core/ext/filters/client_channel/resolver_result_parsing.cc
src/core/ext/filters/client_channel/retry_throttle.cc
src/core/ext/filters/client_channel/subchannel.cc
src/core/ext/filters/client_channel/subchannel_index.cc
@@ -2301,6 +2303,7 @@ add_library(grpc_test_util_unsecure
src/core/ext/transport/chttp2/transport/bin_encoder.cc
src/core/ext/transport/chttp2/transport/chttp2_plugin.cc
src/core/ext/transport/chttp2/transport/chttp2_transport.cc
+ src/core/ext/transport/chttp2/transport/context_list.cc
src/core/ext/transport/chttp2/transport/flow_control.cc
src/core/ext/transport/chttp2/transport/frame_data.cc
src/core/ext/transport/chttp2/transport/frame_goaway.cc
@@ -2574,6 +2577,7 @@ add_library(grpc_unsecure
src/core/ext/transport/chttp2/transport/bin_encoder.cc
src/core/ext/transport/chttp2/transport/chttp2_plugin.cc
src/core/ext/transport/chttp2/transport/chttp2_transport.cc
+ src/core/ext/transport/chttp2/transport/context_list.cc
src/core/ext/transport/chttp2/transport/flow_control.cc
src/core/ext/transport/chttp2/transport/frame_data.cc
src/core/ext/transport/chttp2/transport/frame_goaway.cc
@@ -2615,12 +2619,12 @@ add_library(grpc_unsecure
src/core/ext/filters/client_channel/lb_policy.cc
src/core/ext/filters/client_channel/lb_policy_factory.cc
src/core/ext/filters/client_channel/lb_policy_registry.cc
- src/core/ext/filters/client_channel/method_params.cc
src/core/ext/filters/client_channel/parse_address.cc
src/core/ext/filters/client_channel/proxy_mapper.cc
src/core/ext/filters/client_channel/proxy_mapper_registry.cc
src/core/ext/filters/client_channel/resolver.cc
src/core/ext/filters/client_channel/resolver_registry.cc
+ src/core/ext/filters/client_channel/resolver_result_parsing.cc
src/core/ext/filters/client_channel/retry_throttle.cc
src/core/ext/filters/client_channel/subchannel.cc
src/core/ext/filters/client_channel/subchannel_index.cc
@@ -3278,6 +3282,7 @@ add_library(grpc++_cronet
src/core/ext/transport/chttp2/transport/bin_encoder.cc
src/core/ext/transport/chttp2/transport/chttp2_plugin.cc
src/core/ext/transport/chttp2/transport/chttp2_transport.cc
+ src/core/ext/transport/chttp2/transport/context_list.cc
src/core/ext/transport/chttp2/transport/flow_control.cc
src/core/ext/transport/chttp2/transport/frame_data.cc
src/core/ext/transport/chttp2/transport/frame_goaway.cc
@@ -3466,12 +3471,12 @@ add_library(grpc++_cronet
src/core/ext/filters/client_channel/lb_policy.cc
src/core/ext/filters/client_channel/lb_policy_factory.cc
src/core/ext/filters/client_channel/lb_policy_registry.cc
- src/core/ext/filters/client_channel/method_params.cc
src/core/ext/filters/client_channel/parse_address.cc
src/core/ext/filters/client_channel/proxy_mapper.cc
src/core/ext/filters/client_channel/proxy_mapper_registry.cc
src/core/ext/filters/client_channel/resolver.cc
src/core/ext/filters/client_channel/resolver_registry.cc
+ src/core/ext/filters/client_channel/resolver_result_parsing.cc
src/core/ext/filters/client_channel/retry_throttle.cc
src/core/ext/filters/client_channel/subchannel.cc
src/core/ext/filters/client_channel/subchannel_index.cc
@@ -12703,6 +12708,45 @@ target_link_libraries(codegen_test_minimal
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
+add_executable(context_list_test
+ test/core/transport/chttp2/context_list_test.cc
+ third_party/googletest/googletest/src/gtest-all.cc
+ third_party/googletest/googlemock/src/gmock-all.cc
+)
+
+
+target_include_directories(context_list_test
+ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include
+ PRIVATE ${_gRPC_SSL_INCLUDE_DIR}
+ PRIVATE ${_gRPC_PROTOBUF_INCLUDE_DIR}
+ PRIVATE ${_gRPC_ZLIB_INCLUDE_DIR}
+ PRIVATE ${_gRPC_BENCHMARK_INCLUDE_DIR}
+ PRIVATE ${_gRPC_CARES_INCLUDE_DIR}
+ PRIVATE ${_gRPC_GFLAGS_INCLUDE_DIR}
+ PRIVATE ${_gRPC_ADDRESS_SORTING_INCLUDE_DIR}
+ PRIVATE ${_gRPC_NANOPB_INCLUDE_DIR}
+ PRIVATE third_party/googletest/googletest/include
+ PRIVATE third_party/googletest/googletest
+ PRIVATE third_party/googletest/googlemock/include
+ PRIVATE third_party/googletest/googlemock
+ PRIVATE ${_gRPC_PROTO_GENS_DIR}
+)
+
+target_link_libraries(context_list_test
+ ${_gRPC_PROTOBUF_LIBRARIES}
+ ${_gRPC_ALLTARGETS_LIBRARIES}
+ grpc_test_util
+ grpc
+ gpr_test_util
+ gpr
+ ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
add_executable(credentials_test
test/cpp/client/credentials_test.cc
third_party/googletest/googletest/src/gtest-all.cc
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index e8582d9af5..1d14d5e0e3 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -81,7 +81,7 @@ How to get your contributions merged smoothly and quickly.
copyright holder for the contribution (yourself, if you are signing the
individual CLA, or your company, for corporate CLAs) in the same PR as your
contribution. This needs to be done only once, for each company, or
- individual.
+ individual. Please keep this file in alphabetical order.
- Maintain **clean commit history** and use **meaningful commit messages**.
PRs with messy commit history are difficult to review and won't be merged.
diff --git a/Makefile b/Makefile
index ca881ab0e1..4f7cd13012 100644
--- a/Makefile
+++ b/Makefile
@@ -438,8 +438,8 @@ Q = @
endif
CORE_VERSION = 7.0.0-dev
-CPP_VERSION = 1.17.0-dev
-CSHARP_VERSION = 1.17.0-dev
+CPP_VERSION = 1.18.0-dev
+CSHARP_VERSION = 1.18.0-dev
CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES))
CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS)
@@ -1168,6 +1168,7 @@ client_interceptors_end2end_test: $(BINDIR)/$(CONFIG)/client_interceptors_end2en
client_lb_end2end_test: $(BINDIR)/$(CONFIG)/client_lb_end2end_test
codegen_test_full: $(BINDIR)/$(CONFIG)/codegen_test_full
codegen_test_minimal: $(BINDIR)/$(CONFIG)/codegen_test_minimal
+context_list_test: $(BINDIR)/$(CONFIG)/context_list_test
credentials_test: $(BINDIR)/$(CONFIG)/credentials_test
cxx_byte_buffer_test: $(BINDIR)/$(CONFIG)/cxx_byte_buffer_test
cxx_slice_test: $(BINDIR)/$(CONFIG)/cxx_slice_test
@@ -1673,6 +1674,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/client_lb_end2end_test \
$(BINDIR)/$(CONFIG)/codegen_test_full \
$(BINDIR)/$(CONFIG)/codegen_test_minimal \
+ $(BINDIR)/$(CONFIG)/context_list_test \
$(BINDIR)/$(CONFIG)/credentials_test \
$(BINDIR)/$(CONFIG)/cxx_byte_buffer_test \
$(BINDIR)/$(CONFIG)/cxx_slice_test \
@@ -1856,6 +1858,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/client_lb_end2end_test \
$(BINDIR)/$(CONFIG)/codegen_test_full \
$(BINDIR)/$(CONFIG)/codegen_test_minimal \
+ $(BINDIR)/$(CONFIG)/context_list_test \
$(BINDIR)/$(CONFIG)/credentials_test \
$(BINDIR)/$(CONFIG)/cxx_byte_buffer_test \
$(BINDIR)/$(CONFIG)/cxx_slice_test \
@@ -2320,6 +2323,8 @@ test_cxx: buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/codegen_test_full || ( echo test codegen_test_full failed ; exit 1 )
$(E) "[RUN] Testing codegen_test_minimal"
$(Q) $(BINDIR)/$(CONFIG)/codegen_test_minimal || ( echo test codegen_test_minimal failed ; exit 1 )
+ $(E) "[RUN] Testing context_list_test"
+ $(Q) $(BINDIR)/$(CONFIG)/context_list_test || ( echo test context_list_test failed ; exit 1 )
$(E) "[RUN] Testing credentials_test"
$(Q) $(BINDIR)/$(CONFIG)/credentials_test || ( echo test credentials_test failed ; exit 1 )
$(E) "[RUN] Testing cxx_byte_buffer_test"
@@ -3064,7 +3069,7 @@ install-shared_cxx: shared_cxx strip-shared_cxx install-shared_c install-pkg-con
ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++$(SHARED_VERSION_CPP)-dll.a $(prefix)/lib/libgrpc++.a
else ifneq ($(SYSTEM),Darwin)
- $(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++.so.7
+ $(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++.so.1
$(Q) ln -sf $(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++.so
endif
$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)"
@@ -3073,7 +3078,7 @@ endif
ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_cronet$(SHARED_VERSION_CPP)-dll.a $(prefix)/lib/libgrpc++_cronet.a
else ifneq ($(SYSTEM),Darwin)
- $(Q) ln -sf $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_cronet.so.7
+ $(Q) ln -sf $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_cronet.so.1
$(Q) ln -sf $(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_cronet.so
endif
$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)"
@@ -3082,7 +3087,7 @@ endif
ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_error_details$(SHARED_VERSION_CPP)-dll.a $(prefix)/lib/libgrpc++_error_details.a
else ifneq ($(SYSTEM),Darwin)
- $(Q) ln -sf $(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_error_details.so.7
+ $(Q) ln -sf $(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_error_details.so.1
$(Q) ln -sf $(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_error_details.so
endif
$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)"
@@ -3091,7 +3096,7 @@ endif
ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection$(SHARED_VERSION_CPP)-dll.a $(prefix)/lib/libgrpc++_reflection.a
else ifneq ($(SYSTEM),Darwin)
- $(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_reflection.so.7
+ $(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_reflection.so.1
$(Q) ln -sf $(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_reflection.so
endif
$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)"
@@ -3100,7 +3105,7 @@ endif
ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure$(SHARED_VERSION_CPP)-dll.a $(prefix)/lib/libgrpc++_unsecure.a
else ifneq ($(SYSTEM),Darwin)
- $(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_unsecure.so.7
+ $(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_unsecure.so.1
$(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_unsecure.so
endif
$(E) "[INSTALL] Installing $(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)"
@@ -3109,7 +3114,7 @@ endif
ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz$(SHARED_VERSION_CPP)-dll.a $(prefix)/lib/libgrpcpp_channelz.a
else ifneq ($(SYSTEM),Darwin)
- $(Q) ln -sf $(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpcpp_channelz.so.7
+ $(Q) ln -sf $(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpcpp_channelz.so.1
$(Q) ln -sf $(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpcpp_channelz.so
endif
ifneq ($(SYSTEM),MINGW32)
@@ -3126,7 +3131,7 @@ install-shared_csharp: shared_csharp strip-shared_csharp
ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext$(SHARED_VERSION_CSHARP)-dll.a $(prefix)/lib/libgrpc_csharp_ext.a
else ifneq ($(SYSTEM),Darwin)
- $(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(prefix)/lib/libgrpc_csharp_ext.so.7
+ $(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(prefix)/lib/libgrpc_csharp_ext.so.1
$(Q) ln -sf $(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP) $(prefix)/lib/libgrpc_csharp_ext.so
endif
ifneq ($(SYSTEM),MINGW32)
@@ -3607,6 +3612,7 @@ LIBGRPC_SRC = \
src/core/ext/transport/chttp2/transport/bin_encoder.cc \
src/core/ext/transport/chttp2/transport/chttp2_plugin.cc \
src/core/ext/transport/chttp2/transport/chttp2_transport.cc \
+ src/core/ext/transport/chttp2/transport/context_list.cc \
src/core/ext/transport/chttp2/transport/flow_control.cc \
src/core/ext/transport/chttp2/transport/frame_data.cc \
src/core/ext/transport/chttp2/transport/frame_goaway.cc \
@@ -3715,18 +3721,17 @@ LIBGRPC_SRC = \
src/core/ext/filters/client_channel/lb_policy.cc \
src/core/ext/filters/client_channel/lb_policy_factory.cc \
src/core/ext/filters/client_channel/lb_policy_registry.cc \
- src/core/ext/filters/client_channel/method_params.cc \
src/core/ext/filters/client_channel/parse_address.cc \
src/core/ext/filters/client_channel/proxy_mapper.cc \
src/core/ext/filters/client_channel/proxy_mapper_registry.cc \
src/core/ext/filters/client_channel/resolver.cc \
src/core/ext/filters/client_channel/resolver_registry.cc \
+ src/core/ext/filters/client_channel/resolver_result_parsing.cc \
src/core/ext/filters/client_channel/retry_throttle.cc \
src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel_index.cc \
src/core/ext/filters/deadline/deadline_filter.cc \
src/core/ext/filters/client_channel/health/health.pb.c \
- src/core/tsi/alts_transport_security.cc \
src/core/tsi/fake_transport_security.cc \
src/core/tsi/local_transport_security.cc \
src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc \
@@ -4025,6 +4030,7 @@ LIBGRPC_CRONET_SRC = \
src/core/ext/transport/chttp2/transport/bin_encoder.cc \
src/core/ext/transport/chttp2/transport/chttp2_plugin.cc \
src/core/ext/transport/chttp2/transport/chttp2_transport.cc \
+ src/core/ext/transport/chttp2/transport/context_list.cc \
src/core/ext/transport/chttp2/transport/flow_control.cc \
src/core/ext/transport/chttp2/transport/frame_data.cc \
src/core/ext/transport/chttp2/transport/frame_goaway.cc \
@@ -4061,12 +4067,12 @@ LIBGRPC_CRONET_SRC = \
src/core/ext/filters/client_channel/lb_policy.cc \
src/core/ext/filters/client_channel/lb_policy_factory.cc \
src/core/ext/filters/client_channel/lb_policy_registry.cc \
- src/core/ext/filters/client_channel/method_params.cc \
src/core/ext/filters/client_channel/parse_address.cc \
src/core/ext/filters/client_channel/proxy_mapper.cc \
src/core/ext/filters/client_channel/proxy_mapper_registry.cc \
src/core/ext/filters/client_channel/resolver.cc \
src/core/ext/filters/client_channel/resolver_registry.cc \
+ src/core/ext/filters/client_channel/resolver_result_parsing.cc \
src/core/ext/filters/client_channel/retry_throttle.cc \
src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel_index.cc \
@@ -4144,7 +4150,6 @@ LIBGRPC_CRONET_SRC = \
src/core/ext/transport/chttp2/client/insecure/channel_create_posix.cc \
src/core/ext/transport/chttp2/client/authority.cc \
src/core/ext/transport/chttp2/client/chttp2_connector.cc \
- src/core/tsi/alts_transport_security.cc \
src/core/tsi/fake_transport_security.cc \
src/core/tsi/local_transport_security.cc \
src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc \
@@ -4426,12 +4431,12 @@ LIBGRPC_TEST_UTIL_SRC = \
src/core/ext/filters/client_channel/lb_policy.cc \
src/core/ext/filters/client_channel/lb_policy_factory.cc \
src/core/ext/filters/client_channel/lb_policy_registry.cc \
- src/core/ext/filters/client_channel/method_params.cc \
src/core/ext/filters/client_channel/parse_address.cc \
src/core/ext/filters/client_channel/proxy_mapper.cc \
src/core/ext/filters/client_channel/proxy_mapper_registry.cc \
src/core/ext/filters/client_channel/resolver.cc \
src/core/ext/filters/client_channel/resolver_registry.cc \
+ src/core/ext/filters/client_channel/resolver_result_parsing.cc \
src/core/ext/filters/client_channel/retry_throttle.cc \
src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel_index.cc \
@@ -4444,6 +4449,7 @@ LIBGRPC_TEST_UTIL_SRC = \
src/core/ext/transport/chttp2/transport/bin_encoder.cc \
src/core/ext/transport/chttp2/transport/chttp2_plugin.cc \
src/core/ext/transport/chttp2/transport/chttp2_transport.cc \
+ src/core/ext/transport/chttp2/transport/context_list.cc \
src/core/ext/transport/chttp2/transport/flow_control.cc \
src/core/ext/transport/chttp2/transport/frame_data.cc \
src/core/ext/transport/chttp2/transport/frame_goaway.cc \
@@ -4731,12 +4737,12 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \
src/core/ext/filters/client_channel/lb_policy.cc \
src/core/ext/filters/client_channel/lb_policy_factory.cc \
src/core/ext/filters/client_channel/lb_policy_registry.cc \
- src/core/ext/filters/client_channel/method_params.cc \
src/core/ext/filters/client_channel/parse_address.cc \
src/core/ext/filters/client_channel/proxy_mapper.cc \
src/core/ext/filters/client_channel/proxy_mapper_registry.cc \
src/core/ext/filters/client_channel/resolver.cc \
src/core/ext/filters/client_channel/resolver_registry.cc \
+ src/core/ext/filters/client_channel/resolver_result_parsing.cc \
src/core/ext/filters/client_channel/retry_throttle.cc \
src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel_index.cc \
@@ -4749,6 +4755,7 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \
src/core/ext/transport/chttp2/transport/bin_encoder.cc \
src/core/ext/transport/chttp2/transport/chttp2_plugin.cc \
src/core/ext/transport/chttp2/transport/chttp2_transport.cc \
+ src/core/ext/transport/chttp2/transport/context_list.cc \
src/core/ext/transport/chttp2/transport/flow_control.cc \
src/core/ext/transport/chttp2/transport/frame_data.cc \
src/core/ext/transport/chttp2/transport/frame_goaway.cc \
@@ -4995,6 +5002,7 @@ LIBGRPC_UNSECURE_SRC = \
src/core/ext/transport/chttp2/transport/bin_encoder.cc \
src/core/ext/transport/chttp2/transport/chttp2_plugin.cc \
src/core/ext/transport/chttp2/transport/chttp2_transport.cc \
+ src/core/ext/transport/chttp2/transport/context_list.cc \
src/core/ext/transport/chttp2/transport/flow_control.cc \
src/core/ext/transport/chttp2/transport/frame_data.cc \
src/core/ext/transport/chttp2/transport/frame_goaway.cc \
@@ -5036,12 +5044,12 @@ LIBGRPC_UNSECURE_SRC = \
src/core/ext/filters/client_channel/lb_policy.cc \
src/core/ext/filters/client_channel/lb_policy_factory.cc \
src/core/ext/filters/client_channel/lb_policy_registry.cc \
- src/core/ext/filters/client_channel/method_params.cc \
src/core/ext/filters/client_channel/parse_address.cc \
src/core/ext/filters/client_channel/proxy_mapper.cc \
src/core/ext/filters/client_channel/proxy_mapper_registry.cc \
src/core/ext/filters/client_channel/resolver.cc \
src/core/ext/filters/client_channel/resolver_registry.cc \
+ src/core/ext/filters/client_channel/resolver_result_parsing.cc \
src/core/ext/filters/client_channel/retry_throttle.cc \
src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel_index.cc \
@@ -5674,6 +5682,7 @@ LIBGRPC++_CRONET_SRC = \
src/core/ext/transport/chttp2/transport/bin_encoder.cc \
src/core/ext/transport/chttp2/transport/chttp2_plugin.cc \
src/core/ext/transport/chttp2/transport/chttp2_transport.cc \
+ src/core/ext/transport/chttp2/transport/context_list.cc \
src/core/ext/transport/chttp2/transport/flow_control.cc \
src/core/ext/transport/chttp2/transport/frame_data.cc \
src/core/ext/transport/chttp2/transport/frame_goaway.cc \
@@ -5862,12 +5871,12 @@ LIBGRPC++_CRONET_SRC = \
src/core/ext/filters/client_channel/lb_policy.cc \
src/core/ext/filters/client_channel/lb_policy_factory.cc \
src/core/ext/filters/client_channel/lb_policy_registry.cc \
- src/core/ext/filters/client_channel/method_params.cc \
src/core/ext/filters/client_channel/parse_address.cc \
src/core/ext/filters/client_channel/proxy_mapper.cc \
src/core/ext/filters/client_channel/proxy_mapper_registry.cc \
src/core/ext/filters/client_channel/resolver.cc \
src/core/ext/filters/client_channel/resolver_registry.cc \
+ src/core/ext/filters/client_channel/resolver_result_parsing.cc \
src/core/ext/filters/client_channel/retry_throttle.cc \
src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel_index.cc \
@@ -17550,6 +17559,49 @@ $(OBJDIR)/$(CONFIG)/test/cpp/codegen/codegen_test_minimal.o: $(GENDIR)/src/proto
$(OBJDIR)/$(CONFIG)/src/cpp/codegen/codegen_init.o: $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.pb.cc $(GENDIR)/src/proto/grpc/testing/payloads.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.pb.cc $(GENDIR)/src/proto/grpc/testing/benchmark_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.pb.cc $(GENDIR)/src/proto/grpc/testing/report_qps_scenario_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.pb.cc $(GENDIR)/src/proto/grpc/testing/worker_service.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc
+CONTEXT_LIST_TEST_SRC = \
+ test/core/transport/chttp2/context_list_test.cc \
+
+CONTEXT_LIST_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CONTEXT_LIST_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/context_list_test: openssl_dep_error
+
+else
+
+
+
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.5.0+.
+
+$(BINDIR)/$(CONFIG)/context_list_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/context_list_test: $(PROTOBUF_DEP) $(CONTEXT_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+ $(E) "[LD] Linking $@"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(LDXX) $(LDFLAGS) $(CONTEXT_LIST_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/context_list_test
+
+endif
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/transport/chttp2/context_list_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_context_list_test: $(CONTEXT_LIST_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(CONTEXT_LIST_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
CREDENTIALS_TEST_SRC = \
test/cpp/client/credentials_test.cc \
@@ -25037,7 +25089,6 @@ src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_privacy_integrity_record_p
src/core/tsi/alts/zero_copy_frame_protector/alts_grpc_record_protocol_common.cc: $(OPENSSL_DEP)
src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.cc: $(OPENSSL_DEP)
src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc: $(OPENSSL_DEP)
-src/core/tsi/alts_transport_security.cc: $(OPENSSL_DEP)
src/core/tsi/fake_transport_security.cc: $(OPENSSL_DEP)
src/core/tsi/local_transport_security.cc: $(OPENSSL_DEP)
src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc: $(OPENSSL_DEP)
diff --git a/README.md b/README.md
index 1960f44137..b3a4c1f17d 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
gRPC - An RPC library and framework
===================================
-gRPC is a modern, open source, high-performance remote procedure call (RPC) framework that can run anywhere. It enables client and server applications to communicate transparently, and makes it easier to build connected systems.
+gRPC is a modern, open source, high-performance remote procedure call (RPC) framework that can run anywhere. gRPC enables client and server applications to communicate transparently, and simplifies the building of connected systems.
<table>
<tr>
@@ -18,10 +18,10 @@ gRPC is a modern, open source, high-performance remote procedure call (RPC) fram
# To start using gRPC
-To maximize usability, gRPC supports the standard way of adding dependencies in your language of choice (if there is one).
-In most languages, the gRPC runtime comes in form of a package available in your language's package manager.
+To maximize usability, gRPC supports the standard method for adding dependencies to a user's chosen language (if there is one).
+In most languages, the gRPC runtime comes as a package available in a user's language package manager.
-For instructions on how to use the language-specific gRPC runtime in your project, please refer to these documents
+For instructions on how to use the language-specific gRPC runtime for a project, please refer to these documents
* [C++](src/cpp): follow the instructions under the `src/cpp` directory
* [C#](src/csharp): NuGet package `Grpc`
@@ -35,7 +35,7 @@ For instructions on how to use the language-specific gRPC runtime in your projec
* [Ruby](src/ruby): `gem install grpc`
* [WebJS](https://github.com/grpc/grpc-web): follow the grpc-web instructions
-You can find per-language quickstart guides and tutorials in [Documentation section on grpc.io website](https://grpc.io/docs/). The code examples are available in the [examples](examples) directory.
+Per-language quickstart guides and tutorials can be found in the [documentation section on the grpc.io website](https://grpc.io/docs/). Code examples are available in the [examples](examples) directory.
Precompiled bleeding-edge package builds of gRPC `master` branch's `HEAD` are uploaded daily to [packages.grpc.io](https://packages.grpc.io).
@@ -43,9 +43,9 @@ Precompiled bleeding-edge package builds of gRPC `master` branch's `HEAD` are up
Contributions are welcome!
-Please read [How to contribute](CONTRIBUTING.md) which will guide you through the entire workflow of how to build the source code, how to run the tests and how to contribute your changes to
+Please read [How to contribute](CONTRIBUTING.md) which will guide you through the entire workflow of how to build the source code, how to run the tests, and how to contribute changes to
the gRPC codebase.
-The document also contains info on how the contributing process works and contains best practices for creating contributions.
+The "How to contribute" document also contains info on how the contribution process works and contains best practices for creating contributions.
# Troubleshooting
@@ -53,7 +53,7 @@ Sometimes things go wrong. Please check out the [Troubleshooting guide](TROUBLES
# Performance
-See [Performance dashboard](http://performance-dot-grpc-testing.appspot.com/explore?dashboard=5636470266134528) for the performance numbers for the latest released version.
+See the [Performance dashboard](http://performance-dot-grpc-testing.appspot.com/explore?dashboard=5636470266134528) for performance numbers of the latest released version.
# Concepts
@@ -61,9 +61,9 @@ See [gRPC Concepts](CONCEPTS.md)
# About This Repository
-This repository contains source code for gRPC libraries for multiple languages written on top of shared C core library [src/core](src/core).
+This repository contains source code for gRPC libraries implemented in multiple languages written on top of a shared C core library [src/core](src/core).
-Libraries in different languages may be in different states of development. We are seeking contributions for all of these libraries.
+Libraries in different languages may be in various states of development. We are seeking contributions for all of these libraries:
| Language | Source |
|-------------------------|-------------------------------------|
diff --git a/WORKSPACE b/WORKSPACE
index c1e63d86e5..8d0fd693c6 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -1,47 +1,60 @@
-workspace(name="com_github_grpc_grpc")
+workspace(name = "com_github_grpc_grpc")
load("//bazel:grpc_deps.bzl", "grpc_deps", "grpc_test_only_deps")
load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
grpc_deps()
+
grpc_test_only_deps()
+register_execution_platforms(
+ "//third_party/toolchains:all",
+)
+
+register_toolchains(
+ "//third_party/toolchains:all",
+)
+
new_http_archive(
- name="cython",
- sha256="d68138a2381afbdd0876c3cb2a22389043fa01c4badede1228ee073032b07a27",
- urls=[
+ name = "cython",
+ build_file = "//third_party:cython.BUILD",
+ sha256 = "d68138a2381afbdd0876c3cb2a22389043fa01c4badede1228ee073032b07a27",
+ strip_prefix = "cython-c2b80d87658a8525ce091cbe146cb7eaa29fed5c",
+ urls = [
"https://github.com/cython/cython/archive/c2b80d87658a8525ce091cbe146cb7eaa29fed5c.tar.gz",
],
- strip_prefix="cython-c2b80d87658a8525ce091cbe146cb7eaa29fed5c",
- build_file="//third_party:cython.BUILD",
)
load("//third_party/py:python_configure.bzl", "python_configure")
-python_configure(name="local_config_python")
+
+python_configure(name = "local_config_python")
git_repository(
- name="io_bazel_rules_python",
- remote="https://github.com/bazelbuild/rules_python.git",
- commit="8b5d0683a7d878b28fffe464779c8a53659fc645",
+ name = "io_bazel_rules_python",
+ commit = "8b5d0683a7d878b28fffe464779c8a53659fc645",
+ remote = "https://github.com/bazelbuild/rules_python.git",
)
load("@io_bazel_rules_python//python:pip.bzl", "pip_repositories", "pip_import")
pip_repositories()
+
pip_import(
- name="grpc_python_dependencies",
- requirements="//:requirements.bazel.txt",
+ name = "grpc_python_dependencies",
+ requirements = "//:requirements.bazel.txt",
)
load("@grpc_python_dependencies//:requirements.bzl", "pip_install")
+
pip_install()
# NOTE(https://github.com/pubref/rules_protobuf/pull/196): Switch to upstream repo after this gets merged.
git_repository(
- name="org_pubref_rules_protobuf",
- remote="https://github.com/ghostwriternr/rules_protobuf",
- tag="v0.8.2.1-alpha",
+ name = "org_pubref_rules_protobuf",
+ remote = "https://github.com/ghostwriternr/rules_protobuf",
+ tag = "v0.8.2.1-alpha",
)
load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_repositories")
+
py_proto_repositories()
diff --git a/bazel/grpc_build_system.bzl b/bazel/grpc_build_system.bzl
index 159ebd5d1f..65fe5a10aa 100644
--- a/bazel/grpc_build_system.bzl
+++ b/bazel/grpc_build_system.bzl
@@ -131,7 +131,7 @@ def grpc_proto_library(
generate_mocks = generate_mocks,
)
-def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data = [], uses_polling = True, language = "C++", size = "medium", timeout = "moderate", tags = []):
+def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data = [], uses_polling = True, language = "C++", size = "medium", timeout = "moderate", tags = [], exec_compatible_with = []):
copts = []
if language.upper() == "C":
copts = if_not_windows(["-std=c99"])
@@ -145,6 +145,7 @@ def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data
"linkopts": if_not_windows(["-pthread"]),
"size": size,
"timeout": timeout,
+ "exec_compatible_with": exec_compatible_with,
}
if uses_polling:
native.cc_test(testonly = True, tags = ["manual"], **args)
@@ -162,6 +163,7 @@ def grpc_cc_test(name, srcs = [], deps = [], external_deps = [], args = [], data
"$(location %s)" % name,
] + args["args"],
tags = tags,
+ exec_compatible_with = exec_compatible_with,
)
else:
native.cc_test(**args)
diff --git a/bazel/grpc_deps.bzl b/bazel/grpc_deps.bzl
index 82aada2462..3eacd2b047 100644
--- a/bazel/grpc_deps.bzl
+++ b/bazel/grpc_deps.bzl
@@ -12,6 +12,11 @@ def grpc_deps():
)
native.bind(
+ name = "upblib",
+ actual = "@upb//:upb",
+ )
+
+ native.bind(
name = "absl-base",
actual = "@com_google_absl//absl/base",
)
@@ -187,6 +192,13 @@ def grpc_deps():
url = "https://github.com/census-instrumentation/opencensus-cpp/archive/fdf0f308b1631bb4a942e32ba5d22536a6170274.tar.gz",
)
+ if "upb" not in native.existing_rules():
+ http_archive(
+ name = "upb",
+ strip_prefix = "upb-9ce4a77f61c134bbed28bfd5be5cd7dc0e80f5e3",
+ url = "https://github.com/google/upb/archive/9ce4a77f61c134bbed28bfd5be5cd7dc0e80f5e3.tar.gz",
+ )
+
# TODO: move some dependencies from "grpc_deps" here?
def grpc_test_only_deps():
diff --git a/build.yaml b/build.yaml
index 9090a80b6a..381e649b39 100644
--- a/build.yaml
+++ b/build.yaml
@@ -13,8 +13,8 @@ settings:
'#09': Per-language overrides are possible with (eg) ruby_version tag here
'#10': See the expand_version.py for all the quirks here
core_version: 7.0.0-dev
- g_stands_for: gizmo
- version: 1.17.0-dev
+ g_stands_for: goose
+ version: 1.18.0-dev
filegroups:
- name: alts_proto
headers:
@@ -580,13 +580,13 @@ filegroups:
- src/core/ext/filters/client_channel/lb_policy.h
- src/core/ext/filters/client_channel/lb_policy_factory.h
- src/core/ext/filters/client_channel/lb_policy_registry.h
- - src/core/ext/filters/client_channel/method_params.h
- src/core/ext/filters/client_channel/parse_address.h
- src/core/ext/filters/client_channel/proxy_mapper.h
- src/core/ext/filters/client_channel/proxy_mapper_registry.h
- src/core/ext/filters/client_channel/resolver.h
- src/core/ext/filters/client_channel/resolver_factory.h
- src/core/ext/filters/client_channel/resolver_registry.h
+ - src/core/ext/filters/client_channel/resolver_result_parsing.h
- src/core/ext/filters/client_channel/retry_throttle.h
- src/core/ext/filters/client_channel/subchannel.h
- src/core/ext/filters/client_channel/subchannel_index.h
@@ -604,12 +604,12 @@ filegroups:
- src/core/ext/filters/client_channel/lb_policy.cc
- src/core/ext/filters/client_channel/lb_policy_factory.cc
- src/core/ext/filters/client_channel/lb_policy_registry.cc
- - src/core/ext/filters/client_channel/method_params.cc
- src/core/ext/filters/client_channel/parse_address.cc
- src/core/ext/filters/client_channel/proxy_mapper.cc
- src/core/ext/filters/client_channel/proxy_mapper_registry.cc
- src/core/ext/filters/client_channel/resolver.cc
- src/core/ext/filters/client_channel/resolver_registry.cc
+ - src/core/ext/filters/client_channel/resolver_result_parsing.cc
- src/core/ext/filters/client_channel/retry_throttle.cc
- src/core/ext/filters/client_channel/subchannel.cc
- src/core/ext/filters/client_channel/subchannel_index.cc
@@ -962,6 +962,7 @@ filegroups:
- src/core/ext/transport/chttp2/transport/bin_decoder.h
- src/core/ext/transport/chttp2/transport/bin_encoder.h
- src/core/ext/transport/chttp2/transport/chttp2_transport.h
+ - src/core/ext/transport/chttp2/transport/context_list.h
- src/core/ext/transport/chttp2/transport/flow_control.h
- src/core/ext/transport/chttp2/transport/frame.h
- src/core/ext/transport/chttp2/transport/frame_data.h
@@ -984,6 +985,7 @@ filegroups:
- src/core/ext/transport/chttp2/transport/bin_encoder.cc
- src/core/ext/transport/chttp2/transport/chttp2_plugin.cc
- src/core/ext/transport/chttp2/transport/chttp2_transport.cc
+ - src/core/ext/transport/chttp2/transport/context_list.cc
- src/core/ext/transport/chttp2/transport/flow_control.cc
- src/core/ext/transport/chttp2/transport/frame_data.cc
- src/core/ext/transport/chttp2/transport/frame_goaway.cc
@@ -1146,7 +1148,6 @@ filegroups:
- grpc
- name: tsi
headers:
- - src/core/tsi/alts_transport_security.h
- src/core/tsi/fake_transport_security.h
- src/core/tsi/local_transport_security.h
- src/core/tsi/ssl/session_cache/ssl_session.h
@@ -1155,7 +1156,6 @@ filegroups:
- src/core/tsi/ssl_types.h
- src/core/tsi/transport_security_grpc.h
src:
- - src/core/tsi/alts_transport_security.cc
- src/core/tsi/fake_transport_security.cc
- src/core/tsi/local_transport_security.cc
- src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc
@@ -1165,7 +1165,6 @@ filegroups:
- src/core/tsi/transport_security_grpc.cc
deps:
- gpr
- plugin: grpc_tsi_alts
secure: true
uses:
- tsi_interface
@@ -4489,6 +4488,7 @@ targets:
- gpr
- name: client_channel_stress_test
gtest: false
+ cpu_cost: 10.0
build: test
language: c++
src:
@@ -4604,6 +4604,18 @@ targets:
- grpc++_codegen_base
- grpc++_codegen_base_src
uses_polling: false
+- name: context_list_test
+ gtest: true
+ build: test
+ language: c++
+ src:
+ - test/core/transport/chttp2/context_list_test.cc
+ deps:
+ - grpc_test_util
+ - grpc
+ - gpr_test_util
+ - gpr
+ uses_polling: false
- name: credentials_test
gtest: true
build: test
diff --git a/config.m4 b/config.m4
index 15f3a54321..3db660acee 100644
--- a/config.m4
+++ b/config.m4
@@ -241,6 +241,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/transport/chttp2/transport/bin_encoder.cc \
src/core/ext/transport/chttp2/transport/chttp2_plugin.cc \
src/core/ext/transport/chttp2/transport/chttp2_transport.cc \
+ src/core/ext/transport/chttp2/transport/context_list.cc \
src/core/ext/transport/chttp2/transport/flow_control.cc \
src/core/ext/transport/chttp2/transport/frame_data.cc \
src/core/ext/transport/chttp2/transport/frame_goaway.cc \
@@ -349,18 +350,17 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/filters/client_channel/lb_policy.cc \
src/core/ext/filters/client_channel/lb_policy_factory.cc \
src/core/ext/filters/client_channel/lb_policy_registry.cc \
- src/core/ext/filters/client_channel/method_params.cc \
src/core/ext/filters/client_channel/parse_address.cc \
src/core/ext/filters/client_channel/proxy_mapper.cc \
src/core/ext/filters/client_channel/proxy_mapper_registry.cc \
src/core/ext/filters/client_channel/resolver.cc \
src/core/ext/filters/client_channel/resolver_registry.cc \
+ src/core/ext/filters/client_channel/resolver_result_parsing.cc \
src/core/ext/filters/client_channel/retry_throttle.cc \
src/core/ext/filters/client_channel/subchannel.cc \
src/core/ext/filters/client_channel/subchannel_index.cc \
src/core/ext/filters/deadline/deadline_filter.cc \
src/core/ext/filters/client_channel/health/health.pb.c \
- src/core/tsi/alts_transport_security.cc \
src/core/tsi/fake_transport_security.cc \
src/core/tsi/local_transport_security.cc \
src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc \
@@ -665,7 +665,8 @@ if test "$PHP_GRPC" != "no"; then
third_party/boringssl/third_party/fiat/curve25519.c \
, $ext_shared, , -fvisibility=hidden \
-DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN \
- -D_HAS_EXCEPTIONS=0 -DNOMINMAX -DGRPC_ARES=0)
+ -D_HAS_EXCEPTIONS=0 -DNOMINMAX -DGRPC_ARES=0 \
+ -DGRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK=1)
PHP_ADD_BUILD_DIR($ext_builddir/src/php/ext/grpc)
diff --git a/config.w32 b/config.w32
index 8dff1229be..7f8b6eee5f 100644
--- a/config.w32
+++ b/config.w32
@@ -216,6 +216,7 @@ if (PHP_GRPC != "no") {
"src\\core\\ext\\transport\\chttp2\\transport\\bin_encoder.cc " +
"src\\core\\ext\\transport\\chttp2\\transport\\chttp2_plugin.cc " +
"src\\core\\ext\\transport\\chttp2\\transport\\chttp2_transport.cc " +
+ "src\\core\\ext\\transport\\chttp2\\transport\\context_list.cc " +
"src\\core\\ext\\transport\\chttp2\\transport\\flow_control.cc " +
"src\\core\\ext\\transport\\chttp2\\transport\\frame_data.cc " +
"src\\core\\ext\\transport\\chttp2\\transport\\frame_goaway.cc " +
@@ -324,18 +325,17 @@ if (PHP_GRPC != "no") {
"src\\core\\ext\\filters\\client_channel\\lb_policy.cc " +
"src\\core\\ext\\filters\\client_channel\\lb_policy_factory.cc " +
"src\\core\\ext\\filters\\client_channel\\lb_policy_registry.cc " +
- "src\\core\\ext\\filters\\client_channel\\method_params.cc " +
"src\\core\\ext\\filters\\client_channel\\parse_address.cc " +
"src\\core\\ext\\filters\\client_channel\\proxy_mapper.cc " +
"src\\core\\ext\\filters\\client_channel\\proxy_mapper_registry.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver_registry.cc " +
+ "src\\core\\ext\\filters\\client_channel\\resolver_result_parsing.cc " +
"src\\core\\ext\\filters\\client_channel\\retry_throttle.cc " +
"src\\core\\ext\\filters\\client_channel\\subchannel.cc " +
"src\\core\\ext\\filters\\client_channel\\subchannel_index.cc " +
"src\\core\\ext\\filters\\deadline\\deadline_filter.cc " +
"src\\core\\ext\\filters\\client_channel\\health\\health.pb.c " +
- "src\\core\\tsi\\alts_transport_security.cc " +
"src\\core\\tsi\\fake_transport_security.cc " +
"src\\core\\tsi\\local_transport_security.cc " +
"src\\core\\tsi\\ssl\\session_cache\\ssl_session_boringssl.cc " +
diff --git a/doc/g_stands_for.md b/doc/g_stands_for.md
index a5a8efb21c..1e49b4d3f1 100644
--- a/doc/g_stands_for.md
+++ b/doc/g_stands_for.md
@@ -16,4 +16,5 @@
- 1.14 'g' stands for ['gladiolus'](https://github.com/grpc/grpc/tree/v1.14.x)
- 1.15 'g' stands for ['glider'](https://github.com/grpc/grpc/tree/v1.15.x)
- 1.16 'g' stands for ['gao'](https://github.com/grpc/grpc/tree/v1.16.x)
-- 1.17 'g' stands for ['gizmo'](https://github.com/grpc/grpc/tree/master)
+- 1.17 'g' stands for ['gizmo'](https://github.com/grpc/grpc/tree/v1.17.x)
+- 1.18 'g' stands for ['goose'](https://github.com/grpc/grpc/tree/master)
diff --git a/doc/grpc_release_schedule.md b/doc/grpc_release_schedule.md
new file mode 100644
index 0000000000..bacd375859
--- /dev/null
+++ b/doc/grpc_release_schedule.md
@@ -0,0 +1,22 @@
+# gRPC Release Schedule
+
+Below is the release schedule for gRPC [Java](https://github.com/grpc/grpc-java/releases), [Go](https://github.com/grpc/grpc-go/releases) and [Core](https://github.com/grpc/grpc/releases) and its dependent languages C++, C#, Objective-C, PHP, Python and Ruby.
+
+Releases are scheduled every six weeks on Tuesdays on a best effort basis. In some unavoidable situations a release may be delayed or a language may skip a release altogether and do the next release to catch up with other languages. See the past releases in the links above. A six-week cycle gives us a good balance between delivering new features/fixes quickly and keeping the release overhead low.
+
+Releases are cut from release branches. For Core and Java repos, the release branch is cut two weeks before the scheduled release date. For Go, the branch is cut just before the release. An RC (release candidate) is published for Core and its dependent languages just after the branch cut. This RC is later promoted to release version if no further changes are made to the release branch. We do our best to keep head of master branch stable at all times regardless of release schedule. Daily build packages from master branch for C#, PHP, Python, Ruby and Protoc plugins are published on [packages.grpc.io](https://packages.grpc.io/). If you depend on gRPC in production we recommend to set up your CI system to test the RCs and, if possible, the daily builds.
+
+Names of gRPC releases are [here](https://github.com/grpc/grpc/blob/master/doc/g_stands_for.md).
+
+Release |Scheduled Branch Cut|Scheduled Release Date
+--------|--------------------|-------------
+v1.17.0 |Nov 19, 2018 |Dec 4, 2018
+v1.18.0 |Jan 2, 2019 |Jan 15, 2019
+v1.19.0 |Feb 12, 2019 |Feb 26, 2019
+v1.20.0 |Mar 26, 2019 |Apr 9, 2019
+v1.21.0 |May 7, 2019 |May 21, 2019
+v1.22.0 |Jun 18, 2019 |Jul 2, 2019
+v1.23.0 |Jul 30, 2019 |Aug 13, 2019
+v1.24.0 |Sept 10, 2019 |Sept 24, 2019
+v1.25.0 |Oct 22, 2019 |Nov 5, 2019
+v1.26.0 |Dec 3, 2019 |Dec 17, 2019
diff --git a/doc/python/sphinx/conf.py b/doc/python/sphinx/conf.py
index 1eb3a5de7f..307c3bdaf6 100644
--- a/doc/python/sphinx/conf.py
+++ b/doc/python/sphinx/conf.py
@@ -19,6 +19,7 @@ import sys
PYTHON_FOLDER = os.path.join(os.path.dirname(os.path.realpath(__file__)),
'..', '..', '..', 'src', 'python')
sys.path.insert(0, os.path.join(PYTHON_FOLDER, 'grpcio'))
+sys.path.insert(0, os.path.join(PYTHON_FOLDER, 'grpcio_channelz'))
sys.path.insert(0, os.path.join(PYTHON_FOLDER, 'grpcio_health_checking'))
sys.path.insert(0, os.path.join(PYTHON_FOLDER, 'grpcio_reflection'))
sys.path.insert(0, os.path.join(PYTHON_FOLDER, 'grpcio_testing'))
@@ -63,6 +64,8 @@ autodoc_default_options = {
autodoc_mock_imports = [
'grpc._cython',
+ 'grpc_channelz.v1.channelz_pb2',
+ 'grpc_channelz.v1.channelz_pb2_grpc',
'grpc_health.v1.health_pb2',
'grpc_health.v1.health_pb2_grpc',
'grpc_reflection.v1alpha.reflection_pb2',
diff --git a/doc/python/sphinx/api.rst b/doc/python/sphinx/grpc.rst
index 425504fb28..bd2df9596b 100644
--- a/doc/python/sphinx/api.rst
+++ b/doc/python/sphinx/grpc.rst
@@ -1,10 +1,26 @@
-API Reference
+gRPC
=============
.. module:: grpc
+Tutorial
+--------
+
+If you want to see gRPC in action first, visit the `Python Quickstart <https://grpc.io/docs/quickstart/python.html>`_.
+Or, if you would like dive in with more extensive usage of gRPC Python, check `gRPC Basics - Python <https://grpc.io/docs/tutorials/basic/python.html>`_ out.
+
+
+Example
+-------
+
+Go to `gRPC Python Examples <https://github.com/grpc/grpc/tree/master/examples/python>`_
+
+
+Module Contents
+---------------
+
Create Client
--------------
+^^^^^^^^^^^^^
.. autofunction:: insecure_channel
.. autofunction:: secure_channel
@@ -12,7 +28,7 @@ Create Client
Create Client Credentials
--------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: ssl_channel_credentials
.. autofunction:: metadata_call_credentials
@@ -22,13 +38,13 @@ Create Client Credentials
Create Server
--------------
+^^^^^^^^^^^^^
.. autofunction:: server
Create Server Credentials
--------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: ssl_server_credentials
.. autofunction:: ssl_server_certificate_configuration
@@ -36,7 +52,7 @@ Create Server Credentials
RPC Method Handlers
---------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: unary_unary_rpc_method_handler
.. autofunction:: unary_stream_rpc_method_handler
@@ -46,37 +62,37 @@ RPC Method Handlers
Channel Ready Future
---------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autofunction:: channel_ready_future
Channel Connectivity
---------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autoclass:: ChannelConnectivity
gRPC Status Code
---------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autoclass:: StatusCode
Channel Object
---------------
+^^^^^^^^^^^^^^
.. autoclass:: Channel
Server Object
--------------
+^^^^^^^^^^^^^
.. autoclass:: Server
Authentication & Authorization Objects
---------------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autoclass:: ChannelCredentials
.. autoclass:: CallCredentials
@@ -88,25 +104,25 @@ Authentication & Authorization Objects
gRPC Exceptions
----------------
+^^^^^^^^^^^^^^^
.. autoexception:: RpcError
Shared Context
---------------
+^^^^^^^^^^^^^^
.. autoclass:: RpcContext
Client-Side Context
------------------------
+^^^^^^^^^^^^^^^^^^^^^^^
.. autoclass:: Call
Client-Side Interceptor
-------------------------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autoclass:: ClientCallDetails
.. autoclass:: UnaryUnaryClientInterceptor
@@ -116,13 +132,13 @@ Client-Side Interceptor
Service-Side Context
---------------------
+^^^^^^^^^^^^^^^^^^^^
.. autoclass:: ServicerContext
Service-Side Handler
--------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. autoclass:: RpcMethodHandler
.. autoclass:: HandlerCallDetails
@@ -131,13 +147,13 @@ Service-Side Handler
Service-Side Interceptor
-------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^
.. autoclass:: ServerInterceptor
-Multi-Callable
--------------------------
+Multi-Callable Interfaces
+^^^^^^^^^^^^^^^^^^^^^^^^^
.. autoclass:: UnaryUnaryMultiCallable
.. autoclass:: UnaryStreamMultiCallable
@@ -145,8 +161,8 @@ Multi-Callable
.. autoclass:: StreamStreamMultiCallable
-Future
-----------------
+Future Interfaces
+^^^^^^^^^^^^^^^^^
.. autoexception:: FutureTimeoutError
.. autoexception:: FutureCancelledError
diff --git a/doc/python/sphinx/grpc_channelz.rst b/doc/python/sphinx/grpc_channelz.rst
new file mode 100644
index 0000000000..f65793a071
--- /dev/null
+++ b/doc/python/sphinx/grpc_channelz.rst
@@ -0,0 +1,12 @@
+gRPC Channelz
+====================
+
+What is gRPC Channelz?
+---------------------------------------------
+
+Design Document `gRPC Channelz <https://github.com/grpc/proposal/blob/master/A14-channelz.md>`_
+
+Module Contents
+---------------
+
+.. automodule:: grpc_channelz.v1.channelz
diff --git a/doc/python/sphinx/index.rst b/doc/python/sphinx/index.rst
index b602b2934f..2f8a47a074 100644
--- a/doc/python/sphinx/index.rst
+++ b/doc/python/sphinx/index.rst
@@ -9,7 +9,8 @@ API Reference
.. toctree::
:caption: Contents:
- api
+ grpc
+ grpc_channelz
grpc_health_checking
grpc_reflection
grpc_testing
diff --git a/examples/objective-c/helloworld_macos/HelloWorld.podspec b/examples/objective-c/helloworld_macos/HelloWorld.podspec
new file mode 100644
index 0000000000..fc671ef4da
--- /dev/null
+++ b/examples/objective-c/helloworld_macos/HelloWorld.podspec
@@ -0,0 +1,66 @@
+Pod::Spec.new do |s|
+ s.name = "HelloWorld"
+ s.version = "0.0.1"
+ s.license = "Apache License, Version 2.0"
+ s.authors = { 'gRPC contributors' => 'grpc-io@googlegroups.com' }
+ s.homepage = "https://grpc.io/"
+ s.summary = "HelloWorld example"
+ s.source = { :git => 'https://github.com/grpc/grpc.git' }
+
+ s.ios.deployment_target = "7.1"
+ s.osx.deployment_target = "10.9"
+
+ # Base directory where the .proto files are.
+ src = "../../protos"
+
+ # Run protoc with the Objective-C and gRPC plugins to generate protocol messages and gRPC clients.
+ s.dependency "!ProtoCompiler-gRPCPlugin", "~> 1.0"
+
+ # Pods directory corresponding to this app's Podfile, relative to the location of this podspec.
+ pods_root = 'Pods'
+
+ # Path where Cocoapods downloads protoc and the gRPC plugin.
+ protoc_dir = "#{pods_root}/!ProtoCompiler"
+ protoc = "#{protoc_dir}/protoc"
+ plugin = "#{pods_root}/!ProtoCompiler-gRPCPlugin/grpc_objective_c_plugin"
+
+ # Directory where the generated files will be placed.
+ dir = "#{pods_root}/#{s.name}"
+
+ s.prepare_command = <<-CMD
+ mkdir -p #{dir}
+ #{protoc} \
+ --plugin=protoc-gen-grpc=#{plugin} \
+ --objc_out=#{dir} \
+ --grpc_out=#{dir} \
+ -I #{src} \
+ -I #{protoc_dir} \
+ #{src}/helloworld.proto
+ CMD
+
+ # Files generated by protoc
+ s.subspec "Messages" do |ms|
+ ms.source_files = "#{dir}/*.pbobjc.{h,m}", "#{dir}/**/*.pbobjc.{h,m}"
+ ms.header_mappings_dir = dir
+ ms.requires_arc = false
+ # The generated files depend on the protobuf runtime.
+ ms.dependency "Protobuf"
+ end
+
+ # Files generated by the gRPC plugin
+ s.subspec "Services" do |ss|
+ ss.source_files = "#{dir}/*.pbrpc.{h,m}", "#{dir}/**/*.pbrpc.{h,m}"
+ ss.header_mappings_dir = dir
+ ss.requires_arc = true
+ # The generated files depend on the gRPC runtime, and on the files generated by protoc.
+ ss.dependency "gRPC-ProtoRPC"
+ ss.dependency "#{s.name}/Messages"
+ end
+
+ s.pod_target_xcconfig = {
+ # This is needed by all pods that depend on Protobuf:
+ 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS=1',
+ # This is needed by all pods that depend on gRPC-RxLibrary:
+ 'CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES' => 'YES',
+ }
+end
diff --git a/examples/objective-c/helloworld_macos/HelloWorld.xcodeproj/project.pbxproj b/examples/objective-c/helloworld_macos/HelloWorld.xcodeproj/project.pbxproj
new file mode 100644
index 0000000000..06f06290d5
--- /dev/null
+++ b/examples/objective-c/helloworld_macos/HelloWorld.xcodeproj/project.pbxproj
@@ -0,0 +1,399 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 50;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 5EF711A4215174880077496F /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EF711A3215174880077496F /* AppDelegate.m */; };
+ 5EF711A7215174880077496F /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EF711A6215174880077496F /* ViewController.m */; };
+ 5EF711A9215174890077496F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5EF711A8215174890077496F /* Assets.xcassets */; };
+ 5EF711AC215174890077496F /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5EF711AA215174890077496F /* Main.storyboard */; };
+ 5EF711AF215174890077496F /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 5EF711AE215174890077496F /* main.m */; };
+ 827B966E84F6A63FD0F3F6BC /* libPods-HelloWorld.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 369D887F6054EBA486218C69 /* libPods-HelloWorld.a */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+ 2AAF8E8BA7DBFD2D3886AA25 /* Pods-HelloWorld.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HelloWorld.release.xcconfig"; path = "Pods/Target Support Files/Pods-HelloWorld/Pods-HelloWorld.release.xcconfig"; sourceTree = "<group>"; };
+ 369D887F6054EBA486218C69 /* libPods-HelloWorld.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-HelloWorld.a"; sourceTree = BUILT_PRODUCTS_DIR; };
+ 5EF7119F215174870077496F /* HelloWorld.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HelloWorld.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 5EF711A2215174880077496F /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
+ 5EF711A3215174880077496F /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
+ 5EF711A5215174880077496F /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = "<group>"; };
+ 5EF711A6215174880077496F /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = "<group>"; };
+ 5EF711A8215174890077496F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
+ 5EF711AB215174890077496F /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
+ 5EF711AD215174890077496F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
+ 5EF711AE215174890077496F /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
+ 5EF711B0215174890077496F /* HelloWorld.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = HelloWorld.entitlements; sourceTree = "<group>"; };
+ CA4699782F6344C8E67C9FEE /* Pods-HelloWorld.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-HelloWorld.debug.xcconfig"; path = "Pods/Target Support Files/Pods-HelloWorld/Pods-HelloWorld.debug.xcconfig"; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 5EF7119C215174870077496F /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 827B966E84F6A63FD0F3F6BC /* libPods-HelloWorld.a in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 5EF71196215174870077496F = {
+ isa = PBXGroup;
+ children = (
+ 5EF711AE215174890077496F /* main.m */,
+ 5EF711A1215174870077496F /* HelloWorld */,
+ 5EF711A0215174870077496F /* Products */,
+ 8D3EFBB796129582177142C4 /* Pods */,
+ A986548CB5622AF6CC3ECCCE /* Frameworks */,
+ );
+ sourceTree = "<group>";
+ };
+ 5EF711A0215174870077496F /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 5EF7119F215174870077496F /* HelloWorld.app */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
+ 5EF711A1215174870077496F /* HelloWorld */ = {
+ isa = PBXGroup;
+ children = (
+ 5EF711A2215174880077496F /* AppDelegate.h */,
+ 5EF711A3215174880077496F /* AppDelegate.m */,
+ 5EF711A5215174880077496F /* ViewController.h */,
+ 5EF711A6215174880077496F /* ViewController.m */,
+ 5EF711A8215174890077496F /* Assets.xcassets */,
+ 5EF711AA215174890077496F /* Main.storyboard */,
+ 5EF711AD215174890077496F /* Info.plist */,
+ 5EF711B0215174890077496F /* HelloWorld.entitlements */,
+ );
+ path = HelloWorld;
+ sourceTree = "<group>";
+ };
+ 8D3EFBB796129582177142C4 /* Pods */ = {
+ isa = PBXGroup;
+ children = (
+ CA4699782F6344C8E67C9FEE /* Pods-HelloWorld.debug.xcconfig */,
+ 2AAF8E8BA7DBFD2D3886AA25 /* Pods-HelloWorld.release.xcconfig */,
+ );
+ name = Pods;
+ sourceTree = "<group>";
+ };
+ A986548CB5622AF6CC3ECCCE /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 369D887F6054EBA486218C69 /* libPods-HelloWorld.a */,
+ );
+ name = Frameworks;
+ sourceTree = "<group>";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 5EF7119E215174870077496F /* HelloWorld */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 5EF711B3215174890077496F /* Build configuration list for PBXNativeTarget "HelloWorld" */;
+ buildPhases = (
+ 3694AEA482289A5BDD5EA5A4 /* [CP] Check Pods Manifest.lock */,
+ 5EF7119B215174870077496F /* Sources */,
+ 5EF7119C215174870077496F /* Frameworks */,
+ 5EF7119D215174870077496F /* Resources */,
+ DF5241368CCEAA9DC73E7EA8 /* [CP] Copy Pods Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = HelloWorld;
+ productName = HelloWorld;
+ productReference = 5EF7119F215174870077496F /* HelloWorld.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 5EF71197215174870077496F /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ LastUpgradeCheck = 0930;
+ ORGANIZATIONNAME = gRPC;
+ TargetAttributes = {
+ 5EF7119E215174870077496F = {
+ CreatedOnToolsVersion = 9.3;
+ SystemCapabilities = {
+ com.apple.Sandbox = {
+ enabled = 0;
+ };
+ };
+ };
+ };
+ };
+ buildConfigurationList = 5EF7119A215174870077496F /* Build configuration list for PBXProject "HelloWorld" */;
+ compatibilityVersion = "Xcode 9.3";
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = 5EF71196215174870077496F;
+ productRefGroup = 5EF711A0215174870077496F /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 5EF7119E215174870077496F /* HelloWorld */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 5EF7119D215174870077496F /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 5EF711A9215174890077496F /* Assets.xcassets in Resources */,
+ 5EF711AC215174890077496F /* Main.storyboard in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ 3694AEA482289A5BDD5EA5A4 /* [CP] Check Pods Manifest.lock */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+ "${PODS_ROOT}/Manifest.lock",
+ );
+ name = "[CP] Check Pods Manifest.lock";
+ outputPaths = (
+ "$(DERIVED_FILE_DIR)/Pods-HelloWorld-checkManifestLockResult.txt",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
+ showEnvVarsInLog = 0;
+ };
+ DF5241368CCEAA9DC73E7EA8 /* [CP] Copy Pods Resources */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ "${SRCROOT}/Pods/Target Support Files/Pods-HelloWorld/Pods-HelloWorld-resources.sh",
+ "${PODS_CONFIGURATION_BUILD_DIR}/gRPC/gRPCCertificates.bundle",
+ );
+ name = "[CP] Copy Pods Resources";
+ outputPaths = (
+ "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/gRPCCertificates.bundle",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-HelloWorld/Pods-HelloWorld-resources.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 5EF7119B215174870077496F /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 5EF711A7215174880077496F /* ViewController.m in Sources */,
+ 5EF711AF215174890077496F /* main.m in Sources */,
+ 5EF711A4215174880077496F /* AppDelegate.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXVariantGroup section */
+ 5EF711AA215174890077496F /* Main.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 5EF711AB215174890077496F /* Base */,
+ );
+ name = Main.storyboard;
+ sourceTree = "<group>";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ 5EF711B1215174890077496F /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_IDENTITY = "-";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ MACOSX_DEPLOYMENT_TARGET = 10.13;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = macosx;
+ };
+ name = Debug;
+ };
+ 5EF711B2215174890077496F /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_ENABLE_OBJC_WEAK = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ CODE_SIGN_IDENTITY = "-";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ GCC_C_LANGUAGE_STANDARD = gnu11;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ MACOSX_DEPLOYMENT_TARGET = 10.13;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = macosx;
+ };
+ name = Release;
+ };
+ 5EF711B4215174890077496F /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = CA4699782F6344C8E67C9FEE /* Pods-HelloWorld.debug.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CODE_SIGN_STYLE = Automatic;
+ COMBINE_HIDPI_IMAGES = YES;
+ INFOPLIST_FILE = HelloWorld/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/../Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = io.grpc.HelloWorld;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Debug;
+ };
+ 5EF711B5215174890077496F /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 2AAF8E8BA7DBFD2D3886AA25 /* Pods-HelloWorld.release.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
+ CODE_SIGN_STYLE = Automatic;
+ COMBINE_HIDPI_IMAGES = YES;
+ INFOPLIST_FILE = HelloWorld/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/../Frameworks",
+ );
+ PRODUCT_BUNDLE_IDENTIFIER = io.grpc.HelloWorld;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 5EF7119A215174870077496F /* Build configuration list for PBXProject "HelloWorld" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 5EF711B1215174890077496F /* Debug */,
+ 5EF711B2215174890077496F /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 5EF711B3215174890077496F /* Build configuration list for PBXNativeTarget "HelloWorld" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 5EF711B4215174890077496F /* Debug */,
+ 5EF711B5215174890077496F /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 5EF71197215174870077496F /* Project object */;
+}
diff --git a/examples/objective-c/helloworld_macos/HelloWorld/AppDelegate.h b/examples/objective-c/helloworld_macos/HelloWorld/AppDelegate.h
new file mode 100644
index 0000000000..1b88e35d22
--- /dev/null
+++ b/examples/objective-c/helloworld_macos/HelloWorld/AppDelegate.h
@@ -0,0 +1,25 @@
+/*
+ *
+ * Copyright 2018 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#import <Cocoa/Cocoa.h>
+
+@interface AppDelegate : NSObject <NSApplicationDelegate>
+
+
+@end
+
diff --git a/src/core/tsi/alts_transport_security.cc b/examples/objective-c/helloworld_macos/HelloWorld/AppDelegate.m
index 5a1494ae5c..7da5e1171b 100644
--- a/src/core/tsi/alts_transport_security.cc
+++ b/examples/objective-c/helloworld_macos/HelloWorld/AppDelegate.m
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2017 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,26 +16,22 @@
*
*/
-#include <grpc/support/port_platform.h>
+#import "AppDelegate.h"
-#include <string.h>
+@interface AppDelegate ()
-#include "src/core/tsi/alts_transport_security.h"
+@end
-static alts_shared_resource g_alts_resource;
+@implementation AppDelegate
-alts_shared_resource* alts_get_shared_resource(void) {
- return &g_alts_resource;
+- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
+ // Insert code here to initialize your application
}
-void grpc_tsi_alts_init() {
- g_alts_resource.channel = nullptr;
- gpr_mu_init(&g_alts_resource.mu);
-}
-void grpc_tsi_alts_shutdown() {
- if (g_alts_resource.channel != nullptr) {
- grpc_channel_destroy(g_alts_resource.channel);
- }
- gpr_mu_destroy(&g_alts_resource.mu);
+- (void)applicationWillTerminate:(NSNotification *)aNotification {
+ // Insert code here to tear down your application
}
+
+
+@end
diff --git a/examples/objective-c/helloworld_macos/HelloWorld/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/objective-c/helloworld_macos/HelloWorld/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000000..2db2b1c7c6
--- /dev/null
+++ b/examples/objective-c/helloworld_macos/HelloWorld/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,58 @@
+{
+ "images" : [
+ {
+ "idiom" : "mac",
+ "size" : "16x16",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "16x16",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "32x32",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "32x32",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "128x128",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "128x128",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "256x256",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "256x256",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "512x512",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "mac",
+ "size" : "512x512",
+ "scale" : "2x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+} \ No newline at end of file
diff --git a/examples/objective-c/helloworld_macos/HelloWorld/Assets.xcassets/Contents.json b/examples/objective-c/helloworld_macos/HelloWorld/Assets.xcassets/Contents.json
new file mode 100644
index 0000000000..da4a164c91
--- /dev/null
+++ b/examples/objective-c/helloworld_macos/HelloWorld/Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+} \ No newline at end of file
diff --git a/examples/objective-c/helloworld_macos/HelloWorld/Base.lproj/Main.storyboard b/examples/objective-c/helloworld_macos/HelloWorld/Base.lproj/Main.storyboard
new file mode 100644
index 0000000000..3ed4144fba
--- /dev/null
+++ b/examples/objective-c/helloworld_macos/HelloWorld/Base.lproj/Main.storyboard
@@ -0,0 +1,717 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="11134" systemVersion="15F34" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS">
+ <dependencies>
+ <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11134"/>
+ </dependencies>
+ <scenes>
+ <!--Application-->
+ <scene sceneID="JPo-4y-FX3">
+ <objects>
+ <application id="hnw-xV-0zn" sceneMemberID="viewController">
+ <menu key="mainMenu" title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
+ <items>
+ <menuItem title="HelloWorld" id="1Xt-HY-uBw">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="HelloWorld" systemMenu="apple" id="uQy-DD-JDr">
+ <items>
+ <menuItem title="About HelloWorld" id="5kV-Vb-QxS">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="orderFrontStandardAboutPanel:" target="Ady-hI-5gd" id="Exp-CZ-Vem"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/>
+ <menuItem title="Preferences…" keyEquivalent="," id="BOF-NM-1cW"/>
+ <menuItem isSeparatorItem="YES" id="wFC-TO-SCJ"/>
+ <menuItem title="Services" id="NMo-om-nkz">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Services" systemMenu="services" id="hz9-B4-Xy5"/>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="4je-JR-u6R"/>
+ <menuItem title="Hide HelloWorld" keyEquivalent="h" id="Olw-nP-bQN">
+ <connections>
+ <action selector="hide:" target="Ady-hI-5gd" id="PnN-Uc-m68"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO">
+ <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
+ <connections>
+ <action selector="hideOtherApplications:" target="Ady-hI-5gd" id="VT4-aY-XCT"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Show All" id="Kd2-mp-pUS">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="unhideAllApplications:" target="Ady-hI-5gd" id="Dhg-Le-xox"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/>
+ <menuItem title="Quit HelloWorld" keyEquivalent="q" id="4sb-4s-VLi">
+ <connections>
+ <action selector="terminate:" target="Ady-hI-5gd" id="Te7-pn-YzF"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="File" id="dMs-cI-mzQ">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="File" id="bib-Uj-vzu">
+ <items>
+ <menuItem title="New" keyEquivalent="n" id="Was-JA-tGl">
+ <connections>
+ <action selector="newDocument:" target="Ady-hI-5gd" id="4Si-XN-c54"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Open…" keyEquivalent="o" id="IAo-SY-fd9">
+ <connections>
+ <action selector="openDocument:" target="Ady-hI-5gd" id="bVn-NM-KNZ"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Open Recent" id="tXI-mr-wws">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Open Recent" systemMenu="recentDocuments" id="oas-Oc-fiZ">
+ <items>
+ <menuItem title="Clear Menu" id="vNY-rz-j42">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="clearRecentDocuments:" target="Ady-hI-5gd" id="Daa-9d-B3U"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="m54-Is-iLE"/>
+ <menuItem title="Close" keyEquivalent="w" id="DVo-aG-piG">
+ <connections>
+ <action selector="performClose:" target="Ady-hI-5gd" id="HmO-Ls-i7Q"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Save…" keyEquivalent="s" id="pxx-59-PXV">
+ <connections>
+ <action selector="saveDocument:" target="Ady-hI-5gd" id="teZ-XB-qJY"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Save As…" keyEquivalent="S" id="Bw7-FT-i3A">
+ <connections>
+ <action selector="saveDocumentAs:" target="Ady-hI-5gd" id="mDf-zr-I0C"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Revert to Saved" keyEquivalent="r" id="KaW-ft-85H">
+ <connections>
+ <action selector="revertDocumentToSaved:" target="Ady-hI-5gd" id="iJ3-Pv-kwq"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="aJh-i4-bef"/>
+ <menuItem title="Page Setup…" keyEquivalent="P" id="qIS-W8-SiK">
+ <modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
+ <connections>
+ <action selector="runPageLayout:" target="Ady-hI-5gd" id="Din-rz-gC5"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Print…" keyEquivalent="p" id="aTl-1u-JFS">
+ <connections>
+ <action selector="print:" target="Ady-hI-5gd" id="qaZ-4w-aoO"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Edit" id="5QF-Oa-p0T">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Edit" id="W48-6f-4Dl">
+ <items>
+ <menuItem title="Undo" keyEquivalent="z" id="dRJ-4n-Yzg">
+ <connections>
+ <action selector="undo:" target="Ady-hI-5gd" id="M6e-cu-g7V"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Redo" keyEquivalent="Z" id="6dh-zS-Vam">
+ <connections>
+ <action selector="redo:" target="Ady-hI-5gd" id="oIA-Rs-6OD"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="WRV-NI-Exz"/>
+ <menuItem title="Cut" keyEquivalent="x" id="uRl-iY-unG">
+ <connections>
+ <action selector="cut:" target="Ady-hI-5gd" id="YJe-68-I9s"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Copy" keyEquivalent="c" id="x3v-GG-iWU">
+ <connections>
+ <action selector="copy:" target="Ady-hI-5gd" id="G1f-GL-Joy"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Paste" keyEquivalent="v" id="gVA-U4-sdL">
+ <connections>
+ <action selector="paste:" target="Ady-hI-5gd" id="UvS-8e-Qdg"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Paste and Match Style" keyEquivalent="V" id="WeT-3V-zwk">
+ <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
+ <connections>
+ <action selector="pasteAsPlainText:" target="Ady-hI-5gd" id="cEh-KX-wJQ"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Delete" id="pa3-QI-u2k">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="delete:" target="Ady-hI-5gd" id="0Mk-Ml-PaM"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Select All" keyEquivalent="a" id="Ruw-6m-B2m">
+ <connections>
+ <action selector="selectAll:" target="Ady-hI-5gd" id="VNm-Mi-diN"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="uyl-h8-XO2"/>
+ <menuItem title="Find" id="4EN-yA-p0u">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Find" id="1b7-l0-nxx">
+ <items>
+ <menuItem title="Find…" tag="1" keyEquivalent="f" id="Xz5-n4-O0W">
+ <connections>
+ <action selector="performFindPanelAction:" target="Ady-hI-5gd" id="cD7-Qs-BN4"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Find and Replace…" tag="12" keyEquivalent="f" id="YEy-JH-Tfz">
+ <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
+ <connections>
+ <action selector="performFindPanelAction:" target="Ady-hI-5gd" id="WD3-Gg-5AJ"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Find Next" tag="2" keyEquivalent="g" id="q09-fT-Sye">
+ <connections>
+ <action selector="performFindPanelAction:" target="Ady-hI-5gd" id="NDo-RZ-v9R"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Find Previous" tag="3" keyEquivalent="G" id="OwM-mh-QMV">
+ <connections>
+ <action selector="performFindPanelAction:" target="Ady-hI-5gd" id="HOh-sY-3ay"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="buJ-ug-pKt">
+ <connections>
+ <action selector="performFindPanelAction:" target="Ady-hI-5gd" id="U76-nv-p5D"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Jump to Selection" keyEquivalent="j" id="S0p-oC-mLd">
+ <connections>
+ <action selector="centerSelectionInVisibleArea:" target="Ady-hI-5gd" id="IOG-6D-g5B"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Spelling and Grammar" id="Dv1-io-Yv7">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Spelling" id="3IN-sU-3Bg">
+ <items>
+ <menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="HFo-cy-zxI">
+ <connections>
+ <action selector="showGuessPanel:" target="Ady-hI-5gd" id="vFj-Ks-hy3"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Check Document Now" keyEquivalent=";" id="hz2-CU-CR7">
+ <connections>
+ <action selector="checkSpelling:" target="Ady-hI-5gd" id="fz7-VC-reM"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="bNw-od-mp5"/>
+ <menuItem title="Check Spelling While Typing" id="rbD-Rh-wIN">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleContinuousSpellChecking:" target="Ady-hI-5gd" id="7w6-Qz-0kB"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Check Grammar With Spelling" id="mK6-2p-4JG">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleGrammarChecking:" target="Ady-hI-5gd" id="muD-Qn-j4w"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Correct Spelling Automatically" id="78Y-hA-62v">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleAutomaticSpellingCorrection:" target="Ady-hI-5gd" id="2lM-Qi-WAP"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Substitutions" id="9ic-FL-obx">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Substitutions" id="FeM-D8-WVr">
+ <items>
+ <menuItem title="Show Substitutions" id="z6F-FW-3nz">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="orderFrontSubstitutionsPanel:" target="Ady-hI-5gd" id="oku-mr-iSq"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="gPx-C9-uUO"/>
+ <menuItem title="Smart Copy/Paste" id="9yt-4B-nSM">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleSmartInsertDelete:" target="Ady-hI-5gd" id="3IJ-Se-DZD"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Smart Quotes" id="hQb-2v-fYv">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleAutomaticQuoteSubstitution:" target="Ady-hI-5gd" id="ptq-xd-QOA"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Smart Dashes" id="rgM-f4-ycn">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleAutomaticDashSubstitution:" target="Ady-hI-5gd" id="oCt-pO-9gS"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Smart Links" id="cwL-P1-jid">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleAutomaticLinkDetection:" target="Ady-hI-5gd" id="Gip-E3-Fov"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Data Detectors" id="tRr-pd-1PS">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleAutomaticDataDetection:" target="Ady-hI-5gd" id="R1I-Nq-Kbl"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Text Replacement" id="HFQ-gK-NFA">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleAutomaticTextReplacement:" target="Ady-hI-5gd" id="DvP-Fe-Py6"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Transformations" id="2oI-Rn-ZJC">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Transformations" id="c8a-y6-VQd">
+ <items>
+ <menuItem title="Make Upper Case" id="vmV-6d-7jI">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="uppercaseWord:" target="Ady-hI-5gd" id="sPh-Tk-edu"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Make Lower Case" id="d9M-CD-aMd">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="lowercaseWord:" target="Ady-hI-5gd" id="iUZ-b5-hil"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Capitalize" id="UEZ-Bs-lqG">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="capitalizeWord:" target="Ady-hI-5gd" id="26H-TL-nsh"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Speech" id="xrE-MZ-jX0">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Speech" id="3rS-ZA-NoH">
+ <items>
+ <menuItem title="Start Speaking" id="Ynk-f8-cLZ">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="startSpeaking:" target="Ady-hI-5gd" id="654-Ng-kyl"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Stop Speaking" id="Oyz-dy-DGm">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="stopSpeaking:" target="Ady-hI-5gd" id="dX8-6p-jy9"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Format" id="jxT-CU-nIS">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Format" id="GEO-Iw-cKr">
+ <items>
+ <menuItem title="Font" id="Gi5-1S-RQB">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Font" systemMenu="font" id="aXa-aM-Jaq">
+ <items>
+ <menuItem title="Show Fonts" keyEquivalent="t" id="Q5e-8K-NDq">
+ <connections>
+ <action selector="orderFrontFontPanel:" target="YLy-65-1bz" id="WHr-nq-2xA"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Bold" tag="2" keyEquivalent="b" id="GB9-OM-e27">
+ <connections>
+ <action selector="addFontTrait:" target="YLy-65-1bz" id="hqk-hr-sYV"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Italic" tag="1" keyEquivalent="i" id="Vjx-xi-njq">
+ <connections>
+ <action selector="addFontTrait:" target="YLy-65-1bz" id="IHV-OB-c03"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Underline" keyEquivalent="u" id="WRG-CD-K1S">
+ <connections>
+ <action selector="underline:" target="Ady-hI-5gd" id="FYS-2b-JAY"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="5gT-KC-WSO"/>
+ <menuItem title="Bigger" tag="3" keyEquivalent="+" id="Ptp-SP-VEL">
+ <connections>
+ <action selector="modifyFont:" target="YLy-65-1bz" id="Uc7-di-UnL"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Smaller" tag="4" keyEquivalent="-" id="i1d-Er-qST">
+ <connections>
+ <action selector="modifyFont:" target="YLy-65-1bz" id="HcX-Lf-eNd"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="kx3-Dk-x3B"/>
+ <menuItem title="Kern" id="jBQ-r6-VK2">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Kern" id="tlD-Oa-oAM">
+ <items>
+ <menuItem title="Use Default" id="GUa-eO-cwY">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="useStandardKerning:" target="Ady-hI-5gd" id="6dk-9l-Ckg"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Use None" id="cDB-IK-hbR">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="turnOffKerning:" target="Ady-hI-5gd" id="U8a-gz-Maa"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Tighten" id="46P-cB-AYj">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="tightenKerning:" target="Ady-hI-5gd" id="hr7-Nz-8ro"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Loosen" id="ogc-rX-tC1">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="loosenKerning:" target="Ady-hI-5gd" id="8i4-f9-FKE"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Ligatures" id="o6e-r0-MWq">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Ligatures" id="w0m-vy-SC9">
+ <items>
+ <menuItem title="Use Default" id="agt-UL-0e3">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="useStandardLigatures:" target="Ady-hI-5gd" id="7uR-wd-Dx6"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Use None" id="J7y-lM-qPV">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="turnOffLigatures:" target="Ady-hI-5gd" id="iX2-gA-Ilz"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Use All" id="xQD-1f-W4t">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="useAllLigatures:" target="Ady-hI-5gd" id="KcB-kA-TuK"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Baseline" id="OaQ-X3-Vso">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Baseline" id="ijk-EB-dga">
+ <items>
+ <menuItem title="Use Default" id="3Om-Ey-2VK">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="unscript:" target="Ady-hI-5gd" id="0vZ-95-Ywn"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Superscript" id="Rqc-34-cIF">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="superscript:" target="Ady-hI-5gd" id="3qV-fo-wpU"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Subscript" id="I0S-gh-46l">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="subscript:" target="Ady-hI-5gd" id="Q6W-4W-IGz"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Raise" id="2h7-ER-AoG">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="raiseBaseline:" target="Ady-hI-5gd" id="4sk-31-7Q9"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Lower" id="1tx-W0-xDw">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="lowerBaseline:" target="Ady-hI-5gd" id="OF1-bc-KW4"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="Ndw-q3-faq"/>
+ <menuItem title="Show Colors" keyEquivalent="C" id="bgn-CT-cEk">
+ <connections>
+ <action selector="orderFrontColorPanel:" target="Ady-hI-5gd" id="mSX-Xz-DV3"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="iMs-zA-UFJ"/>
+ <menuItem title="Copy Style" keyEquivalent="c" id="5Vv-lz-BsD">
+ <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
+ <connections>
+ <action selector="copyFont:" target="Ady-hI-5gd" id="GJO-xA-L4q"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Paste Style" keyEquivalent="v" id="vKC-jM-MkH">
+ <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
+ <connections>
+ <action selector="pasteFont:" target="Ady-hI-5gd" id="JfD-CL-leO"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Text" id="Fal-I4-PZk">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Text" id="d9c-me-L2H">
+ <items>
+ <menuItem title="Align Left" keyEquivalent="{" id="ZM1-6Q-yy1">
+ <connections>
+ <action selector="alignLeft:" target="Ady-hI-5gd" id="zUv-R1-uAa"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Center" keyEquivalent="|" id="VIY-Ag-zcb">
+ <connections>
+ <action selector="alignCenter:" target="Ady-hI-5gd" id="spX-mk-kcS"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Justify" id="J5U-5w-g23">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="alignJustified:" target="Ady-hI-5gd" id="ljL-7U-jND"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Align Right" keyEquivalent="}" id="wb2-vD-lq4">
+ <connections>
+ <action selector="alignRight:" target="Ady-hI-5gd" id="r48-bG-YeY"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="4s2-GY-VfK"/>
+ <menuItem title="Writing Direction" id="H1b-Si-o9J">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Writing Direction" id="8mr-sm-Yjd">
+ <items>
+ <menuItem title="Paragraph" enabled="NO" id="ZvO-Gk-QUH">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ </menuItem>
+ <menuItem id="YGs-j5-SAR">
+ <string key="title"> Default</string>
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="makeBaseWritingDirectionNatural:" target="Ady-hI-5gd" id="qtV-5e-UBP"/>
+ </connections>
+ </menuItem>
+ <menuItem id="Lbh-J2-qVU">
+ <string key="title"> Left to Right</string>
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="makeBaseWritingDirectionLeftToRight:" target="Ady-hI-5gd" id="S0X-9S-QSf"/>
+ </connections>
+ </menuItem>
+ <menuItem id="jFq-tB-4Kx">
+ <string key="title"> Right to Left</string>
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="makeBaseWritingDirectionRightToLeft:" target="Ady-hI-5gd" id="5fk-qB-AqJ"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="swp-gr-a21"/>
+ <menuItem title="Selection" enabled="NO" id="cqv-fj-IhA">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ </menuItem>
+ <menuItem id="Nop-cj-93Q">
+ <string key="title"> Default</string>
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="makeTextWritingDirectionNatural:" target="Ady-hI-5gd" id="lPI-Se-ZHp"/>
+ </connections>
+ </menuItem>
+ <menuItem id="BgM-ve-c93">
+ <string key="title"> Left to Right</string>
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="makeTextWritingDirectionLeftToRight:" target="Ady-hI-5gd" id="caW-Bv-w94"/>
+ </connections>
+ </menuItem>
+ <menuItem id="RB4-Sm-HuC">
+ <string key="title"> Right to Left</string>
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="makeTextWritingDirectionRightToLeft:" target="Ady-hI-5gd" id="EXD-6r-ZUu"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="fKy-g9-1gm"/>
+ <menuItem title="Show Ruler" id="vLm-3I-IUL">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="toggleRuler:" target="Ady-hI-5gd" id="FOx-HJ-KwY"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Copy Ruler" keyEquivalent="c" id="MkV-Pr-PK5">
+ <modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
+ <connections>
+ <action selector="copyRuler:" target="Ady-hI-5gd" id="71i-fW-3W2"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Paste Ruler" keyEquivalent="v" id="LVM-kO-fVI">
+ <modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
+ <connections>
+ <action selector="pasteRuler:" target="Ady-hI-5gd" id="cSh-wd-qM2"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="View" id="H8h-7b-M4v">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="View" id="HyV-fh-RgO">
+ <items>
+ <menuItem title="Show Toolbar" keyEquivalent="t" id="snW-S8-Cw5">
+ <modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
+ <connections>
+ <action selector="toggleToolbarShown:" target="Ady-hI-5gd" id="BXY-wc-z0C"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Customize Toolbar…" id="1UK-8n-QPP">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="runToolbarCustomizationPalette:" target="Ady-hI-5gd" id="pQI-g3-MTW"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="hB3-LF-h0Y"/>
+ <menuItem title="Show Sidebar" keyEquivalent="s" id="kIP-vf-haE">
+ <modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
+ <connections>
+ <action selector="toggleSourceList:" target="Ady-hI-5gd" id="iwa-gc-5KM"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Enter Full Screen" keyEquivalent="f" id="4J7-dP-txa">
+ <modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
+ <connections>
+ <action selector="toggleFullScreen:" target="Ady-hI-5gd" id="dU3-MA-1Rq"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Window" id="aUF-d1-5bR">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo">
+ <items>
+ <menuItem title="Minimize" keyEquivalent="m" id="OY7-WF-poV">
+ <connections>
+ <action selector="performMiniaturize:" target="Ady-hI-5gd" id="VwT-WD-YPe"/>
+ </connections>
+ </menuItem>
+ <menuItem title="Zoom" id="R4o-n2-Eq4">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="performZoom:" target="Ady-hI-5gd" id="DIl-cC-cCs"/>
+ </connections>
+ </menuItem>
+ <menuItem isSeparatorItem="YES" id="eu3-7i-yIM"/>
+ <menuItem title="Bring All to Front" id="LE2-aR-0XJ">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <connections>
+ <action selector="arrangeInFront:" target="Ady-hI-5gd" id="DRN-fu-gQh"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ <menuItem title="Help" id="wpr-3q-Mcd">
+ <modifierMask key="keyEquivalentModifierMask"/>
+ <menu key="submenu" title="Help" systemMenu="help" id="F2S-fz-NVQ">
+ <items>
+ <menuItem title="HelloWorld Help" keyEquivalent="?" id="FKE-Sm-Kum">
+ <connections>
+ <action selector="showHelp:" target="Ady-hI-5gd" id="y7X-2Q-9no"/>
+ </connections>
+ </menuItem>
+ </items>
+ </menu>
+ </menuItem>
+ </items>
+ </menu>
+ <connections>
+ <outlet property="delegate" destination="Voe-Tx-rLC" id="PrD-fu-P6m"/>
+ </connections>
+ </application>
+ <customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModuleProvider=""/>
+ <customObject id="YLy-65-1bz" customClass="NSFontManager"/>
+ <customObject id="Ady-hI-5gd" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
+ </objects>
+ <point key="canvasLocation" x="75" y="0.0"/>
+ </scene>
+ <!--Window Controller-->
+ <scene sceneID="R2V-B0-nI4">
+ <objects>
+ <windowController id="B8D-0N-5wS" sceneMemberID="viewController">
+ <window key="window" title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" showsToolbarButton="NO" visibleAtLaunch="NO" animationBehavior="default" id="IQv-IB-iLA">
+ <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
+ <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
+ <rect key="contentRect" x="196" y="240" width="480" height="270"/>
+ <rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/>
+ <connections>
+ <outlet property="delegate" destination="B8D-0N-5wS" id="98r-iN-zZc"/>
+ </connections>
+ </window>
+ <connections>
+ <segue destination="XfG-lQ-9wD" kind="relationship" relationship="window.shadowedContentViewController" id="cq2-FE-JQM"/>
+ </connections>
+ </windowController>
+ <customObject id="Oky-zY-oP4" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
+ </objects>
+ <point key="canvasLocation" x="75" y="250"/>
+ </scene>
+ <!--View Controller-->
+ <scene sceneID="hIz-AP-VOD">
+ <objects>
+ <viewController id="XfG-lQ-9wD" customClass="ViewController" customModuleProvider="" sceneMemberID="viewController">
+ <view key="view" wantsLayer="YES" id="m2S-Jp-Qdl">
+ <rect key="frame" x="0.0" y="0.0" width="480" height="270"/>
+ <autoresizingMask key="autoresizingMask"/>
+ </view>
+ </viewController>
+ <customObject id="rPt-NT-nkU" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
+ </objects>
+ <point key="canvasLocation" x="75" y="655"/>
+ </scene>
+ </scenes>
+</document>
diff --git a/examples/objective-c/helloworld_macos/HelloWorld/HelloWorld.entitlements b/examples/objective-c/helloworld_macos/HelloWorld/HelloWorld.entitlements
new file mode 100644
index 0000000000..0c67376eba
--- /dev/null
+++ b/examples/objective-c/helloworld_macos/HelloWorld/HelloWorld.entitlements
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict/>
+</plist>
diff --git a/examples/objective-c/helloworld_macos/HelloWorld/Info.plist b/examples/objective-c/helloworld_macos/HelloWorld/Info.plist
new file mode 100644
index 0000000000..f7bfdac9d6
--- /dev/null
+++ b/examples/objective-c/helloworld_macos/HelloWorld/Info.plist
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>$(DEVELOPMENT_LANGUAGE)</string>
+ <key>CFBundleExecutable</key>
+ <string>$(EXECUTABLE_NAME)</string>
+ <key>CFBundleIconFile</key>
+ <string></string>
+ <key>CFBundleIdentifier</key>
+ <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>$(PRODUCT_NAME)</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleVersion</key>
+ <string>1</string>
+ <key>LSMinimumSystemVersion</key>
+ <string>$(MACOSX_DEPLOYMENT_TARGET)</string>
+ <key>NSHumanReadableCopyright</key>
+ <string>Copyright © 2018 gRPC. All rights reserved.</string>
+ <key>NSMainStoryboardFile</key>
+ <string>Main</string>
+ <key>NSPrincipalClass</key>
+ <string>NSApplication</string>
+</dict>
+</plist>
diff --git a/examples/objective-c/helloworld_macos/HelloWorld/ViewController.h b/examples/objective-c/helloworld_macos/HelloWorld/ViewController.h
new file mode 100644
index 0000000000..ff620dc426
--- /dev/null
+++ b/examples/objective-c/helloworld_macos/HelloWorld/ViewController.h
@@ -0,0 +1,25 @@
+/*
+ *
+ * Copyright 2018 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#import <Cocoa/Cocoa.h>
+
+@interface ViewController : NSViewController
+
+
+@end
+
diff --git a/src/core/tsi/alts_transport_security.h b/examples/objective-c/helloworld_macos/HelloWorld/ViewController.m
index f4319d10d2..fc9e95f9a6 100644
--- a/src/core/tsi/alts_transport_security.h
+++ b/examples/objective-c/helloworld_macos/HelloWorld/ViewController.m
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2017 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,23 +16,22 @@
*
*/
-#ifndef GRPC_CORE_TSI_ALTS_TRANSPORT_SECURITY_H
-#define GRPC_CORE_TSI_ALTS_TRANSPORT_SECURITY_H
+#import "ViewController.h"
-#include <grpc/support/port_platform.h>
+@implementation ViewController
-#include <grpc/grpc.h>
-#include <grpc/support/sync.h>
+- (void)viewDidLoad {
+ [super viewDidLoad];
-#include "src/core/lib/gprpp/thd.h"
+ // Do any additional setup after loading the view.
+}
-typedef struct alts_shared_resource {
- grpc_channel* channel;
- gpr_mu mu;
-} alts_shared_resource;
-/* This method returns the address of alts_shared_resource object shared by all
- * TSI handshakes. */
-alts_shared_resource* alts_get_shared_resource(void);
+- (void)setRepresentedObject:(id)representedObject {
+ [super setRepresentedObject:representedObject];
-#endif /* GRPC_CORE_TSI_ALTS_TRANSPORT_SECURITY_H */
+ // Update the view, if already loaded.
+}
+
+
+@end
diff --git a/examples/objective-c/helloworld_macos/Podfile b/examples/objective-c/helloworld_macos/Podfile
new file mode 100644
index 0000000000..bf1488cba6
--- /dev/null
+++ b/examples/objective-c/helloworld_macos/Podfile
@@ -0,0 +1,9 @@
+source 'https://github.com/CocoaPods/Specs.git'
+platform :macos, '10.9'
+
+install! 'cocoapods', :deterministic_uuids => false
+
+target 'HelloWorld' do
+ # Depend on the generated HelloWorld library.
+ pod 'HelloWorld', :path => '.'
+end
diff --git a/examples/objective-c/helloworld_macos/README.md b/examples/objective-c/helloworld_macos/README.md
new file mode 100644
index 0000000000..295701b5e6
--- /dev/null
+++ b/examples/objective-c/helloworld_macos/README.md
@@ -0,0 +1,6 @@
+# gRPC Objective-C Mac OS Hello World Example
+
+A hello world example app on Mac OS. Note that Mac OS is not a first class supported platform of gRPC
+Objective-C library. This example is only for reference.
+
+Refer to [Hello World Example](../helloworld) for instructions on installation and running.
diff --git a/examples/objective-c/helloworld_macos/main.m b/examples/objective-c/helloworld_macos/main.m
new file mode 100644
index 0000000000..2a98ec4966
--- /dev/null
+++ b/examples/objective-c/helloworld_macos/main.m
@@ -0,0 +1,43 @@
+/*
+ *
+ * Copyright 2018 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#import <Cocoa/Cocoa.h>
+
+#import <GRPCClient/GRPCCall+ChannelArg.h>
+#import <GRPCClient/GRPCCall+Tests.h>
+#import <HelloWorld/Helloworld.pbrpc.h>
+
+static NSString * const kHostAddress = @"localhost:50051";
+
+int main(int argc, const char * argv[]) {
+ @autoreleasepool {
+ [GRPCCall useInsecureConnectionsForHost:kHostAddress];
+ [GRPCCall setUserAgentPrefix:@"HelloWorld/1.0" forHost:kHostAddress];
+
+ HLWGreeter *client = [[HLWGreeter alloc] initWithHost:kHostAddress];
+
+ HLWHelloRequest *request = [HLWHelloRequest message];
+ request.name = @"Objective-C";
+
+ [client sayHelloWithRequest:request handler:^(HLWHelloReply *response, NSError *error) {
+ NSLog(@"%@", response.message);
+ }];
+ }
+
+ return NSApplicationMain(argc, argv);
+}
diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec
index d4b0548532..6647201714 100644
--- a/gRPC-C++.podspec
+++ b/gRPC-C++.podspec
@@ -23,15 +23,15 @@
Pod::Spec.new do |s|
s.name = 'gRPC-C++'
# TODO (mxyan): use version that match gRPC version when pod is stabilized
- # version = '1.17.0-dev'
- version = '0.0.3'
+ # version = '1.18.0-dev'
+ version = '0.0.4'
s.version = version
s.summary = 'gRPC C++ library'
s.homepage = 'https://grpc.io'
s.license = 'Apache License, Version 2.0'
s.authors = { 'The gRPC contributors' => 'grpc-packages@google.com' }
- grpc_version = '1.17.0-dev'
+ grpc_version = '1.18.0-dev'
s.source = {
:git => 'https://github.com/grpc/grpc.git',
@@ -256,6 +256,7 @@ Pod::Spec.new do |s|
'src/core/ext/transport/chttp2/transport/bin_decoder.h',
'src/core/ext/transport/chttp2/transport/bin_encoder.h',
'src/core/ext/transport/chttp2/transport/chttp2_transport.h',
+ 'src/core/ext/transport/chttp2/transport/context_list.h',
'src/core/ext/transport/chttp2/transport/flow_control.h',
'src/core/ext/transport/chttp2/transport/frame.h',
'src/core/ext/transport/chttp2/transport/frame_data.h',
@@ -347,19 +348,18 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/lb_policy.h',
'src/core/ext/filters/client_channel/lb_policy_factory.h',
'src/core/ext/filters/client_channel/lb_policy_registry.h',
- 'src/core/ext/filters/client_channel/method_params.h',
'src/core/ext/filters/client_channel/parse_address.h',
'src/core/ext/filters/client_channel/proxy_mapper.h',
'src/core/ext/filters/client_channel/proxy_mapper_registry.h',
'src/core/ext/filters/client_channel/resolver.h',
'src/core/ext/filters/client_channel/resolver_factory.h',
'src/core/ext/filters/client_channel/resolver_registry.h',
+ 'src/core/ext/filters/client_channel/resolver_result_parsing.h',
'src/core/ext/filters/client_channel/retry_throttle.h',
'src/core/ext/filters/client_channel/subchannel.h',
'src/core/ext/filters/client_channel/subchannel_index.h',
'src/core/ext/filters/deadline/deadline_filter.h',
'src/core/ext/filters/client_channel/health/health.pb.h',
- 'src/core/tsi/alts_transport_security.h',
'src/core/tsi/fake_transport_security.h',
'src/core/tsi/local_transport_security.h',
'src/core/tsi/ssl/session_cache/ssl_session.h',
diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index 6a43420830..3ec0852ad3 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -22,7 +22,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-Core'
- version = '1.17.0-dev'
+ version = '1.18.0-dev'
s.version = version
s.summary = 'Core cross-platform gRPC library, written in C'
s.homepage = 'https://grpc.io'
@@ -254,6 +254,7 @@ Pod::Spec.new do |s|
'src/core/ext/transport/chttp2/transport/bin_decoder.h',
'src/core/ext/transport/chttp2/transport/bin_encoder.h',
'src/core/ext/transport/chttp2/transport/chttp2_transport.h',
+ 'src/core/ext/transport/chttp2/transport/context_list.h',
'src/core/ext/transport/chttp2/transport/flow_control.h',
'src/core/ext/transport/chttp2/transport/frame.h',
'src/core/ext/transport/chttp2/transport/frame_data.h',
@@ -345,19 +346,18 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/lb_policy.h',
'src/core/ext/filters/client_channel/lb_policy_factory.h',
'src/core/ext/filters/client_channel/lb_policy_registry.h',
- 'src/core/ext/filters/client_channel/method_params.h',
'src/core/ext/filters/client_channel/parse_address.h',
'src/core/ext/filters/client_channel/proxy_mapper.h',
'src/core/ext/filters/client_channel/proxy_mapper_registry.h',
'src/core/ext/filters/client_channel/resolver.h',
'src/core/ext/filters/client_channel/resolver_factory.h',
'src/core/ext/filters/client_channel/resolver_registry.h',
+ 'src/core/ext/filters/client_channel/resolver_result_parsing.h',
'src/core/ext/filters/client_channel/retry_throttle.h',
'src/core/ext/filters/client_channel/subchannel.h',
'src/core/ext/filters/client_channel/subchannel_index.h',
'src/core/ext/filters/deadline/deadline_filter.h',
'src/core/ext/filters/client_channel/health/health.pb.h',
- 'src/core/tsi/alts_transport_security.h',
'src/core/tsi/fake_transport_security.h',
'src/core/tsi/local_transport_security.h',
'src/core/tsi/ssl/session_cache/ssl_session.h',
@@ -681,6 +681,7 @@ Pod::Spec.new do |s|
'src/core/ext/transport/chttp2/transport/bin_encoder.cc',
'src/core/ext/transport/chttp2/transport/chttp2_plugin.cc',
'src/core/ext/transport/chttp2/transport/chttp2_transport.cc',
+ 'src/core/ext/transport/chttp2/transport/context_list.cc',
'src/core/ext/transport/chttp2/transport/flow_control.cc',
'src/core/ext/transport/chttp2/transport/frame_data.cc',
'src/core/ext/transport/chttp2/transport/frame_goaway.cc',
@@ -786,18 +787,17 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/lb_policy.cc',
'src/core/ext/filters/client_channel/lb_policy_factory.cc',
'src/core/ext/filters/client_channel/lb_policy_registry.cc',
- 'src/core/ext/filters/client_channel/method_params.cc',
'src/core/ext/filters/client_channel/parse_address.cc',
'src/core/ext/filters/client_channel/proxy_mapper.cc',
'src/core/ext/filters/client_channel/proxy_mapper_registry.cc',
'src/core/ext/filters/client_channel/resolver.cc',
'src/core/ext/filters/client_channel/resolver_registry.cc',
+ 'src/core/ext/filters/client_channel/resolver_result_parsing.cc',
'src/core/ext/filters/client_channel/retry_throttle.cc',
'src/core/ext/filters/client_channel/subchannel.cc',
'src/core/ext/filters/client_channel/subchannel_index.cc',
'src/core/ext/filters/deadline/deadline_filter.cc',
'src/core/ext/filters/client_channel/health/health.pb.c',
- 'src/core/tsi/alts_transport_security.cc',
'src/core/tsi/fake_transport_security.cc',
'src/core/tsi/local_transport_security.cc',
'src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc',
@@ -873,6 +873,7 @@ Pod::Spec.new do |s|
'src/core/ext/transport/chttp2/transport/bin_decoder.h',
'src/core/ext/transport/chttp2/transport/bin_encoder.h',
'src/core/ext/transport/chttp2/transport/chttp2_transport.h',
+ 'src/core/ext/transport/chttp2/transport/context_list.h',
'src/core/ext/transport/chttp2/transport/flow_control.h',
'src/core/ext/transport/chttp2/transport/frame.h',
'src/core/ext/transport/chttp2/transport/frame_data.h',
@@ -964,19 +965,18 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/lb_policy.h',
'src/core/ext/filters/client_channel/lb_policy_factory.h',
'src/core/ext/filters/client_channel/lb_policy_registry.h',
- 'src/core/ext/filters/client_channel/method_params.h',
'src/core/ext/filters/client_channel/parse_address.h',
'src/core/ext/filters/client_channel/proxy_mapper.h',
'src/core/ext/filters/client_channel/proxy_mapper_registry.h',
'src/core/ext/filters/client_channel/resolver.h',
'src/core/ext/filters/client_channel/resolver_factory.h',
'src/core/ext/filters/client_channel/resolver_registry.h',
+ 'src/core/ext/filters/client_channel/resolver_result_parsing.h',
'src/core/ext/filters/client_channel/retry_throttle.h',
'src/core/ext/filters/client_channel/subchannel.h',
'src/core/ext/filters/client_channel/subchannel_index.h',
'src/core/ext/filters/deadline/deadline_filter.h',
'src/core/ext/filters/client_channel/health/health.pb.h',
- 'src/core/tsi/alts_transport_security.h',
'src/core/tsi/fake_transport_security.h',
'src/core/tsi/local_transport_security.h',
'src/core/tsi/ssl/session_cache/ssl_session.h',
diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec
index 693b873d14..13fe3e0b9c 100644
--- a/gRPC-ProtoRPC.podspec
+++ b/gRPC-ProtoRPC.podspec
@@ -21,7 +21,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-ProtoRPC'
- version = '1.17.0-dev'
+ version = '1.18.0-dev'
s.version = version
s.summary = 'RPC library for Protocol Buffers, based on gRPC'
s.homepage = 'https://grpc.io'
diff --git a/gRPC-RxLibrary.podspec b/gRPC-RxLibrary.podspec
index fd590023e1..e132ad41b4 100644
--- a/gRPC-RxLibrary.podspec
+++ b/gRPC-RxLibrary.podspec
@@ -21,7 +21,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-RxLibrary'
- version = '1.17.0-dev'
+ version = '1.18.0-dev'
s.version = version
s.summary = 'Reactive Extensions library for iOS/OSX.'
s.homepage = 'https://grpc.io'
diff --git a/gRPC.podspec b/gRPC.podspec
index 5e513cb127..940a1ac621 100644
--- a/gRPC.podspec
+++ b/gRPC.podspec
@@ -20,7 +20,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC'
- version = '1.17.0-dev'
+ version = '1.18.0-dev'
s.version = version
s.summary = 'gRPC client library for iOS/OSX'
s.homepage = 'https://grpc.io'
diff --git a/grpc.gemspec b/grpc.gemspec
index a9d3a95f2c..b5a1ef43fd 100644
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -186,6 +186,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/transport/chttp2/transport/bin_decoder.h )
s.files += %w( src/core/ext/transport/chttp2/transport/bin_encoder.h )
s.files += %w( src/core/ext/transport/chttp2/transport/chttp2_transport.h )
+ s.files += %w( src/core/ext/transport/chttp2/transport/context_list.h )
s.files += %w( src/core/ext/transport/chttp2/transport/flow_control.h )
s.files += %w( src/core/ext/transport/chttp2/transport/frame.h )
s.files += %w( src/core/ext/transport/chttp2/transport/frame_data.h )
@@ -281,19 +282,18 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/client_channel/lb_policy.h )
s.files += %w( src/core/ext/filters/client_channel/lb_policy_factory.h )
s.files += %w( src/core/ext/filters/client_channel/lb_policy_registry.h )
- s.files += %w( src/core/ext/filters/client_channel/method_params.h )
s.files += %w( src/core/ext/filters/client_channel/parse_address.h )
s.files += %w( src/core/ext/filters/client_channel/proxy_mapper.h )
s.files += %w( src/core/ext/filters/client_channel/proxy_mapper_registry.h )
s.files += %w( src/core/ext/filters/client_channel/resolver.h )
s.files += %w( src/core/ext/filters/client_channel/resolver_factory.h )
s.files += %w( src/core/ext/filters/client_channel/resolver_registry.h )
+ s.files += %w( src/core/ext/filters/client_channel/resolver_result_parsing.h )
s.files += %w( src/core/ext/filters/client_channel/retry_throttle.h )
s.files += %w( src/core/ext/filters/client_channel/subchannel.h )
s.files += %w( src/core/ext/filters/client_channel/subchannel_index.h )
s.files += %w( src/core/ext/filters/deadline/deadline_filter.h )
s.files += %w( src/core/ext/filters/client_channel/health/health.pb.h )
- s.files += %w( src/core/tsi/alts_transport_security.h )
s.files += %w( src/core/tsi/fake_transport_security.h )
s.files += %w( src/core/tsi/local_transport_security.h )
s.files += %w( src/core/tsi/ssl/session_cache/ssl_session.h )
@@ -617,6 +617,7 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/transport/chttp2/transport/bin_encoder.cc )
s.files += %w( src/core/ext/transport/chttp2/transport/chttp2_plugin.cc )
s.files += %w( src/core/ext/transport/chttp2/transport/chttp2_transport.cc )
+ s.files += %w( src/core/ext/transport/chttp2/transport/context_list.cc )
s.files += %w( src/core/ext/transport/chttp2/transport/flow_control.cc )
s.files += %w( src/core/ext/transport/chttp2/transport/frame_data.cc )
s.files += %w( src/core/ext/transport/chttp2/transport/frame_goaway.cc )
@@ -725,18 +726,17 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/client_channel/lb_policy.cc )
s.files += %w( src/core/ext/filters/client_channel/lb_policy_factory.cc )
s.files += %w( src/core/ext/filters/client_channel/lb_policy_registry.cc )
- s.files += %w( src/core/ext/filters/client_channel/method_params.cc )
s.files += %w( src/core/ext/filters/client_channel/parse_address.cc )
s.files += %w( src/core/ext/filters/client_channel/proxy_mapper.cc )
s.files += %w( src/core/ext/filters/client_channel/proxy_mapper_registry.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver_registry.cc )
+ s.files += %w( src/core/ext/filters/client_channel/resolver_result_parsing.cc )
s.files += %w( src/core/ext/filters/client_channel/retry_throttle.cc )
s.files += %w( src/core/ext/filters/client_channel/subchannel.cc )
s.files += %w( src/core/ext/filters/client_channel/subchannel_index.cc )
s.files += %w( src/core/ext/filters/deadline/deadline_filter.cc )
s.files += %w( src/core/ext/filters/client_channel/health/health.pb.c )
- s.files += %w( src/core/tsi/alts_transport_security.cc )
s.files += %w( src/core/tsi/fake_transport_security.cc )
s.files += %w( src/core/tsi/local_transport_security.cc )
s.files += %w( src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc )
diff --git a/grpc.gyp b/grpc.gyp
index c365b7e2ad..136867378f 100644
--- a/grpc.gyp
+++ b/grpc.gyp
@@ -433,6 +433,7 @@
'src/core/ext/transport/chttp2/transport/bin_encoder.cc',
'src/core/ext/transport/chttp2/transport/chttp2_plugin.cc',
'src/core/ext/transport/chttp2/transport/chttp2_transport.cc',
+ 'src/core/ext/transport/chttp2/transport/context_list.cc',
'src/core/ext/transport/chttp2/transport/flow_control.cc',
'src/core/ext/transport/chttp2/transport/frame_data.cc',
'src/core/ext/transport/chttp2/transport/frame_goaway.cc',
@@ -541,18 +542,17 @@
'src/core/ext/filters/client_channel/lb_policy.cc',
'src/core/ext/filters/client_channel/lb_policy_factory.cc',
'src/core/ext/filters/client_channel/lb_policy_registry.cc',
- 'src/core/ext/filters/client_channel/method_params.cc',
'src/core/ext/filters/client_channel/parse_address.cc',
'src/core/ext/filters/client_channel/proxy_mapper.cc',
'src/core/ext/filters/client_channel/proxy_mapper_registry.cc',
'src/core/ext/filters/client_channel/resolver.cc',
'src/core/ext/filters/client_channel/resolver_registry.cc',
+ 'src/core/ext/filters/client_channel/resolver_result_parsing.cc',
'src/core/ext/filters/client_channel/retry_throttle.cc',
'src/core/ext/filters/client_channel/subchannel.cc',
'src/core/ext/filters/client_channel/subchannel_index.cc',
'src/core/ext/filters/deadline/deadline_filter.cc',
'src/core/ext/filters/client_channel/health/health.pb.c',
- 'src/core/tsi/alts_transport_security.cc',
'src/core/tsi/fake_transport_security.cc',
'src/core/tsi/local_transport_security.cc',
'src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc',
@@ -801,12 +801,12 @@
'src/core/ext/filters/client_channel/lb_policy.cc',
'src/core/ext/filters/client_channel/lb_policy_factory.cc',
'src/core/ext/filters/client_channel/lb_policy_registry.cc',
- 'src/core/ext/filters/client_channel/method_params.cc',
'src/core/ext/filters/client_channel/parse_address.cc',
'src/core/ext/filters/client_channel/proxy_mapper.cc',
'src/core/ext/filters/client_channel/proxy_mapper_registry.cc',
'src/core/ext/filters/client_channel/resolver.cc',
'src/core/ext/filters/client_channel/resolver_registry.cc',
+ 'src/core/ext/filters/client_channel/resolver_result_parsing.cc',
'src/core/ext/filters/client_channel/retry_throttle.cc',
'src/core/ext/filters/client_channel/subchannel.cc',
'src/core/ext/filters/client_channel/subchannel_index.cc',
@@ -819,6 +819,7 @@
'src/core/ext/transport/chttp2/transport/bin_encoder.cc',
'src/core/ext/transport/chttp2/transport/chttp2_plugin.cc',
'src/core/ext/transport/chttp2/transport/chttp2_transport.cc',
+ 'src/core/ext/transport/chttp2/transport/context_list.cc',
'src/core/ext/transport/chttp2/transport/flow_control.cc',
'src/core/ext/transport/chttp2/transport/frame_data.cc',
'src/core/ext/transport/chttp2/transport/frame_goaway.cc',
@@ -1040,12 +1041,12 @@
'src/core/ext/filters/client_channel/lb_policy.cc',
'src/core/ext/filters/client_channel/lb_policy_factory.cc',
'src/core/ext/filters/client_channel/lb_policy_registry.cc',
- 'src/core/ext/filters/client_channel/method_params.cc',
'src/core/ext/filters/client_channel/parse_address.cc',
'src/core/ext/filters/client_channel/proxy_mapper.cc',
'src/core/ext/filters/client_channel/proxy_mapper_registry.cc',
'src/core/ext/filters/client_channel/resolver.cc',
'src/core/ext/filters/client_channel/resolver_registry.cc',
+ 'src/core/ext/filters/client_channel/resolver_result_parsing.cc',
'src/core/ext/filters/client_channel/retry_throttle.cc',
'src/core/ext/filters/client_channel/subchannel.cc',
'src/core/ext/filters/client_channel/subchannel_index.cc',
@@ -1058,6 +1059,7 @@
'src/core/ext/transport/chttp2/transport/bin_encoder.cc',
'src/core/ext/transport/chttp2/transport/chttp2_plugin.cc',
'src/core/ext/transport/chttp2/transport/chttp2_transport.cc',
+ 'src/core/ext/transport/chttp2/transport/context_list.cc',
'src/core/ext/transport/chttp2/transport/flow_control.cc',
'src/core/ext/transport/chttp2/transport/frame_data.cc',
'src/core/ext/transport/chttp2/transport/frame_goaway.cc',
@@ -1250,6 +1252,7 @@
'src/core/ext/transport/chttp2/transport/bin_encoder.cc',
'src/core/ext/transport/chttp2/transport/chttp2_plugin.cc',
'src/core/ext/transport/chttp2/transport/chttp2_transport.cc',
+ 'src/core/ext/transport/chttp2/transport/context_list.cc',
'src/core/ext/transport/chttp2/transport/flow_control.cc',
'src/core/ext/transport/chttp2/transport/frame_data.cc',
'src/core/ext/transport/chttp2/transport/frame_goaway.cc',
@@ -1291,12 +1294,12 @@
'src/core/ext/filters/client_channel/lb_policy.cc',
'src/core/ext/filters/client_channel/lb_policy_factory.cc',
'src/core/ext/filters/client_channel/lb_policy_registry.cc',
- 'src/core/ext/filters/client_channel/method_params.cc',
'src/core/ext/filters/client_channel/parse_address.cc',
'src/core/ext/filters/client_channel/proxy_mapper.cc',
'src/core/ext/filters/client_channel/proxy_mapper_registry.cc',
'src/core/ext/filters/client_channel/resolver.cc',
'src/core/ext/filters/client_channel/resolver_registry.cc',
+ 'src/core/ext/filters/client_channel/resolver_result_parsing.cc',
'src/core/ext/filters/client_channel/retry_throttle.cc',
'src/core/ext/filters/client_channel/subchannel.cc',
'src/core/ext/filters/client_channel/subchannel_index.cc',
diff --git a/include/grpc/impl/codegen/atm_gcc_sync.h b/include/grpc/impl/codegen/atm_gcc_sync.h
index c0010a3469..728c3d5412 100644
--- a/include/grpc/impl/codegen/atm_gcc_sync.h
+++ b/include/grpc/impl/codegen/atm_gcc_sync.h
@@ -26,6 +26,8 @@
typedef intptr_t gpr_atm;
#define GPR_ATM_MAX INTPTR_MAX
#define GPR_ATM_MIN INTPTR_MIN
+#define GPR_ATM_INC_CAS_THEN(blah) blah
+#define GPR_ATM_INC_ADD_THEN(blah) blah
#define GPR_ATM_COMPILE_BARRIER_() __asm__ __volatile__("" : : : "memory")
diff --git a/include/grpc/impl/codegen/atm_windows.h b/include/grpc/impl/codegen/atm_windows.h
index f6b27e5df7..c016b90095 100644
--- a/include/grpc/impl/codegen/atm_windows.h
+++ b/include/grpc/impl/codegen/atm_windows.h
@@ -25,6 +25,8 @@
typedef intptr_t gpr_atm;
#define GPR_ATM_MAX INTPTR_MAX
#define GPR_ATM_MIN INTPTR_MIN
+#define GPR_ATM_INC_CAS_THEN(blah) blah
+#define GPR_ATM_INC_ADD_THEN(blah) blah
#define gpr_atm_full_barrier MemoryBarrier
diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h
index 17a43fab0f..d1cc6af04f 100644
--- a/include/grpc/impl/codegen/grpc_types.h
+++ b/include/grpc/impl/codegen/grpc_types.h
@@ -293,7 +293,7 @@ typedef struct {
"grpc.max_channel_trace_event_memory_per_node"
/** If non-zero, gRPC library will track stats and information at at per channel
* level. Disabling channelz naturally disables channel tracing. The default
- * is for channelz to be disabled. */
+ * is for channelz to be enabled. */
#define GRPC_ARG_ENABLE_CHANNELZ "grpc.enable_channelz"
/** If non-zero, Cronet transport will coalesce packets to fewer frames
* when possible. */
diff --git a/include/grpcpp/channel.h b/include/grpcpp/channel.h
index 4502b94b17..ee83396069 100644
--- a/include/grpcpp/channel.h
+++ b/include/grpcpp/channel.h
@@ -65,13 +65,13 @@ class Channel final : public ChannelInterface,
friend void experimental::ChannelResetConnectionBackoff(Channel* channel);
friend std::shared_ptr<Channel> CreateChannelInternal(
const grpc::string& host, grpc_channel* c_channel,
- std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>
+ std::vector<
+ std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators);
friend class internal::InterceptedChannel;
Channel(const grpc::string& host, grpc_channel* c_channel,
- std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>
+ std::vector<
+ std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators);
internal::Call CreateCall(const internal::RpcMethod& method,
diff --git a/include/grpcpp/create_channel.h b/include/grpcpp/create_channel.h
index 43188d09e7..e8a2a70581 100644
--- a/include/grpcpp/create_channel.h
+++ b/include/grpcpp/create_channel.h
@@ -70,8 +70,8 @@ std::shared_ptr<Channel> CreateCustomChannelWithInterceptors(
const grpc::string& target,
const std::shared_ptr<ChannelCredentials>& creds,
const ChannelArguments& args,
- std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>
+ std::vector<
+ std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators);
} // namespace experimental
} // namespace grpc
diff --git a/include/grpcpp/impl/codegen/client_unary_call.h b/include/grpcpp/impl/codegen/client_unary_call.h
index b1c80764f2..5151839412 100644
--- a/include/grpcpp/impl/codegen/client_unary_call.h
+++ b/include/grpcpp/impl/codegen/client_unary_call.h
@@ -69,13 +69,17 @@ class BlockingUnaryCallImpl {
ops.ClientSendClose();
ops.ClientRecvStatus(context, &status_);
call.PerformOps(&ops);
- if (cq.Pluck(&ops)) {
- if (!ops.got_message && status_.ok()) {
- status_ = Status(StatusCode::UNIMPLEMENTED,
- "No message returned for unary request");
- }
- } else {
- GPR_CODEGEN_ASSERT(!status_.ok());
+ cq.Pluck(&ops);
+ // Some of the ops might fail. If the ops fail in the core layer, status
+ // would reflect the error. But, if the ops fail in the C++ layer, the
+ // status would still be the same as the one returned by gRPC Core. This can
+ // happen if deserialization of the message fails.
+ // TODO(yashykt): If deserialization fails, but the status received is OK,
+ // then it might be a good idea to change the status to something better
+ // than StatusCode::UNIMPLEMENTED to reflect this.
+ if (!ops.got_message && status_.ok()) {
+ status_ = Status(StatusCode::UNIMPLEMENTED,
+ "No message returned for unary request");
}
}
Status status() { return status_; }
diff --git a/include/grpcpp/impl/codegen/completion_queue.h b/include/grpcpp/impl/codegen/completion_queue.h
index d603c7c700..fb38788f7d 100644
--- a/include/grpcpp/impl/codegen/completion_queue.h
+++ b/include/grpcpp/impl/codegen/completion_queue.h
@@ -307,8 +307,7 @@ class CompletionQueue : private GrpcLibraryCodegen {
void* ignored = tag;
if (tag->FinalizeResult(&ignored, &ok)) {
GPR_CODEGEN_ASSERT(ignored == tag);
- // Ignore mutations by FinalizeResult: Pluck returns the C API status
- return ev.success != 0;
+ return ok;
}
}
}
diff --git a/include/grpcpp/impl/codegen/metadata_map.h b/include/grpcpp/impl/codegen/metadata_map.h
index 0bba3ed4e3..9cec54d9f0 100644
--- a/include/grpcpp/impl/codegen/metadata_map.h
+++ b/include/grpcpp/impl/codegen/metadata_map.h
@@ -32,11 +32,9 @@ const char kBinaryErrorDetailsKey[] = "grpc-status-details-bin";
class MetadataMap {
public:
- MetadataMap() { memset(&arr_, 0, sizeof(arr_)); }
+ MetadataMap() { Setup(); }
- ~MetadataMap() {
- g_core_codegen_interface->grpc_metadata_array_destroy(&arr_);
- }
+ ~MetadataMap() { Destroy(); }
grpc::string GetBinaryErrorDetails() {
// if filled_, extract from the multimap for O(log(n))
@@ -71,11 +69,24 @@ class MetadataMap {
}
grpc_metadata_array* arr() { return &arr_; }
+ void Reset() {
+ filled_ = false;
+ map_.clear();
+ Destroy();
+ Setup();
+ }
+
private:
bool filled_ = false;
grpc_metadata_array arr_;
std::multimap<grpc::string_ref, grpc::string_ref> map_;
+ void Destroy() {
+ g_core_codegen_interface->grpc_metadata_array_destroy(&arr_);
+ }
+
+ void Setup() { memset(&arr_, 0, sizeof(arr_)); }
+
void FillMap() {
if (filled_) return;
filled_ = true;
diff --git a/include/grpcpp/security/credentials.h b/include/grpcpp/security/credentials.h
index 8dfbdec3e6..d8c9e04d77 100644
--- a/include/grpcpp/security/credentials.h
+++ b/include/grpcpp/security/credentials.h
@@ -46,8 +46,8 @@ std::shared_ptr<Channel> CreateCustomChannelWithInterceptors(
const grpc::string& target,
const std::shared_ptr<ChannelCredentials>& creds,
const ChannelArguments& args,
- std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>
+ std::vector<
+ std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators);
} // namespace experimental
@@ -80,8 +80,8 @@ class ChannelCredentials : private GrpcLibraryCodegen {
const grpc::string& target,
const std::shared_ptr<ChannelCredentials>& creds,
const ChannelArguments& args,
- std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>
+ std::vector<
+ std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators);
virtual std::shared_ptr<Channel> CreateChannel(
@@ -91,8 +91,8 @@ class ChannelCredentials : private GrpcLibraryCodegen {
// implemented as a virtual function so that it does not break API.
virtual std::shared_ptr<Channel> CreateChannelWithInterceptors(
const grpc::string& target, const ChannelArguments& args,
- std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>
+ std::vector<
+ std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators) {
return nullptr;
};
diff --git a/include/grpcpp/server.h b/include/grpcpp/server.h
index a14a4da578..cdcac186cb 100644
--- a/include/grpcpp/server.h
+++ b/include/grpcpp/server.h
@@ -111,8 +111,8 @@ class Server : public ServerInterface, private GrpcLibraryCodegen {
/// interceptors
std::shared_ptr<Channel> InProcessChannelWithInterceptors(
const ChannelArguments& args,
- std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>
+ std::vector<
+ std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators);
private:
diff --git a/package.xml b/package.xml
index 69f952c466..a354ad5fa7 100644
--- a/package.xml
+++ b/package.xml
@@ -13,8 +13,8 @@
<date>2018-01-19</date>
<time>16:06:07</time>
<version>
- <release>1.17.0dev</release>
- <api>1.17.0dev</api>
+ <release>1.18.0dev</release>
+ <api>1.18.0dev</api>
</version>
<stability>
<release>beta</release>
@@ -191,6 +191,7 @@
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/bin_decoder.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/bin_encoder.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/chttp2_transport.h" role="src" />
+ <file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/context_list.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/flow_control.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/frame.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/frame_data.h" role="src" />
@@ -286,19 +287,18 @@
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy_factory.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy_registry.h" role="src" />
- <file baseinstalldir="/" name="src/core/ext/filters/client_channel/method_params.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/parse_address.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/proxy_mapper.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/proxy_mapper_registry.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver_factory.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver_registry.h" role="src" />
+ <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver_result_parsing.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/retry_throttle.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/subchannel.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/subchannel_index.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/deadline/deadline_filter.h" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/health/health.pb.h" role="src" />
- <file baseinstalldir="/" name="src/core/tsi/alts_transport_security.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/fake_transport_security.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/local_transport_security.h" role="src" />
<file baseinstalldir="/" name="src/core/tsi/ssl/session_cache/ssl_session.h" role="src" />
@@ -622,6 +622,7 @@
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/bin_encoder.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/chttp2_plugin.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/chttp2_transport.cc" role="src" />
+ <file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/context_list.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/flow_control.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/frame_data.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/transport/chttp2/transport/frame_goaway.cc" role="src" />
@@ -730,18 +731,17 @@
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy_factory.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/lb_policy_registry.cc" role="src" />
- <file baseinstalldir="/" name="src/core/ext/filters/client_channel/method_params.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/parse_address.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/proxy_mapper.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/proxy_mapper_registry.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver_registry.cc" role="src" />
+ <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver_result_parsing.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/retry_throttle.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/subchannel.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/subchannel_index.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/deadline/deadline_filter.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/health/health.pb.c" role="src" />
- <file baseinstalldir="/" name="src/core/tsi/alts_transport_security.cc" role="src" />
<file baseinstalldir="/" name="src/core/tsi/fake_transport_security.cc" role="src" />
<file baseinstalldir="/" name="src/core/tsi/local_transport_security.cc" role="src" />
<file baseinstalldir="/" name="src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc" role="src" />
diff --git a/requirements.bazel.txt b/requirements.bazel.txt
index efbf5314af..61e529a6ec 100644
--- a/requirements.bazel.txt
+++ b/requirements.bazel.txt
@@ -9,3 +9,7 @@ futures>=2.2.0
google-auth>=1.0.0
oauth2client==4.1.0
requests>=2.14.2
+urllib3==1.22
+chardet==3.0.4
+certifi==2017.4.17
+idna==2.7
diff --git a/src/compiler/csharp_generator.cc b/src/compiler/csharp_generator.cc
index a923ce8e38..59ddbd82f6 100644
--- a/src/compiler/csharp_generator.cc
+++ b/src/compiler/csharp_generator.cc
@@ -609,6 +609,42 @@ void GenerateBindServiceMethod(Printer* out, const ServiceDescriptor* service) {
out->Print("\n");
}
+void GenerateBindServiceWithBinderMethod(Printer* out,
+ const ServiceDescriptor* service) {
+ out->Print(
+ "/// <summary>Register service method implementations with a service "
+ "binder. Useful when customizing the service binding logic.\n"
+ "/// Note: this method is part of an experimental API that can change or "
+ "be "
+ "removed without any prior notice.</summary>\n");
+ out->Print(
+ "/// <param name=\"serviceBinder\">Service methods will be bound by "
+ "calling <c>AddMethod</c> on this object."
+ "</param>\n");
+ out->Print(
+ "/// <param name=\"serviceImpl\">An object implementing the server-side"
+ " handling logic.</param>\n");
+ out->Print(
+ "public static void BindService(grpc::ServiceBinderBase serviceBinder, "
+ "$implclass$ "
+ "serviceImpl)\n",
+ "implclass", GetServerClassName(service));
+ out->Print("{\n");
+ out->Indent();
+
+ for (int i = 0; i < service->method_count(); i++) {
+ const MethodDescriptor* method = service->method(i);
+ out->Print(
+ "serviceBinder.AddMethod($methodfield$, serviceImpl.$methodname$);\n",
+ "methodfield", GetMethodFieldName(method), "methodname",
+ method->name());
+ }
+
+ out->Outdent();
+ out->Print("}\n");
+ out->Print("\n");
+}
+
void GenerateService(Printer* out, const ServiceDescriptor* service,
bool generate_client, bool generate_server,
bool internal_access) {
@@ -637,6 +673,7 @@ void GenerateService(Printer* out, const ServiceDescriptor* service,
}
if (generate_server) {
GenerateBindServiceMethod(out, service);
+ GenerateBindServiceWithBinderMethod(out, service);
}
out->Outdent();
diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc
index d42961fc60..be7962261b 100644
--- a/src/core/ext/filters/client_channel/client_channel.cc
+++ b/src/core/ext/filters/client_channel/client_channel.cc
@@ -34,9 +34,9 @@
#include "src/core/ext/filters/client_channel/backup_poller.h"
#include "src/core/ext/filters/client_channel/http_connect_handshaker.h"
#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
-#include "src/core/ext/filters/client_channel/method_params.h"
#include "src/core/ext/filters/client_channel/proxy_mapper_registry.h"
#include "src/core/ext/filters/client_channel/resolver_registry.h"
+#include "src/core/ext/filters/client_channel/resolver_result_parsing.h"
#include "src/core/ext/filters/client_channel/retry_throttle.h"
#include "src/core/ext/filters/client_channel/subchannel.h"
#include "src/core/ext/filters/deadline/deadline_filter.h"
@@ -63,6 +63,8 @@
#include "src/core/lib/transport/status_metadata.h"
using grpc_core::internal::ClientChannelMethodParams;
+using grpc_core::internal::ClientChannelMethodParamsTable;
+using grpc_core::internal::ProcessedResolverResult;
using grpc_core::internal::ServerRetryThrottleData;
/* Client channel implementation */
@@ -83,10 +85,6 @@ grpc_core::TraceFlag grpc_client_channel_trace(false, "client_channel");
struct external_connectivity_watcher;
-typedef grpc_core::SliceHashTable<
- grpc_core::RefCountedPtr<ClientChannelMethodParams>>
- MethodParamsTable;
-
typedef struct client_channel_channel_data {
grpc_core::OrphanablePtr<grpc_core::Resolver> resolver;
bool started_resolving;
@@ -102,7 +100,7 @@ typedef struct client_channel_channel_data {
/** retry throttle data */
grpc_core::RefCountedPtr<ServerRetryThrottleData> retry_throttle_data;
/** maps method names to method_parameters structs */
- grpc_core::RefCountedPtr<MethodParamsTable> method_params_table;
+ grpc_core::RefCountedPtr<ClientChannelMethodParamsTable> method_params_table;
/** incoming resolver result - set by resolver.next() */
grpc_channel_args* resolver_result;
/** a list of closures that are all waiting for resolver result to come in */
@@ -251,66 +249,6 @@ static void start_resolving_locked(channel_data* chand) {
&chand->on_resolver_result_changed);
}
-typedef struct {
- char* server_name;
- grpc_core::RefCountedPtr<ServerRetryThrottleData> retry_throttle_data;
-} service_config_parsing_state;
-
-static void parse_retry_throttle_params(
- const grpc_json* field, service_config_parsing_state* parsing_state) {
- if (strcmp(field->key, "retryThrottling") == 0) {
- if (parsing_state->retry_throttle_data != nullptr) return; // Duplicate.
- if (field->type != GRPC_JSON_OBJECT) return;
- int max_milli_tokens = 0;
- int milli_token_ratio = 0;
- for (grpc_json* sub_field = field->child; sub_field != nullptr;
- sub_field = sub_field->next) {
- if (sub_field->key == nullptr) return;
- if (strcmp(sub_field->key, "maxTokens") == 0) {
- if (max_milli_tokens != 0) return; // Duplicate.
- if (sub_field->type != GRPC_JSON_NUMBER) return;
- max_milli_tokens = gpr_parse_nonnegative_int(sub_field->value);
- if (max_milli_tokens == -1) return;
- max_milli_tokens *= 1000;
- } else if (strcmp(sub_field->key, "tokenRatio") == 0) {
- if (milli_token_ratio != 0) return; // Duplicate.
- if (sub_field->type != GRPC_JSON_NUMBER) return;
- // We support up to 3 decimal digits.
- size_t whole_len = strlen(sub_field->value);
- uint32_t multiplier = 1;
- uint32_t decimal_value = 0;
- const char* decimal_point = strchr(sub_field->value, '.');
- if (decimal_point != nullptr) {
- whole_len = static_cast<size_t>(decimal_point - sub_field->value);
- multiplier = 1000;
- size_t decimal_len = strlen(decimal_point + 1);
- if (decimal_len > 3) decimal_len = 3;
- if (!gpr_parse_bytes_to_uint32(decimal_point + 1, decimal_len,
- &decimal_value)) {
- return;
- }
- uint32_t decimal_multiplier = 1;
- for (size_t i = 0; i < (3 - decimal_len); ++i) {
- decimal_multiplier *= 10;
- }
- decimal_value *= decimal_multiplier;
- }
- uint32_t whole_value;
- if (!gpr_parse_bytes_to_uint32(sub_field->value, whole_len,
- &whole_value)) {
- return;
- }
- milli_token_ratio =
- static_cast<int>((whole_value * multiplier) + decimal_value);
- if (milli_token_ratio <= 0) return;
- }
- }
- parsing_state->retry_throttle_data =
- grpc_core::internal::ServerRetryThrottleMap::GetDataForServer(
- parsing_state->server_name, max_milli_tokens, milli_token_ratio);
- }
-}
-
// Invoked from the resolver NextLocked() callback when the resolver
// is shutting down.
static void on_resolver_shutdown_locked(channel_data* chand,
@@ -352,37 +290,6 @@ static void on_resolver_shutdown_locked(channel_data* chand,
GRPC_ERROR_UNREF(error);
}
-// Returns the LB policy name from the resolver result.
-static grpc_core::UniquePtr<char>
-get_lb_policy_name_from_resolver_result_locked(channel_data* chand) {
- // Find LB policy name in channel args.
- const grpc_arg* channel_arg =
- grpc_channel_args_find(chand->resolver_result, GRPC_ARG_LB_POLICY_NAME);
- const char* lb_policy_name = grpc_channel_arg_get_string(channel_arg);
- // Special case: If at least one balancer address is present, we use
- // the grpclb policy, regardless of what the resolver actually specified.
- channel_arg =
- grpc_channel_args_find(chand->resolver_result, GRPC_ARG_LB_ADDRESSES);
- if (channel_arg != nullptr && channel_arg->type == GRPC_ARG_POINTER) {
- grpc_lb_addresses* addresses =
- static_cast<grpc_lb_addresses*>(channel_arg->value.pointer.p);
- if (grpc_lb_addresses_contains_balancer_address(*addresses)) {
- if (lb_policy_name != nullptr &&
- gpr_stricmp(lb_policy_name, "grpclb") != 0) {
- gpr_log(GPR_INFO,
- "resolver requested LB policy %s but provided at least one "
- "balancer address -- forcing use of grpclb LB policy",
- lb_policy_name);
- }
- lb_policy_name = "grpclb";
- }
- }
- // Use pick_first if nothing was specified and we didn't select grpclb
- // above.
- if (lb_policy_name == nullptr) lb_policy_name = "pick_first";
- return grpc_core::UniquePtr<char>(gpr_strdup(lb_policy_name));
-}
-
static void request_reresolution_locked(void* arg, grpc_error* error) {
reresolution_request_args* args =
static_cast<reresolution_request_args*>(arg);
@@ -410,13 +317,14 @@ using TraceStringVector = grpc_core::InlinedVector<char*, 3>;
// *connectivity_error to its initial connectivity state; otherwise,
// leaves them unchanged.
static void create_new_lb_policy_locked(
- channel_data* chand, char* lb_policy_name,
+ channel_data* chand, char* lb_policy_name, grpc_json* lb_config,
grpc_connectivity_state* connectivity_state,
grpc_error** connectivity_error, TraceStringVector* trace_strings) {
grpc_core::LoadBalancingPolicy::Args lb_policy_args;
lb_policy_args.combiner = chand->combiner;
lb_policy_args.client_channel_factory = chand->client_channel_factory;
lb_policy_args.args = chand->resolver_result;
+ lb_policy_args.lb_config = lb_config;
grpc_core::OrphanablePtr<grpc_core::LoadBalancingPolicy> new_lb_policy =
grpc_core::LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy(
lb_policy_name, lb_policy_args);
@@ -473,44 +381,6 @@ static void create_new_lb_policy_locked(
}
}
-// Returns the service config (as a JSON string) from the resolver result.
-// Also updates state in chand.
-static grpc_core::UniquePtr<char>
-get_service_config_from_resolver_result_locked(channel_data* chand) {
- const grpc_arg* channel_arg =
- grpc_channel_args_find(chand->resolver_result, GRPC_ARG_SERVICE_CONFIG);
- const char* service_config_json = grpc_channel_arg_get_string(channel_arg);
- if (service_config_json != nullptr) {
- if (grpc_client_channel_trace.enabled()) {
- gpr_log(GPR_INFO, "chand=%p: resolver returned service config: \"%s\"",
- chand, service_config_json);
- }
- grpc_core::UniquePtr<grpc_core::ServiceConfig> service_config =
- grpc_core::ServiceConfig::Create(service_config_json);
- if (service_config != nullptr) {
- if (chand->enable_retries) {
- channel_arg =
- grpc_channel_args_find(chand->resolver_result, GRPC_ARG_SERVER_URI);
- const char* server_uri = grpc_channel_arg_get_string(channel_arg);
- GPR_ASSERT(server_uri != nullptr);
- grpc_uri* uri = grpc_uri_parse(server_uri, true);
- GPR_ASSERT(uri->path[0] != '\0');
- service_config_parsing_state parsing_state;
- parsing_state.server_name =
- uri->path[0] == '/' ? uri->path + 1 : uri->path;
- service_config->ParseGlobalParams(parse_retry_throttle_params,
- &parsing_state);
- grpc_uri_destroy(uri);
- chand->retry_throttle_data =
- std::move(parsing_state.retry_throttle_data);
- }
- chand->method_params_table = service_config->CreateMethodConfigTable(
- ClientChannelMethodParams::CreateFromJson);
- }
- }
- return grpc_core::UniquePtr<char>(gpr_strdup(service_config_json));
-}
-
static void maybe_add_trace_message_for_address_changes_locked(
channel_data* chand, TraceStringVector* trace_strings) {
int resolution_contains_addresses = false;
@@ -597,9 +467,23 @@ static void on_resolver_result_changed_locked(void* arg, grpc_error* error) {
if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_INFO, "chand=%p: resolver transient failure", chand);
}
+ // Don't override connectivity state if we already have an LB policy.
+ if (chand->lb_policy != nullptr) set_connectivity_state = false;
} else {
+ // Parse the resolver result.
+ ProcessedResolverResult resolver_result(chand->resolver_result,
+ chand->enable_retries);
+ chand->retry_throttle_data = resolver_result.retry_throttle_data();
+ chand->method_params_table = resolver_result.method_params_table();
+ grpc_core::UniquePtr<char> service_config_json =
+ resolver_result.service_config_json();
+ if (service_config_json != nullptr && grpc_client_channel_trace.enabled()) {
+ gpr_log(GPR_INFO, "chand=%p: resolver returned service config: \"%s\"",
+ chand, service_config_json.get());
+ }
grpc_core::UniquePtr<char> lb_policy_name =
- get_lb_policy_name_from_resolver_result_locked(chand);
+ resolver_result.lb_policy_name();
+ grpc_json* lb_policy_config = resolver_result.lb_policy_config();
// Check to see if we're already using the right LB policy.
// Note: It's safe to use chand->info_lb_policy_name here without
// taking a lock on chand->info_mu, because this function is the
@@ -614,19 +498,16 @@ static void on_resolver_result_changed_locked(void* arg, grpc_error* error) {
gpr_log(GPR_INFO, "chand=%p: updating existing LB policy \"%s\" (%p)",
chand, lb_policy_name.get(), chand->lb_policy.get());
}
- chand->lb_policy->UpdateLocked(*chand->resolver_result);
+ chand->lb_policy->UpdateLocked(*chand->resolver_result, lb_policy_config);
// No need to set the channel's connectivity state; the existing
// watch on the LB policy will take care of that.
set_connectivity_state = false;
} else {
// Instantiate new LB policy.
- create_new_lb_policy_locked(chand, lb_policy_name.get(),
+ create_new_lb_policy_locked(chand, lb_policy_name.get(), lb_policy_config,
&connectivity_state, &connectivity_error,
&trace_strings);
}
- // Find service config.
- grpc_core::UniquePtr<char> service_config_json =
- get_service_config_from_resolver_result_locked(chand);
// Note: It's safe to use chand->info_service_config_json here without
// taking a lock on chand->info_mu, because this function is the
// only thing that modifies its value, and it can only be invoked
@@ -1023,13 +904,17 @@ struct subchannel_call_retry_state {
bool completed_recv_initial_metadata : 1;
bool started_recv_trailing_metadata : 1;
bool completed_recv_trailing_metadata : 1;
- // State for callback processing.
- bool retry_dispatched : 1;
subchannel_batch_data* recv_initial_metadata_ready_deferred_batch = nullptr;
grpc_error* recv_initial_metadata_error = GRPC_ERROR_NONE;
subchannel_batch_data* recv_message_ready_deferred_batch = nullptr;
grpc_error* recv_message_error = GRPC_ERROR_NONE;
subchannel_batch_data* recv_trailing_metadata_internal_batch = nullptr;
+ // State for callback processing.
+ // NOTE: Do not move this next to the metadata bitfields above. That would
+ // save space but will also result in a data race because compiler will
+ // generate a 2 byte store which overwrites the meta-data fields upon
+ // setting this field.
+ bool retry_dispatched : 1;
};
// Pending batches stored in call data.
diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h
index b0040457a6..6733fdca81 100644
--- a/src/core/ext/filters/client_channel/lb_policy.h
+++ b/src/core/ext/filters/client_channel/lb_policy.h
@@ -58,6 +58,8 @@ class LoadBalancingPolicy
/// Note that the LB policy gets the set of addresses from the
/// GRPC_ARG_LB_ADDRESSES channel arg.
grpc_channel_args* args = nullptr;
+ /// Load balancing config from the resolver.
+ grpc_json* lb_config = nullptr;
};
/// State used for an LB pick.
@@ -92,10 +94,11 @@ class LoadBalancingPolicy
LoadBalancingPolicy(const LoadBalancingPolicy&) = delete;
LoadBalancingPolicy& operator=(const LoadBalancingPolicy&) = delete;
- /// Updates the policy with a new set of \a args from the resolver.
- /// Note that the LB policy gets the set of addresses from the
+ /// Updates the policy with a new set of \a args and a new \a lb_config from
+ /// the resolver. Note that the LB policy gets the set of addresses from the
/// GRPC_ARG_LB_ADDRESSES channel arg.
- virtual void UpdateLocked(const grpc_channel_args& args) GRPC_ABSTRACT;
+ virtual void UpdateLocked(const grpc_channel_args& args,
+ grpc_json* lb_config) GRPC_ABSTRACT;
/// Finds an appropriate subchannel for a call, based on data in \a pick.
/// \a pick must remain alive until the pick is complete.
diff --git a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
index 17e0d26875..7e70f1c28b 100644
--- a/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
+++ b/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc
@@ -123,7 +123,8 @@ class GrpcLb : public LoadBalancingPolicy {
public:
GrpcLb(const grpc_lb_addresses* addresses, const Args& args);
- void UpdateLocked(const grpc_channel_args& args) override;
+ void UpdateLocked(const grpc_channel_args& args,
+ grpc_json* lb_config) override;
bool PickLocked(PickState* pick, grpc_error** error) override;
void CancelPickLocked(PickState* pick, grpc_error* error) override;
void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask,
@@ -748,7 +749,7 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked(
void* arg, grpc_error* error) {
BalancerCallState* lb_calld = static_cast<BalancerCallState*>(arg);
GrpcLb* grpclb_policy = lb_calld->grpclb_policy();
- // Empty payload means the LB call was cancelled.
+ // Null payload means the LB call was cancelled.
if (lb_calld != grpclb_policy->lb_calld_.get() ||
lb_calld->recv_message_payload_ == nullptr) {
lb_calld->Unref(DEBUG_LOCATION, "on_message_received");
@@ -802,54 +803,45 @@ void GrpcLb::BalancerCallState::OnBalancerMessageReceivedLocked(
gpr_free(ipport);
}
}
- /* update serverlist */
- if (serverlist->num_servers > 0) {
- // Start sending client load report only after we start using the
- // serverlist returned from the current LB call.
- if (lb_calld->client_stats_report_interval_ > 0 &&
- lb_calld->client_stats_ == nullptr) {
- lb_calld->client_stats_.reset(New<GrpcLbClientStats>());
- // TODO(roth): We currently track this ref manually. Once the
- // ClosureRef API is ready, we should pass the RefCountedPtr<> along
- // with the callback.
- auto self = lb_calld->Ref(DEBUG_LOCATION, "client_load_report");
- self.release();
- lb_calld->ScheduleNextClientLoadReportLocked();
- }
- if (grpc_grpclb_serverlist_equals(grpclb_policy->serverlist_,
- serverlist)) {
- if (grpc_lb_glb_trace.enabled()) {
- gpr_log(GPR_INFO,
- "[grpclb %p] Incoming server list identical to current, "
- "ignoring.",
- grpclb_policy);
- }
- grpc_grpclb_destroy_serverlist(serverlist);
- } else { /* new serverlist */
- if (grpclb_policy->serverlist_ != nullptr) {
- /* dispose of the old serverlist */
- grpc_grpclb_destroy_serverlist(grpclb_policy->serverlist_);
- } else {
- /* or dispose of the fallback */
- grpc_lb_addresses_destroy(grpclb_policy->fallback_backend_addresses_);
- grpclb_policy->fallback_backend_addresses_ = nullptr;
- if (grpclb_policy->fallback_timer_callback_pending_) {
- grpc_timer_cancel(&grpclb_policy->lb_fallback_timer_);
- }
- }
- // and update the copy in the GrpcLb instance. This
- // serverlist instance will be destroyed either upon the next
- // update or when the GrpcLb instance is destroyed.
- grpclb_policy->serverlist_ = serverlist;
- grpclb_policy->serverlist_index_ = 0;
- grpclb_policy->CreateOrUpdateRoundRobinPolicyLocked();
- }
- } else {
+ // Start sending client load report only after we start using the
+ // serverlist returned from the current LB call.
+ if (lb_calld->client_stats_report_interval_ > 0 &&
+ lb_calld->client_stats_ == nullptr) {
+ lb_calld->client_stats_.reset(New<GrpcLbClientStats>());
+ // TODO(roth): We currently track this ref manually. Once the
+ // ClosureRef API is ready, we should pass the RefCountedPtr<> along
+ // with the callback.
+ auto self = lb_calld->Ref(DEBUG_LOCATION, "client_load_report");
+ self.release();
+ lb_calld->ScheduleNextClientLoadReportLocked();
+ }
+ // Check if the serverlist differs from the previous one.
+ if (grpc_grpclb_serverlist_equals(grpclb_policy->serverlist_, serverlist)) {
if (grpc_lb_glb_trace.enabled()) {
- gpr_log(GPR_INFO, "[grpclb %p] Received empty server list, ignoring.",
+ gpr_log(GPR_INFO,
+ "[grpclb %p] Incoming server list identical to current, "
+ "ignoring.",
grpclb_policy);
}
grpc_grpclb_destroy_serverlist(serverlist);
+ } else { // New serverlist.
+ if (grpclb_policy->serverlist_ != nullptr) {
+ // Dispose of the old serverlist.
+ grpc_grpclb_destroy_serverlist(grpclb_policy->serverlist_);
+ } else {
+ // Dispose of the fallback.
+ grpc_lb_addresses_destroy(grpclb_policy->fallback_backend_addresses_);
+ grpclb_policy->fallback_backend_addresses_ = nullptr;
+ if (grpclb_policy->fallback_timer_callback_pending_) {
+ grpc_timer_cancel(&grpclb_policy->lb_fallback_timer_);
+ }
+ }
+ // Update the serverlist in the GrpcLb instance. This serverlist
+ // instance will be destroyed either upon the next update or when the
+ // GrpcLb instance is destroyed.
+ grpclb_policy->serverlist_ = serverlist;
+ grpclb_policy->serverlist_index_ = 0;
+ grpclb_policy->CreateOrUpdateRoundRobinPolicyLocked();
}
} else {
// No valid initial response or serverlist found.
@@ -1331,13 +1323,10 @@ void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) {
grpc_channel_args_destroy(lb_channel_args);
}
-void GrpcLb::UpdateLocked(const grpc_channel_args& args) {
+void GrpcLb::UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) {
ProcessChannelArgsLocked(args);
- // If fallback is configured and the RR policy already exists, update
- // it with the new fallback addresses.
- if (lb_fallback_timeout_ms_ > 0 && rr_policy_ != nullptr) {
- CreateOrUpdateRoundRobinPolicyLocked();
- }
+ // Update the existing RR policy.
+ if (rr_policy_ != nullptr) CreateOrUpdateRoundRobinPolicyLocked();
// Start watching the LB channel connectivity for connection, if not
// already doing so.
if (!watching_lb_channel_) {
@@ -1585,7 +1574,7 @@ void GrpcLb::AddPendingPick(PendingPick* pp) {
bool GrpcLb::PickFromRoundRobinPolicyLocked(bool force_async, PendingPick* pp,
grpc_error** error) {
// Check for drops if we are not using fallback backend addresses.
- if (serverlist_ != nullptr) {
+ if (serverlist_ != nullptr && serverlist_->num_servers > 0) {
// Look at the index into the serverlist to see if we should drop this call.
grpc_grpclb_server* server = serverlist_->servers[serverlist_index_++];
if (serverlist_index_ == serverlist_->num_servers) {
@@ -1683,7 +1672,6 @@ grpc_channel_args* GrpcLb::CreateRoundRobinPolicyArgsLocked() {
grpc_lb_addresses* addresses;
bool is_backend_from_grpclb_load_balancer = false;
if (serverlist_ != nullptr) {
- GPR_ASSERT(serverlist_->num_servers > 0);
addresses = ProcessServerlist(serverlist_);
is_backend_from_grpclb_load_balancer = true;
} else {
@@ -1730,7 +1718,7 @@ void GrpcLb::CreateOrUpdateRoundRobinPolicyLocked() {
gpr_log(GPR_INFO, "[grpclb %p] Updating RR policy %p", this,
rr_policy_.get());
}
- rr_policy_->UpdateLocked(*args);
+ rr_policy_->UpdateLocked(*args, nullptr);
} else {
LoadBalancingPolicy::Args lb_policy_args;
lb_policy_args.combiner = combiner();
diff --git a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
index eb494486b9..d454401a66 100644
--- a/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
+++ b/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc
@@ -46,7 +46,8 @@ class PickFirst : public LoadBalancingPolicy {
public:
explicit PickFirst(const Args& args);
- void UpdateLocked(const grpc_channel_args& args) override;
+ void UpdateLocked(const grpc_channel_args& args,
+ grpc_json* lb_config) override;
bool PickLocked(PickState* pick, grpc_error** error) override;
void CancelPickLocked(PickState* pick, grpc_error* error) override;
void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask,
@@ -159,7 +160,7 @@ PickFirst::PickFirst(const Args& args) : LoadBalancingPolicy(args) {
if (grpc_lb_pick_first_trace.enabled()) {
gpr_log(GPR_INFO, "Pick First %p created.", this);
}
- UpdateLocked(*args.args);
+ UpdateLocked(*args.args, args.lb_config);
grpc_subchannel_index_ref();
}
@@ -333,7 +334,8 @@ void PickFirst::UpdateChildRefsLocked() {
child_subchannels_ = std::move(cs);
}
-void PickFirst::UpdateLocked(const grpc_channel_args& args) {
+void PickFirst::UpdateLocked(const grpc_channel_args& args,
+ grpc_json* lb_config) {
AutoChildRefsUpdater guard(this);
const grpc_arg* arg = grpc_channel_args_find(&args, GRPC_ARG_LB_ADDRESSES);
if (arg == nullptr || arg->type != GRPC_ARG_POINTER) {
diff --git a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
index e9ed85cf66..2a16975131 100644
--- a/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
+++ b/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc
@@ -57,7 +57,8 @@ class RoundRobin : public LoadBalancingPolicy {
public:
explicit RoundRobin(const Args& args);
- void UpdateLocked(const grpc_channel_args& args) override;
+ void UpdateLocked(const grpc_channel_args& args,
+ grpc_json* lb_config) override;
bool PickLocked(PickState* pick, grpc_error** error) override;
void CancelPickLocked(PickState* pick, grpc_error* error) override;
void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask,
@@ -232,7 +233,7 @@ RoundRobin::RoundRobin(const Args& args) : LoadBalancingPolicy(args) {
gpr_mu_init(&child_refs_mu_);
grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE,
"round_robin");
- UpdateLocked(*args.args);
+ UpdateLocked(*args.args, args.lb_config);
if (grpc_lb_round_robin_trace.enabled()) {
gpr_log(GPR_INFO, "[RR %p] Created with %" PRIuPTR " subchannels", this,
subchannel_list_->num_subchannels());
@@ -664,7 +665,8 @@ void RoundRobin::NotifyOnStateChangeLocked(grpc_connectivity_state* current,
notify);
}
-void RoundRobin::UpdateLocked(const grpc_channel_args& args) {
+void RoundRobin::UpdateLocked(const grpc_channel_args& args,
+ grpc_json* lb_config) {
const grpc_arg* arg = grpc_channel_args_find(&args, GRPC_ARG_LB_ADDRESSES);
AutoChildRefsUpdater guard(this);
if (GPR_UNLIKELY(arg == nullptr || arg->type != GRPC_ARG_POINTER)) {
diff --git a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc
index 38f8072e8d..89b86b38a6 100644
--- a/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc
+++ b/src/core/ext/filters/client_channel/lb_policy/xds/xds.cc
@@ -26,30 +26,26 @@
/// channel that uses pick_first to select from the list of balancer
/// addresses.
///
-/// The first time the policy gets a request for a pick, a ping, or to exit
-/// the idle state, \a StartPickingLocked() is called. This method is
-/// responsible for instantiating the internal *streaming* call to the LB
-/// server (whichever address pick_first chose). The call will be complete
-/// when either the balancer sends status or when we cancel the call (e.g.,
-/// because we are shutting down). In needed, we retry the call. If we
-/// received at least one valid message from the server, a new call attempt
-/// will be made immediately; otherwise, we apply back-off delays between
-/// attempts.
+/// The first time the xDS policy gets a request for a pick or to exit the idle
+/// state, \a StartPickingLocked() is called. This method is responsible for
+/// instantiating the internal *streaming* call to the LB server (whichever
+/// address pick_first chose). The call will be complete when either the
+/// balancer sends status or when we cancel the call (e.g., because we are
+/// shutting down). In needed, we retry the call. If we received at least one
+/// valid message from the server, a new call attempt will be made immediately;
+/// otherwise, we apply back-off delays between attempts.
///
-/// We maintain an internal round_robin policy instance for distributing
+/// We maintain an internal child policy (round_robin) instance for distributing
/// requests across backends. Whenever we receive a new serverlist from
-/// the balancer, we update the round_robin policy with the new list of
-/// addresses. If we cannot communicate with the balancer on startup,
-/// however, we may enter fallback mode, in which case we will populate
-/// the RR policy's addresses from the backend addresses returned by the
-/// resolver.
+/// the balancer, we update the child policy with the new list of
+/// addresses.
///
-/// Once an RR policy instance is in place (and getting updated as described),
-/// calls for a pick, a ping, or a cancellation will be serviced right
-/// away by forwarding them to the RR instance. Any time there's no RR
-/// policy available (i.e., right after the creation of the gRPCLB policy),
-/// pick and ping requests are added to a list of pending picks and pings
-/// to be flushed and serviced when the RR policy instance becomes available.
+/// Once a child policy instance is in place (and getting updated as
+/// described), calls for a pick, or a cancellation will be serviced right away
+/// by forwarding them to the child policy instance. Any time there's no child
+/// policy available (i.e., right after the creation of the xDS policy), pick
+/// requests are added to a list of pending picks to be flushed and serviced
+/// when the child policy instance becomes available.
///
/// \see https://github.com/grpc/grpc/blob/master/doc/load-balancing.md for the
/// high level design and details.
@@ -122,7 +118,8 @@ class XdsLb : public LoadBalancingPolicy {
public:
XdsLb(const grpc_lb_addresses* addresses, const Args& args);
- void UpdateLocked(const grpc_channel_args& args) override;
+ void UpdateLocked(const grpc_channel_args& args,
+ grpc_json* lb_config) override;
bool PickLocked(PickState* pick, grpc_error** error) override;
void CancelPickLocked(PickState* pick, grpc_error* error) override;
void CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask,
@@ -141,10 +138,10 @@ class XdsLb : public LoadBalancingPolicy {
private:
/// Linked list of pending pick requests. It stores all information needed to
- /// eventually call (Round Robin's) pick() on them. They mainly stay pending
- /// waiting for the RR policy to be created.
+ /// eventually call pick() on them. They mainly stay pending waiting for the
+ /// child policy to be created.
///
- /// Note that when a pick is sent to the RR policy, we inject our own
+ /// Note that when a pick is sent to the child policy, we inject our own
/// on_complete callback, so that we can intercept the result before
/// invoking the original on_complete callback. This allows us to set the
/// LB token metadata and add client_stats to the call context.
@@ -202,7 +199,6 @@ class XdsLb : public LoadBalancingPolicy {
static bool LoadReportCountersAreZero(xds_grpclb_request* request);
static void MaybeSendClientLoadReportLocked(void* arg, grpc_error* error);
- static void ClientLoadReportDoneLocked(void* arg, grpc_error* error);
static void OnInitialRequestSentLocked(void* arg, grpc_error* error);
static void OnBalancerMessageReceivedLocked(void* arg, grpc_error* error);
static void OnBalancerStatusReceivedLocked(void* arg, grpc_error* error);
@@ -266,18 +262,18 @@ class XdsLb : public LoadBalancingPolicy {
void AddPendingPick(PendingPick* pp);
static void OnPendingPickComplete(void* arg, grpc_error* error);
- // Methods for dealing with the RR policy.
- void CreateOrUpdateRoundRobinPolicyLocked();
- grpc_channel_args* CreateRoundRobinPolicyArgsLocked();
- void CreateRoundRobinPolicyLocked(const Args& args);
- bool PickFromRoundRobinPolicyLocked(bool force_async, PendingPick* pp,
- grpc_error** error);
- void UpdateConnectivityStateFromRoundRobinPolicyLocked(
- grpc_error* rr_state_error);
- static void OnRoundRobinConnectivityChangedLocked(void* arg,
- grpc_error* error);
- static void OnRoundRobinRequestReresolutionLocked(void* arg,
- grpc_error* error);
+ // Methods for dealing with the child policy.
+ void CreateOrUpdateChildPolicyLocked();
+ grpc_channel_args* CreateChildPolicyArgsLocked();
+ void CreateChildPolicyLocked(const Args& args);
+ bool PickFromChildPolicyLocked(bool force_async, PendingPick* pp,
+ grpc_error** error);
+ void UpdateConnectivityStateFromChildPolicyLocked(
+ grpc_error* child_state_error);
+ static void OnChildPolicyConnectivityChangedLocked(void* arg,
+ grpc_error* error);
+ static void OnChildPolicyRequestReresolutionLocked(void* arg,
+ grpc_error* error);
// Who the client is trying to communicate with.
const char* server_name_ = nullptr;
@@ -330,14 +326,14 @@ class XdsLb : public LoadBalancingPolicy {
grpc_timer lb_fallback_timer_;
grpc_closure lb_on_fallback_;
- // Pending picks that are waiting on the RR policy's connectivity.
+ // Pending picks that are waiting on the xDS policy's connectivity.
PendingPick* pending_picks_ = nullptr;
- // The RR policy to use for the backends.
- OrphanablePtr<LoadBalancingPolicy> rr_policy_;
- grpc_connectivity_state rr_connectivity_state_;
- grpc_closure on_rr_connectivity_changed_;
- grpc_closure on_rr_request_reresolution_;
+ // The policy to use for the backends.
+ OrphanablePtr<LoadBalancingPolicy> child_policy_;
+ grpc_connectivity_state child_connectivity_state_;
+ grpc_closure on_child_connectivity_changed_;
+ grpc_closure on_child_request_reresolution_;
};
//
@@ -444,7 +440,7 @@ grpc_lb_addresses* ProcessServerlist(const xds_grpclb_serverlist* serverlist) {
grpc_lb_addresses* lb_addresses =
grpc_lb_addresses_create(num_valid, &lb_token_vtable);
/* second pass: actually populate the addresses and LB tokens (aka user data
- * to the outside world) to be read by the RR policy during its creation.
+ * to the outside world) to be read by the child policy during its creation.
* Given that the validity tests are very cheap, they are performed again
* instead of marking the valid ones during the first pass, as this would
* incurr in an allocation due to the arbitrary number of server */
@@ -671,6 +667,7 @@ bool XdsLb::BalancerCallState::LoadReportCountersAreZero(
(drop_entries == nullptr || drop_entries->empty());
}
+// TODO(vpowar): Use LRS to send the client Load Report.
void XdsLb::BalancerCallState::SendClientLoadReportLocked() {
// Construct message payload.
GPR_ASSERT(send_message_payload_ == nullptr);
@@ -688,38 +685,8 @@ void XdsLb::BalancerCallState::SendClientLoadReportLocked() {
} else {
last_client_load_report_counters_were_zero_ = false;
}
- grpc_slice request_payload_slice = xds_grpclb_request_encode(request);
- send_message_payload_ =
- grpc_raw_byte_buffer_create(&request_payload_slice, 1);
- grpc_slice_unref_internal(request_payload_slice);
+ // TODO(vpowar): Send the report on LRS stream.
xds_grpclb_request_destroy(request);
- // Send the report.
- grpc_op op;
- memset(&op, 0, sizeof(op));
- op.op = GRPC_OP_SEND_MESSAGE;
- op.data.send_message.send_message = send_message_payload_;
- GRPC_CLOSURE_INIT(&client_load_report_closure_, ClientLoadReportDoneLocked,
- this, grpc_combiner_scheduler(xdslb_policy()->combiner()));
- grpc_call_error call_error = grpc_call_start_batch_and_execute(
- lb_call_, &op, 1, &client_load_report_closure_);
- if (GPR_UNLIKELY(call_error != GRPC_CALL_OK)) {
- gpr_log(GPR_ERROR, "[xdslb %p] call_error=%d", xdslb_policy_.get(),
- call_error);
- GPR_ASSERT(GRPC_CALL_OK == call_error);
- }
-}
-
-void XdsLb::BalancerCallState::ClientLoadReportDoneLocked(void* arg,
- grpc_error* error) {
- BalancerCallState* lb_calld = static_cast<BalancerCallState*>(arg);
- XdsLb* xdslb_policy = lb_calld->xdslb_policy();
- grpc_byte_buffer_destroy(lb_calld->send_message_payload_);
- lb_calld->send_message_payload_ = nullptr;
- if (error != GRPC_ERROR_NONE || lb_calld != xdslb_policy->lb_calld_.get()) {
- lb_calld->Unref(DEBUG_LOCATION, "client_load_report");
- return;
- }
- lb_calld->ScheduleNextClientLoadReportLocked();
}
void XdsLb::BalancerCallState::OnInitialRequestSentLocked(void* arg,
@@ -833,7 +800,7 @@ void XdsLb::BalancerCallState::OnBalancerMessageReceivedLocked(
// serverlist instance will be destroyed either upon the next
// update or when the XdsLb instance is destroyed.
xdslb_policy->serverlist_ = serverlist;
- xdslb_policy->CreateOrUpdateRoundRobinPolicyLocked();
+ xdslb_policy->CreateOrUpdateChildPolicyLocked();
}
} else {
if (grpc_lb_xds_trace.enabled()) {
@@ -866,7 +833,7 @@ void XdsLb::BalancerCallState::OnBalancerMessageReceivedLocked(
&lb_calld->lb_on_balancer_message_received_);
GPR_ASSERT(GRPC_CALL_OK == call_error);
} else {
- lb_calld->Unref(DEBUG_LOCATION, "on_message_received+grpclb_shutdown");
+ lb_calld->Unref(DEBUG_LOCATION, "on_message_received+xds_shutdown");
}
}
@@ -944,7 +911,7 @@ grpc_lb_addresses* ExtractBalancerAddresses(
* - \a addresses: corresponding to the balancers.
* - \a response_generator: in order to propagate updates from the resolver
* above the grpclb policy.
- * - \a args: other args inherited from the grpclb policy. */
+ * - \a args: other args inherited from the xds policy. */
grpc_channel_args* BuildBalancerChannelArgs(
const grpc_lb_addresses* addresses,
FakeResolverResponseGenerator* response_generator,
@@ -966,10 +933,10 @@ grpc_channel_args* BuildBalancerChannelArgs(
// resolver will have is_balancer=false, whereas our own addresses have
// is_balancer=true. We need the LB channel to return addresses with
// is_balancer=false so that it does not wind up recursively using the
- // grpclb LB policy, as per the special case logic in client_channel.c.
+ // xds LB policy, as per the special case logic in client_channel.c.
GRPC_ARG_LB_ADDRESSES,
// The fake resolver response generator, because we are replacing it
- // with the one from the grpclb policy, used to propagate updates to
+ // with the one from the xds policy, used to propagate updates to
// the LB channel.
GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR,
// The LB channel should use the authority indicated by the target
@@ -991,7 +958,7 @@ grpc_channel_args* BuildBalancerChannelArgs(
// address updates into the LB channel.
grpc_core::FakeResolverResponseGenerator::MakeChannelArg(
response_generator),
- // A channel arg indicating the target is a grpclb load balancer.
+ // A channel arg indicating the target is a xds load balancer.
grpc_channel_arg_integer_create(
const_cast<char*>(GRPC_ARG_ADDRESS_IS_XDS_LOAD_BALANCER), 1),
// A channel arg indicating this is an internal channels, aka it is
@@ -1014,6 +981,7 @@ grpc_channel_args* BuildBalancerChannelArgs(
// ctor and dtor
//
+// TODO(vishalpowar): Use lb_config in args to configure LB policy.
XdsLb::XdsLb(const grpc_lb_addresses* addresses,
const LoadBalancingPolicy::Args& args)
: LoadBalancingPolicy(args),
@@ -1031,11 +999,11 @@ XdsLb::XdsLb(const grpc_lb_addresses* addresses,
GRPC_CLOSURE_INIT(&lb_channel_on_connectivity_changed_,
&XdsLb::OnBalancerChannelConnectivityChangedLocked, this,
grpc_combiner_scheduler(args.combiner));
- GRPC_CLOSURE_INIT(&on_rr_connectivity_changed_,
- &XdsLb::OnRoundRobinConnectivityChangedLocked, this,
+ GRPC_CLOSURE_INIT(&on_child_connectivity_changed_,
+ &XdsLb::OnChildPolicyConnectivityChangedLocked, this,
grpc_combiner_scheduler(args.combiner));
- GRPC_CLOSURE_INIT(&on_rr_request_reresolution_,
- &XdsLb::OnRoundRobinRequestReresolutionLocked, this,
+ GRPC_CLOSURE_INIT(&on_child_request_reresolution_,
+ &XdsLb::OnChildPolicyRequestReresolutionLocked, this,
grpc_combiner_scheduler(args.combiner));
grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE, "xds");
// Record server name.
@@ -1087,7 +1055,7 @@ void XdsLb::ShutdownLocked() {
if (fallback_timer_callback_pending_) {
grpc_timer_cancel(&lb_fallback_timer_);
}
- rr_policy_.reset();
+ child_policy_.reset();
TryReresolutionLocked(&grpc_lb_xds_trace, GRPC_ERROR_CANCELLED);
// We destroy the LB channel here instead of in our destructor because
// destroying the channel triggers a last callback to
@@ -1100,7 +1068,7 @@ void XdsLb::ShutdownLocked() {
gpr_mu_unlock(&lb_channel_mu_);
}
grpc_connectivity_state_set(&state_tracker_, GRPC_CHANNEL_SHUTDOWN,
- GRPC_ERROR_REF(error), "grpclb_shutdown");
+ GRPC_ERROR_REF(error), "xds_shutdown");
// Clear pending picks.
PendingPick* pp;
while ((pp = pending_picks_) != nullptr) {
@@ -1133,13 +1101,13 @@ void XdsLb::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) {
// Cancel a specific pending pick.
//
-// A grpclb pick progresses as follows:
-// - If there's a Round Robin policy (rr_policy_) available, it'll be
-// handed over to the RR policy (in CreateRoundRobinPolicyLocked()). From
-// that point onwards, it'll be RR's responsibility. For cancellations, that
-// implies the pick needs also be cancelled by the RR instance.
-// - Otherwise, without an RR instance, picks stay pending at this policy's
-// level (grpclb), inside the pending_picks_ list. To cancel these,
+// A pick progresses as follows:
+// - If there's a child policy available, it'll be handed over to child policy
+// (in CreateChildPolicyLocked()). From that point onwards, it'll be the
+// child policy's responsibility. For cancellations, that implies the pick
+// needs to be also cancelled by the child policy instance.
+// - Otherwise, without a child policy instance, picks stay pending at this
+// policy's level (xds), inside the pending_picks_ list. To cancel these,
// we invoke the completion closure and set the pick's connected
// subchannel to nullptr right here.
void XdsLb::CancelPickLocked(PickState* pick, grpc_error* error) {
@@ -1159,21 +1127,21 @@ void XdsLb::CancelPickLocked(PickState* pick, grpc_error* error) {
}
pp = next;
}
- if (rr_policy_ != nullptr) {
- rr_policy_->CancelPickLocked(pick, GRPC_ERROR_REF(error));
+ if (child_policy_ != nullptr) {
+ child_policy_->CancelPickLocked(pick, GRPC_ERROR_REF(error));
}
GRPC_ERROR_UNREF(error);
}
// Cancel all pending picks.
//
-// A grpclb pick progresses as follows:
-// - If there's a Round Robin policy (rr_policy_) available, it'll be
-// handed over to the RR policy (in CreateRoundRobinPolicyLocked()). From
-// that point onwards, it'll be RR's responsibility. For cancellations, that
-// implies the pick needs also be cancelled by the RR instance.
-// - Otherwise, without an RR instance, picks stay pending at this policy's
-// level (grpclb), inside the pending_picks_ list. To cancel these,
+// A pick progresses as follows:
+// - If there's a child policy available, it'll be handed over to child policy
+// (in CreateChildPolicyLocked()). From that point onwards, it'll be the
+// child policy's responsibility. For cancellations, that implies the pick
+// needs to be also cancelled by the child policy instance.
+// - Otherwise, without a child policy instance, picks stay pending at this
+// policy's level (xds), inside the pending_picks_ list. To cancel these,
// we invoke the completion closure and set the pick's connected
// subchannel to nullptr right here.
void XdsLb::CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask,
@@ -1195,10 +1163,10 @@ void XdsLb::CancelMatchingPicksLocked(uint32_t initial_metadata_flags_mask,
}
pp = next;
}
- if (rr_policy_ != nullptr) {
- rr_policy_->CancelMatchingPicksLocked(initial_metadata_flags_mask,
- initial_metadata_flags_eq,
- GRPC_ERROR_REF(error));
+ if (child_policy_ != nullptr) {
+ child_policy_->CancelMatchingPicksLocked(initial_metadata_flags_mask,
+ initial_metadata_flags_eq,
+ GRPC_ERROR_REF(error));
}
GRPC_ERROR_UNREF(error);
}
@@ -1213,22 +1181,21 @@ void XdsLb::ResetBackoffLocked() {
if (lb_channel_ != nullptr) {
grpc_channel_reset_connect_backoff(lb_channel_);
}
- if (rr_policy_ != nullptr) {
- rr_policy_->ResetBackoffLocked();
+ if (child_policy_ != nullptr) {
+ child_policy_->ResetBackoffLocked();
}
}
bool XdsLb::PickLocked(PickState* pick, grpc_error** error) {
PendingPick* pp = PendingPickCreate(pick);
bool pick_done = false;
- if (rr_policy_ != nullptr) {
+ if (child_policy_ != nullptr) {
if (grpc_lb_xds_trace.enabled()) {
- gpr_log(GPR_INFO, "[xdslb %p] about to PICK from RR %p", this,
- rr_policy_.get());
+ gpr_log(GPR_INFO, "[xdslb %p] about to PICK from policy %p", this,
+ child_policy_.get());
}
- pick_done =
- PickFromRoundRobinPolicyLocked(false /* force_async */, pp, error);
- } else { // rr_policy_ == NULL
+ pick_done = PickFromChildPolicyLocked(false /* force_async */, pp, error);
+ } else { // child_policy_ == NULL
if (pick->on_complete == nullptr) {
*error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"No pick result available but synchronous result required.");
@@ -1236,7 +1203,7 @@ bool XdsLb::PickLocked(PickState* pick, grpc_error** error) {
} else {
if (grpc_lb_xds_trace.enabled()) {
gpr_log(GPR_INFO,
- "[xdslb %p] No RR policy. Adding to grpclb's pending picks",
+ "[xdslb %p] No child policy. Adding to xds's pending picks",
this);
}
AddPendingPick(pp);
@@ -1251,8 +1218,8 @@ bool XdsLb::PickLocked(PickState* pick, grpc_error** error) {
void XdsLb::FillChildRefsForChannelz(channelz::ChildRefsList* child_subchannels,
channelz::ChildRefsList* child_channels) {
- // delegate to the RoundRobin to fill the children subchannels.
- rr_policy_->FillChildRefsForChannelz(child_subchannels, child_channels);
+ // delegate to the child_policy_ to fill the children subchannels.
+ child_policy_->FillChildRefsForChannelz(child_subchannels, child_channels);
MutexLock lock(&lb_channel_mu_);
if (lb_channel_ != nullptr) {
grpc_core::channelz::ChannelNode* channel_node =
@@ -1319,13 +1286,15 @@ void XdsLb::ProcessChannelArgsLocked(const grpc_channel_args& args) {
grpc_channel_args_destroy(lb_channel_args);
}
-void XdsLb::UpdateLocked(const grpc_channel_args& args) {
+// TODO(vishalpowar): Use lb_config to configure LB policy.
+void XdsLb::UpdateLocked(const grpc_channel_args& args, grpc_json* lb_config) {
ProcessChannelArgsLocked(args);
- // If fallback is configured and the RR policy already exists, update
- // it with the new fallback addresses.
- if (lb_fallback_timeout_ms_ > 0 && rr_policy_ != nullptr) {
- CreateOrUpdateRoundRobinPolicyLocked();
- }
+ // Update the existing child policy.
+ // Note: We have disabled fallback mode in the code, so this child policy must
+ // have been created from a serverlist.
+ // TODO(vpowar): Handle the fallback_address changes when we add support for
+ // fallback in xDS.
+ if (child_policy_ != nullptr) CreateOrUpdateChildPolicyLocked();
// Start watching the LB channel connectivity for connection, if not
// already doing so.
if (!watching_lb_channel_) {
@@ -1393,11 +1362,10 @@ void XdsLb::OnFallbackTimerLocked(void* arg, grpc_error* error) {
if (xdslb_policy->serverlist_ == nullptr && !xdslb_policy->shutting_down_ &&
error == GRPC_ERROR_NONE) {
if (grpc_lb_xds_trace.enabled()) {
- gpr_log(GPR_INFO, "[xdslb %p] Falling back to use backends from resolver",
+ gpr_log(GPR_INFO,
+ "[xdslb %p] Fallback timer fired. Not using fallback backends",
xdslb_policy);
}
- GPR_ASSERT(xdslb_policy->fallback_backend_addresses_ != nullptr);
- xdslb_policy->CreateOrUpdateRoundRobinPolicyLocked();
}
xdslb_policy->Unref(DEBUG_LOCATION, "on_fallback_timer");
}
@@ -1447,8 +1415,8 @@ void XdsLb::OnBalancerChannelConnectivityChangedLocked(void* arg,
XdsLb* xdslb_policy = static_cast<XdsLb*>(arg);
if (xdslb_policy->shutting_down_) goto done;
// Re-initialize the lb_call. This should also take care of updating the
- // embedded RR policy. Note that the current RR policy, if any, will stay in
- // effect until an update from the new lb_call is received.
+ // child policy. Note that the current child policy, if any, will
+ // stay in effect until an update from the new lb_call is received.
switch (xdslb_policy->lb_channel_connectivity_) {
case GRPC_CHANNEL_CONNECTING:
case GRPC_CHANNEL_TRANSIENT_FAILURE: {
@@ -1507,8 +1475,8 @@ void DestroyClientStats(void* arg) {
}
void XdsLb::PendingPickSetMetadataAndContext(PendingPick* pp) {
- /* if connected_subchannel is nullptr, no pick has been made by the RR
- * policy (e.g., all addresses failed to connect). There won't be any
+ /* if connected_subchannel is nullptr, no pick has been made by the
+ * child policy (e.g., all addresses failed to connect). There won't be any
* user_data/token available */
if (pp->pick->connected_subchannel != nullptr) {
if (GPR_LIKELY(!GRPC_MDISNULL(pp->lb_token))) {
@@ -1534,8 +1502,8 @@ void XdsLb::PendingPickSetMetadataAndContext(PendingPick* pp) {
}
/* The \a on_complete closure passed as part of the pick requires keeping a
- * reference to its associated round robin instance. We wrap this closure in
- * order to unref the round robin instance upon its invocation */
+ * reference to its associated child policy instance. We wrap this closure in
+ * order to unref the child policy instance upon its invocation */
void XdsLb::OnPendingPickComplete(void* arg, grpc_error* error) {
PendingPick* pp = static_cast<PendingPick*>(arg);
PendingPickSetMetadataAndContext(pp);
@@ -1560,24 +1528,24 @@ void XdsLb::AddPendingPick(PendingPick* pp) {
}
//
-// code for interacting with the RR policy
+// code for interacting with the child policy
//
-// Performs a pick over \a rr_policy_. Given that a pick can return
+// Performs a pick over \a child_policy_. Given that a pick can return
// immediately (ignoring its completion callback), we need to perform the
// cleanups this callback would otherwise be responsible for.
// If \a force_async is true, then we will manually schedule the
// completion callback even if the pick is available immediately.
-bool XdsLb::PickFromRoundRobinPolicyLocked(bool force_async, PendingPick* pp,
- grpc_error** error) {
+bool XdsLb::PickFromChildPolicyLocked(bool force_async, PendingPick* pp,
+ grpc_error** error) {
// Set client_stats and user_data.
if (lb_calld_ != nullptr && lb_calld_->client_stats() != nullptr) {
pp->client_stats = lb_calld_->client_stats()->Ref();
}
GPR_ASSERT(pp->pick->user_data == nullptr);
pp->pick->user_data = (void**)&pp->lb_token;
- // Pick via the RR policy.
- bool pick_done = rr_policy_->PickLocked(pp->pick, error);
+ // Pick via the child policy.
+ bool pick_done = child_policy_->PickLocked(pp->pick, error);
if (pick_done) {
PendingPickSetMetadataAndContext(pp);
if (force_async) {
@@ -1588,72 +1556,67 @@ bool XdsLb::PickFromRoundRobinPolicyLocked(bool force_async, PendingPick* pp,
Delete(pp);
}
// else, the pending pick will be registered and taken care of by the
- // pending pick list inside the RR policy. Eventually,
+ // pending pick list inside the child policy. Eventually,
// OnPendingPickComplete() will be called, which will (among other
// things) add the LB token to the call's initial metadata.
return pick_done;
}
-void XdsLb::CreateRoundRobinPolicyLocked(const Args& args) {
- GPR_ASSERT(rr_policy_ == nullptr);
- rr_policy_ = LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy(
+void XdsLb::CreateChildPolicyLocked(const Args& args) {
+ GPR_ASSERT(child_policy_ == nullptr);
+ child_policy_ = LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy(
"round_robin", args);
- if (GPR_UNLIKELY(rr_policy_ == nullptr)) {
- gpr_log(GPR_ERROR, "[xdslb %p] Failure creating a RoundRobin policy", this);
+ if (GPR_UNLIKELY(child_policy_ == nullptr)) {
+ gpr_log(GPR_ERROR, "[xdslb %p] Failure creating a child policy", this);
return;
}
// TODO(roth): We currently track this ref manually. Once the new
// ClosureRef API is done, pass the RefCountedPtr<> along with the closure.
- auto self = Ref(DEBUG_LOCATION, "on_rr_reresolution_requested");
+ auto self = Ref(DEBUG_LOCATION, "on_child_reresolution_requested");
self.release();
- rr_policy_->SetReresolutionClosureLocked(&on_rr_request_reresolution_);
- grpc_error* rr_state_error = nullptr;
- rr_connectivity_state_ = rr_policy_->CheckConnectivityLocked(&rr_state_error);
- // Connectivity state is a function of the RR policy updated/created.
- UpdateConnectivityStateFromRoundRobinPolicyLocked(rr_state_error);
- // Add the gRPC LB's interested_parties pollset_set to that of the newly
- // created RR policy. This will make the RR policy progress upon activity on
- // gRPC LB, which in turn is tied to the application's call.
- grpc_pollset_set_add_pollset_set(rr_policy_->interested_parties(),
+ child_policy_->SetReresolutionClosureLocked(&on_child_request_reresolution_);
+ grpc_error* child_state_error = nullptr;
+ child_connectivity_state_ =
+ child_policy_->CheckConnectivityLocked(&child_state_error);
+ // Connectivity state is a function of the child policy updated/created.
+ UpdateConnectivityStateFromChildPolicyLocked(child_state_error);
+ // Add the xDS's interested_parties pollset_set to that of the newly created
+ // child policy. This will make the child policy progress upon activity on
+ // xDS LB, which in turn is tied to the application's call.
+ grpc_pollset_set_add_pollset_set(child_policy_->interested_parties(),
interested_parties());
- // Subscribe to changes to the connectivity of the new RR.
+ // Subscribe to changes to the connectivity of the new child policy.
// TODO(roth): We currently track this ref manually. Once the new
// ClosureRef API is done, pass the RefCountedPtr<> along with the closure.
- self = Ref(DEBUG_LOCATION, "on_rr_connectivity_changed");
+ self = Ref(DEBUG_LOCATION, "on_child_connectivity_changed");
self.release();
- rr_policy_->NotifyOnStateChangeLocked(&rr_connectivity_state_,
- &on_rr_connectivity_changed_);
- rr_policy_->ExitIdleLocked();
- // Send pending picks to RR policy.
+ child_policy_->NotifyOnStateChangeLocked(&child_connectivity_state_,
+ &on_child_connectivity_changed_);
+ child_policy_->ExitIdleLocked();
+ // Send pending picks to child policy.
PendingPick* pp;
while ((pp = pending_picks_)) {
pending_picks_ = pp->next;
if (grpc_lb_xds_trace.enabled()) {
- gpr_log(GPR_INFO,
- "[xdslb %p] Pending pick about to (async) PICK from RR %p", this,
- rr_policy_.get());
+ gpr_log(
+ GPR_INFO,
+ "[xdslb %p] Pending pick about to (async) PICK from child policy %p",
+ this, child_policy_.get());
}
grpc_error* error = GRPC_ERROR_NONE;
- PickFromRoundRobinPolicyLocked(true /* force_async */, pp, &error);
+ PickFromChildPolicyLocked(true /* force_async */, pp, &error);
}
}
-grpc_channel_args* XdsLb::CreateRoundRobinPolicyArgsLocked() {
+grpc_channel_args* XdsLb::CreateChildPolicyArgsLocked() {
grpc_lb_addresses* addresses;
bool is_backend_from_grpclb_load_balancer = false;
- if (serverlist_ != nullptr) {
- GPR_ASSERT(serverlist_->num_servers > 0);
- addresses = ProcessServerlist(serverlist_);
- is_backend_from_grpclb_load_balancer = true;
- } else {
- // If CreateOrUpdateRoundRobinPolicyLocked() is invoked when we haven't
- // received any serverlist from the balancer, we use the fallback backends
- // returned by the resolver. Note that the fallback backend list may be
- // empty, in which case the new round_robin policy will keep the requested
- // picks pending.
- GPR_ASSERT(fallback_backend_addresses_ != nullptr);
- addresses = grpc_lb_addresses_copy(fallback_backend_addresses_);
- }
+ // This should never be invoked if we do not have serverlist_, as fallback
+ // mode is disabled for xDS plugin.
+ GPR_ASSERT(serverlist_ != nullptr);
+ GPR_ASSERT(serverlist_->num_servers > 0);
+ addresses = ProcessServerlist(serverlist_);
+ is_backend_from_grpclb_load_balancer = true;
GPR_ASSERT(addresses != nullptr);
// Replace the LB addresses in the channel args that we pass down to
// the subchannel.
@@ -1673,66 +1636,68 @@ grpc_channel_args* XdsLb::CreateRoundRobinPolicyArgsLocked() {
return args;
}
-void XdsLb::CreateOrUpdateRoundRobinPolicyLocked() {
+void XdsLb::CreateOrUpdateChildPolicyLocked() {
if (shutting_down_) return;
- grpc_channel_args* args = CreateRoundRobinPolicyArgsLocked();
+ grpc_channel_args* args = CreateChildPolicyArgsLocked();
GPR_ASSERT(args != nullptr);
- if (rr_policy_ != nullptr) {
+ if (child_policy_ != nullptr) {
if (grpc_lb_xds_trace.enabled()) {
- gpr_log(GPR_INFO, "[xdslb %p] Updating RR policy %p", this,
- rr_policy_.get());
+ gpr_log(GPR_INFO, "[xdslb %p] Updating the child policy %p", this,
+ child_policy_.get());
}
- rr_policy_->UpdateLocked(*args);
+ // TODO(vishalpowar): Pass the correct LB config.
+ child_policy_->UpdateLocked(*args, nullptr);
} else {
LoadBalancingPolicy::Args lb_policy_args;
lb_policy_args.combiner = combiner();
lb_policy_args.client_channel_factory = client_channel_factory();
lb_policy_args.args = args;
- CreateRoundRobinPolicyLocked(lb_policy_args);
+ CreateChildPolicyLocked(lb_policy_args);
if (grpc_lb_xds_trace.enabled()) {
- gpr_log(GPR_INFO, "[xdslb %p] Created new RR policy %p", this,
- rr_policy_.get());
+ gpr_log(GPR_INFO, "[xdslb %p] Created a new child policy %p", this,
+ child_policy_.get());
}
}
grpc_channel_args_destroy(args);
}
-void XdsLb::OnRoundRobinRequestReresolutionLocked(void* arg,
- grpc_error* error) {
+void XdsLb::OnChildPolicyRequestReresolutionLocked(void* arg,
+ grpc_error* error) {
XdsLb* xdslb_policy = static_cast<XdsLb*>(arg);
if (xdslb_policy->shutting_down_ || error != GRPC_ERROR_NONE) {
- xdslb_policy->Unref(DEBUG_LOCATION, "on_rr_reresolution_requested");
+ xdslb_policy->Unref(DEBUG_LOCATION, "on_child_reresolution_requested");
return;
}
if (grpc_lb_xds_trace.enabled()) {
- gpr_log(
- GPR_INFO,
- "[xdslb %p] Re-resolution requested from the internal RR policy (%p).",
- xdslb_policy, xdslb_policy->rr_policy_.get());
+ gpr_log(GPR_INFO,
+ "[xdslb %p] Re-resolution requested from child policy "
+ "(%p).",
+ xdslb_policy, xdslb_policy->child_policy_.get());
}
// If we are talking to a balancer, we expect to get updated addresses form
- // the balancer, so we can ignore the re-resolution request from the RR
- // policy. Otherwise, handle the re-resolution request using the
- // grpclb policy's original re-resolution closure.
+ // the balancer, so we can ignore the re-resolution request from the child
+ // policy.
+ // Otherwise, handle the re-resolution request using the xds policy's
+ // original re-resolution closure.
if (xdslb_policy->lb_calld_ == nullptr ||
!xdslb_policy->lb_calld_->seen_initial_response()) {
xdslb_policy->TryReresolutionLocked(&grpc_lb_xds_trace, GRPC_ERROR_NONE);
}
- // Give back the wrapper closure to the RR policy.
- xdslb_policy->rr_policy_->SetReresolutionClosureLocked(
- &xdslb_policy->on_rr_request_reresolution_);
+ // Give back the wrapper closure to the child policy.
+ xdslb_policy->child_policy_->SetReresolutionClosureLocked(
+ &xdslb_policy->on_child_request_reresolution_);
}
-void XdsLb::UpdateConnectivityStateFromRoundRobinPolicyLocked(
- grpc_error* rr_state_error) {
+void XdsLb::UpdateConnectivityStateFromChildPolicyLocked(
+ grpc_error* child_state_error) {
const grpc_connectivity_state curr_glb_state =
grpc_connectivity_state_check(&state_tracker_);
/* The new connectivity status is a function of the previous one and the new
- * input coming from the status of the RR policy.
+ * input coming from the status of the child policy.
*
- * current state (grpclb's)
+ * current state (xds's)
* |
- * v || I | C | R | TF | SD | <- new state (RR's)
+ * v || I | C | R | TF | SD | <- new state (child policy's)
* ===++====+=====+=====+======+======+
* I || I | C | R | [I] | [I] |
* ---++----+-----+-----+------+------+
@@ -1745,52 +1710,51 @@ void XdsLb::UpdateConnectivityStateFromRoundRobinPolicyLocked(
* SD || NA | NA | NA | NA | NA | (*)
* ---++----+-----+-----+------+------+
*
- * A [STATE] indicates that the old RR policy is kept. In those cases, STATE
- * is the current state of grpclb, which is left untouched.
+ * A [STATE] indicates that the old child policy is kept. In those cases,
+ * STATE is the current state of xds, which is left untouched.
*
* In summary, if the new state is TRANSIENT_FAILURE or SHUTDOWN, stick to
- * the previous RR instance.
+ * the previous child policy instance.
*
* Note that the status is never updated to SHUTDOWN as a result of calling
* this function. Only glb_shutdown() has the power to set that state.
*
* (*) This function mustn't be called during shutting down. */
GPR_ASSERT(curr_glb_state != GRPC_CHANNEL_SHUTDOWN);
- switch (rr_connectivity_state_) {
+ switch (child_connectivity_state_) {
case GRPC_CHANNEL_TRANSIENT_FAILURE:
case GRPC_CHANNEL_SHUTDOWN:
- GPR_ASSERT(rr_state_error != GRPC_ERROR_NONE);
+ GPR_ASSERT(child_state_error != GRPC_ERROR_NONE);
break;
case GRPC_CHANNEL_IDLE:
case GRPC_CHANNEL_CONNECTING:
case GRPC_CHANNEL_READY:
- GPR_ASSERT(rr_state_error == GRPC_ERROR_NONE);
+ GPR_ASSERT(child_state_error == GRPC_ERROR_NONE);
}
if (grpc_lb_xds_trace.enabled()) {
- gpr_log(
- GPR_INFO,
- "[xdslb %p] Setting grpclb's state to %s from new RR policy %p state.",
- this, grpc_connectivity_state_name(rr_connectivity_state_),
- rr_policy_.get());
+ gpr_log(GPR_INFO,
+ "[xdslb %p] Setting xds's state to %s from child policy %p state.",
+ this, grpc_connectivity_state_name(child_connectivity_state_),
+ child_policy_.get());
}
- grpc_connectivity_state_set(&state_tracker_, rr_connectivity_state_,
- rr_state_error,
+ grpc_connectivity_state_set(&state_tracker_, child_connectivity_state_,
+ child_state_error,
"update_lb_connectivity_status_locked");
}
-void XdsLb::OnRoundRobinConnectivityChangedLocked(void* arg,
- grpc_error* error) {
+void XdsLb::OnChildPolicyConnectivityChangedLocked(void* arg,
+ grpc_error* error) {
XdsLb* xdslb_policy = static_cast<XdsLb*>(arg);
if (xdslb_policy->shutting_down_) {
- xdslb_policy->Unref(DEBUG_LOCATION, "on_rr_connectivity_changed");
+ xdslb_policy->Unref(DEBUG_LOCATION, "on_child_connectivity_changed");
return;
}
- xdslb_policy->UpdateConnectivityStateFromRoundRobinPolicyLocked(
+ xdslb_policy->UpdateConnectivityStateFromChildPolicyLocked(
GRPC_ERROR_REF(error));
- // Resubscribe. Reuse the "on_rr_connectivity_changed" ref.
- xdslb_policy->rr_policy_->NotifyOnStateChangeLocked(
- &xdslb_policy->rr_connectivity_state_,
- &xdslb_policy->on_rr_connectivity_changed_);
+ // Resubscribe. Reuse the "on_child_connectivity_changed" ref.
+ xdslb_policy->child_policy_->NotifyOnStateChangeLocked(
+ &xdslb_policy->child_connectivity_state_,
+ &xdslb_policy->on_child_connectivity_changed_);
}
//
diff --git a/src/core/ext/filters/client_channel/lb_policy_registry.cc b/src/core/ext/filters/client_channel/lb_policy_registry.cc
index d651b1120d..ad459c9c8c 100644
--- a/src/core/ext/filters/client_channel/lb_policy_registry.cc
+++ b/src/core/ext/filters/client_channel/lb_policy_registry.cc
@@ -94,4 +94,9 @@ LoadBalancingPolicyRegistry::CreateLoadBalancingPolicy(
return factory->CreateLoadBalancingPolicy(args);
}
+bool LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(const char* name) {
+ GPR_ASSERT(g_state != nullptr);
+ return g_state->GetLoadBalancingPolicyFactory(name) != nullptr;
+}
+
} // namespace grpc_core
diff --git a/src/core/ext/filters/client_channel/lb_policy_registry.h b/src/core/ext/filters/client_channel/lb_policy_registry.h
index 2e9bb061ed..338f7c9f69 100644
--- a/src/core/ext/filters/client_channel/lb_policy_registry.h
+++ b/src/core/ext/filters/client_channel/lb_policy_registry.h
@@ -47,6 +47,10 @@ class LoadBalancingPolicyRegistry {
/// Creates an LB policy of the type specified by \a name.
static OrphanablePtr<LoadBalancingPolicy> CreateLoadBalancingPolicy(
const char* name, const LoadBalancingPolicy::Args& args);
+
+ /// Returns true if the LB policy factory specified by \a name exists in this
+ /// registry.
+ static bool LoadBalancingPolicyExists(const char* name);
};
} // namespace grpc_core
diff --git a/src/core/ext/filters/client_channel/method_params.cc b/src/core/ext/filters/client_channel/method_params.cc
deleted file mode 100644
index 1f116bb67d..0000000000
--- a/src/core/ext/filters/client_channel/method_params.cc
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- *
- * Copyright 2015 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#include <grpc/support/port_platform.h>
-
-#include <stdio.h>
-#include <string.h>
-
-#include <grpc/support/alloc.h>
-#include <grpc/support/log.h>
-#include <grpc/support/string_util.h>
-
-#include "src/core/ext/filters/client_channel/method_params.h"
-#include "src/core/lib/channel/status_util.h"
-#include "src/core/lib/gpr/string.h"
-#include "src/core/lib/gprpp/memory.h"
-
-// As per the retry design, we do not allow more than 5 retry attempts.
-#define MAX_MAX_RETRY_ATTEMPTS 5
-
-namespace grpc_core {
-namespace internal {
-
-namespace {
-
-bool ParseWaitForReady(
- grpc_json* field, ClientChannelMethodParams::WaitForReady* wait_for_ready) {
- if (field->type != GRPC_JSON_TRUE && field->type != GRPC_JSON_FALSE) {
- return false;
- }
- *wait_for_ready = field->type == GRPC_JSON_TRUE
- ? ClientChannelMethodParams::WAIT_FOR_READY_TRUE
- : ClientChannelMethodParams::WAIT_FOR_READY_FALSE;
- return true;
-}
-
-// Parses a JSON field of the form generated for a google.proto.Duration
-// proto message, as per:
-// https://developers.google.com/protocol-buffers/docs/proto3#json
-bool ParseDuration(grpc_json* field, grpc_millis* duration) {
- if (field->type != GRPC_JSON_STRING) return false;
- size_t len = strlen(field->value);
- if (field->value[len - 1] != 's') return false;
- UniquePtr<char> buf(gpr_strdup(field->value));
- *(buf.get() + len - 1) = '\0'; // Remove trailing 's'.
- char* decimal_point = strchr(buf.get(), '.');
- int nanos = 0;
- if (decimal_point != nullptr) {
- *decimal_point = '\0';
- nanos = gpr_parse_nonnegative_int(decimal_point + 1);
- if (nanos == -1) {
- return false;
- }
- int num_digits = static_cast<int>(strlen(decimal_point + 1));
- if (num_digits > 9) { // We don't accept greater precision than nanos.
- return false;
- }
- for (int i = 0; i < (9 - num_digits); ++i) {
- nanos *= 10;
- }
- }
- int seconds =
- decimal_point == buf.get() ? 0 : gpr_parse_nonnegative_int(buf.get());
- if (seconds == -1) return false;
- *duration = seconds * GPR_MS_PER_SEC + nanos / GPR_NS_PER_MS;
- return true;
-}
-
-UniquePtr<ClientChannelMethodParams::RetryPolicy> ParseRetryPolicy(
- grpc_json* field) {
- auto retry_policy = MakeUnique<ClientChannelMethodParams::RetryPolicy>();
- if (field->type != GRPC_JSON_OBJECT) return nullptr;
- for (grpc_json* sub_field = field->child; sub_field != nullptr;
- sub_field = sub_field->next) {
- if (sub_field->key == nullptr) return nullptr;
- if (strcmp(sub_field->key, "maxAttempts") == 0) {
- if (retry_policy->max_attempts != 0) return nullptr; // Duplicate.
- if (sub_field->type != GRPC_JSON_NUMBER) return nullptr;
- retry_policy->max_attempts = gpr_parse_nonnegative_int(sub_field->value);
- if (retry_policy->max_attempts <= 1) return nullptr;
- if (retry_policy->max_attempts > MAX_MAX_RETRY_ATTEMPTS) {
- gpr_log(GPR_ERROR,
- "service config: clamped retryPolicy.maxAttempts at %d",
- MAX_MAX_RETRY_ATTEMPTS);
- retry_policy->max_attempts = MAX_MAX_RETRY_ATTEMPTS;
- }
- } else if (strcmp(sub_field->key, "initialBackoff") == 0) {
- if (retry_policy->initial_backoff > 0) return nullptr; // Duplicate.
- if (!ParseDuration(sub_field, &retry_policy->initial_backoff)) {
- return nullptr;
- }
- if (retry_policy->initial_backoff == 0) return nullptr;
- } else if (strcmp(sub_field->key, "maxBackoff") == 0) {
- if (retry_policy->max_backoff > 0) return nullptr; // Duplicate.
- if (!ParseDuration(sub_field, &retry_policy->max_backoff)) {
- return nullptr;
- }
- if (retry_policy->max_backoff == 0) return nullptr;
- } else if (strcmp(sub_field->key, "backoffMultiplier") == 0) {
- if (retry_policy->backoff_multiplier != 0) return nullptr; // Duplicate.
- if (sub_field->type != GRPC_JSON_NUMBER) return nullptr;
- if (sscanf(sub_field->value, "%f", &retry_policy->backoff_multiplier) !=
- 1) {
- return nullptr;
- }
- if (retry_policy->backoff_multiplier <= 0) return nullptr;
- } else if (strcmp(sub_field->key, "retryableStatusCodes") == 0) {
- if (!retry_policy->retryable_status_codes.Empty()) {
- return nullptr; // Duplicate.
- }
- if (sub_field->type != GRPC_JSON_ARRAY) return nullptr;
- for (grpc_json* element = sub_field->child; element != nullptr;
- element = element->next) {
- if (element->type != GRPC_JSON_STRING) return nullptr;
- grpc_status_code status;
- if (!grpc_status_code_from_string(element->value, &status)) {
- return nullptr;
- }
- retry_policy->retryable_status_codes.Add(status);
- }
- if (retry_policy->retryable_status_codes.Empty()) return nullptr;
- }
- }
- // Make sure required fields are set.
- if (retry_policy->max_attempts == 0 || retry_policy->initial_backoff == 0 ||
- retry_policy->max_backoff == 0 || retry_policy->backoff_multiplier == 0 ||
- retry_policy->retryable_status_codes.Empty()) {
- return nullptr;
- }
- return retry_policy;
-}
-
-} // namespace
-
-RefCountedPtr<ClientChannelMethodParams>
-ClientChannelMethodParams::CreateFromJson(const grpc_json* json) {
- RefCountedPtr<ClientChannelMethodParams> method_params =
- MakeRefCounted<ClientChannelMethodParams>();
- for (grpc_json* field = json->child; field != nullptr; field = field->next) {
- if (field->key == nullptr) continue;
- if (strcmp(field->key, "waitForReady") == 0) {
- if (method_params->wait_for_ready_ != WAIT_FOR_READY_UNSET) {
- return nullptr; // Duplicate.
- }
- if (!ParseWaitForReady(field, &method_params->wait_for_ready_)) {
- return nullptr;
- }
- } else if (strcmp(field->key, "timeout") == 0) {
- if (method_params->timeout_ > 0) return nullptr; // Duplicate.
- if (!ParseDuration(field, &method_params->timeout_)) return nullptr;
- } else if (strcmp(field->key, "retryPolicy") == 0) {
- if (method_params->retry_policy_ != nullptr) {
- return nullptr; // Duplicate.
- }
- method_params->retry_policy_ = ParseRetryPolicy(field);
- if (method_params->retry_policy_ == nullptr) return nullptr;
- }
- }
- return method_params;
-}
-
-} // namespace internal
-} // namespace grpc_core
diff --git a/src/core/ext/filters/client_channel/method_params.h b/src/core/ext/filters/client_channel/method_params.h
deleted file mode 100644
index a31d360f17..0000000000
--- a/src/core/ext/filters/client_channel/method_params.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- *
- * Copyright 2015 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-
-#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_METHOD_PARAMS_H
-#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_METHOD_PARAMS_H
-
-#include <grpc/support/port_platform.h>
-
-#include "src/core/lib/channel/status_util.h"
-#include "src/core/lib/gprpp/ref_counted.h"
-#include "src/core/lib/gprpp/ref_counted_ptr.h"
-#include "src/core/lib/iomgr/exec_ctx.h" // for grpc_millis
-#include "src/core/lib/json/json.h"
-
-namespace grpc_core {
-namespace internal {
-
-class ClientChannelMethodParams : public RefCounted<ClientChannelMethodParams> {
- public:
- enum WaitForReady {
- WAIT_FOR_READY_UNSET = 0,
- WAIT_FOR_READY_FALSE,
- WAIT_FOR_READY_TRUE
- };
-
- struct RetryPolicy {
- int max_attempts = 0;
- grpc_millis initial_backoff = 0;
- grpc_millis max_backoff = 0;
- float backoff_multiplier = 0;
- StatusCodeSet retryable_status_codes;
- };
-
- /// Creates a method_parameters object from \a json.
- /// Intended for use with ServiceConfig::CreateMethodConfigTable().
- static RefCountedPtr<ClientChannelMethodParams> CreateFromJson(
- const grpc_json* json);
-
- grpc_millis timeout() const { return timeout_; }
- WaitForReady wait_for_ready() const { return wait_for_ready_; }
- const RetryPolicy* retry_policy() const { return retry_policy_.get(); }
-
- private:
- // So New() can call our private ctor.
- template <typename T, typename... Args>
- friend T* grpc_core::New(Args&&... args);
-
- // So Delete() can call our private dtor.
- template <typename T>
- friend void grpc_core::Delete(T*);
-
- ClientChannelMethodParams() {}
- virtual ~ClientChannelMethodParams() {}
-
- grpc_millis timeout_ = 0;
- WaitForReady wait_for_ready_ = WAIT_FOR_READY_UNSET;
- UniquePtr<RetryPolicy> retry_policy_;
-};
-
-} // namespace internal
-} // namespace grpc_core
-
-#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_METHOD_PARAMS_H */
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
index 01796ca08f..90bc88961d 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
@@ -120,6 +120,8 @@ class AresDnsResolver : public Resolver {
grpc_lb_addresses* lb_addresses_ = nullptr;
/// currently resolving service config
char* service_config_json_ = nullptr;
+ // has shutdown been initiated
+ bool shutdown_initiated_ = false;
};
AresDnsResolver::AresDnsResolver(const ResolverArgs& args)
@@ -197,6 +199,7 @@ void AresDnsResolver::ResetBackoffLocked() {
}
void AresDnsResolver::ShutdownLocked() {
+ shutdown_initiated_ = true;
if (have_next_resolution_timer_) {
grpc_timer_cancel(&next_resolution_timer_);
}
@@ -213,9 +216,13 @@ void AresDnsResolver::ShutdownLocked() {
void AresDnsResolver::OnNextResolutionLocked(void* arg, grpc_error* error) {
AresDnsResolver* r = static_cast<AresDnsResolver*>(arg);
+ GRPC_CARES_TRACE_LOG(
+ "%p re-resolution timer fired. error: %s. shutdown_initiated_: %d", r,
+ grpc_error_string(error), r->shutdown_initiated_);
r->have_next_resolution_timer_ = false;
- if (error == GRPC_ERROR_NONE) {
+ if (error == GRPC_ERROR_NONE && !r->shutdown_initiated_) {
if (!r->resolving_) {
+ GRPC_CARES_TRACE_LOG("%p start resolving due to re-resolution timer", r);
r->StartResolvingLocked();
}
}
@@ -301,13 +308,12 @@ void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) {
gpr_free(r->pending_request_);
r->pending_request_ = nullptr;
if (r->lb_addresses_ != nullptr) {
- static const char* args_to_remove[2];
+ static const char* args_to_remove[1];
size_t num_args_to_remove = 0;
- grpc_arg new_args[3];
+ grpc_arg args_to_add[2];
size_t num_args_to_add = 0;
- new_args[num_args_to_add++] =
+ args_to_add[num_args_to_add++] =
grpc_lb_addresses_create_channel_arg(r->lb_addresses_);
- grpc_core::UniquePtr<grpc_core::ServiceConfig> service_config;
char* service_config_string = nullptr;
if (r->service_config_json_ != nullptr) {
service_config_string = ChooseServiceConfig(r->service_config_json_);
@@ -316,31 +322,19 @@ void AresDnsResolver::OnResolvedLocked(void* arg, grpc_error* error) {
gpr_log(GPR_INFO, "selected service config choice: %s",
service_config_string);
args_to_remove[num_args_to_remove++] = GRPC_ARG_SERVICE_CONFIG;
- new_args[num_args_to_add++] = grpc_channel_arg_string_create(
+ args_to_add[num_args_to_add++] = grpc_channel_arg_string_create(
(char*)GRPC_ARG_SERVICE_CONFIG, service_config_string);
- service_config =
- grpc_core::ServiceConfig::Create(service_config_string);
- if (service_config != nullptr) {
- const char* lb_policy_name =
- service_config->GetLoadBalancingPolicyName();
- if (lb_policy_name != nullptr) {
- args_to_remove[num_args_to_remove++] = GRPC_ARG_LB_POLICY_NAME;
- new_args[num_args_to_add++] = grpc_channel_arg_string_create(
- (char*)GRPC_ARG_LB_POLICY_NAME,
- const_cast<char*>(lb_policy_name));
- }
- }
}
}
result = grpc_channel_args_copy_and_add_and_remove(
- r->channel_args_, args_to_remove, num_args_to_remove, new_args,
+ r->channel_args_, args_to_remove, num_args_to_remove, args_to_add,
num_args_to_add);
gpr_free(service_config_string);
grpc_lb_addresses_destroy(r->lb_addresses_);
// Reset backoff state so that we start from the beginning when the
// next request gets triggered.
r->backoff_.Reset();
- } else {
+ } else if (!r->shutdown_initiated_) {
const char* msg = grpc_error_string(error);
gpr_log(GPR_DEBUG, "dns resolution failed: %s", msg);
grpc_millis next_try = r->backoff_.NextAttemptTime();
diff --git a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc
index 144ac24a56..3aa690bea4 100644
--- a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc
+++ b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc
@@ -103,7 +103,7 @@ void FakeResolver::NextLocked(grpc_channel_args** target_result,
}
void FakeResolver::RequestReresolutionLocked() {
- if (reresolution_results_ != nullptr) {
+ if (reresolution_results_ != nullptr || return_failure_) {
grpc_channel_args_destroy(next_results_);
next_results_ = grpc_channel_args_copy(reresolution_results_);
MaybeFinishNextLocked();
@@ -141,6 +141,7 @@ struct SetResponseClosureArg {
grpc_closure set_response_closure;
FakeResolverResponseGenerator* generator;
grpc_channel_args* response;
+ bool immediate = true;
};
void FakeResolverResponseGenerator::SetResponseLocked(void* arg,
@@ -194,7 +195,7 @@ void FakeResolverResponseGenerator::SetFailureLocked(void* arg,
SetResponseClosureArg* closure_arg = static_cast<SetResponseClosureArg*>(arg);
FakeResolver* resolver = closure_arg->generator->resolver_;
resolver->return_failure_ = true;
- resolver->MaybeFinishNextLocked();
+ if (closure_arg->immediate) resolver->MaybeFinishNextLocked();
Delete(closure_arg);
}
@@ -209,6 +210,18 @@ void FakeResolverResponseGenerator::SetFailure() {
GRPC_ERROR_NONE);
}
+void FakeResolverResponseGenerator::SetFailureOnReresolution() {
+ GPR_ASSERT(resolver_ != nullptr);
+ SetResponseClosureArg* closure_arg = New<SetResponseClosureArg>();
+ closure_arg->generator = this;
+ closure_arg->immediate = false;
+ GRPC_CLOSURE_SCHED(
+ GRPC_CLOSURE_INIT(&closure_arg->set_response_closure, SetFailureLocked,
+ closure_arg,
+ grpc_combiner_scheduler(resolver_->combiner())),
+ GRPC_ERROR_NONE);
+}
+
namespace {
static void* response_generator_arg_copy(void* p) {
diff --git a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h
index 74a3062e7f..7f69059351 100644
--- a/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h
+++ b/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h
@@ -61,6 +61,10 @@ class FakeResolverResponseGenerator
// returning a null result with no error).
void SetFailure();
+ // Same as SetFailure(), but instead of returning the error
+ // immediately, waits for the next call to RequestReresolutionLocked().
+ void SetFailureOnReresolution();
+
// Returns a channel arg containing \a generator.
static grpc_arg MakeChannelArg(FakeResolverResponseGenerator* generator);
diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.cc b/src/core/ext/filters/client_channel/resolver_result_parsing.cc
new file mode 100644
index 0000000000..82a26ace63
--- /dev/null
+++ b/src/core/ext/filters/client_channel/resolver_result_parsing.cc
@@ -0,0 +1,384 @@
+/*
+ *
+ * Copyright 2018 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <grpc/support/port_platform.h>
+
+#include "src/core/ext/filters/client_channel/resolver_result_parsing.h"
+
+#include <ctype.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+
+#include "src/core/ext/filters/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
+#include "src/core/lib/channel/status_util.h"
+#include "src/core/lib/gpr/string.h"
+#include "src/core/lib/gprpp/memory.h"
+
+// As per the retry design, we do not allow more than 5 retry attempts.
+#define MAX_MAX_RETRY_ATTEMPTS 5
+
+namespace grpc_core {
+namespace internal {
+
+namespace {
+
+// Converts string format from JSON to proto.
+grpc_core::UniquePtr<char> ConvertCamelToSnake(const char* camel) {
+ const size_t size = strlen(camel);
+ char* snake = static_cast<char*>(gpr_malloc(size * 2));
+ size_t j = 0;
+ for (size_t i = 0; i < size; ++i) {
+ if (isupper(camel[i])) {
+ snake[j++] = '_';
+ snake[j++] = tolower(camel[i]);
+ } else {
+ snake[j++] = camel[i];
+ }
+ }
+ snake[j] = '\0';
+ return grpc_core::UniquePtr<char>(snake);
+}
+
+} // namespace
+
+ProcessedResolverResult::ProcessedResolverResult(
+ const grpc_channel_args* resolver_result, bool parse_retry) {
+ ProcessServiceConfig(resolver_result, parse_retry);
+ // If no LB config was found above, just find the LB policy name then.
+ if (lb_policy_config_ == nullptr) ProcessLbPolicyName(resolver_result);
+}
+
+void ProcessedResolverResult::ProcessServiceConfig(
+ const grpc_channel_args* resolver_result, bool parse_retry) {
+ const grpc_arg* channel_arg =
+ grpc_channel_args_find(resolver_result, GRPC_ARG_SERVICE_CONFIG);
+ const char* service_config_json = grpc_channel_arg_get_string(channel_arg);
+ if (service_config_json != nullptr) {
+ service_config_json_.reset(gpr_strdup(service_config_json));
+ service_config_ = grpc_core::ServiceConfig::Create(service_config_json);
+ if (service_config_ != nullptr) {
+ if (parse_retry) {
+ channel_arg =
+ grpc_channel_args_find(resolver_result, GRPC_ARG_SERVER_URI);
+ const char* server_uri = grpc_channel_arg_get_string(channel_arg);
+ GPR_ASSERT(server_uri != nullptr);
+ grpc_uri* uri = grpc_uri_parse(server_uri, true);
+ GPR_ASSERT(uri->path[0] != '\0');
+ server_name_ = uri->path[0] == '/' ? uri->path + 1 : uri->path;
+ service_config_->ParseGlobalParams(ParseServiceConfig, this);
+ grpc_uri_destroy(uri);
+ } else {
+ service_config_->ParseGlobalParams(ParseServiceConfig, this);
+ }
+ method_params_table_ = service_config_->CreateMethodConfigTable(
+ ClientChannelMethodParams::CreateFromJson);
+ }
+ }
+}
+
+void ProcessedResolverResult::ProcessLbPolicyName(
+ const grpc_channel_args* resolver_result) {
+ const char* lb_policy_name = nullptr;
+ // Prefer the LB policy name found in the service config. Note that this is
+ // checking the deprecated loadBalancingPolicy field, rather than the new
+ // loadBalancingConfig field.
+ if (service_config_ != nullptr) {
+ lb_policy_name = service_config_->GetLoadBalancingPolicyName();
+ }
+ // Otherwise, find the LB policy name set by the client API.
+ if (lb_policy_name == nullptr) {
+ const grpc_arg* channel_arg =
+ grpc_channel_args_find(resolver_result, GRPC_ARG_LB_POLICY_NAME);
+ lb_policy_name = grpc_channel_arg_get_string(channel_arg);
+ }
+ // Special case: If at least one balancer address is present, we use
+ // the grpclb policy, regardless of what the resolver has returned.
+ const grpc_arg* channel_arg =
+ grpc_channel_args_find(resolver_result, GRPC_ARG_LB_ADDRESSES);
+ if (channel_arg != nullptr && channel_arg->type == GRPC_ARG_POINTER) {
+ grpc_lb_addresses* addresses =
+ static_cast<grpc_lb_addresses*>(channel_arg->value.pointer.p);
+ if (grpc_lb_addresses_contains_balancer_address(*addresses)) {
+ if (lb_policy_name != nullptr &&
+ gpr_stricmp(lb_policy_name, "grpclb") != 0) {
+ gpr_log(GPR_INFO,
+ "resolver requested LB policy %s but provided at least one "
+ "balancer address -- forcing use of grpclb LB policy",
+ lb_policy_name);
+ }
+ lb_policy_name = "grpclb";
+ }
+ }
+ // Use pick_first if nothing was specified and we didn't select grpclb
+ // above.
+ if (lb_policy_name == nullptr) lb_policy_name = "pick_first";
+ lb_policy_name_.reset(gpr_strdup(lb_policy_name));
+}
+
+void ProcessedResolverResult::ParseServiceConfig(
+ const grpc_json* field, ProcessedResolverResult* parsing_state) {
+ parsing_state->ParseLbConfigFromServiceConfig(field);
+ if (parsing_state->server_name_ != nullptr) {
+ parsing_state->ParseRetryThrottleParamsFromServiceConfig(field);
+ }
+}
+
+void ProcessedResolverResult::ParseLbConfigFromServiceConfig(
+ const grpc_json* field) {
+ if (lb_policy_config_ != nullptr) return; // Already found.
+ // Find the LB config global parameter.
+ if (field->key == nullptr || strcmp(field->key, "loadBalancingConfig") != 0 ||
+ field->type != GRPC_JSON_ARRAY) {
+ return; // Not valid lb config array.
+ }
+ // Find the first LB policy that this client supports.
+ for (grpc_json* lb_config = field->child; lb_config != nullptr;
+ lb_config = lb_config->next) {
+ if (lb_config->type != GRPC_JSON_OBJECT) return;
+ // Find the policy object.
+ grpc_json* policy = nullptr;
+ for (grpc_json* field = lb_config->child; field != nullptr;
+ field = field->next) {
+ if (field->key == nullptr || strcmp(field->key, "policy") != 0 ||
+ field->type != GRPC_JSON_OBJECT) {
+ return;
+ }
+ if (policy != nullptr) return; // Duplicate.
+ policy = field;
+ }
+ // Find the specific policy content since the policy object is of type
+ // "oneof".
+ grpc_json* policy_content = nullptr;
+ for (grpc_json* field = policy->child; field != nullptr;
+ field = field->next) {
+ if (field->key == nullptr || field->type != GRPC_JSON_OBJECT) return;
+ if (policy_content != nullptr) return; // Violate "oneof" type.
+ policy_content = field;
+ }
+ grpc_core::UniquePtr<char> lb_policy_name =
+ ConvertCamelToSnake(policy_content->key);
+ if (!grpc_core::LoadBalancingPolicyRegistry::LoadBalancingPolicyExists(
+ lb_policy_name.get())) {
+ continue;
+ }
+ lb_policy_name_ = std::move(lb_policy_name);
+ lb_policy_config_ = policy_content->child;
+ return;
+ }
+}
+
+void ProcessedResolverResult::ParseRetryThrottleParamsFromServiceConfig(
+ const grpc_json* field) {
+ if (strcmp(field->key, "retryThrottling") == 0) {
+ if (retry_throttle_data_ != nullptr) return; // Duplicate.
+ if (field->type != GRPC_JSON_OBJECT) return;
+ int max_milli_tokens = 0;
+ int milli_token_ratio = 0;
+ for (grpc_json* sub_field = field->child; sub_field != nullptr;
+ sub_field = sub_field->next) {
+ if (sub_field->key == nullptr) return;
+ if (strcmp(sub_field->key, "maxTokens") == 0) {
+ if (max_milli_tokens != 0) return; // Duplicate.
+ if (sub_field->type != GRPC_JSON_NUMBER) return;
+ max_milli_tokens = gpr_parse_nonnegative_int(sub_field->value);
+ if (max_milli_tokens == -1) return;
+ max_milli_tokens *= 1000;
+ } else if (strcmp(sub_field->key, "tokenRatio") == 0) {
+ if (milli_token_ratio != 0) return; // Duplicate.
+ if (sub_field->type != GRPC_JSON_NUMBER) return;
+ // We support up to 3 decimal digits.
+ size_t whole_len = strlen(sub_field->value);
+ uint32_t multiplier = 1;
+ uint32_t decimal_value = 0;
+ const char* decimal_point = strchr(sub_field->value, '.');
+ if (decimal_point != nullptr) {
+ whole_len = static_cast<size_t>(decimal_point - sub_field->value);
+ multiplier = 1000;
+ size_t decimal_len = strlen(decimal_point + 1);
+ if (decimal_len > 3) decimal_len = 3;
+ if (!gpr_parse_bytes_to_uint32(decimal_point + 1, decimal_len,
+ &decimal_value)) {
+ return;
+ }
+ uint32_t decimal_multiplier = 1;
+ for (size_t i = 0; i < (3 - decimal_len); ++i) {
+ decimal_multiplier *= 10;
+ }
+ decimal_value *= decimal_multiplier;
+ }
+ uint32_t whole_value;
+ if (!gpr_parse_bytes_to_uint32(sub_field->value, whole_len,
+ &whole_value)) {
+ return;
+ }
+ milli_token_ratio =
+ static_cast<int>((whole_value * multiplier) + decimal_value);
+ if (milli_token_ratio <= 0) return;
+ }
+ }
+ retry_throttle_data_ =
+ grpc_core::internal::ServerRetryThrottleMap::GetDataForServer(
+ server_name_, max_milli_tokens, milli_token_ratio);
+ }
+}
+
+namespace {
+
+bool ParseWaitForReady(
+ grpc_json* field, ClientChannelMethodParams::WaitForReady* wait_for_ready) {
+ if (field->type != GRPC_JSON_TRUE && field->type != GRPC_JSON_FALSE) {
+ return false;
+ }
+ *wait_for_ready = field->type == GRPC_JSON_TRUE
+ ? ClientChannelMethodParams::WAIT_FOR_READY_TRUE
+ : ClientChannelMethodParams::WAIT_FOR_READY_FALSE;
+ return true;
+}
+
+// Parses a JSON field of the form generated for a google.proto.Duration
+// proto message, as per:
+// https://developers.google.com/protocol-buffers/docs/proto3#json
+bool ParseDuration(grpc_json* field, grpc_millis* duration) {
+ if (field->type != GRPC_JSON_STRING) return false;
+ size_t len = strlen(field->value);
+ if (field->value[len - 1] != 's') return false;
+ UniquePtr<char> buf(gpr_strdup(field->value));
+ *(buf.get() + len - 1) = '\0'; // Remove trailing 's'.
+ char* decimal_point = strchr(buf.get(), '.');
+ int nanos = 0;
+ if (decimal_point != nullptr) {
+ *decimal_point = '\0';
+ nanos = gpr_parse_nonnegative_int(decimal_point + 1);
+ if (nanos == -1) {
+ return false;
+ }
+ int num_digits = static_cast<int>(strlen(decimal_point + 1));
+ if (num_digits > 9) { // We don't accept greater precision than nanos.
+ return false;
+ }
+ for (int i = 0; i < (9 - num_digits); ++i) {
+ nanos *= 10;
+ }
+ }
+ int seconds =
+ decimal_point == buf.get() ? 0 : gpr_parse_nonnegative_int(buf.get());
+ if (seconds == -1) return false;
+ *duration = seconds * GPR_MS_PER_SEC + nanos / GPR_NS_PER_MS;
+ return true;
+}
+
+UniquePtr<ClientChannelMethodParams::RetryPolicy> ParseRetryPolicy(
+ grpc_json* field) {
+ auto retry_policy = MakeUnique<ClientChannelMethodParams::RetryPolicy>();
+ if (field->type != GRPC_JSON_OBJECT) return nullptr;
+ for (grpc_json* sub_field = field->child; sub_field != nullptr;
+ sub_field = sub_field->next) {
+ if (sub_field->key == nullptr) return nullptr;
+ if (strcmp(sub_field->key, "maxAttempts") == 0) {
+ if (retry_policy->max_attempts != 0) return nullptr; // Duplicate.
+ if (sub_field->type != GRPC_JSON_NUMBER) return nullptr;
+ retry_policy->max_attempts = gpr_parse_nonnegative_int(sub_field->value);
+ if (retry_policy->max_attempts <= 1) return nullptr;
+ if (retry_policy->max_attempts > MAX_MAX_RETRY_ATTEMPTS) {
+ gpr_log(GPR_ERROR,
+ "service config: clamped retryPolicy.maxAttempts at %d",
+ MAX_MAX_RETRY_ATTEMPTS);
+ retry_policy->max_attempts = MAX_MAX_RETRY_ATTEMPTS;
+ }
+ } else if (strcmp(sub_field->key, "initialBackoff") == 0) {
+ if (retry_policy->initial_backoff > 0) return nullptr; // Duplicate.
+ if (!ParseDuration(sub_field, &retry_policy->initial_backoff)) {
+ return nullptr;
+ }
+ if (retry_policy->initial_backoff == 0) return nullptr;
+ } else if (strcmp(sub_field->key, "maxBackoff") == 0) {
+ if (retry_policy->max_backoff > 0) return nullptr; // Duplicate.
+ if (!ParseDuration(sub_field, &retry_policy->max_backoff)) {
+ return nullptr;
+ }
+ if (retry_policy->max_backoff == 0) return nullptr;
+ } else if (strcmp(sub_field->key, "backoffMultiplier") == 0) {
+ if (retry_policy->backoff_multiplier != 0) return nullptr; // Duplicate.
+ if (sub_field->type != GRPC_JSON_NUMBER) return nullptr;
+ if (sscanf(sub_field->value, "%f", &retry_policy->backoff_multiplier) !=
+ 1) {
+ return nullptr;
+ }
+ if (retry_policy->backoff_multiplier <= 0) return nullptr;
+ } else if (strcmp(sub_field->key, "retryableStatusCodes") == 0) {
+ if (!retry_policy->retryable_status_codes.Empty()) {
+ return nullptr; // Duplicate.
+ }
+ if (sub_field->type != GRPC_JSON_ARRAY) return nullptr;
+ for (grpc_json* element = sub_field->child; element != nullptr;
+ element = element->next) {
+ if (element->type != GRPC_JSON_STRING) return nullptr;
+ grpc_status_code status;
+ if (!grpc_status_code_from_string(element->value, &status)) {
+ return nullptr;
+ }
+ retry_policy->retryable_status_codes.Add(status);
+ }
+ if (retry_policy->retryable_status_codes.Empty()) return nullptr;
+ }
+ }
+ // Make sure required fields are set.
+ if (retry_policy->max_attempts == 0 || retry_policy->initial_backoff == 0 ||
+ retry_policy->max_backoff == 0 || retry_policy->backoff_multiplier == 0 ||
+ retry_policy->retryable_status_codes.Empty()) {
+ return nullptr;
+ }
+ return retry_policy;
+}
+
+} // namespace
+
+RefCountedPtr<ClientChannelMethodParams>
+ClientChannelMethodParams::CreateFromJson(const grpc_json* json) {
+ RefCountedPtr<ClientChannelMethodParams> method_params =
+ MakeRefCounted<ClientChannelMethodParams>();
+ for (grpc_json* field = json->child; field != nullptr; field = field->next) {
+ if (field->key == nullptr) continue;
+ if (strcmp(field->key, "waitForReady") == 0) {
+ if (method_params->wait_for_ready_ != WAIT_FOR_READY_UNSET) {
+ return nullptr; // Duplicate.
+ }
+ if (!ParseWaitForReady(field, &method_params->wait_for_ready_)) {
+ return nullptr;
+ }
+ } else if (strcmp(field->key, "timeout") == 0) {
+ if (method_params->timeout_ > 0) return nullptr; // Duplicate.
+ if (!ParseDuration(field, &method_params->timeout_)) return nullptr;
+ } else if (strcmp(field->key, "retryPolicy") == 0) {
+ if (method_params->retry_policy_ != nullptr) {
+ return nullptr; // Duplicate.
+ }
+ method_params->retry_policy_ = ParseRetryPolicy(field);
+ if (method_params->retry_policy_ == nullptr) return nullptr;
+ }
+ }
+ return method_params;
+}
+
+} // namespace internal
+} // namespace grpc_core
diff --git a/src/core/ext/filters/client_channel/resolver_result_parsing.h b/src/core/ext/filters/client_channel/resolver_result_parsing.h
new file mode 100644
index 0000000000..f1fb7406bc
--- /dev/null
+++ b/src/core/ext/filters/client_channel/resolver_result_parsing.h
@@ -0,0 +1,146 @@
+/*
+ *
+ * Copyright 2018 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_RESULT_PARSING_H
+#define GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_RESULT_PARSING_H
+
+#include <grpc/support/port_platform.h>
+
+#include "src/core/ext/filters/client_channel/retry_throttle.h"
+#include "src/core/lib/channel/status_util.h"
+#include "src/core/lib/gprpp/ref_counted.h"
+#include "src/core/lib/gprpp/ref_counted_ptr.h"
+#include "src/core/lib/iomgr/exec_ctx.h" // for grpc_millis
+#include "src/core/lib/json/json.h"
+#include "src/core/lib/slice/slice_hash_table.h"
+#include "src/core/lib/transport/service_config.h"
+
+namespace grpc_core {
+namespace internal {
+
+class ClientChannelMethodParams;
+
+// A table mapping from a method name to its method parameters.
+typedef grpc_core::SliceHashTable<
+ grpc_core::RefCountedPtr<ClientChannelMethodParams>>
+ ClientChannelMethodParamsTable;
+
+// A container of processed fields from the resolver result. Simplifies the
+// usage of resolver result.
+class ProcessedResolverResult {
+ public:
+ // Processes the resolver result and populates the relative members
+ // for later consumption. Tries to parse retry parameters only if parse_retry
+ // is true.
+ ProcessedResolverResult(const grpc_channel_args* resolver_result,
+ bool parse_retry);
+
+ // Getters. Any managed object's ownership is transferred.
+ grpc_core::UniquePtr<char> service_config_json() {
+ return std::move(service_config_json_);
+ }
+ grpc_core::RefCountedPtr<ServerRetryThrottleData> retry_throttle_data() {
+ return std::move(retry_throttle_data_);
+ }
+ grpc_core::RefCountedPtr<ClientChannelMethodParamsTable>
+ method_params_table() {
+ return std::move(method_params_table_);
+ }
+ grpc_core::UniquePtr<char> lb_policy_name() {
+ return std::move(lb_policy_name_);
+ }
+ grpc_json* lb_policy_config() { return lb_policy_config_; }
+
+ private:
+ // Finds the service config; extracts LB config and (maybe) retry throttle
+ // params from it.
+ void ProcessServiceConfig(const grpc_channel_args* resolver_result,
+ bool parse_retry);
+
+ // Finds the LB policy name (when no LB config was found).
+ void ProcessLbPolicyName(const grpc_channel_args* resolver_result);
+
+ // Parses the service config. Intended to be used by
+ // ServiceConfig::ParseGlobalParams.
+ static void ParseServiceConfig(const grpc_json* field,
+ ProcessedResolverResult* parsing_state);
+ // Parses the LB config from service config.
+ void ParseLbConfigFromServiceConfig(const grpc_json* field);
+ // Parses the retry throttle parameters from service config.
+ void ParseRetryThrottleParamsFromServiceConfig(const grpc_json* field);
+
+ // Service config.
+ grpc_core::UniquePtr<char> service_config_json_;
+ grpc_core::UniquePtr<grpc_core::ServiceConfig> service_config_;
+ // LB policy.
+ grpc_json* lb_policy_config_ = nullptr;
+ grpc_core::UniquePtr<char> lb_policy_name_;
+ // Retry throttle data.
+ char* server_name_ = nullptr;
+ grpc_core::RefCountedPtr<ServerRetryThrottleData> retry_throttle_data_;
+ // Method params table.
+ grpc_core::RefCountedPtr<ClientChannelMethodParamsTable> method_params_table_;
+};
+
+// The parameters of a method.
+class ClientChannelMethodParams : public RefCounted<ClientChannelMethodParams> {
+ public:
+ enum WaitForReady {
+ WAIT_FOR_READY_UNSET = 0,
+ WAIT_FOR_READY_FALSE,
+ WAIT_FOR_READY_TRUE
+ };
+
+ struct RetryPolicy {
+ int max_attempts = 0;
+ grpc_millis initial_backoff = 0;
+ grpc_millis max_backoff = 0;
+ float backoff_multiplier = 0;
+ StatusCodeSet retryable_status_codes;
+ };
+
+ /// Creates a method_parameters object from \a json.
+ /// Intended for use with ServiceConfig::CreateMethodConfigTable().
+ static RefCountedPtr<ClientChannelMethodParams> CreateFromJson(
+ const grpc_json* json);
+
+ grpc_millis timeout() const { return timeout_; }
+ WaitForReady wait_for_ready() const { return wait_for_ready_; }
+ const RetryPolicy* retry_policy() const { return retry_policy_.get(); }
+
+ private:
+ // So New() can call our private ctor.
+ template <typename T, typename... Args>
+ friend T* grpc_core::New(Args&&... args);
+
+ // So Delete() can call our private dtor.
+ template <typename T>
+ friend void grpc_core::Delete(T*);
+
+ ClientChannelMethodParams() {}
+ virtual ~ClientChannelMethodParams() {}
+
+ grpc_millis timeout_ = 0;
+ WaitForReady wait_for_ready_ = WAIT_FOR_READY_UNSET;
+ UniquePtr<RetryPolicy> retry_policy_;
+};
+
+} // namespace internal
+} // namespace grpc_core
+
+#endif /* GRPC_CORE_EXT_FILTERS_CLIENT_CHANNEL_RESOLVER_RESULT_PARSING_H */
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc
index 978ecd59e4..99c675f503 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015 gRPC authors.
+ * Copyright 2018 gRPC authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -31,6 +31,7 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
+#include "src/core/ext/transport/chttp2/transport/context_list.h"
#include "src/core/ext/transport/chttp2/transport/frame_data.h"
#include "src/core/ext/transport/chttp2/transport/internal.h"
#include "src/core/ext/transport/chttp2/transport/varint.h"
@@ -154,6 +155,7 @@ bool g_flow_control_enabled = true;
/*******************************************************************************
* CONSTRUCTION/DESTRUCTION/REFCOUNTING
*/
+
grpc_chttp2_transport::~grpc_chttp2_transport() {
size_t i;
@@ -168,6 +170,9 @@ grpc_chttp2_transport::~grpc_chttp2_transport() {
grpc_slice_buffer_destroy_internal(&outbuf);
grpc_chttp2_hpack_compressor_destroy(&hpack_compressor);
+ grpc_core::ContextList::Execute(cl, nullptr, GRPC_ERROR_NONE);
+ cl = nullptr;
+
grpc_slice_buffer_destroy_internal(&read_buffer);
grpc_chttp2_hpack_parser_destroy(&hpack_parser);
grpc_chttp2_goaway_parser_destroy(&goaway_parser);
@@ -206,32 +211,23 @@ grpc_chttp2_transport::~grpc_chttp2_transport() {
void grpc_chttp2_unref_transport(grpc_chttp2_transport* t, const char* reason,
const char* file, int line) {
if (grpc_trace_chttp2_refcount.enabled()) {
- gpr_atm val = gpr_atm_no_barrier_load(&t->refs.count);
+ const grpc_core::RefCount::Value val = t->refs.get();
gpr_log(GPR_DEBUG, "chttp2:unref:%p %" PRIdPTR "->%" PRIdPTR " %s [%s:%d]",
t, val, val - 1, reason, file, line);
}
- if (!gpr_unref(&t->refs)) return;
- t->~grpc_chttp2_transport();
- gpr_free(t);
+ if (!t->refs.Unref()) return;
+ grpc_core::Delete(t);
}
void grpc_chttp2_ref_transport(grpc_chttp2_transport* t, const char* reason,
const char* file, int line) {
if (grpc_trace_chttp2_refcount.enabled()) {
- gpr_atm val = gpr_atm_no_barrier_load(&t->refs.count);
+ const grpc_core::RefCount::Value val = t->refs.get();
gpr_log(GPR_DEBUG, "chttp2: ref:%p %" PRIdPTR "->%" PRIdPTR " %s [%s:%d]",
t, val, val + 1, reason, file, line);
}
- gpr_ref(&t->refs);
+ t->refs.Ref();
}
-#else
-void grpc_chttp2_unref_transport(grpc_chttp2_transport* t) {
- if (!gpr_unref(&t->refs)) return;
- t->~grpc_chttp2_transport();
- gpr_free(t);
-}
-
-void grpc_chttp2_ref_transport(grpc_chttp2_transport* t) { gpr_ref(&t->refs); }
#endif
static const grpc_transport_vtable* get_vtable(void);
@@ -495,8 +491,6 @@ grpc_chttp2_transport::grpc_chttp2_transport(
GPR_ASSERT(strlen(GRPC_CHTTP2_CLIENT_CONNECT_STRING) ==
GRPC_CHTTP2_CLIENT_CONNECT_STRLEN);
base.vtable = get_vtable();
- /* one ref is for destroy */
- gpr_ref_init(&refs, 1);
/* 8 is a random stab in the dark as to a good initial size: it's small enough
that it shouldn't waste memory for infrequently used connections, yet
large enough that the exponential growth should happen nicely when it's
@@ -1065,11 +1059,13 @@ static void write_action_begin_locked(void* gt, grpc_error* error_ignored) {
static void write_action(void* gt, grpc_error* error) {
GPR_TIMER_SCOPE("write_action", 0);
grpc_chttp2_transport* t = static_cast<grpc_chttp2_transport*>(gt);
+ void* cl = t->cl;
+ t->cl = nullptr;
grpc_endpoint_write(
t->ep, &t->outbuf,
GRPC_CLOSURE_INIT(&t->write_action_end_locked, write_action_end_locked, t,
grpc_combiner_scheduler(t->combiner)),
- nullptr);
+ cl);
}
/* Callback from the grpc_endpoint after bytes have been written by calling
@@ -1393,6 +1389,8 @@ static void perform_stream_op_locked(void* stream_op,
GRPC_STATS_INC_HTTP2_OP_BATCHES();
+ s->context = op->payload->context;
+ s->traced = op->is_traced;
if (grpc_http_trace.enabled()) {
char* str = grpc_transport_stream_op_batch_string(op);
gpr_log(GPR_INFO, "perform_stream_op_locked: %s; on_complete = %p", str,
@@ -2837,8 +2835,8 @@ Chttp2IncomingByteStream::Chttp2IncomingByteStream(
: ByteStream(frame_size, flags),
transport_(transport),
stream_(stream),
+ refs_(2),
remaining_bytes_(frame_size) {
- gpr_ref_init(&refs_, 2);
GRPC_ERROR_UNREF(stream->byte_stream_error);
stream->byte_stream_error = GRPC_ERROR_NONE;
}
@@ -2863,14 +2861,6 @@ void Chttp2IncomingByteStream::Orphan() {
GRPC_ERROR_NONE);
}
-void Chttp2IncomingByteStream::Unref() {
- if (gpr_unref(&refs_)) {
- Delete(this);
- }
-}
-
-void Chttp2IncomingByteStream::Ref() { gpr_ref(&refs_); }
-
void Chttp2IncomingByteStream::NextLocked(void* arg,
grpc_error* error_ignored) {
Chttp2IncomingByteStream* bs = static_cast<Chttp2IncomingByteStream*>(arg);
@@ -3190,8 +3180,8 @@ intptr_t grpc_chttp2_transport_get_socket_uuid(grpc_transport* transport) {
grpc_transport* grpc_create_chttp2_transport(
const grpc_channel_args* channel_args, grpc_endpoint* ep, bool is_client,
grpc_resource_user* resource_user) {
- auto t = new (gpr_malloc(sizeof(grpc_chttp2_transport)))
- grpc_chttp2_transport(channel_args, ep, is_client, resource_user);
+ auto t = grpc_core::New<grpc_chttp2_transport>(channel_args, ep, is_client,
+ resource_user);
return &t->base;
}
diff --git a/src/core/ext/transport/chttp2/transport/context_list.cc b/src/core/ext/transport/chttp2/transport/context_list.cc
new file mode 100644
index 0000000000..f30d41c332
--- /dev/null
+++ b/src/core/ext/transport/chttp2/transport/context_list.cc
@@ -0,0 +1,51 @@
+/*
+ *
+ * Copyright 2018 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <grpc/support/port_platform.h>
+
+#include "src/core/ext/transport/chttp2/transport/context_list.h"
+
+namespace {
+void (*write_timestamps_callback_g)(void*, grpc_core::Timestamps*) = nullptr;
+}
+
+namespace grpc_core {
+void ContextList::Execute(void* arg, grpc_core::Timestamps* ts,
+ grpc_error* error) {
+ ContextList* head = static_cast<ContextList*>(arg);
+ ContextList* to_be_freed;
+ while (head != nullptr) {
+ if (error == GRPC_ERROR_NONE && ts != nullptr) {
+ if (write_timestamps_callback_g) {
+ ts->byte_offset = static_cast<uint32_t>(head->byte_offset_);
+ write_timestamps_callback_g(head->s_->context, ts);
+ }
+ }
+ GRPC_CHTTP2_STREAM_UNREF(static_cast<grpc_chttp2_stream*>(head->s_),
+ "timestamp");
+ to_be_freed = head;
+ head = head->next_;
+ grpc_core::Delete(to_be_freed);
+ }
+}
+
+void grpc_http2_set_write_timestamps_callback(
+ void (*fn)(void*, grpc_core::Timestamps*)) {
+ write_timestamps_callback_g = fn;
+}
+} /* namespace grpc_core */
diff --git a/src/core/ext/transport/chttp2/transport/context_list.h b/src/core/ext/transport/chttp2/transport/context_list.h
new file mode 100644
index 0000000000..d870107749
--- /dev/null
+++ b/src/core/ext/transport/chttp2/transport/context_list.h
@@ -0,0 +1,72 @@
+/*
+ *
+ * Copyright 2018 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_CONTEXT_LIST_H
+#define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_CONTEXT_LIST_H
+
+#include <grpc/support/port_platform.h>
+
+#include "src/core/lib/iomgr/buffer_list.h"
+
+#include "src/core/ext/transport/chttp2/transport/internal.h"
+
+namespace grpc_core {
+/** A list of RPC Contexts */
+class ContextList {
+ public:
+ /* Creates a new element with \a context as the value and appends it to the
+ * list. */
+ static void Append(ContextList** head, grpc_chttp2_stream* s) {
+ /* Make sure context is not already present */
+ GRPC_CHTTP2_STREAM_REF(s, "timestamp");
+
+#ifndef NDEBUG
+ ContextList* ptr = *head;
+ while (ptr != nullptr) {
+ if (ptr->s_ == s) {
+ GPR_ASSERT(
+ false &&
+ "Trying to append a stream that is already present in the list");
+ }
+ ptr = ptr->next_;
+ }
+#endif
+
+ /* Create a new element in the list and add it at the front */
+ ContextList* elem = grpc_core::New<ContextList>();
+ elem->s_ = s;
+ elem->byte_offset_ = s->byte_counter;
+ elem->next_ = *head;
+ *head = elem;
+ }
+
+ /* Executes a function \a fn with each context in the list and \a ts. It also
+ * frees up the entire list after this operation. */
+ static void Execute(void* arg, grpc_core::Timestamps* ts, grpc_error* error);
+
+ private:
+ grpc_chttp2_stream* s_ = nullptr;
+ ContextList* next_ = nullptr;
+ size_t byte_offset_ = 0;
+};
+
+void grpc_http2_set_write_timestamps_callback(
+ void (*fn)(void*, grpc_core::Timestamps*));
+} /* namespace grpc_core */
+
+#endif /* GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_CONTEXT_LIST_H */
diff --git a/src/core/ext/transport/chttp2/transport/internal.h b/src/core/ext/transport/chttp2/transport/internal.h
index 3ee408c103..6aa68f5d4a 100644
--- a/src/core/ext/transport/chttp2/transport/internal.h
+++ b/src/core/ext/transport/chttp2/transport/internal.h
@@ -45,6 +45,10 @@
#include "src/core/lib/transport/connectivity_state.h"
#include "src/core/lib/transport/transport_impl.h"
+namespace grpc_core {
+class ContextList;
+}
+
/* streams are kept in various linked lists depending on what things need to
happen to them... this enum labels each list */
typedef enum {
@@ -232,8 +236,12 @@ class Chttp2IncomingByteStream : public ByteStream {
// alone for now. We can revisit this once we're able to link against
// libc++, at which point we can eliminate New<> and Delete<> and
// switch to std::shared_ptr<>.
- void Ref();
- void Unref();
+ void Ref() { refs_.Ref(); }
+ void Unref() {
+ if (refs_.Unref()) {
+ grpc_core::Delete(this);
+ }
+ }
void PublishError(grpc_error* error);
@@ -252,7 +260,7 @@ class Chttp2IncomingByteStream : public ByteStream {
grpc_chttp2_transport* transport_; // Immutable.
grpc_chttp2_stream* stream_; // Immutable.
- gpr_refcount refs_;
+ grpc_core::RefCount refs_;
/* Accessed only by transport thread when stream->pending_byte_stream == false
* Accessed only by application thread when stream->pending_byte_stream ==
@@ -286,7 +294,7 @@ struct grpc_chttp2_transport {
~grpc_chttp2_transport();
grpc_transport base; /* must be first */
- gpr_refcount refs;
+ grpc_core::RefCount refs;
grpc_endpoint* ep;
char* peer_string;
@@ -481,7 +489,7 @@ struct grpc_chttp2_transport {
bool keepalive_permit_without_calls = false;
/** keep-alive state machine state */
grpc_chttp2_keepalive_state keepalive_state;
-
+ grpc_core::ContextList* cl = nullptr;
grpc_core::RefCountedPtr<grpc_core::channelz::SocketNode> channelz_socket;
uint32_t num_messages_in_next_write = 0;
};
@@ -498,6 +506,7 @@ struct grpc_chttp2_stream {
const void* server_data, gpr_arena* arena);
~grpc_chttp2_stream();
+ void* context;
grpc_chttp2_transport* t;
grpc_stream_refcount* refcount;
@@ -633,8 +642,12 @@ struct grpc_chttp2_stream {
/** Whether bytes stored in unprocessed_incoming_byte_stream is decompressed
*/
bool unprocessed_incoming_frames_decompressed = false;
+ /** Whether the bytes needs to be traced using Fathom */
+ bool traced = false;
/** gRPC header bytes that are already decompressed */
size_t decompressed_header_bytes = 0;
+ /** Byte counter for number of bytes written */
+ size_t byte_counter = 0;
};
/** Transport writing call flow:
@@ -786,8 +799,14 @@ void grpc_chttp2_ref_transport(grpc_chttp2_transport* t, const char* reason,
#else
#define GRPC_CHTTP2_REF_TRANSPORT(t, r) grpc_chttp2_ref_transport(t)
#define GRPC_CHTTP2_UNREF_TRANSPORT(t, r) grpc_chttp2_unref_transport(t)
-void grpc_chttp2_unref_transport(grpc_chttp2_transport* t);
-void grpc_chttp2_ref_transport(grpc_chttp2_transport* t);
+inline void grpc_chttp2_unref_transport(grpc_chttp2_transport* t) {
+ if (t->refs.Unref()) {
+ grpc_core::Delete(t);
+ }
+}
+inline void grpc_chttp2_ref_transport(grpc_chttp2_transport* t) {
+ t->refs.Ref();
+}
#endif
void grpc_chttp2_ack_ping(grpc_chttp2_transport* t, uint64_t id);
diff --git a/src/core/ext/transport/chttp2/transport/writing.cc b/src/core/ext/transport/chttp2/transport/writing.cc
index d533989444..265d3365d3 100644
--- a/src/core/ext/transport/chttp2/transport/writing.cc
+++ b/src/core/ext/transport/chttp2/transport/writing.cc
@@ -18,6 +18,7 @@
#include <grpc/support/port_platform.h>
+#include "src/core/ext/transport/chttp2/transport/context_list.h"
#include "src/core/ext/transport/chttp2/transport/internal.h"
#include <limits.h>
@@ -362,6 +363,7 @@ class DataSendContext {
grpc_chttp2_encode_data(s_->id, &s_->compressed_data_buffer, send_bytes,
is_last_frame_, &s_->stats.outgoing, &t_->outbuf);
s_->flow_control->SentData(send_bytes);
+ s_->byte_counter += send_bytes;
if (s_->compressed_data_buffer.length == 0) {
s_->sending_bytes += s_->uncompressed_data_size;
}
@@ -496,6 +498,9 @@ class StreamWriteContext {
data_send_context.CompressMoreBytes();
}
}
+ if (s_->traced && grpc_endpoint_can_track_err(t_->ep)) {
+ grpc_core::ContextList::Append(&t_->cl, s_);
+ }
write_context_->ResetPingClock();
if (data_send_context.is_last_frame()) {
SentLastFrame();
diff --git a/src/core/lib/gprpp/inlined_vector.h b/src/core/lib/gprpp/inlined_vector.h
index 65c2b9634f..66dc751a56 100644
--- a/src/core/lib/gprpp/inlined_vector.h
+++ b/src/core/lib/gprpp/inlined_vector.h
@@ -100,10 +100,7 @@ class InlinedVector {
void reserve(size_t capacity) {
if (capacity > capacity_) {
T* new_dynamic = static_cast<T*>(gpr_malloc(sizeof(T) * capacity));
- for (size_t i = 0; i < size_; ++i) {
- new (&new_dynamic[i]) T(std::move(data()[i]));
- data()[i].~T();
- }
+ move_elements(data(), new_dynamic, size_);
gpr_free(dynamic_);
dynamic_ = new_dynamic;
capacity_ = capacity;
@@ -131,13 +128,25 @@ class InlinedVector {
size_--;
}
+ size_t size() const { return size_; }
+ bool empty() const { return size_ == 0; }
+
+ size_t capacity() const { return capacity_; }
+
+ void clear() {
+ destroy_elements();
+ init_data();
+ }
+
+ private:
void copy_from(const InlinedVector& v) {
- // if v is allocated, copy over the buffer.
+ // if v is allocated, make sure we have enough capacity.
if (v.dynamic_ != nullptr) {
reserve(v.capacity_);
- memcpy(dynamic_, v.dynamic_, v.size_ * sizeof(T));
- } else {
- memcpy(inline_, v.inline_, v.size_ * sizeof(T));
+ }
+ // copy over elements
+ for (size_t i = 0; i < v.size_; ++i) {
+ new (&(data()[i])) T(v[i]);
}
// copy over metadata
size_ = v.size_;
@@ -145,11 +154,12 @@ class InlinedVector {
}
void move_from(InlinedVector& v) {
- // if v is allocated, then we steal its buffer, else we copy it.
+ // if v is allocated, then we steal its dynamic array; otherwise, we
+ // move the elements individually.
if (v.dynamic_ != nullptr) {
dynamic_ = v.dynamic_;
} else {
- memcpy(inline_, v.inline_, v.size_ * sizeof(T));
+ move_elements(v.data(), data(), v.size_);
}
// copy over metadata
size_ = v.size_;
@@ -158,17 +168,13 @@ class InlinedVector {
v.init_data();
}
- size_t size() const { return size_; }
- bool empty() const { return size_ == 0; }
-
- size_t capacity() const { return capacity_; }
-
- void clear() {
- destroy_elements();
- init_data();
+ static void move_elements(T* src, T* dst, size_t num_elements) {
+ for (size_t i = 0; i < num_elements; ++i) {
+ new (&dst[i]) T(std::move(src[i]));
+ src[i].~T();
+ }
}
- private:
void init_data() {
dynamic_ = nullptr;
size_ = 0;
diff --git a/src/core/lib/gprpp/orphanable.h b/src/core/lib/gprpp/orphanable.h
index 3123e3f5a3..3eb510165e 100644
--- a/src/core/lib/gprpp/orphanable.h
+++ b/src/core/lib/gprpp/orphanable.h
@@ -31,6 +31,7 @@
#include "src/core/lib/gprpp/abstract.h"
#include "src/core/lib/gprpp/debug_location.h"
#include "src/core/lib/gprpp/memory.h"
+#include "src/core/lib/gprpp/ref_counted.h"
#include "src/core/lib/gprpp/ref_counted_ptr.h"
namespace grpc_core {
@@ -89,8 +90,8 @@ class InternallyRefCounted : public Orphanable {
template <typename T>
friend class RefCountedPtr;
- InternallyRefCounted() { gpr_ref_init(&refs_, 1); }
- virtual ~InternallyRefCounted() {}
+ InternallyRefCounted() = default;
+ virtual ~InternallyRefCounted() = default;
RefCountedPtr<Child> Ref() GRPC_MUST_USE_RESULT {
IncrementRefCount();
@@ -98,15 +99,15 @@ class InternallyRefCounted : public Orphanable {
}
void Unref() {
- if (gpr_unref(&refs_)) {
+ if (refs_.Unref()) {
Delete(static_cast<Child*>(this));
}
}
private:
- void IncrementRefCount() { gpr_ref(&refs_); }
+ void IncrementRefCount() { refs_.Ref(); }
- gpr_refcount refs_;
+ grpc_core::RefCount refs_;
};
// An alternative version of the InternallyRefCounted base class that
@@ -137,16 +138,14 @@ class InternallyRefCountedWithTracing : public Orphanable {
: InternallyRefCountedWithTracing(static_cast<TraceFlag*>(nullptr)) {}
explicit InternallyRefCountedWithTracing(TraceFlag* trace_flag)
- : trace_flag_(trace_flag) {
- gpr_ref_init(&refs_, 1);
- }
+ : trace_flag_(trace_flag) {}
#ifdef NDEBUG
explicit InternallyRefCountedWithTracing(DebugOnlyTraceFlag* trace_flag)
: InternallyRefCountedWithTracing() {}
#endif
- virtual ~InternallyRefCountedWithTracing() {}
+ virtual ~InternallyRefCountedWithTracing() = default;
RefCountedPtr<Child> Ref() GRPC_MUST_USE_RESULT {
IncrementRefCount();
@@ -156,7 +155,7 @@ class InternallyRefCountedWithTracing : public Orphanable {
RefCountedPtr<Child> Ref(const DebugLocation& location,
const char* reason) GRPC_MUST_USE_RESULT {
if (location.Log() && trace_flag_ != nullptr && trace_flag_->enabled()) {
- gpr_atm old_refs = gpr_atm_no_barrier_load(&refs_.count);
+ const grpc_core::RefCount::Value old_refs = refs_.get();
gpr_log(GPR_INFO, "%s:%p %s:%d ref %" PRIdPTR " -> %" PRIdPTR " %s",
trace_flag_->name(), this, location.file(), location.line(),
old_refs, old_refs + 1, reason);
@@ -170,14 +169,14 @@ class InternallyRefCountedWithTracing : public Orphanable {
// friend of this class.
void Unref() {
- if (gpr_unref(&refs_)) {
+ if (refs_.Unref()) {
Delete(static_cast<Child*>(this));
}
}
void Unref(const DebugLocation& location, const char* reason) {
if (location.Log() && trace_flag_ != nullptr && trace_flag_->enabled()) {
- gpr_atm old_refs = gpr_atm_no_barrier_load(&refs_.count);
+ const grpc_core::RefCount::Value old_refs = refs_.get();
gpr_log(GPR_INFO, "%s:%p %s:%d unref %" PRIdPTR " -> %" PRIdPTR " %s",
trace_flag_->name(), this, location.file(), location.line(),
old_refs, old_refs - 1, reason);
@@ -186,10 +185,10 @@ class InternallyRefCountedWithTracing : public Orphanable {
}
private:
- void IncrementRefCount() { gpr_ref(&refs_); }
+ void IncrementRefCount() { refs_.Ref(); }
TraceFlag* trace_flag_ = nullptr;
- gpr_refcount refs_;
+ grpc_core::RefCount refs_;
};
} // namespace grpc_core
diff --git a/src/core/lib/gprpp/ref_counted.h b/src/core/lib/gprpp/ref_counted.h
index 03c293f6ed..98de1a3653 100644
--- a/src/core/lib/gprpp/ref_counted.h
+++ b/src/core/lib/gprpp/ref_counted.h
@@ -21,9 +21,12 @@
#include <grpc/support/port_platform.h>
+#include <grpc/support/atm.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
+#include <atomic>
+#include <cassert>
#include <cinttypes>
#include "src/core/lib/debug/trace.h"
@@ -34,14 +37,103 @@
namespace grpc_core {
+// PolymorphicRefCount enforces polymorphic destruction of RefCounted.
+class PolymorphicRefCount {
+ public:
+ GRPC_ABSTRACT_BASE_CLASS
+
+ protected:
+ GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
+
+ virtual ~PolymorphicRefCount() = default;
+};
+
+// NonPolymorphicRefCount does not enforce polymorphic destruction of
+// RefCounted. Please refer to grpc_core::RefCounted for more details, and
+// when in doubt use PolymorphicRefCount.
+class NonPolymorphicRefCount {
+ public:
+ GRPC_ABSTRACT_BASE_CLASS
+
+ protected:
+ GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
+
+ ~NonPolymorphicRefCount() = default;
+};
+
+// RefCount is a simple atomic ref-count.
+//
+// This is a C++ implementation of gpr_refcount, with inline functions. Due to
+// inline functions, this class is significantly more efficient than
+// gpr_refcount and should be preferred over gpr_refcount whenever possible.
+//
+// TODO(soheil): Remove gpr_refcount after submitting the GRFC and the paragraph
+// above.
+class RefCount {
+ public:
+ using Value = intptr_t;
+
+ // `init` is the initial refcount stored in this object.
+ constexpr explicit RefCount(Value init = 1) : value_(init) {}
+
+ // Increases the ref-count by `n`.
+ void Ref(Value n = 1) {
+ GPR_ATM_INC_ADD_THEN(value_.fetch_add(n, std::memory_order_relaxed));
+ }
+
+ // Similar to Ref() with an assert on the ref-count being non-zero.
+ void RefNonZero() {
+#ifndef NDEBUG
+ const Value prior =
+ GPR_ATM_INC_ADD_THEN(value_.fetch_add(1, std::memory_order_relaxed));
+ assert(prior > 0);
+#else
+ Ref();
+#endif
+ }
+
+ // Decrements the ref-count and returns true if the ref-count reaches 0.
+ bool Unref() {
+ const Value prior =
+ GPR_ATM_INC_ADD_THEN(value_.fetch_sub(1, std::memory_order_acq_rel));
+ GPR_DEBUG_ASSERT(prior > 0);
+ return prior == 1;
+ }
+
+ Value get() const { return value_.load(std::memory_order_relaxed); }
+
+ private:
+ std::atomic<Value> value_;
+};
+
// A base class for reference-counted objects.
// New objects should be created via New() and start with a refcount of 1.
// When the refcount reaches 0, the object will be deleted via Delete().
//
// This will commonly be used by CRTP (curiously-recurring template pattern)
// e.g., class MyClass : public RefCounted<MyClass>
-template <typename Child>
-class RefCounted {
+//
+// Use PolymorphicRefCount and NonPolymorphicRefCount to select between
+// different implementations of RefCounted.
+//
+// Note that NonPolymorphicRefCount does not support polymorphic destruction.
+// So, use NonPolymorphicRefCount only when both of the following conditions
+// are guaranteed to hold:
+// (a) Child is a concrete leaf class in RefCounted<Child>, and
+// (b) you are gauranteed to call Unref only on concrete leaf classes and not
+// their parents.
+//
+// The following example is illegal, because calling Unref() will not call
+// the dtor of Child.
+//
+// class Parent : public RefCounted<Parent, NonPolymorphicRefCount> {}
+// class Child : public Parent {}
+//
+// Child* ch;
+// ch->Unref();
+//
+template <typename Child, typename Impl = PolymorphicRefCount>
+class RefCounted : public Impl {
public:
RefCountedPtr<Child> Ref() GRPC_MUST_USE_RESULT {
IncrementRefCount();
@@ -53,7 +145,7 @@ class RefCounted {
// private, since it will only be used by RefCountedPtr<>, which is a
// friend of this class.
void Unref() {
- if (gpr_unref(&refs_)) {
+ if (refs_.Unref()) {
Delete(static_cast<Child*>(this));
}
}
@@ -67,18 +159,19 @@ class RefCounted {
protected:
GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
- RefCounted() { gpr_ref_init(&refs_, 1); }
+ RefCounted() = default;
- virtual ~RefCounted() {}
+ // Note: Depending on the Impl used, this dtor can be implicitly virtual.
+ ~RefCounted() = default;
private:
// Allow RefCountedPtr<> to access IncrementRefCount().
template <typename T>
friend class RefCountedPtr;
- void IncrementRefCount() { gpr_ref(&refs_); }
+ void IncrementRefCount() { refs_.Ref(); }
- gpr_refcount refs_;
+ RefCount refs_;
};
// An alternative version of the RefCounted base class that
@@ -87,8 +180,8 @@ class RefCounted {
// pointers and legacy code that is manually calling Ref() and Unref().
// Once all of our code is converted to idiomatic C++, we may be able to
// eliminate this class.
-template <typename Child>
-class RefCountedWithTracing {
+template <typename Child, typename Impl = PolymorphicRefCount>
+class RefCountedWithTracing : public Impl {
public:
RefCountedPtr<Child> Ref() GRPC_MUST_USE_RESULT {
IncrementRefCount();
@@ -98,7 +191,7 @@ class RefCountedWithTracing {
RefCountedPtr<Child> Ref(const DebugLocation& location,
const char* reason) GRPC_MUST_USE_RESULT {
if (location.Log() && trace_flag_ != nullptr && trace_flag_->enabled()) {
- gpr_atm old_refs = gpr_atm_no_barrier_load(&refs_.count);
+ const RefCount::Value old_refs = refs_.get();
gpr_log(GPR_INFO, "%s:%p %s:%d ref %" PRIdPTR " -> %" PRIdPTR " %s",
trace_flag_->name(), this, location.file(), location.line(),
old_refs, old_refs + 1, reason);
@@ -112,14 +205,14 @@ class RefCountedWithTracing {
// friend of this class.
void Unref() {
- if (gpr_unref(&refs_)) {
+ if (refs_.Unref()) {
Delete(static_cast<Child*>(this));
}
}
void Unref(const DebugLocation& location, const char* reason) {
if (location.Log() && trace_flag_ != nullptr && trace_flag_->enabled()) {
- gpr_atm old_refs = gpr_atm_no_barrier_load(&refs_.count);
+ const RefCount::Value old_refs = refs_.get();
gpr_log(GPR_INFO, "%s:%p %s:%d unref %" PRIdPTR " -> %" PRIdPTR " %s",
trace_flag_->name(), this, location.file(), location.line(),
old_refs, old_refs - 1, reason);
@@ -140,26 +233,25 @@ class RefCountedWithTracing {
: RefCountedWithTracing(static_cast<TraceFlag*>(nullptr)) {}
explicit RefCountedWithTracing(TraceFlag* trace_flag)
- : trace_flag_(trace_flag) {
- gpr_ref_init(&refs_, 1);
- }
+ : trace_flag_(trace_flag) {}
#ifdef NDEBUG
explicit RefCountedWithTracing(DebugOnlyTraceFlag* trace_flag)
: RefCountedWithTracing() {}
#endif
- virtual ~RefCountedWithTracing() {}
+ // Note: Depending on the Impl used, this dtor can be implicitly virtual.
+ ~RefCountedWithTracing() = default;
private:
// Allow RefCountedPtr<> to access IncrementRefCount().
template <typename T>
friend class RefCountedPtr;
- void IncrementRefCount() { gpr_ref(&refs_); }
+ void IncrementRefCount() { refs_.Ref(); }
TraceFlag* trace_flag_ = nullptr;
- gpr_refcount refs_;
+ RefCount refs_;
};
} // namespace grpc_core
diff --git a/src/core/lib/gprpp/ref_counted_ptr.h b/src/core/lib/gprpp/ref_counted_ptr.h
index c2dfbdd90f..facd7c6dce 100644
--- a/src/core/lib/gprpp/ref_counted_ptr.h
+++ b/src/core/lib/gprpp/ref_counted_ptr.h
@@ -21,6 +21,7 @@
#include <grpc/support/port_platform.h>
+#include <type_traits>
#include <utility>
#include "src/core/lib/gprpp/memory.h"
@@ -74,6 +75,8 @@ class RefCountedPtr {
}
template <typename Y>
RefCountedPtr(const RefCountedPtr<Y>& other) {
+ static_assert(std::has_virtual_destructor<T>::value,
+ "T does not have a virtual dtor");
if (other.value_ != nullptr) other.value_->IncrementRefCount();
value_ = other.value_;
}
@@ -89,6 +92,8 @@ class RefCountedPtr {
}
template <typename Y>
RefCountedPtr& operator=(const RefCountedPtr<Y>& other) {
+ static_assert(std::has_virtual_destructor<T>::value,
+ "T does not have a virtual dtor");
// Note: Order of reffing and unreffing is important here in case value_
// and other.value_ are the same object.
if (other.value_ != nullptr) other.value_->IncrementRefCount();
@@ -102,8 +107,14 @@ class RefCountedPtr {
}
// If value is non-null, we take ownership of a ref to it.
+ void reset(T* value) {
+ if (value_ != nullptr) value_->Unref();
+ value_ = value;
+ }
template <typename Y>
void reset(Y* value) {
+ static_assert(std::has_virtual_destructor<T>::value,
+ "T does not have a virtual dtor");
if (value_ != nullptr) value_->Unref();
value_ = value;
}
diff --git a/src/core/lib/iomgr/buffer_list.cc b/src/core/lib/iomgr/buffer_list.cc
index 6ada23db1c..ace17a108d 100644
--- a/src/core/lib/iomgr/buffer_list.cc
+++ b/src/core/lib/iomgr/buffer_list.cc
@@ -35,6 +35,9 @@ void TracedBuffer::AddNewEntry(TracedBuffer** head, uint32_t seq_no,
TracedBuffer* new_elem = New<TracedBuffer>(seq_no, arg);
/* Store the current time as the sendmsg time. */
new_elem->ts_.sendmsg_time = gpr_now(GPR_CLOCK_REALTIME);
+ new_elem->ts_.scheduled_time = gpr_inf_past(GPR_CLOCK_REALTIME);
+ new_elem->ts_.sent_time = gpr_inf_past(GPR_CLOCK_REALTIME);
+ new_elem->ts_.acked_time = gpr_inf_past(GPR_CLOCK_REALTIME);
if (*head == nullptr) {
*head = new_elem;
return;
@@ -55,10 +58,16 @@ void fill_gpr_from_timestamp(gpr_timespec* gts, const struct timespec* ts) {
gts->clock_type = GPR_CLOCK_REALTIME;
}
+void default_timestamps_callback(void* arg, grpc_core::Timestamps* ts,
+ grpc_error* shudown_err) {
+ gpr_log(GPR_DEBUG, "Timestamps callback has not been registered");
+}
+
/** The saved callback function that will be invoked when we get all the
* timestamps that we are going to get for a TracedBuffer. */
void (*timestamps_callback)(void*, grpc_core::Timestamps*,
- grpc_error* shutdown_err);
+ grpc_error* shutdown_err) =
+ default_timestamps_callback;
} /* namespace */
void TracedBuffer::ProcessTimestamp(TracedBuffer** head,
@@ -99,18 +108,20 @@ void TracedBuffer::ProcessTimestamp(TracedBuffer** head,
}
}
-void TracedBuffer::Shutdown(TracedBuffer** head, grpc_error* shutdown_err) {
+void TracedBuffer::Shutdown(TracedBuffer** head, void* remaining,
+ grpc_error* shutdown_err) {
GPR_DEBUG_ASSERT(head != nullptr);
TracedBuffer* elem = *head;
while (elem != nullptr) {
- if (timestamps_callback) {
- timestamps_callback(elem->arg_, &(elem->ts_), shutdown_err);
- }
+ timestamps_callback(elem->arg_, &(elem->ts_), shutdown_err);
auto* next = elem->next_;
Delete<TracedBuffer>(elem);
elem = next;
}
*head = nullptr;
+ if (remaining != nullptr) {
+ timestamps_callback(remaining, nullptr, shutdown_err);
+ }
GRPC_ERROR_UNREF(shutdown_err);
}
diff --git a/src/core/lib/iomgr/buffer_list.h b/src/core/lib/iomgr/buffer_list.h
index cbbf50a657..627f1bde99 100644
--- a/src/core/lib/iomgr/buffer_list.h
+++ b/src/core/lib/iomgr/buffer_list.h
@@ -37,6 +37,8 @@ struct Timestamps {
gpr_timespec scheduled_time;
gpr_timespec sent_time;
gpr_timespec acked_time;
+
+ uint32_t byte_offset; /* byte offset relative to the start of the RPC */
};
/** TracedBuffer is a class to keep track of timestamps for a specific buffer in
@@ -67,13 +69,13 @@ class TracedBuffer {
/** Cleans the list by calling the callback for each traced buffer in the list
* with timestamps that it has. */
- static void Shutdown(grpc_core::TracedBuffer** head,
+ static void Shutdown(grpc_core::TracedBuffer** head, void* remaining,
grpc_error* shutdown_err);
private:
GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW
- TracedBuffer(int seq_no, void* arg)
+ TracedBuffer(uint32_t seq_no, void* arg)
: seq_no_(seq_no), arg_(arg), next_(nullptr) {}
uint32_t seq_no_; /* The sequence number for the last byte in the buffer */
@@ -82,7 +84,12 @@ class TracedBuffer {
grpc_core::TracedBuffer* next_; /* The next TracedBuffer in the list */
};
#else /* GRPC_LINUX_ERRQUEUE */
-class TracedBuffer {};
+class TracedBuffer {
+ public:
+ /* Dummy shutdown function */
+ static void Shutdown(grpc_core::TracedBuffer** head, void* remaining,
+ grpc_error* shutdown_err) {}
+};
#endif /* GRPC_LINUX_ERRQUEUE */
/** Sets the callback function to call when timestamps for a write are
diff --git a/src/core/lib/iomgr/endpoint.cc b/src/core/lib/iomgr/endpoint.cc
index 44fb47e19d..06316c6031 100644
--- a/src/core/lib/iomgr/endpoint.cc
+++ b/src/core/lib/iomgr/endpoint.cc
@@ -61,3 +61,7 @@ int grpc_endpoint_get_fd(grpc_endpoint* ep) { return ep->vtable->get_fd(ep); }
grpc_resource_user* grpc_endpoint_get_resource_user(grpc_endpoint* ep) {
return ep->vtable->get_resource_user(ep);
}
+
+bool grpc_endpoint_can_track_err(grpc_endpoint* ep) {
+ return ep->vtable->can_track_err(ep);
+}
diff --git a/src/core/lib/iomgr/endpoint.h b/src/core/lib/iomgr/endpoint.h
index 1f590a80ca..79c8ece263 100644
--- a/src/core/lib/iomgr/endpoint.h
+++ b/src/core/lib/iomgr/endpoint.h
@@ -47,6 +47,7 @@ struct grpc_endpoint_vtable {
grpc_resource_user* (*get_resource_user)(grpc_endpoint* ep);
char* (*get_peer)(grpc_endpoint* ep);
int (*get_fd)(grpc_endpoint* ep);
+ bool (*can_track_err)(grpc_endpoint* ep);
};
/* When data is available on the connection, calls the callback with slices.
@@ -95,6 +96,8 @@ void grpc_endpoint_delete_from_pollset_set(grpc_endpoint* ep,
grpc_resource_user* grpc_endpoint_get_resource_user(grpc_endpoint* endpoint);
+bool grpc_endpoint_can_track_err(grpc_endpoint* ep);
+
struct grpc_endpoint {
const grpc_endpoint_vtable* vtable;
};
diff --git a/src/core/lib/iomgr/endpoint_cfstream.cc b/src/core/lib/iomgr/endpoint_cfstream.cc
index df2cf508c8..7c4bc1ace2 100644
--- a/src/core/lib/iomgr/endpoint_cfstream.cc
+++ b/src/core/lib/iomgr/endpoint_cfstream.cc
@@ -315,6 +315,8 @@ char* CFStreamGetPeer(grpc_endpoint* ep) {
int CFStreamGetFD(grpc_endpoint* ep) { return 0; }
+bool CFStreamCanTrackErr(grpc_endpoint* ep) { return false; }
+
void CFStreamAddToPollset(grpc_endpoint* ep, grpc_pollset* pollset) {}
void CFStreamAddToPollsetSet(grpc_endpoint* ep, grpc_pollset_set* pollset) {}
void CFStreamDeleteFromPollsetSet(grpc_endpoint* ep,
@@ -329,7 +331,8 @@ static const grpc_endpoint_vtable vtable = {CFStreamRead,
CFStreamDestroy,
CFStreamGetResourceUser,
CFStreamGetPeer,
- CFStreamGetFD};
+ CFStreamGetFD,
+ CFStreamCanTrackErr};
grpc_endpoint* grpc_cfstream_endpoint_create(
CFReadStreamRef read_stream, CFWriteStreamRef write_stream,
diff --git a/src/core/lib/iomgr/endpoint_pair_posix.cc b/src/core/lib/iomgr/endpoint_pair_posix.cc
index 3afbfd7254..5c5c246f99 100644
--- a/src/core/lib/iomgr/endpoint_pair_posix.cc
+++ b/src/core/lib/iomgr/endpoint_pair_posix.cc
@@ -59,11 +59,11 @@ grpc_endpoint_pair grpc_iomgr_create_endpoint_pair(const char* name,
grpc_core::ExecCtx exec_ctx;
gpr_asprintf(&final_name, "%s:client", name);
- p.client = grpc_tcp_create(grpc_fd_create(sv[1], final_name, true), args,
+ p.client = grpc_tcp_create(grpc_fd_create(sv[1], final_name, false), args,
"socketpair-server");
gpr_free(final_name);
gpr_asprintf(&final_name, "%s:server", name);
- p.server = grpc_tcp_create(grpc_fd_create(sv[0], final_name, true), args,
+ p.server = grpc_tcp_create(grpc_fd_create(sv[0], final_name, false), args,
"socketpair-client");
gpr_free(final_name);
diff --git a/src/core/lib/iomgr/ev_epoll1_linux.cc b/src/core/lib/iomgr/ev_epoll1_linux.cc
index 38571b1957..4b8c891e9b 100644
--- a/src/core/lib/iomgr/ev_epoll1_linux.cc
+++ b/src/core/lib/iomgr/ev_epoll1_linux.cc
@@ -1242,6 +1242,8 @@ static void pollset_set_del_pollset_set(grpc_pollset_set* bag,
* Event engine binding
*/
+static void shutdown_background_closure(void) {}
+
static void shutdown_engine(void) {
fd_global_shutdown();
pollset_global_shutdown();
@@ -1255,6 +1257,7 @@ static void shutdown_engine(void) {
static const grpc_event_engine_vtable vtable = {
sizeof(grpc_pollset),
true,
+ false,
fd_create,
fd_wrapped_fd,
@@ -1284,6 +1287,7 @@ static const grpc_event_engine_vtable vtable = {
pollset_set_add_fd,
pollset_set_del_fd,
+ shutdown_background_closure,
shutdown_engine,
};
diff --git a/src/core/lib/iomgr/ev_epollex_linux.cc b/src/core/lib/iomgr/ev_epollex_linux.cc
index 06a382c556..7a4870db78 100644
--- a/src/core/lib/iomgr/ev_epollex_linux.cc
+++ b/src/core/lib/iomgr/ev_epollex_linux.cc
@@ -1604,6 +1604,8 @@ static void pollset_set_del_pollset_set(grpc_pollset_set* bag,
* Event engine binding
*/
+static void shutdown_background_closure(void) {}
+
static void shutdown_engine(void) {
fd_global_shutdown();
pollset_global_shutdown();
@@ -1612,6 +1614,7 @@ static void shutdown_engine(void) {
static const grpc_event_engine_vtable vtable = {
sizeof(grpc_pollset),
true,
+ false,
fd_create,
fd_wrapped_fd,
@@ -1641,6 +1644,7 @@ static const grpc_event_engine_vtable vtable = {
pollset_set_add_fd,
pollset_set_del_fd,
+ shutdown_background_closure,
shutdown_engine,
};
diff --git a/src/core/lib/iomgr/ev_poll_posix.cc b/src/core/lib/iomgr/ev_poll_posix.cc
index 16562538a6..67cbfbbd02 100644
--- a/src/core/lib/iomgr/ev_poll_posix.cc
+++ b/src/core/lib/iomgr/ev_poll_posix.cc
@@ -1782,6 +1782,8 @@ static void global_cv_fd_table_shutdown() {
* event engine binding
*/
+static void shutdown_background_closure(void) {}
+
static void shutdown_engine(void) {
pollset_global_shutdown();
if (grpc_cv_wakeup_fds_enabled()) {
@@ -1796,6 +1798,7 @@ static void shutdown_engine(void) {
static const grpc_event_engine_vtable vtable = {
sizeof(grpc_pollset),
false,
+ false,
fd_create,
fd_wrapped_fd,
@@ -1825,6 +1828,7 @@ static const grpc_event_engine_vtable vtable = {
pollset_set_add_fd,
pollset_set_del_fd,
+ shutdown_background_closure,
shutdown_engine,
};
diff --git a/src/core/lib/iomgr/ev_posix.cc b/src/core/lib/iomgr/ev_posix.cc
index 8a7dc7b004..32d1b6c43e 100644
--- a/src/core/lib/iomgr/ev_posix.cc
+++ b/src/core/lib/iomgr/ev_posix.cc
@@ -36,6 +36,7 @@
#include "src/core/lib/iomgr/ev_epoll1_linux.h"
#include "src/core/lib/iomgr/ev_epollex_linux.h"
#include "src/core/lib/iomgr/ev_poll_posix.h"
+#include "src/core/lib/iomgr/internal_errqueue.h"
grpc_core::TraceFlag grpc_polling_trace(false,
"polling"); /* Disabled by default */
@@ -236,19 +237,22 @@ void grpc_event_engine_shutdown(void) {
}
bool grpc_event_engine_can_track_errors(void) {
-/* Only track errors if platform supports errqueue. */
-#ifdef GRPC_LINUX_ERRQUEUE
- return g_event_engine->can_track_err;
-#else
+ /* Only track errors if platform supports errqueue. */
+ if (grpc_core::kernel_supports_errqueue()) {
+ return g_event_engine->can_track_err;
+ }
return false;
-#endif /* GRPC_LINUX_ERRQUEUE */
+}
+
+bool grpc_event_engine_run_in_background(void) {
+ return g_event_engine->run_in_background;
}
grpc_fd* grpc_fd_create(int fd, const char* name, bool track_err) {
GRPC_POLLING_API_TRACE("fd_create(%d, %s, %d)", fd, name, track_err);
GRPC_FD_TRACE("fd_create(%d, %s, %d)", fd, name, track_err);
- return g_event_engine->fd_create(fd, name,
- track_err && g_event_engine->can_track_err);
+ return g_event_engine->fd_create(
+ fd, name, track_err && grpc_event_engine_can_track_errors());
}
int grpc_fd_wrapped_fd(grpc_fd* fd) {
@@ -395,4 +399,8 @@ void grpc_pollset_set_del_fd(grpc_pollset_set* pollset_set, grpc_fd* fd) {
g_event_engine->pollset_set_del_fd(pollset_set, fd);
}
+void grpc_shutdown_background_closure(void) {
+ g_event_engine->shutdown_background_closure();
+}
+
#endif // GRPC_POSIX_SOCKET_EV
diff --git a/src/core/lib/iomgr/ev_posix.h b/src/core/lib/iomgr/ev_posix.h
index b8fb8f534b..812c7a0f0f 100644
--- a/src/core/lib/iomgr/ev_posix.h
+++ b/src/core/lib/iomgr/ev_posix.h
@@ -42,6 +42,7 @@ typedef struct grpc_fd grpc_fd;
typedef struct grpc_event_engine_vtable {
size_t pollset_size;
bool can_track_err;
+ bool run_in_background;
grpc_fd* (*fd_create)(int fd, const char* name, bool track_err);
int (*fd_wrapped_fd)(grpc_fd* fd);
@@ -79,6 +80,7 @@ typedef struct grpc_event_engine_vtable {
void (*pollset_set_add_fd)(grpc_pollset_set* pollset_set, grpc_fd* fd);
void (*pollset_set_del_fd)(grpc_pollset_set* pollset_set, grpc_fd* fd);
+ void (*shutdown_background_closure)(void);
void (*shutdown_engine)(void);
} grpc_event_engine_vtable;
@@ -101,6 +103,11 @@ const char* grpc_get_poll_strategy_name();
*/
bool grpc_event_engine_can_track_errors();
+/* Returns true if polling engine runs in the background, false otherwise.
+ * Currently only 'epollbg' runs in the background.
+ */
+bool grpc_event_engine_run_in_background();
+
/* Create a wrapped file descriptor.
Requires fd is a non-blocking file descriptor.
\a track_err if true means that error events would be tracked separately
@@ -174,6 +181,9 @@ void grpc_pollset_add_fd(grpc_pollset* pollset, struct grpc_fd* fd);
void grpc_pollset_set_add_fd(grpc_pollset_set* pollset_set, grpc_fd* fd);
void grpc_pollset_set_del_fd(grpc_pollset_set* pollset_set, grpc_fd* fd);
+/* Shut down all the closures registered in the background poller. */
+void grpc_shutdown_background_closure();
+
/* override to allow tests to hook poll() usage */
typedef int (*grpc_poll_function_type)(struct pollfd*, nfds_t, int);
extern grpc_poll_function_type grpc_poll_function;
diff --git a/src/core/lib/iomgr/fork_posix.cc b/src/core/lib/iomgr/fork_posix.cc
index e957bad73d..05ecd2a49b 100644
--- a/src/core/lib/iomgr/fork_posix.cc
+++ b/src/core/lib/iomgr/fork_posix.cc
@@ -60,7 +60,7 @@ void grpc_prefork() {
}
if (strcmp(grpc_get_poll_strategy_name(), "epoll1") != 0 &&
strcmp(grpc_get_poll_strategy_name(), "poll") != 0) {
- gpr_log(GPR_ERROR,
+ gpr_log(GPR_INFO,
"Fork support is only compatible with the epoll1 and poll polling "
"strategies");
}
diff --git a/src/core/lib/iomgr/internal_errqueue.cc b/src/core/lib/iomgr/internal_errqueue.cc
index 99c22e9055..982d709f09 100644
--- a/src/core/lib/iomgr/internal_errqueue.cc
+++ b/src/core/lib/iomgr/internal_errqueue.cc
@@ -20,17 +20,50 @@
#include "src/core/lib/iomgr/port.h"
+#include <grpc/impl/codegen/log.h>
#include "src/core/lib/iomgr/internal_errqueue.h"
#ifdef GRPC_POSIX_SOCKET_TCP
-bool kernel_supports_errqueue() {
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/utsname.h>
+
+namespace grpc_core {
+static bool errqueue_supported = false;
+
+bool kernel_supports_errqueue() { return errqueue_supported; }
+
+void grpc_errqueue_init() {
+/* Both-compile time and run-time linux kernel versions should be atleast 4.0.0
+ */
#ifdef LINUX_VERSION_CODE
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)
- return true;
+ struct utsname buffer;
+ if (uname(&buffer) != 0) {
+ gpr_log(GPR_ERROR, "uname: %s", strerror(errno));
+ return;
+ }
+ char* release = buffer.release;
+ if (release == nullptr) {
+ return;
+ }
+
+ if (strtol(release, nullptr, 10) >= 4) {
+ errqueue_supported = true;
+ } else {
+ gpr_log(GPR_DEBUG, "ERRQUEUE support not enabled");
+ }
#endif /* LINUX_VERSION_CODE <= KERNEL_VERSION(4, 0, 0) */
#endif /* LINUX_VERSION_CODE */
- return false;
}
+} /* namespace grpc_core */
+
+#else
+
+namespace grpc_core {
+void grpc_errqueue_init() {}
+} /* namespace grpc_core */
#endif /* GRPC_POSIX_SOCKET_TCP */
diff --git a/src/core/lib/iomgr/internal_errqueue.h b/src/core/lib/iomgr/internal_errqueue.h
index 9d122808f9..f8644c2536 100644
--- a/src/core/lib/iomgr/internal_errqueue.h
+++ b/src/core/lib/iomgr/internal_errqueue.h
@@ -76,8 +76,14 @@ constexpr uint32_t kTimestampingRecordingOptions =
* Currently allowing only linux kernels above 4.0.0
*/
bool kernel_supports_errqueue();
-} // namespace grpc_core
+
+} /* namespace grpc_core */
#endif /* GRPC_POSIX_SOCKET_TCP */
+namespace grpc_core {
+/* Initializes errqueue support */
+void grpc_errqueue_init();
+} /* namespace grpc_core */
+
#endif /* GRPC_CORE_LIB_IOMGR_INTERNAL_ERRQUEUE_H */
diff --git a/src/core/lib/iomgr/iomgr.cc b/src/core/lib/iomgr/iomgr.cc
index 46afda1774..eb29973514 100644
--- a/src/core/lib/iomgr/iomgr.cc
+++ b/src/core/lib/iomgr/iomgr.cc
@@ -33,8 +33,10 @@
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/gprpp/thd.h"
+#include "src/core/lib/iomgr/buffer_list.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/iomgr/executor.h"
+#include "src/core/lib/iomgr/internal_errqueue.h"
#include "src/core/lib/iomgr/iomgr_internal.h"
#include "src/core/lib/iomgr/network_status_tracker.h"
#include "src/core/lib/iomgr/timer.h"
@@ -57,6 +59,7 @@ void grpc_iomgr_init() {
g_root_object.name = (char*)"root";
grpc_network_status_init();
grpc_iomgr_platform_init();
+ grpc_core::grpc_errqueue_init();
}
void grpc_iomgr_start() { grpc_timer_manager_init(); }
@@ -154,6 +157,10 @@ void grpc_iomgr_shutdown() {
gpr_cv_destroy(&g_rcv);
}
+void grpc_iomgr_shutdown_background_closure() {
+ grpc_iomgr_platform_shutdown_background_closure();
+}
+
void grpc_iomgr_register_object(grpc_iomgr_object* obj, const char* name) {
obj->name = gpr_strdup(name);
gpr_mu_lock(&g_mu);
diff --git a/src/core/lib/iomgr/iomgr.h b/src/core/lib/iomgr/iomgr.h
index 537ef8a6ff..8ea9289e06 100644
--- a/src/core/lib/iomgr/iomgr.h
+++ b/src/core/lib/iomgr/iomgr.h
@@ -35,6 +35,10 @@ void grpc_iomgr_start();
* exec_ctx. */
void grpc_iomgr_shutdown();
+/** Signals the intention to shutdown all the closures registered in the
+ * background poller. */
+void grpc_iomgr_shutdown_background_closure();
+
/* Exposed only for testing */
size_t grpc_iomgr_count_objects_for_testing();
diff --git a/src/core/lib/iomgr/iomgr_custom.cc b/src/core/lib/iomgr/iomgr_custom.cc
index d34c8e7cd1..4b112c9097 100644
--- a/src/core/lib/iomgr/iomgr_custom.cc
+++ b/src/core/lib/iomgr/iomgr_custom.cc
@@ -40,9 +40,11 @@ static void iomgr_platform_init(void) {
}
static void iomgr_platform_flush(void) {}
static void iomgr_platform_shutdown(void) { grpc_pollset_global_shutdown(); }
+static void iomgr_platform_shutdown_background_closure(void) {}
static grpc_iomgr_platform_vtable vtable = {
- iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown};
+ iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown,
+ iomgr_platform_shutdown_background_closure};
void grpc_custom_iomgr_init(grpc_socket_vtable* socket,
grpc_custom_resolver_vtable* resolver,
diff --git a/src/core/lib/iomgr/iomgr_internal.cc b/src/core/lib/iomgr/iomgr_internal.cc
index 32dbabb79d..b6c9211865 100644
--- a/src/core/lib/iomgr/iomgr_internal.cc
+++ b/src/core/lib/iomgr/iomgr_internal.cc
@@ -41,3 +41,7 @@ void grpc_iomgr_platform_init() { iomgr_platform_vtable->init(); }
void grpc_iomgr_platform_flush() { iomgr_platform_vtable->flush(); }
void grpc_iomgr_platform_shutdown() { iomgr_platform_vtable->shutdown(); }
+
+void grpc_iomgr_platform_shutdown_background_closure() {
+ iomgr_platform_vtable->shutdown_background_closure();
+}
diff --git a/src/core/lib/iomgr/iomgr_internal.h b/src/core/lib/iomgr/iomgr_internal.h
index b011d9c7b1..bca7409907 100644
--- a/src/core/lib/iomgr/iomgr_internal.h
+++ b/src/core/lib/iomgr/iomgr_internal.h
@@ -35,6 +35,7 @@ typedef struct grpc_iomgr_platform_vtable {
void (*init)(void);
void (*flush)(void);
void (*shutdown)(void);
+ void (*shutdown_background_closure)(void);
} grpc_iomgr_platform_vtable;
void grpc_iomgr_register_object(grpc_iomgr_object* obj, const char* name);
@@ -52,6 +53,9 @@ void grpc_iomgr_platform_flush(void);
/** tear down all platform specific global iomgr structures */
void grpc_iomgr_platform_shutdown(void);
+/** shut down all the closures registered in the background poller */
+void grpc_iomgr_platform_shutdown_background_closure(void);
+
bool grpc_iomgr_abort_on_leaks(void);
#endif /* GRPC_CORE_LIB_IOMGR_IOMGR_INTERNAL_H */
diff --git a/src/core/lib/iomgr/iomgr_posix.cc b/src/core/lib/iomgr/iomgr_posix.cc
index ca7334c9a4..9386adf060 100644
--- a/src/core/lib/iomgr/iomgr_posix.cc
+++ b/src/core/lib/iomgr/iomgr_posix.cc
@@ -51,8 +51,13 @@ static void iomgr_platform_shutdown(void) {
grpc_wakeup_fd_global_destroy();
}
+static void iomgr_platform_shutdown_background_closure(void) {
+ grpc_shutdown_background_closure();
+}
+
static grpc_iomgr_platform_vtable vtable = {
- iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown};
+ iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown,
+ iomgr_platform_shutdown_background_closure};
void grpc_set_default_iomgr_platform() {
grpc_set_tcp_client_impl(&grpc_posix_tcp_client_vtable);
diff --git a/src/core/lib/iomgr/iomgr_posix_cfstream.cc b/src/core/lib/iomgr/iomgr_posix_cfstream.cc
index 235a9e0712..552ef4309c 100644
--- a/src/core/lib/iomgr/iomgr_posix_cfstream.cc
+++ b/src/core/lib/iomgr/iomgr_posix_cfstream.cc
@@ -54,8 +54,13 @@ static void iomgr_platform_shutdown(void) {
grpc_wakeup_fd_global_destroy();
}
+static void iomgr_platform_shutdown_background_closure(void) {
+ grpc_shutdown_background_closure();
+}
+
static grpc_iomgr_platform_vtable vtable = {
- iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown};
+ iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown,
+ iomgr_platform_shutdown_background_closure};
void grpc_set_default_iomgr_platform() {
char* enable_cfstream = getenv(grpc_cfstream_env_var);
diff --git a/src/core/lib/iomgr/iomgr_windows.cc b/src/core/lib/iomgr/iomgr_windows.cc
index cdef89cbf0..24ef0dba7b 100644
--- a/src/core/lib/iomgr/iomgr_windows.cc
+++ b/src/core/lib/iomgr/iomgr_windows.cc
@@ -71,8 +71,11 @@ static void iomgr_platform_shutdown(void) {
winsock_shutdown();
}
+static void iomgr_platform_shutdown_background_closure(void) {}
+
static grpc_iomgr_platform_vtable vtable = {
- iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown};
+ iomgr_platform_init, iomgr_platform_flush, iomgr_platform_shutdown,
+ iomgr_platform_shutdown_background_closure};
void grpc_set_default_iomgr_platform() {
grpc_set_tcp_client_impl(&grpc_windows_tcp_client_vtable);
diff --git a/src/core/lib/iomgr/port.h b/src/core/lib/iomgr/port.h
index bf56a7298d..c8046b21dc 100644
--- a/src/core/lib/iomgr/port.h
+++ b/src/core/lib/iomgr/port.h
@@ -62,8 +62,7 @@
#define GRPC_HAVE_UNIX_SOCKET 1
#ifdef LINUX_VERSION_CODE
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)
-/* TODO(yashykt): Re-enable once Fathom changes are commited.
-#define GRPC_LINUX_ERRQUEUE 1 */
+#define GRPC_LINUX_ERRQUEUE 1
#endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0) */
#endif /* LINUX_VERSION_CODE */
#define GRPC_LINUX_MULTIPOLL_WITH_EPOLL 1
diff --git a/src/core/lib/iomgr/tcp_client_posix.cc b/src/core/lib/iomgr/tcp_client_posix.cc
index 8553ed0db4..0bff74e88b 100644
--- a/src/core/lib/iomgr/tcp_client_posix.cc
+++ b/src/core/lib/iomgr/tcp_client_posix.cc
@@ -76,6 +76,8 @@ static grpc_error* prepare_socket(const grpc_resolved_address* addr, int fd,
if (!grpc_is_unix_socket(addr)) {
err = grpc_set_socket_low_latency(fd, 1);
if (err != GRPC_ERROR_NONE) goto error;
+ err = grpc_set_socket_reuse_addr(fd, 1);
+ if (err != GRPC_ERROR_NONE) goto error;
err = grpc_set_socket_tcp_user_timeout(fd, channel_args,
true /* is_client */);
if (err != GRPC_ERROR_NONE) goto error;
diff --git a/src/core/lib/iomgr/tcp_custom.cc b/src/core/lib/iomgr/tcp_custom.cc
index e02a1898f2..f7a5f36cdc 100644
--- a/src/core/lib/iomgr/tcp_custom.cc
+++ b/src/core/lib/iomgr/tcp_custom.cc
@@ -326,6 +326,8 @@ static grpc_resource_user* endpoint_get_resource_user(grpc_endpoint* ep) {
static int endpoint_get_fd(grpc_endpoint* ep) { return -1; }
+static bool endpoint_can_track_err(grpc_endpoint* ep) { return false; }
+
static grpc_endpoint_vtable vtable = {endpoint_read,
endpoint_write,
endpoint_add_to_pollset,
@@ -335,7 +337,8 @@ static grpc_endpoint_vtable vtable = {endpoint_read,
endpoint_destroy,
endpoint_get_resource_user,
endpoint_get_peer,
- endpoint_get_fd};
+ endpoint_get_fd,
+ endpoint_can_track_err};
grpc_endpoint* custom_tcp_endpoint_create(grpc_custom_socket* socket,
grpc_resource_quota* resource_quota,
diff --git a/src/core/lib/iomgr/tcp_posix.cc b/src/core/lib/iomgr/tcp_posix.cc
index aa2704ce26..cfcb190d60 100644
--- a/src/core/lib/iomgr/tcp_posix.cc
+++ b/src/core/lib/iomgr/tcp_posix.cc
@@ -260,10 +260,17 @@ static void notify_on_write(grpc_tcp* tcp) {
if (grpc_tcp_trace.enabled()) {
gpr_log(GPR_INFO, "TCP:%p notify_on_write", tcp);
}
- cover_self(tcp);
- GRPC_CLOSURE_INIT(&tcp->write_done_closure,
- tcp_drop_uncovered_then_handle_write, tcp,
- grpc_schedule_on_exec_ctx);
+ if (grpc_event_engine_run_in_background()) {
+ // If there is a polling engine always running in the background, there is
+ // no need to run the backup poller.
+ GRPC_CLOSURE_INIT(&tcp->write_done_closure, tcp_handle_write, tcp,
+ grpc_schedule_on_exec_ctx);
+ } else {
+ cover_self(tcp);
+ GRPC_CLOSURE_INIT(&tcp->write_done_closure,
+ tcp_drop_uncovered_then_handle_write, tcp,
+ grpc_schedule_on_exec_ctx);
+ }
grpc_fd_notify_on_write(tcp->em_fd, &tcp->write_done_closure);
}
@@ -384,6 +391,12 @@ static void tcp_destroy(grpc_endpoint* ep) {
grpc_tcp* tcp = reinterpret_cast<grpc_tcp*>(ep);
grpc_slice_buffer_reset_and_unref_internal(&tcp->last_read_buffer);
if (grpc_event_engine_can_track_errors()) {
+ gpr_mu_lock(&tcp->tb_mu);
+ grpc_core::TracedBuffer::Shutdown(
+ &tcp->tb_head, tcp->outgoing_buffer_arg,
+ GRPC_ERROR_CREATE_FROM_STATIC_STRING("endpoint destroyed"));
+ gpr_mu_unlock(&tcp->tb_mu);
+ tcp->outgoing_buffer_arg = nullptr;
gpr_atm_no_barrier_store(&tcp->stop_error_notification, true);
grpc_fd_set_error(tcp->em_fd);
}
@@ -621,7 +634,7 @@ static bool tcp_write_with_timestamps(grpc_tcp* tcp, struct msghdr* msg,
if (sending_length == static_cast<size_t>(length)) {
gpr_mu_lock(&tcp->tb_mu);
grpc_core::TracedBuffer::AddNewEntry(
- &tcp->tb_head, static_cast<int>(tcp->bytes_counter + length),
+ &tcp->tb_head, static_cast<uint32_t>(tcp->bytes_counter + length),
tcp->outgoing_buffer_arg);
gpr_mu_unlock(&tcp->tb_mu);
tcp->outgoing_buffer_arg = nullptr;
@@ -673,11 +686,9 @@ struct cmsghdr* process_timestamp(grpc_tcp* tcp, msghdr* msg,
}
/** For linux platforms, reads the socket's error queue and processes error
- * messages from the queue. Returns true if all the errors processed were
- * timestamps. Returns false if any of the errors were not timestamps. For
- * non-linux platforms, error processing is not used/enabled currently.
+ * messages from the queue.
*/
-static bool process_errors(grpc_tcp* tcp) {
+static void process_errors(grpc_tcp* tcp) {
while (true) {
struct iovec iov;
iov.iov_base = nullptr;
@@ -706,10 +717,10 @@ static bool process_errors(grpc_tcp* tcp) {
} while (r < 0 && saved_errno == EINTR);
if (r == -1 && saved_errno == EAGAIN) {
- return true; /* No more errors to process */
+ return; /* No more errors to process */
}
if (r == -1) {
- return false;
+ return;
}
if (grpc_tcp_trace.enabled()) {
if ((msg.msg_flags & MSG_CTRUNC) == 1) {
@@ -719,8 +730,9 @@ static bool process_errors(grpc_tcp* tcp) {
if (msg.msg_controllen == 0) {
/* There was no control message found. It was probably spurious. */
- return true;
+ return;
}
+ bool seen = false;
for (auto cmsg = CMSG_FIRSTHDR(&msg); cmsg && cmsg->cmsg_len;
cmsg = CMSG_NXTHDR(&msg, cmsg)) {
if (cmsg->cmsg_level != SOL_SOCKET ||
@@ -732,9 +744,13 @@ static bool process_errors(grpc_tcp* tcp) {
"unknown control message cmsg_level:%d cmsg_type:%d",
cmsg->cmsg_level, cmsg->cmsg_type);
}
- return false;
+ return;
}
- process_timestamp(tcp, &msg, cmsg);
+ cmsg = process_timestamp(tcp, &msg, cmsg);
+ seen = true;
+ }
+ if (!seen) {
+ return;
}
}
}
@@ -749,20 +765,17 @@ static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error) {
static_cast<bool>(gpr_atm_acq_load(&tcp->stop_error_notification))) {
/* We aren't going to register to hear on error anymore, so it is safe to
* unref. */
- grpc_core::TracedBuffer::Shutdown(&tcp->tb_head, GRPC_ERROR_REF(error));
TCP_UNREF(tcp, "error-tracking");
return;
}
/* We are still interested in collecting timestamps, so let's try reading
* them. */
- if (!process_errors(tcp)) {
- /* This was not a timestamps error. This was an actual error. Set the
- * read and write closures to be ready.
- */
- grpc_fd_set_readable(tcp->em_fd);
- grpc_fd_set_writable(tcp->em_fd);
- }
+ process_errors(tcp);
+ /* This might not a timestamps error. Set the read and write closures to be
+ * ready. */
+ grpc_fd_set_readable(tcp->em_fd);
+ grpc_fd_set_writable(tcp->em_fd);
GRPC_CLOSURE_INIT(&tcp->error_closure, tcp_handle_error, tcp,
grpc_schedule_on_exec_ctx);
grpc_fd_notify_on_error(tcp->em_fd, &tcp->error_closure);
@@ -784,6 +797,19 @@ static void tcp_handle_error(void* arg /* grpc_tcp */, grpc_error* error) {
}
#endif /* GRPC_LINUX_ERRQUEUE */
+/* If outgoing_buffer_arg is filled, shuts down the list early, so that any
+ * release operations needed can be performed on the arg */
+void tcp_shutdown_buffer_list(grpc_tcp* tcp) {
+ if (tcp->outgoing_buffer_arg) {
+ gpr_mu_lock(&tcp->tb_mu);
+ grpc_core::TracedBuffer::Shutdown(
+ &tcp->tb_head, tcp->outgoing_buffer_arg,
+ GRPC_ERROR_CREATE_FROM_STATIC_STRING("endpoint destroyed"));
+ gpr_mu_unlock(&tcp->tb_mu);
+ tcp->outgoing_buffer_arg = nullptr;
+ }
+}
+
/* returns true if done, false if pending; if returning true, *error is set */
#if defined(IOV_MAX) && IOV_MAX < 1000
#define MAX_WRITE_IOVEC IOV_MAX
@@ -831,8 +857,10 @@ static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) {
msg.msg_flags = 0;
if (tcp->outgoing_buffer_arg != nullptr) {
if (!tcp_write_with_timestamps(tcp, &msg, sending_length, &sent_length,
- error))
+ error)) {
+ tcp_shutdown_buffer_list(tcp);
return true; /* something went wrong with timestamps */
+ }
} else {
msg.msg_control = nullptr;
msg.msg_controllen = 0;
@@ -856,10 +884,12 @@ static bool tcp_flush(grpc_tcp* tcp, grpc_error** error) {
} else if (errno == EPIPE) {
*error = tcp_annotate_error(GRPC_OS_ERROR(errno, "sendmsg"), tcp);
grpc_slice_buffer_reset_and_unref_internal(tcp->outgoing_buffer);
+ tcp_shutdown_buffer_list(tcp);
return true;
} else {
*error = tcp_annotate_error(GRPC_OS_ERROR(errno, "sendmsg"), tcp);
grpc_slice_buffer_reset_and_unref_internal(tcp->outgoing_buffer);
+ tcp_shutdown_buffer_list(tcp);
return true;
}
}
@@ -936,17 +966,18 @@ static void tcp_write(grpc_endpoint* ep, grpc_slice_buffer* buf,
GPR_ASSERT(tcp->write_cb == nullptr);
+ tcp->outgoing_buffer_arg = arg;
if (buf->length == 0) {
GRPC_CLOSURE_SCHED(
cb, grpc_fd_is_shutdown(tcp->em_fd)
? tcp_annotate_error(
GRPC_ERROR_CREATE_FROM_STATIC_STRING("EOF"), tcp)
: GRPC_ERROR_NONE);
+ tcp_shutdown_buffer_list(tcp);
return;
}
tcp->outgoing_buffer = buf;
tcp->outgoing_byte_idx = 0;
- tcp->outgoing_buffer_arg = arg;
if (arg) {
GPR_ASSERT(grpc_event_engine_can_track_errors());
}
@@ -999,6 +1030,22 @@ static grpc_resource_user* tcp_get_resource_user(grpc_endpoint* ep) {
return tcp->resource_user;
}
+static bool tcp_can_track_err(grpc_endpoint* ep) {
+ grpc_tcp* tcp = reinterpret_cast<grpc_tcp*>(ep);
+ if (!grpc_event_engine_can_track_errors()) {
+ return false;
+ }
+ struct sockaddr addr;
+ socklen_t len = sizeof(addr);
+ if (getsockname(tcp->fd, &addr, &len) < 0) {
+ return false;
+ }
+ if (addr.sa_family == AF_INET || addr.sa_family == AF_INET6) {
+ return true;
+ }
+ return false;
+}
+
static const grpc_endpoint_vtable vtable = {tcp_read,
tcp_write,
tcp_add_to_pollset,
@@ -1008,7 +1055,8 @@ static const grpc_endpoint_vtable vtable = {tcp_read,
tcp_destroy,
tcp_get_resource_user,
tcp_get_peer,
- tcp_get_fd};
+ tcp_get_fd,
+ tcp_can_track_err};
#define MAX_CHUNK_SIZE 32 * 1024 * 1024
@@ -1069,6 +1117,7 @@ grpc_endpoint* grpc_tcp_create(grpc_fd* em_fd,
tcp->is_first_read = true;
tcp->bytes_counter = -1;
tcp->socket_ts_enabled = false;
+ tcp->outgoing_buffer_arg = nullptr;
/* paired with unref in grpc_tcp_destroy */
gpr_ref_init(&tcp->refcount, 1);
gpr_atm_no_barrier_store(&tcp->shutdown_count, 0);
@@ -1113,6 +1162,12 @@ void grpc_tcp_destroy_and_release_fd(grpc_endpoint* ep, int* fd,
grpc_slice_buffer_reset_and_unref_internal(&tcp->last_read_buffer);
if (grpc_event_engine_can_track_errors()) {
/* Stop errors notification. */
+ gpr_mu_lock(&tcp->tb_mu);
+ grpc_core::TracedBuffer::Shutdown(
+ &tcp->tb_head, tcp->outgoing_buffer_arg,
+ GRPC_ERROR_CREATE_FROM_STATIC_STRING("endpoint destroyed"));
+ gpr_mu_unlock(&tcp->tb_mu);
+ tcp->outgoing_buffer_arg = nullptr;
gpr_atm_no_barrier_store(&tcp->stop_error_notification, true);
grpc_fd_set_error(tcp->em_fd);
}
diff --git a/src/core/lib/iomgr/tcp_windows.cc b/src/core/lib/iomgr/tcp_windows.cc
index 64c4a56ae9..4b5250803d 100644
--- a/src/core/lib/iomgr/tcp_windows.cc
+++ b/src/core/lib/iomgr/tcp_windows.cc
@@ -427,6 +427,8 @@ static grpc_resource_user* win_get_resource_user(grpc_endpoint* ep) {
static int win_get_fd(grpc_endpoint* ep) { return -1; }
+static bool win_can_track_err(grpc_endpoint* ep) { return false; }
+
static grpc_endpoint_vtable vtable = {win_read,
win_write,
win_add_to_pollset,
@@ -436,7 +438,8 @@ static grpc_endpoint_vtable vtable = {win_read,
win_destroy,
win_get_resource_user,
win_get_peer,
- win_get_fd};
+ win_get_fd,
+ win_can_track_err};
grpc_endpoint* grpc_tcp_create(grpc_winsocket* socket,
grpc_channel_args* channel_args,
diff --git a/src/core/lib/security/transport/secure_endpoint.cc b/src/core/lib/security/transport/secure_endpoint.cc
index 34d8435907..14fb55884f 100644
--- a/src/core/lib/security/transport/secure_endpoint.cc
+++ b/src/core/lib/security/transport/secure_endpoint.cc
@@ -416,6 +416,11 @@ static grpc_resource_user* endpoint_get_resource_user(
return grpc_endpoint_get_resource_user(ep->wrapped_ep);
}
+static bool endpoint_can_track_err(grpc_endpoint* secure_ep) {
+ secure_endpoint* ep = reinterpret_cast<secure_endpoint*>(secure_ep);
+ return grpc_endpoint_can_track_err(ep->wrapped_ep);
+}
+
static const grpc_endpoint_vtable vtable = {endpoint_read,
endpoint_write,
endpoint_add_to_pollset,
@@ -425,7 +430,8 @@ static const grpc_endpoint_vtable vtable = {endpoint_read,
endpoint_destroy,
endpoint_get_resource_user,
endpoint_get_peer,
- endpoint_get_fd};
+ endpoint_get_fd,
+ endpoint_can_track_err};
grpc_endpoint* grpc_secure_endpoint_create(
struct tsi_frame_protector* protector,
diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc
index 735a78ad08..89b3f77822 100644
--- a/src/core/lib/surface/call.cc
+++ b/src/core/lib/surface/call.cc
@@ -694,6 +694,10 @@ static void cancel_with_error(grpc_call* c, grpc_error* error) {
execute_batch(c, op, &state->start_batch);
}
+void grpc_call_cancel_internal(grpc_call* call) {
+ cancel_with_error(call, GRPC_ERROR_CANCELLED);
+}
+
static grpc_error* error_from_status(grpc_status_code status,
const char* description) {
// copying 'description' is needed to ensure the grpc_call_cancel_with_status
diff --git a/src/core/lib/surface/call.h b/src/core/lib/surface/call.h
index b34260505a..bd7295fe11 100644
--- a/src/core/lib/surface/call.h
+++ b/src/core/lib/surface/call.h
@@ -81,6 +81,10 @@ grpc_call_error grpc_call_start_batch_and_execute(grpc_call* call,
size_t nops,
grpc_closure* closure);
+/* gRPC core internal version of grpc_call_cancel that does not create
+ * exec_ctx. */
+void grpc_call_cancel_internal(grpc_call* call);
+
/* Given the top call_element, get the call object. */
grpc_call* grpc_call_from_top_element(grpc_call_element* surface_element);
diff --git a/src/core/lib/surface/init.cc b/src/core/lib/surface/init.cc
index c6198b8ae7..67cf5d89bf 100644
--- a/src/core/lib/surface/init.cc
+++ b/src/core/lib/surface/init.cc
@@ -161,6 +161,7 @@ void grpc_shutdown(void) {
if (--g_initializations == 0) {
{
grpc_core::ExecCtx exec_ctx(0);
+ grpc_iomgr_shutdown_background_closure();
{
grpc_timer_manager_set_threading(
false); // shutdown timer_manager thread
diff --git a/src/core/lib/surface/server.cc b/src/core/lib/surface/server.cc
index 93b1933809..5dc81b29bb 100644
--- a/src/core/lib/surface/server.cc
+++ b/src/core/lib/surface/server.cc
@@ -47,6 +47,10 @@
grpc_core::TraceFlag grpc_server_channel_trace(false, "server_channel");
+static void server_on_recv_initial_metadata(void* ptr, grpc_error* error);
+static void server_recv_trailing_metadata_ready(void* user_data,
+ grpc_error* error);
+
namespace {
struct listener {
void* arg;
@@ -128,38 +132,62 @@ typedef enum {
typedef struct request_matcher request_matcher;
struct call_data {
+ call_data(grpc_call_element* elem, const grpc_call_element_args& args)
+ : call(grpc_call_from_top_element(elem)),
+ call_combiner(args.call_combiner) {
+ GRPC_CLOSURE_INIT(&server_on_recv_initial_metadata,
+ ::server_on_recv_initial_metadata, elem,
+ grpc_schedule_on_exec_ctx);
+ GRPC_CLOSURE_INIT(&recv_trailing_metadata_ready,
+ server_recv_trailing_metadata_ready, elem,
+ grpc_schedule_on_exec_ctx);
+ }
+ ~call_data() {
+ GPR_ASSERT(state != PENDING);
+ GRPC_ERROR_UNREF(recv_initial_metadata_error);
+ if (host_set) {
+ grpc_slice_unref_internal(host);
+ }
+ if (path_set) {
+ grpc_slice_unref_internal(path);
+ }
+ grpc_metadata_array_destroy(&initial_metadata);
+ grpc_byte_buffer_destroy(payload);
+ }
+
grpc_call* call;
- gpr_atm state;
+ gpr_atm state = NOT_STARTED;
- bool path_set;
- bool host_set;
+ bool path_set = false;
+ bool host_set = false;
grpc_slice path;
grpc_slice host;
- grpc_millis deadline;
+ grpc_millis deadline = GRPC_MILLIS_INF_FUTURE;
- grpc_completion_queue* cq_new;
+ grpc_completion_queue* cq_new = nullptr;
- grpc_metadata_batch* recv_initial_metadata;
- uint32_t recv_initial_metadata_flags;
- grpc_metadata_array initial_metadata;
+ grpc_metadata_batch* recv_initial_metadata = nullptr;
+ uint32_t recv_initial_metadata_flags = 0;
+ grpc_metadata_array initial_metadata =
+ grpc_metadata_array(); // Zero-initialize the C struct.
- request_matcher* matcher;
- grpc_byte_buffer* payload;
+ request_matcher* matcher = nullptr;
+ grpc_byte_buffer* payload = nullptr;
grpc_closure got_initial_metadata;
grpc_closure server_on_recv_initial_metadata;
grpc_closure kill_zombie_closure;
grpc_closure* on_done_recv_initial_metadata;
grpc_closure recv_trailing_metadata_ready;
- grpc_error* recv_initial_metadata_error;
+ grpc_error* recv_initial_metadata_error = GRPC_ERROR_NONE;
grpc_closure* original_recv_trailing_metadata_ready;
- grpc_error* recv_trailing_metadata_error;
- bool seen_recv_trailing_metadata_ready;
+ grpc_error* recv_trailing_metadata_error = GRPC_ERROR_NONE;
+ bool seen_recv_trailing_metadata_ready = false;
grpc_closure publish;
- call_data* pending_next;
+ call_data* pending_next = nullptr;
grpc_call_combiner* call_combiner;
};
@@ -875,40 +903,18 @@ static void channel_connectivity_changed(void* cd, grpc_error* error) {
static grpc_error* init_call_elem(grpc_call_element* elem,
const grpc_call_element_args* args) {
- call_data* calld = static_cast<call_data*>(elem->call_data);
channel_data* chand = static_cast<channel_data*>(elem->channel_data);
- memset(calld, 0, sizeof(call_data));
- calld->deadline = GRPC_MILLIS_INF_FUTURE;
- calld->call = grpc_call_from_top_element(elem);
- calld->call_combiner = args->call_combiner;
-
- GRPC_CLOSURE_INIT(&calld->server_on_recv_initial_metadata,
- server_on_recv_initial_metadata, elem,
- grpc_schedule_on_exec_ctx);
- GRPC_CLOSURE_INIT(&calld->recv_trailing_metadata_ready,
- server_recv_trailing_metadata_ready, elem,
- grpc_schedule_on_exec_ctx);
server_ref(chand->server);
+ new (elem->call_data) call_data(elem, *args);
return GRPC_ERROR_NONE;
}
static void destroy_call_elem(grpc_call_element* elem,
const grpc_call_final_info* final_info,
grpc_closure* ignored) {
- channel_data* chand = static_cast<channel_data*>(elem->channel_data);
call_data* calld = static_cast<call_data*>(elem->call_data);
-
- GPR_ASSERT(calld->state != PENDING);
- GRPC_ERROR_UNREF(calld->recv_initial_metadata_error);
- if (calld->host_set) {
- grpc_slice_unref_internal(calld->host);
- }
- if (calld->path_set) {
- grpc_slice_unref_internal(calld->path);
- }
- grpc_metadata_array_destroy(&calld->initial_metadata);
- grpc_byte_buffer_destroy(calld->payload);
-
+ calld->~call_data();
+ channel_data* chand = static_cast<channel_data*>(elem->channel_data);
server_unref(chand->server);
}
diff --git a/src/core/lib/surface/version.cc b/src/core/lib/surface/version.cc
index 66890ce65a..4829cc80a5 100644
--- a/src/core/lib/surface/version.cc
+++ b/src/core/lib/surface/version.cc
@@ -25,4 +25,4 @@
const char* grpc_version_string(void) { return "7.0.0-dev"; }
-const char* grpc_g_stands_for(void) { return "gizmo"; }
+const char* grpc_g_stands_for(void) { return "goose"; }
diff --git a/src/core/lib/transport/static_metadata.cc b/src/core/lib/transport/static_metadata.cc
index 4ebe73f82a..3dfaaaad5c 100644
--- a/src/core/lib/transport/static_metadata.cc
+++ b/src/core/lib/transport/static_metadata.cc
@@ -65,51 +65,56 @@ static uint8_t g_bytes[] = {
97, 110, 99, 101, 114, 47, 66, 97, 108, 97, 110, 99, 101, 76, 111,
97, 100, 47, 103, 114, 112, 99, 46, 104, 101, 97, 108, 116, 104, 46,
118, 49, 46, 72, 101, 97, 108, 116, 104, 47, 87, 97, 116, 99, 104,
- 100, 101, 102, 108, 97, 116, 101, 103, 122, 105, 112, 115, 116, 114, 101,
- 97, 109, 47, 103, 122, 105, 112, 71, 69, 84, 80, 79, 83, 84, 47,
- 47, 105, 110, 100, 101, 120, 46, 104, 116, 109, 108, 104, 116, 116, 112,
- 104, 116, 116, 112, 115, 50, 48, 48, 50, 48, 52, 50, 48, 54, 51,
- 48, 52, 52, 48, 48, 52, 48, 52, 53, 48, 48, 97, 99, 99, 101,
- 112, 116, 45, 99, 104, 97, 114, 115, 101, 116, 103, 122, 105, 112, 44,
- 32, 100, 101, 102, 108, 97, 116, 101, 97, 99, 99, 101, 112, 116, 45,
- 108, 97, 110, 103, 117, 97, 103, 101, 97, 99, 99, 101, 112, 116, 45,
- 114, 97, 110, 103, 101, 115, 97, 99, 99, 101, 112, 116, 97, 99, 99,
- 101, 115, 115, 45, 99, 111, 110, 116, 114, 111, 108, 45, 97, 108, 108,
- 111, 119, 45, 111, 114, 105, 103, 105, 110, 97, 103, 101, 97, 108, 108,
- 111, 119, 97, 117, 116, 104, 111, 114, 105, 122, 97, 116, 105, 111, 110,
- 99, 97, 99, 104, 101, 45, 99, 111, 110, 116, 114, 111, 108, 99, 111,
- 110, 116, 101, 110, 116, 45, 100, 105, 115, 112, 111, 115, 105, 116, 105,
- 111, 110, 99, 111, 110, 116, 101, 110, 116, 45, 108, 97, 110, 103, 117,
- 97, 103, 101, 99, 111, 110, 116, 101, 110, 116, 45, 108, 101, 110, 103,
- 116, 104, 99, 111, 110, 116, 101, 110, 116, 45, 108, 111, 99, 97, 116,
- 105, 111, 110, 99, 111, 110, 116, 101, 110, 116, 45, 114, 97, 110, 103,
- 101, 99, 111, 111, 107, 105, 101, 100, 97, 116, 101, 101, 116, 97, 103,
- 101, 120, 112, 101, 99, 116, 101, 120, 112, 105, 114, 101, 115, 102, 114,
- 111, 109, 105, 102, 45, 109, 97, 116, 99, 104, 105, 102, 45, 109, 111,
- 100, 105, 102, 105, 101, 100, 45, 115, 105, 110, 99, 101, 105, 102, 45,
- 110, 111, 110, 101, 45, 109, 97, 116, 99, 104, 105, 102, 45, 114, 97,
- 110, 103, 101, 105, 102, 45, 117, 110, 109, 111, 100, 105, 102, 105, 101,
- 100, 45, 115, 105, 110, 99, 101, 108, 97, 115, 116, 45, 109, 111, 100,
- 105, 102, 105, 101, 100, 108, 105, 110, 107, 108, 111, 99, 97, 116, 105,
- 111, 110, 109, 97, 120, 45, 102, 111, 114, 119, 97, 114, 100, 115, 112,
- 114, 111, 120, 121, 45, 97, 117, 116, 104, 101, 110, 116, 105, 99, 97,
- 116, 101, 112, 114, 111, 120, 121, 45, 97, 117, 116, 104, 111, 114, 105,
- 122, 97, 116, 105, 111, 110, 114, 97, 110, 103, 101, 114, 101, 102, 101,
- 114, 101, 114, 114, 101, 102, 114, 101, 115, 104, 114, 101, 116, 114, 121,
- 45, 97, 102, 116, 101, 114, 115, 101, 114, 118, 101, 114, 115, 101, 116,
- 45, 99, 111, 111, 107, 105, 101, 115, 116, 114, 105, 99, 116, 45, 116,
- 114, 97, 110, 115, 112, 111, 114, 116, 45, 115, 101, 99, 117, 114, 105,
- 116, 121, 116, 114, 97, 110, 115, 102, 101, 114, 45, 101, 110, 99, 111,
- 100, 105, 110, 103, 118, 97, 114, 121, 118, 105, 97, 119, 119, 119, 45,
- 97, 117, 116, 104, 101, 110, 116, 105, 99, 97, 116, 101, 48, 105, 100,
- 101, 110, 116, 105, 116, 121, 116, 114, 97, 105, 108, 101, 114, 115, 97,
- 112, 112, 108, 105, 99, 97, 116, 105, 111, 110, 47, 103, 114, 112, 99,
- 103, 114, 112, 99, 80, 85, 84, 108, 98, 45, 99, 111, 115, 116, 45,
- 98, 105, 110, 105, 100, 101, 110, 116, 105, 116, 121, 44, 100, 101, 102,
- 108, 97, 116, 101, 105, 100, 101, 110, 116, 105, 116, 121, 44, 103, 122,
- 105, 112, 100, 101, 102, 108, 97, 116, 101, 44, 103, 122, 105, 112, 105,
- 100, 101, 110, 116, 105, 116, 121, 44, 100, 101, 102, 108, 97, 116, 101,
- 44, 103, 122, 105, 112};
+ 47, 101, 110, 118, 111, 121, 46, 115, 101, 114, 118, 105, 99, 101, 46,
+ 100, 105, 115, 99, 111, 118, 101, 114, 121, 46, 118, 50, 46, 65, 103,
+ 103, 114, 101, 103, 97, 116, 101, 100, 68, 105, 115, 99, 111, 118, 101,
+ 114, 121, 83, 101, 114, 118, 105, 99, 101, 47, 83, 116, 114, 101, 97,
+ 109, 65, 103, 103, 114, 101, 103, 97, 116, 101, 100, 82, 101, 115, 111,
+ 117, 114, 99, 101, 115, 100, 101, 102, 108, 97, 116, 101, 103, 122, 105,
+ 112, 115, 116, 114, 101, 97, 109, 47, 103, 122, 105, 112, 71, 69, 84,
+ 80, 79, 83, 84, 47, 47, 105, 110, 100, 101, 120, 46, 104, 116, 109,
+ 108, 104, 116, 116, 112, 104, 116, 116, 112, 115, 50, 48, 48, 50, 48,
+ 52, 50, 48, 54, 51, 48, 52, 52, 48, 48, 52, 48, 52, 53, 48,
+ 48, 97, 99, 99, 101, 112, 116, 45, 99, 104, 97, 114, 115, 101, 116,
+ 103, 122, 105, 112, 44, 32, 100, 101, 102, 108, 97, 116, 101, 97, 99,
+ 99, 101, 112, 116, 45, 108, 97, 110, 103, 117, 97, 103, 101, 97, 99,
+ 99, 101, 112, 116, 45, 114, 97, 110, 103, 101, 115, 97, 99, 99, 101,
+ 112, 116, 97, 99, 99, 101, 115, 115, 45, 99, 111, 110, 116, 114, 111,
+ 108, 45, 97, 108, 108, 111, 119, 45, 111, 114, 105, 103, 105, 110, 97,
+ 103, 101, 97, 108, 108, 111, 119, 97, 117, 116, 104, 111, 114, 105, 122,
+ 97, 116, 105, 111, 110, 99, 97, 99, 104, 101, 45, 99, 111, 110, 116,
+ 114, 111, 108, 99, 111, 110, 116, 101, 110, 116, 45, 100, 105, 115, 112,
+ 111, 115, 105, 116, 105, 111, 110, 99, 111, 110, 116, 101, 110, 116, 45,
+ 108, 97, 110, 103, 117, 97, 103, 101, 99, 111, 110, 116, 101, 110, 116,
+ 45, 108, 101, 110, 103, 116, 104, 99, 111, 110, 116, 101, 110, 116, 45,
+ 108, 111, 99, 97, 116, 105, 111, 110, 99, 111, 110, 116, 101, 110, 116,
+ 45, 114, 97, 110, 103, 101, 99, 111, 111, 107, 105, 101, 100, 97, 116,
+ 101, 101, 116, 97, 103, 101, 120, 112, 101, 99, 116, 101, 120, 112, 105,
+ 114, 101, 115, 102, 114, 111, 109, 105, 102, 45, 109, 97, 116, 99, 104,
+ 105, 102, 45, 109, 111, 100, 105, 102, 105, 101, 100, 45, 115, 105, 110,
+ 99, 101, 105, 102, 45, 110, 111, 110, 101, 45, 109, 97, 116, 99, 104,
+ 105, 102, 45, 114, 97, 110, 103, 101, 105, 102, 45, 117, 110, 109, 111,
+ 100, 105, 102, 105, 101, 100, 45, 115, 105, 110, 99, 101, 108, 97, 115,
+ 116, 45, 109, 111, 100, 105, 102, 105, 101, 100, 108, 105, 110, 107, 108,
+ 111, 99, 97, 116, 105, 111, 110, 109, 97, 120, 45, 102, 111, 114, 119,
+ 97, 114, 100, 115, 112, 114, 111, 120, 121, 45, 97, 117, 116, 104, 101,
+ 110, 116, 105, 99, 97, 116, 101, 112, 114, 111, 120, 121, 45, 97, 117,
+ 116, 104, 111, 114, 105, 122, 97, 116, 105, 111, 110, 114, 97, 110, 103,
+ 101, 114, 101, 102, 101, 114, 101, 114, 114, 101, 102, 114, 101, 115, 104,
+ 114, 101, 116, 114, 121, 45, 97, 102, 116, 101, 114, 115, 101, 114, 118,
+ 101, 114, 115, 101, 116, 45, 99, 111, 111, 107, 105, 101, 115, 116, 114,
+ 105, 99, 116, 45, 116, 114, 97, 110, 115, 112, 111, 114, 116, 45, 115,
+ 101, 99, 117, 114, 105, 116, 121, 116, 114, 97, 110, 115, 102, 101, 114,
+ 45, 101, 110, 99, 111, 100, 105, 110, 103, 118, 97, 114, 121, 118, 105,
+ 97, 119, 119, 119, 45, 97, 117, 116, 104, 101, 110, 116, 105, 99, 97,
+ 116, 101, 48, 105, 100, 101, 110, 116, 105, 116, 121, 116, 114, 97, 105,
+ 108, 101, 114, 115, 97, 112, 112, 108, 105, 99, 97, 116, 105, 111, 110,
+ 47, 103, 114, 112, 99, 103, 114, 112, 99, 80, 85, 84, 108, 98, 45,
+ 99, 111, 115, 116, 45, 98, 105, 110, 105, 100, 101, 110, 116, 105, 116,
+ 121, 44, 100, 101, 102, 108, 97, 116, 101, 105, 100, 101, 110, 116, 105,
+ 116, 121, 44, 103, 122, 105, 112, 100, 101, 102, 108, 97, 116, 101, 44,
+ 103, 122, 105, 112, 105, 100, 101, 110, 116, 105, 116, 121, 44, 100, 101,
+ 102, 108, 97, 116, 101, 44, 103, 122, 105, 112};
static void static_ref(void* unused) {}
static void static_unref(void* unused) {}
@@ -227,6 +232,7 @@ grpc_slice_refcount grpc_static_metadata_refcounts[GRPC_STATIC_MDSTR_COUNT] = {
{&grpc_static_metadata_vtable, &static_sub_refcnt},
{&grpc_static_metadata_vtable, &static_sub_refcnt},
{&grpc_static_metadata_vtable, &static_sub_refcnt},
+ {&grpc_static_metadata_vtable, &static_sub_refcnt},
};
const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT] = {
@@ -266,76 +272,77 @@ const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT] = {
{&grpc_static_metadata_refcounts[33], {{g_bytes + 415, 31}}},
{&grpc_static_metadata_refcounts[34], {{g_bytes + 446, 36}}},
{&grpc_static_metadata_refcounts[35], {{g_bytes + 482, 28}}},
- {&grpc_static_metadata_refcounts[36], {{g_bytes + 510, 7}}},
- {&grpc_static_metadata_refcounts[37], {{g_bytes + 517, 4}}},
- {&grpc_static_metadata_refcounts[38], {{g_bytes + 521, 11}}},
- {&grpc_static_metadata_refcounts[39], {{g_bytes + 532, 3}}},
- {&grpc_static_metadata_refcounts[40], {{g_bytes + 535, 4}}},
- {&grpc_static_metadata_refcounts[41], {{g_bytes + 539, 1}}},
- {&grpc_static_metadata_refcounts[42], {{g_bytes + 540, 11}}},
- {&grpc_static_metadata_refcounts[43], {{g_bytes + 551, 4}}},
- {&grpc_static_metadata_refcounts[44], {{g_bytes + 555, 5}}},
- {&grpc_static_metadata_refcounts[45], {{g_bytes + 560, 3}}},
- {&grpc_static_metadata_refcounts[46], {{g_bytes + 563, 3}}},
- {&grpc_static_metadata_refcounts[47], {{g_bytes + 566, 3}}},
- {&grpc_static_metadata_refcounts[48], {{g_bytes + 569, 3}}},
- {&grpc_static_metadata_refcounts[49], {{g_bytes + 572, 3}}},
- {&grpc_static_metadata_refcounts[50], {{g_bytes + 575, 3}}},
- {&grpc_static_metadata_refcounts[51], {{g_bytes + 578, 3}}},
- {&grpc_static_metadata_refcounts[52], {{g_bytes + 581, 14}}},
- {&grpc_static_metadata_refcounts[53], {{g_bytes + 595, 13}}},
- {&grpc_static_metadata_refcounts[54], {{g_bytes + 608, 15}}},
- {&grpc_static_metadata_refcounts[55], {{g_bytes + 623, 13}}},
- {&grpc_static_metadata_refcounts[56], {{g_bytes + 636, 6}}},
- {&grpc_static_metadata_refcounts[57], {{g_bytes + 642, 27}}},
- {&grpc_static_metadata_refcounts[58], {{g_bytes + 669, 3}}},
- {&grpc_static_metadata_refcounts[59], {{g_bytes + 672, 5}}},
- {&grpc_static_metadata_refcounts[60], {{g_bytes + 677, 13}}},
- {&grpc_static_metadata_refcounts[61], {{g_bytes + 690, 13}}},
- {&grpc_static_metadata_refcounts[62], {{g_bytes + 703, 19}}},
- {&grpc_static_metadata_refcounts[63], {{g_bytes + 722, 16}}},
- {&grpc_static_metadata_refcounts[64], {{g_bytes + 738, 14}}},
- {&grpc_static_metadata_refcounts[65], {{g_bytes + 752, 16}}},
- {&grpc_static_metadata_refcounts[66], {{g_bytes + 768, 13}}},
- {&grpc_static_metadata_refcounts[67], {{g_bytes + 781, 6}}},
- {&grpc_static_metadata_refcounts[68], {{g_bytes + 787, 4}}},
- {&grpc_static_metadata_refcounts[69], {{g_bytes + 791, 4}}},
- {&grpc_static_metadata_refcounts[70], {{g_bytes + 795, 6}}},
- {&grpc_static_metadata_refcounts[71], {{g_bytes + 801, 7}}},
- {&grpc_static_metadata_refcounts[72], {{g_bytes + 808, 4}}},
- {&grpc_static_metadata_refcounts[73], {{g_bytes + 812, 8}}},
- {&grpc_static_metadata_refcounts[74], {{g_bytes + 820, 17}}},
- {&grpc_static_metadata_refcounts[75], {{g_bytes + 837, 13}}},
- {&grpc_static_metadata_refcounts[76], {{g_bytes + 850, 8}}},
- {&grpc_static_metadata_refcounts[77], {{g_bytes + 858, 19}}},
- {&grpc_static_metadata_refcounts[78], {{g_bytes + 877, 13}}},
- {&grpc_static_metadata_refcounts[79], {{g_bytes + 890, 4}}},
- {&grpc_static_metadata_refcounts[80], {{g_bytes + 894, 8}}},
- {&grpc_static_metadata_refcounts[81], {{g_bytes + 902, 12}}},
- {&grpc_static_metadata_refcounts[82], {{g_bytes + 914, 18}}},
- {&grpc_static_metadata_refcounts[83], {{g_bytes + 932, 19}}},
- {&grpc_static_metadata_refcounts[84], {{g_bytes + 951, 5}}},
- {&grpc_static_metadata_refcounts[85], {{g_bytes + 956, 7}}},
- {&grpc_static_metadata_refcounts[86], {{g_bytes + 963, 7}}},
- {&grpc_static_metadata_refcounts[87], {{g_bytes + 970, 11}}},
- {&grpc_static_metadata_refcounts[88], {{g_bytes + 981, 6}}},
- {&grpc_static_metadata_refcounts[89], {{g_bytes + 987, 10}}},
- {&grpc_static_metadata_refcounts[90], {{g_bytes + 997, 25}}},
- {&grpc_static_metadata_refcounts[91], {{g_bytes + 1022, 17}}},
- {&grpc_static_metadata_refcounts[92], {{g_bytes + 1039, 4}}},
- {&grpc_static_metadata_refcounts[93], {{g_bytes + 1043, 3}}},
- {&grpc_static_metadata_refcounts[94], {{g_bytes + 1046, 16}}},
- {&grpc_static_metadata_refcounts[95], {{g_bytes + 1062, 1}}},
- {&grpc_static_metadata_refcounts[96], {{g_bytes + 1063, 8}}},
- {&grpc_static_metadata_refcounts[97], {{g_bytes + 1071, 8}}},
- {&grpc_static_metadata_refcounts[98], {{g_bytes + 1079, 16}}},
- {&grpc_static_metadata_refcounts[99], {{g_bytes + 1095, 4}}},
- {&grpc_static_metadata_refcounts[100], {{g_bytes + 1099, 3}}},
- {&grpc_static_metadata_refcounts[101], {{g_bytes + 1102, 11}}},
- {&grpc_static_metadata_refcounts[102], {{g_bytes + 1113, 16}}},
- {&grpc_static_metadata_refcounts[103], {{g_bytes + 1129, 13}}},
- {&grpc_static_metadata_refcounts[104], {{g_bytes + 1142, 12}}},
- {&grpc_static_metadata_refcounts[105], {{g_bytes + 1154, 21}}},
+ {&grpc_static_metadata_refcounts[36], {{g_bytes + 510, 80}}},
+ {&grpc_static_metadata_refcounts[37], {{g_bytes + 590, 7}}},
+ {&grpc_static_metadata_refcounts[38], {{g_bytes + 597, 4}}},
+ {&grpc_static_metadata_refcounts[39], {{g_bytes + 601, 11}}},
+ {&grpc_static_metadata_refcounts[40], {{g_bytes + 612, 3}}},
+ {&grpc_static_metadata_refcounts[41], {{g_bytes + 615, 4}}},
+ {&grpc_static_metadata_refcounts[42], {{g_bytes + 619, 1}}},
+ {&grpc_static_metadata_refcounts[43], {{g_bytes + 620, 11}}},
+ {&grpc_static_metadata_refcounts[44], {{g_bytes + 631, 4}}},
+ {&grpc_static_metadata_refcounts[45], {{g_bytes + 635, 5}}},
+ {&grpc_static_metadata_refcounts[46], {{g_bytes + 640, 3}}},
+ {&grpc_static_metadata_refcounts[47], {{g_bytes + 643, 3}}},
+ {&grpc_static_metadata_refcounts[48], {{g_bytes + 646, 3}}},
+ {&grpc_static_metadata_refcounts[49], {{g_bytes + 649, 3}}},
+ {&grpc_static_metadata_refcounts[50], {{g_bytes + 652, 3}}},
+ {&grpc_static_metadata_refcounts[51], {{g_bytes + 655, 3}}},
+ {&grpc_static_metadata_refcounts[52], {{g_bytes + 658, 3}}},
+ {&grpc_static_metadata_refcounts[53], {{g_bytes + 661, 14}}},
+ {&grpc_static_metadata_refcounts[54], {{g_bytes + 675, 13}}},
+ {&grpc_static_metadata_refcounts[55], {{g_bytes + 688, 15}}},
+ {&grpc_static_metadata_refcounts[56], {{g_bytes + 703, 13}}},
+ {&grpc_static_metadata_refcounts[57], {{g_bytes + 716, 6}}},
+ {&grpc_static_metadata_refcounts[58], {{g_bytes + 722, 27}}},
+ {&grpc_static_metadata_refcounts[59], {{g_bytes + 749, 3}}},
+ {&grpc_static_metadata_refcounts[60], {{g_bytes + 752, 5}}},
+ {&grpc_static_metadata_refcounts[61], {{g_bytes + 757, 13}}},
+ {&grpc_static_metadata_refcounts[62], {{g_bytes + 770, 13}}},
+ {&grpc_static_metadata_refcounts[63], {{g_bytes + 783, 19}}},
+ {&grpc_static_metadata_refcounts[64], {{g_bytes + 802, 16}}},
+ {&grpc_static_metadata_refcounts[65], {{g_bytes + 818, 14}}},
+ {&grpc_static_metadata_refcounts[66], {{g_bytes + 832, 16}}},
+ {&grpc_static_metadata_refcounts[67], {{g_bytes + 848, 13}}},
+ {&grpc_static_metadata_refcounts[68], {{g_bytes + 861, 6}}},
+ {&grpc_static_metadata_refcounts[69], {{g_bytes + 867, 4}}},
+ {&grpc_static_metadata_refcounts[70], {{g_bytes + 871, 4}}},
+ {&grpc_static_metadata_refcounts[71], {{g_bytes + 875, 6}}},
+ {&grpc_static_metadata_refcounts[72], {{g_bytes + 881, 7}}},
+ {&grpc_static_metadata_refcounts[73], {{g_bytes + 888, 4}}},
+ {&grpc_static_metadata_refcounts[74], {{g_bytes + 892, 8}}},
+ {&grpc_static_metadata_refcounts[75], {{g_bytes + 900, 17}}},
+ {&grpc_static_metadata_refcounts[76], {{g_bytes + 917, 13}}},
+ {&grpc_static_metadata_refcounts[77], {{g_bytes + 930, 8}}},
+ {&grpc_static_metadata_refcounts[78], {{g_bytes + 938, 19}}},
+ {&grpc_static_metadata_refcounts[79], {{g_bytes + 957, 13}}},
+ {&grpc_static_metadata_refcounts[80], {{g_bytes + 970, 4}}},
+ {&grpc_static_metadata_refcounts[81], {{g_bytes + 974, 8}}},
+ {&grpc_static_metadata_refcounts[82], {{g_bytes + 982, 12}}},
+ {&grpc_static_metadata_refcounts[83], {{g_bytes + 994, 18}}},
+ {&grpc_static_metadata_refcounts[84], {{g_bytes + 1012, 19}}},
+ {&grpc_static_metadata_refcounts[85], {{g_bytes + 1031, 5}}},
+ {&grpc_static_metadata_refcounts[86], {{g_bytes + 1036, 7}}},
+ {&grpc_static_metadata_refcounts[87], {{g_bytes + 1043, 7}}},
+ {&grpc_static_metadata_refcounts[88], {{g_bytes + 1050, 11}}},
+ {&grpc_static_metadata_refcounts[89], {{g_bytes + 1061, 6}}},
+ {&grpc_static_metadata_refcounts[90], {{g_bytes + 1067, 10}}},
+ {&grpc_static_metadata_refcounts[91], {{g_bytes + 1077, 25}}},
+ {&grpc_static_metadata_refcounts[92], {{g_bytes + 1102, 17}}},
+ {&grpc_static_metadata_refcounts[93], {{g_bytes + 1119, 4}}},
+ {&grpc_static_metadata_refcounts[94], {{g_bytes + 1123, 3}}},
+ {&grpc_static_metadata_refcounts[95], {{g_bytes + 1126, 16}}},
+ {&grpc_static_metadata_refcounts[96], {{g_bytes + 1142, 1}}},
+ {&grpc_static_metadata_refcounts[97], {{g_bytes + 1143, 8}}},
+ {&grpc_static_metadata_refcounts[98], {{g_bytes + 1151, 8}}},
+ {&grpc_static_metadata_refcounts[99], {{g_bytes + 1159, 16}}},
+ {&grpc_static_metadata_refcounts[100], {{g_bytes + 1175, 4}}},
+ {&grpc_static_metadata_refcounts[101], {{g_bytes + 1179, 3}}},
+ {&grpc_static_metadata_refcounts[102], {{g_bytes + 1182, 11}}},
+ {&grpc_static_metadata_refcounts[103], {{g_bytes + 1193, 16}}},
+ {&grpc_static_metadata_refcounts[104], {{g_bytes + 1209, 13}}},
+ {&grpc_static_metadata_refcounts[105], {{g_bytes + 1222, 12}}},
+ {&grpc_static_metadata_refcounts[106], {{g_bytes + 1234, 21}}},
};
uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] = {
@@ -345,17 +352,17 @@ uintptr_t grpc_static_mdelem_user_data[GRPC_STATIC_MDELEM_COUNT] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 4, 4, 6, 6, 8, 8, 2, 4, 4};
static const int8_t elems_r[] = {
- 16, 11, -8, 0, 3, -42, -81, -43, 0, 6, -8, 0, 0, 0, -7,
- -3, -10, 0, 0, 0, -1, -2, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, -63, 0, -47, -68, -69, -70, 0, 33,
- 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 20,
- 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5,
- 4, 4, 4, 3, 10, 9, 0, 0, 0, 0, 0, 0, -3, 0};
+ 15, 10, -8, 0, 2, -42, -81, -43, 0, 6, -8, 0, 0, 0, 2,
+ -3, -10, 0, 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, -64, 0, -67, -68, -69, -70, 0,
+ 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21,
+ 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6,
+ 5, 4, 5, 4, 4, 8, 8, 0, 0, 0, 0, 0, 0, -5, 0};
static uint32_t elems_phash(uint32_t i) {
- i -= 41;
- uint32_t x = i % 104;
- uint32_t y = i / 104;
+ i -= 42;
+ uint32_t x = i % 105;
+ uint32_t y = i / 105;
uint32_t h = x;
if (y < GPR_ARRAY_SIZE(elems_r)) {
uint32_t delta = (uint32_t)elems_r[y];
@@ -365,29 +372,29 @@ static uint32_t elems_phash(uint32_t i) {
}
static const uint16_t elem_keys[] = {
- 257, 258, 259, 260, 261, 262, 263, 1096, 1097, 1513, 1725, 145,
- 146, 467, 468, 1619, 41, 42, 1733, 990, 991, 767, 768, 1627,
- 627, 837, 2043, 2149, 2255, 5541, 5859, 5965, 6071, 6177, 1749, 6283,
- 6389, 6495, 6601, 6707, 6813, 6919, 7025, 7131, 7237, 7343, 7449, 7555,
- 7661, 5753, 7767, 7873, 7979, 8085, 8191, 8297, 8403, 8509, 8615, 8721,
- 8827, 8933, 9039, 9145, 9251, 9357, 9463, 1156, 9569, 523, 9675, 9781,
- 206, 1162, 1163, 1164, 1165, 1792, 1582, 1050, 9887, 9993, 1686, 10735,
- 1799, 0, 0, 0, 0, 0, 347, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0};
+ 260, 261, 262, 263, 264, 265, 266, 1107, 1108, 1741, 147, 148,
+ 472, 473, 1634, 42, 43, 1527, 1750, 1000, 1001, 774, 775, 1643,
+ 633, 845, 2062, 2169, 2276, 5700, 5914, 6021, 6128, 6235, 1766, 6342,
+ 6449, 6556, 6663, 6770, 6877, 6984, 7091, 7198, 7305, 7412, 7519, 7626,
+ 7733, 7840, 7947, 8054, 8161, 8268, 8375, 8482, 8589, 8696, 8803, 8910,
+ 9017, 9124, 9231, 9338, 9445, 9552, 9659, 1167, 528, 9766, 9873, 208,
+ 9980, 1173, 1174, 1175, 1176, 1809, 10087, 1060, 10194, 10943, 1702, 0,
+ 1816, 0, 0, 1597, 0, 0, 350, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0};
static const uint8_t elem_idxs[] = {
- 7, 8, 9, 10, 11, 12, 13, 77, 79, 30, 71, 1, 2, 5, 6, 25,
- 3, 4, 84, 66, 65, 62, 63, 73, 67, 61, 57, 37, 74, 14, 17, 18,
- 19, 20, 15, 21, 22, 23, 24, 26, 27, 28, 29, 31, 32, 33, 34, 35,
- 36, 16, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
- 52, 53, 54, 76, 55, 69, 56, 58, 70, 78, 80, 81, 82, 83, 68, 64,
- 59, 60, 72, 75, 85, 255, 255, 255, 255, 255, 0};
+ 7, 8, 9, 10, 11, 12, 13, 77, 79, 71, 1, 2, 5, 6, 25, 3,
+ 4, 30, 84, 66, 65, 62, 63, 73, 67, 61, 57, 37, 74, 14, 16, 17,
+ 18, 19, 15, 20, 21, 22, 23, 24, 26, 27, 28, 29, 31, 32, 33, 34,
+ 35, 36, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, 54, 76, 69, 55, 56, 70, 58, 78, 80, 81, 82, 83, 59, 64,
+ 60, 75, 72, 255, 85, 255, 255, 68, 255, 255, 0};
grpc_mdelem grpc_static_mdelem_for_static_strings(int a, int b) {
if (a == -1 || b == -1) return GRPC_MDNULL;
- uint32_t k = (uint32_t)(a * 106 + b);
+ uint32_t k = (uint32_t)(a * 107 + b);
uint32_t h = elems_phash(k);
return h < GPR_ARRAY_SIZE(elem_keys) && elem_keys[h] == k &&
elem_idxs[h] != 255
@@ -400,175 +407,175 @@ grpc_mdelem_data grpc_static_mdelem_table[GRPC_STATIC_MDELEM_COUNT] = {
{{&grpc_static_metadata_refcounts[3], {{g_bytes + 19, 10}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}},
- {&grpc_static_metadata_refcounts[39], {{g_bytes + 532, 3}}}},
+ {&grpc_static_metadata_refcounts[40], {{g_bytes + 612, 3}}}},
{{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}},
- {&grpc_static_metadata_refcounts[40], {{g_bytes + 535, 4}}}},
+ {&grpc_static_metadata_refcounts[41], {{g_bytes + 615, 4}}}},
{{&grpc_static_metadata_refcounts[0], {{g_bytes + 0, 5}}},
- {&grpc_static_metadata_refcounts[41], {{g_bytes + 539, 1}}}},
+ {&grpc_static_metadata_refcounts[42], {{g_bytes + 619, 1}}}},
{{&grpc_static_metadata_refcounts[0], {{g_bytes + 0, 5}}},
- {&grpc_static_metadata_refcounts[42], {{g_bytes + 540, 11}}}},
+ {&grpc_static_metadata_refcounts[43], {{g_bytes + 620, 11}}}},
{{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}},
- {&grpc_static_metadata_refcounts[43], {{g_bytes + 551, 4}}}},
+ {&grpc_static_metadata_refcounts[44], {{g_bytes + 631, 4}}}},
{{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}},
- {&grpc_static_metadata_refcounts[44], {{g_bytes + 555, 5}}}},
+ {&grpc_static_metadata_refcounts[45], {{g_bytes + 635, 5}}}},
{{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}},
- {&grpc_static_metadata_refcounts[45], {{g_bytes + 560, 3}}}},
+ {&grpc_static_metadata_refcounts[46], {{g_bytes + 640, 3}}}},
{{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}},
- {&grpc_static_metadata_refcounts[46], {{g_bytes + 563, 3}}}},
+ {&grpc_static_metadata_refcounts[47], {{g_bytes + 643, 3}}}},
{{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}},
- {&grpc_static_metadata_refcounts[47], {{g_bytes + 566, 3}}}},
+ {&grpc_static_metadata_refcounts[48], {{g_bytes + 646, 3}}}},
{{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}},
- {&grpc_static_metadata_refcounts[48], {{g_bytes + 569, 3}}}},
+ {&grpc_static_metadata_refcounts[49], {{g_bytes + 649, 3}}}},
{{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}},
- {&grpc_static_metadata_refcounts[49], {{g_bytes + 572, 3}}}},
+ {&grpc_static_metadata_refcounts[50], {{g_bytes + 652, 3}}}},
{{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}},
- {&grpc_static_metadata_refcounts[50], {{g_bytes + 575, 3}}}},
+ {&grpc_static_metadata_refcounts[51], {{g_bytes + 655, 3}}}},
{{&grpc_static_metadata_refcounts[2], {{g_bytes + 12, 7}}},
- {&grpc_static_metadata_refcounts[51], {{g_bytes + 578, 3}}}},
- {{&grpc_static_metadata_refcounts[52], {{g_bytes + 581, 14}}},
+ {&grpc_static_metadata_refcounts[52], {{g_bytes + 658, 3}}}},
+ {{&grpc_static_metadata_refcounts[53], {{g_bytes + 661, 14}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}},
- {&grpc_static_metadata_refcounts[53], {{g_bytes + 595, 13}}}},
- {{&grpc_static_metadata_refcounts[54], {{g_bytes + 608, 15}}},
+ {&grpc_static_metadata_refcounts[54], {{g_bytes + 675, 13}}}},
+ {{&grpc_static_metadata_refcounts[55], {{g_bytes + 688, 15}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[55], {{g_bytes + 623, 13}}},
+ {{&grpc_static_metadata_refcounts[56], {{g_bytes + 703, 13}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[56], {{g_bytes + 636, 6}}},
+ {{&grpc_static_metadata_refcounts[57], {{g_bytes + 716, 6}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[57], {{g_bytes + 642, 27}}},
+ {{&grpc_static_metadata_refcounts[58], {{g_bytes + 722, 27}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[58], {{g_bytes + 669, 3}}},
+ {{&grpc_static_metadata_refcounts[59], {{g_bytes + 749, 3}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[59], {{g_bytes + 672, 5}}},
+ {{&grpc_static_metadata_refcounts[60], {{g_bytes + 752, 5}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[60], {{g_bytes + 677, 13}}},
+ {{&grpc_static_metadata_refcounts[61], {{g_bytes + 757, 13}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[61], {{g_bytes + 690, 13}}},
+ {{&grpc_static_metadata_refcounts[62], {{g_bytes + 770, 13}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[62], {{g_bytes + 703, 19}}},
+ {{&grpc_static_metadata_refcounts[63], {{g_bytes + 783, 19}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[63], {{g_bytes + 722, 16}}},
+ {{&grpc_static_metadata_refcounts[64], {{g_bytes + 802, 16}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[64], {{g_bytes + 738, 14}}},
+ {{&grpc_static_metadata_refcounts[65], {{g_bytes + 818, 14}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[65], {{g_bytes + 752, 16}}},
+ {{&grpc_static_metadata_refcounts[66], {{g_bytes + 832, 16}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[66], {{g_bytes + 768, 13}}},
+ {{&grpc_static_metadata_refcounts[67], {{g_bytes + 848, 13}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[14], {{g_bytes + 158, 12}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[67], {{g_bytes + 781, 6}}},
+ {{&grpc_static_metadata_refcounts[68], {{g_bytes + 861, 6}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[68], {{g_bytes + 787, 4}}},
+ {{&grpc_static_metadata_refcounts[69], {{g_bytes + 867, 4}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[69], {{g_bytes + 791, 4}}},
+ {{&grpc_static_metadata_refcounts[70], {{g_bytes + 871, 4}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[70], {{g_bytes + 795, 6}}},
+ {{&grpc_static_metadata_refcounts[71], {{g_bytes + 875, 6}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[71], {{g_bytes + 801, 7}}},
+ {{&grpc_static_metadata_refcounts[72], {{g_bytes + 881, 7}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[72], {{g_bytes + 808, 4}}},
+ {{&grpc_static_metadata_refcounts[73], {{g_bytes + 888, 4}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[20], {{g_bytes + 278, 4}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[73], {{g_bytes + 812, 8}}},
+ {{&grpc_static_metadata_refcounts[74], {{g_bytes + 892, 8}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[74], {{g_bytes + 820, 17}}},
+ {{&grpc_static_metadata_refcounts[75], {{g_bytes + 900, 17}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[75], {{g_bytes + 837, 13}}},
+ {{&grpc_static_metadata_refcounts[76], {{g_bytes + 917, 13}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[76], {{g_bytes + 850, 8}}},
+ {{&grpc_static_metadata_refcounts[77], {{g_bytes + 930, 8}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[77], {{g_bytes + 858, 19}}},
+ {{&grpc_static_metadata_refcounts[78], {{g_bytes + 938, 19}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[78], {{g_bytes + 877, 13}}},
+ {{&grpc_static_metadata_refcounts[79], {{g_bytes + 957, 13}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[79], {{g_bytes + 890, 4}}},
+ {{&grpc_static_metadata_refcounts[80], {{g_bytes + 970, 4}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[80], {{g_bytes + 894, 8}}},
+ {{&grpc_static_metadata_refcounts[81], {{g_bytes + 974, 8}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[81], {{g_bytes + 902, 12}}},
+ {{&grpc_static_metadata_refcounts[82], {{g_bytes + 982, 12}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[82], {{g_bytes + 914, 18}}},
+ {{&grpc_static_metadata_refcounts[83], {{g_bytes + 994, 18}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[83], {{g_bytes + 932, 19}}},
+ {{&grpc_static_metadata_refcounts[84], {{g_bytes + 1012, 19}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[84], {{g_bytes + 951, 5}}},
+ {{&grpc_static_metadata_refcounts[85], {{g_bytes + 1031, 5}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[85], {{g_bytes + 956, 7}}},
+ {{&grpc_static_metadata_refcounts[86], {{g_bytes + 1036, 7}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[86], {{g_bytes + 963, 7}}},
+ {{&grpc_static_metadata_refcounts[87], {{g_bytes + 1043, 7}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[87], {{g_bytes + 970, 11}}},
+ {{&grpc_static_metadata_refcounts[88], {{g_bytes + 1050, 11}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[88], {{g_bytes + 981, 6}}},
+ {{&grpc_static_metadata_refcounts[89], {{g_bytes + 1061, 6}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[89], {{g_bytes + 987, 10}}},
+ {{&grpc_static_metadata_refcounts[90], {{g_bytes + 1067, 10}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[90], {{g_bytes + 997, 25}}},
+ {{&grpc_static_metadata_refcounts[91], {{g_bytes + 1077, 25}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[91], {{g_bytes + 1022, 17}}},
+ {{&grpc_static_metadata_refcounts[92], {{g_bytes + 1102, 17}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[19], {{g_bytes + 268, 10}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[92], {{g_bytes + 1039, 4}}},
+ {{&grpc_static_metadata_refcounts[93], {{g_bytes + 1119, 4}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[93], {{g_bytes + 1043, 3}}},
+ {{&grpc_static_metadata_refcounts[94], {{g_bytes + 1123, 3}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[94], {{g_bytes + 1046, 16}}},
+ {{&grpc_static_metadata_refcounts[95], {{g_bytes + 1126, 16}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}},
- {&grpc_static_metadata_refcounts[95], {{g_bytes + 1062, 1}}}},
+ {&grpc_static_metadata_refcounts[96], {{g_bytes + 1142, 1}}}},
{{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}},
{&grpc_static_metadata_refcounts[25], {{g_bytes + 350, 1}}}},
{{&grpc_static_metadata_refcounts[7], {{g_bytes + 50, 11}}},
{&grpc_static_metadata_refcounts[26], {{g_bytes + 351, 1}}}},
{{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}},
- {&grpc_static_metadata_refcounts[96], {{g_bytes + 1063, 8}}}},
+ {&grpc_static_metadata_refcounts[97], {{g_bytes + 1143, 8}}}},
{{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}},
- {&grpc_static_metadata_refcounts[37], {{g_bytes + 517, 4}}}},
+ {&grpc_static_metadata_refcounts[38], {{g_bytes + 597, 4}}}},
{{&grpc_static_metadata_refcounts[9], {{g_bytes + 77, 13}}},
- {&grpc_static_metadata_refcounts[36], {{g_bytes + 510, 7}}}},
+ {&grpc_static_metadata_refcounts[37], {{g_bytes + 590, 7}}}},
{{&grpc_static_metadata_refcounts[5], {{g_bytes + 36, 2}}},
- {&grpc_static_metadata_refcounts[97], {{g_bytes + 1071, 8}}}},
+ {&grpc_static_metadata_refcounts[98], {{g_bytes + 1151, 8}}}},
{{&grpc_static_metadata_refcounts[14], {{g_bytes + 158, 12}}},
- {&grpc_static_metadata_refcounts[98], {{g_bytes + 1079, 16}}}},
+ {&grpc_static_metadata_refcounts[99], {{g_bytes + 1159, 16}}}},
{{&grpc_static_metadata_refcounts[4], {{g_bytes + 29, 7}}},
- {&grpc_static_metadata_refcounts[99], {{g_bytes + 1095, 4}}}},
+ {&grpc_static_metadata_refcounts[100], {{g_bytes + 1175, 4}}}},
{{&grpc_static_metadata_refcounts[1], {{g_bytes + 5, 7}}},
- {&grpc_static_metadata_refcounts[100], {{g_bytes + 1099, 3}}}},
+ {&grpc_static_metadata_refcounts[101], {{g_bytes + 1179, 3}}}},
{{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}},
- {&grpc_static_metadata_refcounts[96], {{g_bytes + 1063, 8}}}},
+ {&grpc_static_metadata_refcounts[97], {{g_bytes + 1143, 8}}}},
{{&grpc_static_metadata_refcounts[15], {{g_bytes + 170, 16}}},
- {&grpc_static_metadata_refcounts[37], {{g_bytes + 517, 4}}}},
+ {&grpc_static_metadata_refcounts[38], {{g_bytes + 597, 4}}}},
{{&grpc_static_metadata_refcounts[21], {{g_bytes + 282, 8}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
- {{&grpc_static_metadata_refcounts[101], {{g_bytes + 1102, 11}}},
+ {{&grpc_static_metadata_refcounts[102], {{g_bytes + 1182, 11}}},
{&grpc_static_metadata_refcounts[29], {{g_bytes + 354, 0}}}},
{{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}},
- {&grpc_static_metadata_refcounts[96], {{g_bytes + 1063, 8}}}},
+ {&grpc_static_metadata_refcounts[97], {{g_bytes + 1143, 8}}}},
{{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}},
- {&grpc_static_metadata_refcounts[36], {{g_bytes + 510, 7}}}},
+ {&grpc_static_metadata_refcounts[37], {{g_bytes + 590, 7}}}},
{{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}},
- {&grpc_static_metadata_refcounts[102], {{g_bytes + 1113, 16}}}},
+ {&grpc_static_metadata_refcounts[103], {{g_bytes + 1193, 16}}}},
{{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}},
- {&grpc_static_metadata_refcounts[37], {{g_bytes + 517, 4}}}},
+ {&grpc_static_metadata_refcounts[38], {{g_bytes + 597, 4}}}},
{{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}},
- {&grpc_static_metadata_refcounts[103], {{g_bytes + 1129, 13}}}},
+ {&grpc_static_metadata_refcounts[104], {{g_bytes + 1209, 13}}}},
{{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}},
- {&grpc_static_metadata_refcounts[104], {{g_bytes + 1142, 12}}}},
+ {&grpc_static_metadata_refcounts[105], {{g_bytes + 1222, 12}}}},
{{&grpc_static_metadata_refcounts[10], {{g_bytes + 90, 20}}},
- {&grpc_static_metadata_refcounts[105], {{g_bytes + 1154, 21}}}},
+ {&grpc_static_metadata_refcounts[106], {{g_bytes + 1234, 21}}}},
{{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}},
- {&grpc_static_metadata_refcounts[96], {{g_bytes + 1063, 8}}}},
+ {&grpc_static_metadata_refcounts[97], {{g_bytes + 1143, 8}}}},
{{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}},
- {&grpc_static_metadata_refcounts[37], {{g_bytes + 517, 4}}}},
+ {&grpc_static_metadata_refcounts[38], {{g_bytes + 597, 4}}}},
{{&grpc_static_metadata_refcounts[16], {{g_bytes + 186, 15}}},
- {&grpc_static_metadata_refcounts[103], {{g_bytes + 1129, 13}}}},
+ {&grpc_static_metadata_refcounts[104], {{g_bytes + 1209, 13}}}},
};
const uint8_t grpc_static_accept_encoding_metadata[8] = {0, 76, 77, 78,
79, 80, 81, 82};
diff --git a/src/core/lib/transport/static_metadata.h b/src/core/lib/transport/static_metadata.h
index 2bb9f72838..4f9670232c 100644
--- a/src/core/lib/transport/static_metadata.h
+++ b/src/core/lib/transport/static_metadata.h
@@ -31,7 +31,7 @@
#include "src/core/lib/transport/metadata.h"
-#define GRPC_STATIC_MDSTR_COUNT 106
+#define GRPC_STATIC_MDSTR_COUNT 107
extern const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT];
/* ":path" */
#define GRPC_MDSTR_PATH (grpc_static_slice_table[0])
@@ -110,147 +110,151 @@ extern const grpc_slice grpc_static_slice_table[GRPC_STATIC_MDSTR_COUNT];
/* "/grpc.health.v1.Health/Watch" */
#define GRPC_MDSTR_SLASH_GRPC_DOT_HEALTH_DOT_V1_DOT_HEALTH_SLASH_WATCH \
(grpc_static_slice_table[35])
+/* "/envoy.service.discovery.v2.AggregatedDiscoveryService/StreamAggregatedResources"
+ */
+#define GRPC_MDSTR_SLASH_ENVOY_DOT_SERVICE_DOT_DISCOVERY_DOT_V2_DOT_AGGREGATEDDISCOVERYSERVICE_SLASH_STREAMAGGREGATEDRESOURCES \
+ (grpc_static_slice_table[36])
/* "deflate" */
-#define GRPC_MDSTR_DEFLATE (grpc_static_slice_table[36])
+#define GRPC_MDSTR_DEFLATE (grpc_static_slice_table[37])
/* "gzip" */
-#define GRPC_MDSTR_GZIP (grpc_static_slice_table[37])
+#define GRPC_MDSTR_GZIP (grpc_static_slice_table[38])
/* "stream/gzip" */
-#define GRPC_MDSTR_STREAM_SLASH_GZIP (grpc_static_slice_table[38])
+#define GRPC_MDSTR_STREAM_SLASH_GZIP (grpc_static_slice_table[39])
/* "GET" */
-#define GRPC_MDSTR_GET (grpc_static_slice_table[39])
+#define GRPC_MDSTR_GET (grpc_static_slice_table[40])
/* "POST" */
-#define GRPC_MDSTR_POST (grpc_static_slice_table[40])
+#define GRPC_MDSTR_POST (grpc_static_slice_table[41])
/* "/" */
-#define GRPC_MDSTR_SLASH (grpc_static_slice_table[41])
+#define GRPC_MDSTR_SLASH (grpc_static_slice_table[42])
/* "/index.html" */
-#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (grpc_static_slice_table[42])
+#define GRPC_MDSTR_SLASH_INDEX_DOT_HTML (grpc_static_slice_table[43])
/* "http" */
-#define GRPC_MDSTR_HTTP (grpc_static_slice_table[43])
+#define GRPC_MDSTR_HTTP (grpc_static_slice_table[44])
/* "https" */
-#define GRPC_MDSTR_HTTPS (grpc_static_slice_table[44])
+#define GRPC_MDSTR_HTTPS (grpc_static_slice_table[45])
/* "200" */
-#define GRPC_MDSTR_200 (grpc_static_slice_table[45])
+#define GRPC_MDSTR_200 (grpc_static_slice_table[46])
/* "204" */
-#define GRPC_MDSTR_204 (grpc_static_slice_table[46])
+#define GRPC_MDSTR_204 (grpc_static_slice_table[47])
/* "206" */
-#define GRPC_MDSTR_206 (grpc_static_slice_table[47])
+#define GRPC_MDSTR_206 (grpc_static_slice_table[48])
/* "304" */
-#define GRPC_MDSTR_304 (grpc_static_slice_table[48])
+#define GRPC_MDSTR_304 (grpc_static_slice_table[49])
/* "400" */
-#define GRPC_MDSTR_400 (grpc_static_slice_table[49])
+#define GRPC_MDSTR_400 (grpc_static_slice_table[50])
/* "404" */
-#define GRPC_MDSTR_404 (grpc_static_slice_table[50])
+#define GRPC_MDSTR_404 (grpc_static_slice_table[51])
/* "500" */
-#define GRPC_MDSTR_500 (grpc_static_slice_table[51])
+#define GRPC_MDSTR_500 (grpc_static_slice_table[52])
/* "accept-charset" */
-#define GRPC_MDSTR_ACCEPT_CHARSET (grpc_static_slice_table[52])
+#define GRPC_MDSTR_ACCEPT_CHARSET (grpc_static_slice_table[53])
/* "gzip, deflate" */
-#define GRPC_MDSTR_GZIP_COMMA_DEFLATE (grpc_static_slice_table[53])
+#define GRPC_MDSTR_GZIP_COMMA_DEFLATE (grpc_static_slice_table[54])
/* "accept-language" */
-#define GRPC_MDSTR_ACCEPT_LANGUAGE (grpc_static_slice_table[54])
+#define GRPC_MDSTR_ACCEPT_LANGUAGE (grpc_static_slice_table[55])
/* "accept-ranges" */
-#define GRPC_MDSTR_ACCEPT_RANGES (grpc_static_slice_table[55])
+#define GRPC_MDSTR_ACCEPT_RANGES (grpc_static_slice_table[56])
/* "accept" */
-#define GRPC_MDSTR_ACCEPT (grpc_static_slice_table[56])
+#define GRPC_MDSTR_ACCEPT (grpc_static_slice_table[57])
/* "access-control-allow-origin" */
-#define GRPC_MDSTR_ACCESS_CONTROL_ALLOW_ORIGIN (grpc_static_slice_table[57])
+#define GRPC_MDSTR_ACCESS_CONTROL_ALLOW_ORIGIN (grpc_static_slice_table[58])
/* "age" */
-#define GRPC_MDSTR_AGE (grpc_static_slice_table[58])
+#define GRPC_MDSTR_AGE (grpc_static_slice_table[59])
/* "allow" */
-#define GRPC_MDSTR_ALLOW (grpc_static_slice_table[59])
+#define GRPC_MDSTR_ALLOW (grpc_static_slice_table[60])
/* "authorization" */
-#define GRPC_MDSTR_AUTHORIZATION (grpc_static_slice_table[60])
+#define GRPC_MDSTR_AUTHORIZATION (grpc_static_slice_table[61])
/* "cache-control" */
-#define GRPC_MDSTR_CACHE_CONTROL (grpc_static_slice_table[61])
+#define GRPC_MDSTR_CACHE_CONTROL (grpc_static_slice_table[62])
/* "content-disposition" */
-#define GRPC_MDSTR_CONTENT_DISPOSITION (grpc_static_slice_table[62])
+#define GRPC_MDSTR_CONTENT_DISPOSITION (grpc_static_slice_table[63])
/* "content-language" */
-#define GRPC_MDSTR_CONTENT_LANGUAGE (grpc_static_slice_table[63])
+#define GRPC_MDSTR_CONTENT_LANGUAGE (grpc_static_slice_table[64])
/* "content-length" */
-#define GRPC_MDSTR_CONTENT_LENGTH (grpc_static_slice_table[64])
+#define GRPC_MDSTR_CONTENT_LENGTH (grpc_static_slice_table[65])
/* "content-location" */
-#define GRPC_MDSTR_CONTENT_LOCATION (grpc_static_slice_table[65])
+#define GRPC_MDSTR_CONTENT_LOCATION (grpc_static_slice_table[66])
/* "content-range" */
-#define GRPC_MDSTR_CONTENT_RANGE (grpc_static_slice_table[66])
+#define GRPC_MDSTR_CONTENT_RANGE (grpc_static_slice_table[67])
/* "cookie" */
-#define GRPC_MDSTR_COOKIE (grpc_static_slice_table[67])
+#define GRPC_MDSTR_COOKIE (grpc_static_slice_table[68])
/* "date" */
-#define GRPC_MDSTR_DATE (grpc_static_slice_table[68])
+#define GRPC_MDSTR_DATE (grpc_static_slice_table[69])
/* "etag" */
-#define GRPC_MDSTR_ETAG (grpc_static_slice_table[69])
+#define GRPC_MDSTR_ETAG (grpc_static_slice_table[70])
/* "expect" */
-#define GRPC_MDSTR_EXPECT (grpc_static_slice_table[70])
+#define GRPC_MDSTR_EXPECT (grpc_static_slice_table[71])
/* "expires" */
-#define GRPC_MDSTR_EXPIRES (grpc_static_slice_table[71])
+#define GRPC_MDSTR_EXPIRES (grpc_static_slice_table[72])
/* "from" */
-#define GRPC_MDSTR_FROM (grpc_static_slice_table[72])
+#define GRPC_MDSTR_FROM (grpc_static_slice_table[73])
/* "if-match" */
-#define GRPC_MDSTR_IF_MATCH (grpc_static_slice_table[73])
+#define GRPC_MDSTR_IF_MATCH (grpc_static_slice_table[74])
/* "if-modified-since" */
-#define GRPC_MDSTR_IF_MODIFIED_SINCE (grpc_static_slice_table[74])
+#define GRPC_MDSTR_IF_MODIFIED_SINCE (grpc_static_slice_table[75])
/* "if-none-match" */
-#define GRPC_MDSTR_IF_NONE_MATCH (grpc_static_slice_table[75])
+#define GRPC_MDSTR_IF_NONE_MATCH (grpc_static_slice_table[76])
/* "if-range" */
-#define GRPC_MDSTR_IF_RANGE (grpc_static_slice_table[76])
+#define GRPC_MDSTR_IF_RANGE (grpc_static_slice_table[77])
/* "if-unmodified-since" */
-#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (grpc_static_slice_table[77])
+#define GRPC_MDSTR_IF_UNMODIFIED_SINCE (grpc_static_slice_table[78])
/* "last-modified" */
-#define GRPC_MDSTR_LAST_MODIFIED (grpc_static_slice_table[78])
+#define GRPC_MDSTR_LAST_MODIFIED (grpc_static_slice_table[79])
/* "link" */
-#define GRPC_MDSTR_LINK (grpc_static_slice_table[79])
+#define GRPC_MDSTR_LINK (grpc_static_slice_table[80])
/* "location" */
-#define GRPC_MDSTR_LOCATION (grpc_static_slice_table[80])
+#define GRPC_MDSTR_LOCATION (grpc_static_slice_table[81])
/* "max-forwards" */
-#define GRPC_MDSTR_MAX_FORWARDS (grpc_static_slice_table[81])
+#define GRPC_MDSTR_MAX_FORWARDS (grpc_static_slice_table[82])
/* "proxy-authenticate" */
-#define GRPC_MDSTR_PROXY_AUTHENTICATE (grpc_static_slice_table[82])
+#define GRPC_MDSTR_PROXY_AUTHENTICATE (grpc_static_slice_table[83])
/* "proxy-authorization" */
-#define GRPC_MDSTR_PROXY_AUTHORIZATION (grpc_static_slice_table[83])
+#define GRPC_MDSTR_PROXY_AUTHORIZATION (grpc_static_slice_table[84])
/* "range" */
-#define GRPC_MDSTR_RANGE (grpc_static_slice_table[84])
+#define GRPC_MDSTR_RANGE (grpc_static_slice_table[85])
/* "referer" */
-#define GRPC_MDSTR_REFERER (grpc_static_slice_table[85])
+#define GRPC_MDSTR_REFERER (grpc_static_slice_table[86])
/* "refresh" */
-#define GRPC_MDSTR_REFRESH (grpc_static_slice_table[86])
+#define GRPC_MDSTR_REFRESH (grpc_static_slice_table[87])
/* "retry-after" */
-#define GRPC_MDSTR_RETRY_AFTER (grpc_static_slice_table[87])
+#define GRPC_MDSTR_RETRY_AFTER (grpc_static_slice_table[88])
/* "server" */
-#define GRPC_MDSTR_SERVER (grpc_static_slice_table[88])
+#define GRPC_MDSTR_SERVER (grpc_static_slice_table[89])
/* "set-cookie" */
-#define GRPC_MDSTR_SET_COOKIE (grpc_static_slice_table[89])
+#define GRPC_MDSTR_SET_COOKIE (grpc_static_slice_table[90])
/* "strict-transport-security" */
-#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (grpc_static_slice_table[90])
+#define GRPC_MDSTR_STRICT_TRANSPORT_SECURITY (grpc_static_slice_table[91])
/* "transfer-encoding" */
-#define GRPC_MDSTR_TRANSFER_ENCODING (grpc_static_slice_table[91])
+#define GRPC_MDSTR_TRANSFER_ENCODING (grpc_static_slice_table[92])
/* "vary" */
-#define GRPC_MDSTR_VARY (grpc_static_slice_table[92])
+#define GRPC_MDSTR_VARY (grpc_static_slice_table[93])
/* "via" */
-#define GRPC_MDSTR_VIA (grpc_static_slice_table[93])
+#define GRPC_MDSTR_VIA (grpc_static_slice_table[94])
/* "www-authenticate" */
-#define GRPC_MDSTR_WWW_AUTHENTICATE (grpc_static_slice_table[94])
+#define GRPC_MDSTR_WWW_AUTHENTICATE (grpc_static_slice_table[95])
/* "0" */
-#define GRPC_MDSTR_0 (grpc_static_slice_table[95])
+#define GRPC_MDSTR_0 (grpc_static_slice_table[96])
/* "identity" */
-#define GRPC_MDSTR_IDENTITY (grpc_static_slice_table[96])
+#define GRPC_MDSTR_IDENTITY (grpc_static_slice_table[97])
/* "trailers" */
-#define GRPC_MDSTR_TRAILERS (grpc_static_slice_table[97])
+#define GRPC_MDSTR_TRAILERS (grpc_static_slice_table[98])
/* "application/grpc" */
-#define GRPC_MDSTR_APPLICATION_SLASH_GRPC (grpc_static_slice_table[98])
+#define GRPC_MDSTR_APPLICATION_SLASH_GRPC (grpc_static_slice_table[99])
/* "grpc" */
-#define GRPC_MDSTR_GRPC (grpc_static_slice_table[99])
+#define GRPC_MDSTR_GRPC (grpc_static_slice_table[100])
/* "PUT" */
-#define GRPC_MDSTR_PUT (grpc_static_slice_table[100])
+#define GRPC_MDSTR_PUT (grpc_static_slice_table[101])
/* "lb-cost-bin" */
-#define GRPC_MDSTR_LB_COST_BIN (grpc_static_slice_table[101])
+#define GRPC_MDSTR_LB_COST_BIN (grpc_static_slice_table[102])
/* "identity,deflate" */
-#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE (grpc_static_slice_table[102])
+#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE (grpc_static_slice_table[103])
/* "identity,gzip" */
-#define GRPC_MDSTR_IDENTITY_COMMA_GZIP (grpc_static_slice_table[103])
+#define GRPC_MDSTR_IDENTITY_COMMA_GZIP (grpc_static_slice_table[104])
/* "deflate,gzip" */
-#define GRPC_MDSTR_DEFLATE_COMMA_GZIP (grpc_static_slice_table[104])
+#define GRPC_MDSTR_DEFLATE_COMMA_GZIP (grpc_static_slice_table[105])
/* "identity,deflate,gzip" */
#define GRPC_MDSTR_IDENTITY_COMMA_DEFLATE_COMMA_GZIP \
- (grpc_static_slice_table[105])
+ (grpc_static_slice_table[106])
extern const grpc_slice_refcount_vtable grpc_static_metadata_vtable;
extern grpc_slice_refcount
diff --git a/src/core/lib/transport/transport.cc b/src/core/lib/transport/transport.cc
index cbdb77c844..b32f9c6ec1 100644
--- a/src/core/lib/transport/transport.cc
+++ b/src/core/lib/transport/transport.cc
@@ -27,6 +27,7 @@
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
+#include "src/core/lib/gpr/alloc.h"
#include "src/core/lib/gpr/string.h"
#include "src/core/lib/iomgr/executor.h"
#include "src/core/lib/slice/slice_internal.h"
@@ -149,7 +150,7 @@ void grpc_transport_move_stats(grpc_transport_stream_stats* from,
}
size_t grpc_transport_stream_size(grpc_transport* transport) {
- return transport->vtable->sizeof_stream;
+ return GPR_ROUND_UP_TO_ALIGNMENT_SIZE(transport->vtable->sizeof_stream);
}
void grpc_transport_destroy(grpc_transport* transport) {
diff --git a/src/core/lib/transport/transport.h b/src/core/lib/transport/transport.h
index edfa7030d1..5ce568834e 100644
--- a/src/core/lib/transport/transport.h
+++ b/src/core/lib/transport/transport.h
@@ -129,7 +129,8 @@ struct grpc_transport_stream_op_batch {
recv_initial_metadata(false),
recv_message(false),
recv_trailing_metadata(false),
- cancel_stream(false) {}
+ cancel_stream(false),
+ is_traced(false) {}
/** Should be scheduled when all of the non-recv operations in the batch
are complete.
@@ -167,6 +168,9 @@ struct grpc_transport_stream_op_batch {
/** Cancel this stream with the provided error */
bool cancel_stream : 1;
+ /** Is this stream traced */
+ bool is_traced : 1;
+
/***************************************************************************
* remaining fields are initialized and used at the discretion of the
* current handler of the op */
diff --git a/src/core/plugin_registry/grpc_cronet_plugin_registry.cc b/src/core/plugin_registry/grpc_cronet_plugin_registry.cc
index c0c17b0a4b..92085d31d7 100644
--- a/src/core/plugin_registry/grpc_cronet_plugin_registry.cc
+++ b/src/core/plugin_registry/grpc_cronet_plugin_registry.cc
@@ -28,8 +28,6 @@ void grpc_deadline_filter_init(void);
void grpc_deadline_filter_shutdown(void);
void grpc_client_channel_init(void);
void grpc_client_channel_shutdown(void);
-void grpc_tsi_alts_init(void);
-void grpc_tsi_alts_shutdown(void);
void grpc_register_built_in_plugins(void) {
grpc_register_plugin(grpc_http_filters_init,
@@ -40,6 +38,4 @@ void grpc_register_built_in_plugins(void) {
grpc_deadline_filter_shutdown);
grpc_register_plugin(grpc_client_channel_init,
grpc_client_channel_shutdown);
- grpc_register_plugin(grpc_tsi_alts_init,
- grpc_tsi_alts_shutdown);
}
diff --git a/src/core/plugin_registry/grpc_plugin_registry.cc b/src/core/plugin_registry/grpc_plugin_registry.cc
index 94c2493d5e..cde40ef65c 100644
--- a/src/core/plugin_registry/grpc_plugin_registry.cc
+++ b/src/core/plugin_registry/grpc_plugin_registry.cc
@@ -28,8 +28,6 @@ void grpc_deadline_filter_init(void);
void grpc_deadline_filter_shutdown(void);
void grpc_client_channel_init(void);
void grpc_client_channel_shutdown(void);
-void grpc_tsi_alts_init(void);
-void grpc_tsi_alts_shutdown(void);
void grpc_inproc_plugin_init(void);
void grpc_inproc_plugin_shutdown(void);
void grpc_resolver_fake_init(void);
@@ -66,8 +64,6 @@ void grpc_register_built_in_plugins(void) {
grpc_deadline_filter_shutdown);
grpc_register_plugin(grpc_client_channel_init,
grpc_client_channel_shutdown);
- grpc_register_plugin(grpc_tsi_alts_init,
- grpc_tsi_alts_shutdown);
grpc_register_plugin(grpc_inproc_plugin_init,
grpc_inproc_plugin_shutdown);
grpc_register_plugin(grpc_resolver_fake_init,
diff --git a/src/core/tsi/alts/handshaker/alts_handshaker_client.cc b/src/core/tsi/alts/handshaker/alts_handshaker_client.cc
index 941ca13114..1de6264183 100644
--- a/src/core/tsi/alts/handshaker/alts_handshaker_client.cc
+++ b/src/core/tsi/alts/handshaker/alts_handshaker_client.cc
@@ -376,7 +376,7 @@ static void handshaker_client_shutdown(alts_handshaker_client* c) {
alts_grpc_handshaker_client* client =
reinterpret_cast<alts_grpc_handshaker_client*>(c);
if (client->call != nullptr) {
- GPR_ASSERT(grpc_call_cancel(client->call, nullptr) == GRPC_CALL_OK);
+ grpc_call_cancel_internal(client->call);
}
}
diff --git a/src/core/tsi/alts/handshaker/alts_shared_resource.cc b/src/core/tsi/alts/handshaker/alts_shared_resource.cc
index ffb5e1c655..3501257f05 100644
--- a/src/core/tsi/alts/handshaker/alts_shared_resource.cc
+++ b/src/core/tsi/alts/handshaker/alts_shared_resource.cc
@@ -25,7 +25,6 @@
#include "src/core/tsi/alts/handshaker/alts_handshaker_client.h"
static alts_shared_resource_dedicated g_alts_resource_dedicated;
-static alts_shared_resource* g_shared_resources = alts_get_shared_resource();
alts_shared_resource_dedicated* grpc_alts_get_shared_resource_dedicated(void) {
return &g_alts_resource_dedicated;
@@ -49,16 +48,25 @@ static void thread_worker(void* arg) {
void grpc_alts_shared_resource_dedicated_init() {
g_alts_resource_dedicated.cq = nullptr;
+ gpr_mu_init(&g_alts_resource_dedicated.mu);
}
-void grpc_alts_shared_resource_dedicated_start() {
- g_alts_resource_dedicated.cq = grpc_completion_queue_create_for_next(nullptr);
- g_alts_resource_dedicated.thread =
- grpc_core::Thread("alts_tsi_handshaker", &thread_worker, nullptr);
- g_alts_resource_dedicated.interested_parties = grpc_pollset_set_create();
- grpc_pollset_set_add_pollset(g_alts_resource_dedicated.interested_parties,
- grpc_cq_pollset(g_alts_resource_dedicated.cq));
- g_alts_resource_dedicated.thread.Start();
+void grpc_alts_shared_resource_dedicated_start(
+ const char* handshaker_service_url) {
+ gpr_mu_lock(&g_alts_resource_dedicated.mu);
+ if (g_alts_resource_dedicated.cq == nullptr) {
+ g_alts_resource_dedicated.channel =
+ grpc_insecure_channel_create(handshaker_service_url, nullptr, nullptr);
+ g_alts_resource_dedicated.cq =
+ grpc_completion_queue_create_for_next(nullptr);
+ g_alts_resource_dedicated.thread =
+ grpc_core::Thread("alts_tsi_handshaker", &thread_worker, nullptr);
+ g_alts_resource_dedicated.interested_parties = grpc_pollset_set_create();
+ grpc_pollset_set_add_pollset(g_alts_resource_dedicated.interested_parties,
+ grpc_cq_pollset(g_alts_resource_dedicated.cq));
+ g_alts_resource_dedicated.thread.Start();
+ }
+ gpr_mu_unlock(&g_alts_resource_dedicated.mu);
}
void grpc_alts_shared_resource_dedicated_shutdown() {
@@ -69,5 +77,7 @@ void grpc_alts_shared_resource_dedicated_shutdown() {
g_alts_resource_dedicated.thread.Join();
grpc_pollset_set_destroy(g_alts_resource_dedicated.interested_parties);
grpc_completion_queue_destroy(g_alts_resource_dedicated.cq);
+ grpc_channel_destroy(g_alts_resource_dedicated.channel);
}
+ gpr_mu_destroy(&g_alts_resource_dedicated.mu);
}
diff --git a/src/core/tsi/alts/handshaker/alts_shared_resource.h b/src/core/tsi/alts/handshaker/alts_shared_resource.h
index a07da305a8..8ae0089a11 100644
--- a/src/core/tsi/alts/handshaker/alts_shared_resource.h
+++ b/src/core/tsi/alts/handshaker/alts_shared_resource.h
@@ -37,6 +37,8 @@ typedef struct alts_shared_resource_dedicated {
grpc_completion_queue* cq;
grpc_pollset_set* interested_parties;
grpc_cq_completion storage;
+ gpr_mu mu;
+ grpc_channel* channel;
} alts_shared_resource_dedicated;
/* This method returns the address of alts_shared_resource_dedicated
@@ -64,7 +66,8 @@ void grpc_alts_shared_resource_dedicated_init();
* The API will be invoked by the caller in a lazy manner. That is,
* it will get invoked when ALTS TSI handshake occurs for the first time.
*/
-void grpc_alts_shared_resource_dedicated_start();
+void grpc_alts_shared_resource_dedicated_start(
+ const char* handshaker_service_url);
#endif /* GRPC_CORE_TSI_ALTS_HANDSHAKER_ALTS_SHARED_RESOURCE_H \
*/
diff --git a/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc b/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc
index 1639252883..1b7e58d3ce 100644
--- a/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc
+++ b/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc
@@ -39,9 +39,6 @@
#include "src/core/tsi/alts/handshaker/alts_shared_resource.h"
#include "src/core/tsi/alts/handshaker/alts_tsi_utils.h"
#include "src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.h"
-#include "src/core/tsi/alts_transport_security.h"
-
-static alts_shared_resource* g_shared_resources = alts_get_shared_resource();
/* Main struct for ALTS TSI handshaker. */
struct alts_tsi_handshaker {
@@ -51,11 +48,11 @@ struct alts_tsi_handshaker {
bool is_client;
bool has_sent_start_message;
bool has_created_handshaker_client;
- bool use_dedicated_cq;
char* handshaker_service_url;
grpc_pollset_set* interested_parties;
grpc_alts_credentials_options* options;
alts_handshaker_client_vtable* client_vtable_for_testing;
+ grpc_channel* channel;
};
/* Main struct for ALTS TSI handshaker result. */
@@ -237,20 +234,6 @@ tsi_result alts_tsi_handshaker_result_create(grpc_gcp_handshaker_resp* resp,
return TSI_OK;
}
-static void init_shared_resources(const char* handshaker_service_url,
- bool use_dedicated_cq) {
- GPR_ASSERT(handshaker_service_url != nullptr);
- gpr_mu_lock(&g_shared_resources->mu);
- if (g_shared_resources->channel == nullptr) {
- g_shared_resources->channel =
- grpc_insecure_channel_create(handshaker_service_url, nullptr, nullptr);
- if (use_dedicated_cq) {
- grpc_alts_shared_resource_dedicated_start();
- }
- }
- gpr_mu_unlock(&g_shared_resources->mu);
-}
-
/* gRPC provided callback used when gRPC thread model is applied. */
static void on_handshaker_service_resp_recv(void* arg, grpc_error* error) {
alts_handshaker_client* client = static_cast<alts_handshaker_client*>(arg);
@@ -289,20 +272,24 @@ static tsi_result handshaker_next(
reinterpret_cast<alts_tsi_handshaker*>(self);
tsi_result ok = TSI_OK;
if (!handshaker->has_created_handshaker_client) {
- init_shared_resources(handshaker->handshaker_service_url,
- handshaker->use_dedicated_cq);
- if (handshaker->use_dedicated_cq) {
+ if (handshaker->channel == nullptr) {
+ grpc_alts_shared_resource_dedicated_start(
+ handshaker->handshaker_service_url);
handshaker->interested_parties =
grpc_alts_get_shared_resource_dedicated()->interested_parties;
GPR_ASSERT(handshaker->interested_parties != nullptr);
}
- grpc_iomgr_cb_func grpc_cb = handshaker->use_dedicated_cq
+ grpc_iomgr_cb_func grpc_cb = handshaker->channel == nullptr
? on_handshaker_service_resp_recv_dedicated
: on_handshaker_service_resp_recv;
+ grpc_channel* channel =
+ handshaker->channel == nullptr
+ ? grpc_alts_get_shared_resource_dedicated()->channel
+ : handshaker->channel;
handshaker->client = alts_grpc_handshaker_client_create(
- handshaker, g_shared_resources->channel,
- handshaker->handshaker_service_url, handshaker->interested_parties,
- handshaker->options, handshaker->target_name, grpc_cb, cb, user_data,
+ handshaker, channel, handshaker->handshaker_service_url,
+ handshaker->interested_parties, handshaker->options,
+ handshaker->target_name, grpc_cb, cb, user_data,
handshaker->client_vtable_for_testing, handshaker->is_client);
if (handshaker->client == nullptr) {
gpr_log(GPR_ERROR, "Failed to create ALTS handshaker client");
@@ -310,7 +297,7 @@ static tsi_result handshaker_next(
}
handshaker->has_created_handshaker_client = true;
}
- if (handshaker->use_dedicated_cq &&
+ if (handshaker->channel == nullptr &&
handshaker->client_vtable_for_testing == nullptr) {
GPR_ASSERT(grpc_cq_begin_op(grpc_alts_get_shared_resource_dedicated()->cq,
handshaker->client));
@@ -371,6 +358,9 @@ static void handshaker_destroy(tsi_handshaker* self) {
alts_handshaker_client_destroy(handshaker->client);
grpc_slice_unref_internal(handshaker->target_name);
grpc_alts_credentials_options_destroy(handshaker->options);
+ if (handshaker->channel != nullptr) {
+ grpc_channel_destroy(handshaker->channel);
+ }
gpr_free(handshaker->handshaker_service_url);
gpr_free(handshaker);
}
@@ -407,7 +397,7 @@ tsi_result alts_tsi_handshaker_create(
}
alts_tsi_handshaker* handshaker =
static_cast<alts_tsi_handshaker*>(gpr_zalloc(sizeof(*handshaker)));
- handshaker->use_dedicated_cq = interested_parties == nullptr;
+ bool use_dedicated_cq = interested_parties == nullptr;
handshaker->client = nullptr;
handshaker->is_client = is_client;
handshaker->has_sent_start_message = false;
@@ -418,9 +408,13 @@ tsi_result alts_tsi_handshaker_create(
handshaker->has_created_handshaker_client = false;
handshaker->handshaker_service_url = gpr_strdup(handshaker_service_url);
handshaker->options = grpc_alts_credentials_options_copy(options);
- handshaker->base.vtable = handshaker->use_dedicated_cq
- ? &handshaker_vtable_dedicated
- : &handshaker_vtable;
+ handshaker->base.vtable =
+ use_dedicated_cq ? &handshaker_vtable_dedicated : &handshaker_vtable;
+ handshaker->channel =
+ use_dedicated_cq
+ ? nullptr
+ : grpc_insecure_channel_create(handshaker->handshaker_service_url,
+ nullptr, nullptr);
*self = &handshaker->base;
return TSI_OK;
}
diff --git a/src/core/tsi/alts/handshaker/alts_tsi_handshaker.h b/src/core/tsi/alts/handshaker/alts_tsi_handshaker.h
index c961eae498..32f94bc9d3 100644
--- a/src/core/tsi/alts/handshaker/alts_tsi_handshaker.h
+++ b/src/core/tsi/alts/handshaker/alts_tsi_handshaker.h
@@ -27,7 +27,6 @@
#include "src/core/lib/security/credentials/alts/grpc_alts_credentials_options.h"
#include "src/core/tsi/alts/handshaker/alts_handshaker_client.h"
#include "src/core/tsi/alts/handshaker/alts_handshaker_service_api_util.h"
-#include "src/core/tsi/alts_transport_security.h"
#include "src/core/tsi/transport_security.h"
#include "src/core/tsi/transport_security_interface.h"
diff --git a/src/core/tsi/transport_security.cc b/src/core/tsi/transport_security.cc
index ca861b52de..078a917bba 100644
--- a/src/core/tsi/transport_security.cc
+++ b/src/core/tsi/transport_security.cc
@@ -213,10 +213,10 @@ tsi_result tsi_handshaker_next(
void tsi_handshaker_shutdown(tsi_handshaker* self) {
if (self == nullptr || self->vtable == nullptr) return;
- self->handshake_shutdown = true;
if (self->vtable->shutdown != nullptr) {
self->vtable->shutdown(self);
}
+ self->handshake_shutdown = true;
}
void tsi_handshaker_destroy(tsi_handshaker* self) {
diff --git a/src/cpp/client/channel_cc.cc b/src/cpp/client/channel_cc.cc
index 8e1cea0269..d1c55319f7 100644
--- a/src/cpp/client/channel_cc.cc
+++ b/src/cpp/client/channel_cc.cc
@@ -54,13 +54,11 @@ namespace grpc {
static internal::GrpcLibraryInitializer g_gli_initializer;
Channel::Channel(
const grpc::string& host, grpc_channel* channel,
- std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>
+ std::vector<
+ std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators)
: host_(host), c_channel_(channel) {
- if (interceptor_creators != nullptr) {
- interceptor_creators_ = std::move(*interceptor_creators);
- }
+ interceptor_creators_ = std::move(interceptor_creators);
g_gli_initializer.summon();
}
diff --git a/src/cpp/client/client_context.cc b/src/cpp/client/client_context.cc
index 50da75f09c..c9ea3e5f83 100644
--- a/src/cpp/client/client_context.cc
+++ b/src/cpp/client/client_context.cc
@@ -41,9 +41,10 @@ class DefaultGlobalClientCallbacks final
};
static internal::GrpcLibraryInitializer g_gli_initializer;
-static DefaultGlobalClientCallbacks g_default_client_callbacks;
+static DefaultGlobalClientCallbacks* g_default_client_callbacks =
+ new DefaultGlobalClientCallbacks();
static ClientContext::GlobalCallbacks* g_client_callbacks =
- &g_default_client_callbacks;
+ g_default_client_callbacks;
ClientContext::ClientContext()
: initial_metadata_received_(false),
@@ -139,9 +140,9 @@ grpc::string ClientContext::peer() const {
}
void ClientContext::SetGlobalCallbacks(GlobalCallbacks* client_callbacks) {
- GPR_ASSERT(g_client_callbacks == &g_default_client_callbacks);
+ GPR_ASSERT(g_client_callbacks == g_default_client_callbacks);
GPR_ASSERT(client_callbacks != nullptr);
- GPR_ASSERT(client_callbacks != &g_default_client_callbacks);
+ GPR_ASSERT(client_callbacks != g_default_client_callbacks);
g_client_callbacks = client_callbacks;
}
diff --git a/src/cpp/client/create_channel.cc b/src/cpp/client/create_channel.cc
index efdff6c265..457daa674c 100644
--- a/src/cpp/client/create_channel.cc
+++ b/src/cpp/client/create_channel.cc
@@ -39,13 +39,14 @@ std::shared_ptr<Channel> CreateCustomChannel(
const std::shared_ptr<ChannelCredentials>& creds,
const ChannelArguments& args) {
GrpcLibraryCodegen init_lib; // We need to call init in case of a bad creds.
- return creds
- ? creds->CreateChannel(target, args)
- : CreateChannelInternal("",
- grpc_lame_client_channel_create(
- nullptr, GRPC_STATUS_INVALID_ARGUMENT,
- "Invalid credentials."),
- nullptr);
+ return creds ? creds->CreateChannel(target, args)
+ : CreateChannelInternal(
+ "",
+ grpc_lame_client_channel_create(
+ nullptr, GRPC_STATUS_INVALID_ARGUMENT,
+ "Invalid credentials."),
+ std::vector<std::unique_ptr<
+ experimental::ClientInterceptorFactoryInterface>>());
}
namespace experimental {
@@ -64,17 +65,18 @@ std::shared_ptr<Channel> CreateCustomChannelWithInterceptors(
const grpc::string& target,
const std::shared_ptr<ChannelCredentials>& creds,
const ChannelArguments& args,
- std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>
+ std::vector<
+ std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators) {
- return creds
- ? creds->CreateChannelWithInterceptors(
- target, args, std::move(interceptor_creators))
- : CreateChannelInternal("",
- grpc_lame_client_channel_create(
- nullptr, GRPC_STATUS_INVALID_ARGUMENT,
- "Invalid credentials."),
- nullptr);
+ return creds ? creds->CreateChannelWithInterceptors(
+ target, args, std::move(interceptor_creators))
+ : CreateChannelInternal(
+ "",
+ grpc_lame_client_channel_create(
+ nullptr, GRPC_STATUS_INVALID_ARGUMENT,
+ "Invalid credentials."),
+ std::vector<std::unique_ptr<
+ experimental::ClientInterceptorFactoryInterface>>());
}
} // namespace experimental
diff --git a/src/cpp/client/create_channel_internal.cc b/src/cpp/client/create_channel_internal.cc
index 313d682aae..a0efb97f7e 100644
--- a/src/cpp/client/create_channel_internal.cc
+++ b/src/cpp/client/create_channel_internal.cc
@@ -26,8 +26,8 @@ namespace grpc {
std::shared_ptr<Channel> CreateChannelInternal(
const grpc::string& host, grpc_channel* c_channel,
- std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>
+ std::vector<
+ std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators) {
return std::shared_ptr<Channel>(
new Channel(host, c_channel, std::move(interceptor_creators)));
diff --git a/src/cpp/client/create_channel_internal.h b/src/cpp/client/create_channel_internal.h
index 512fc22866..a90c92c518 100644
--- a/src/cpp/client/create_channel_internal.h
+++ b/src/cpp/client/create_channel_internal.h
@@ -31,8 +31,8 @@ class Channel;
std::shared_ptr<Channel> CreateChannelInternal(
const grpc::string& host, grpc_channel* c_channel,
- std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>
+ std::vector<
+ std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators);
} // namespace grpc
diff --git a/src/cpp/client/create_channel_posix.cc b/src/cpp/client/create_channel_posix.cc
index 8d775e7a87..3affc1ef39 100644
--- a/src/cpp/client/create_channel_posix.cc
+++ b/src/cpp/client/create_channel_posix.cc
@@ -34,7 +34,8 @@ std::shared_ptr<Channel> CreateInsecureChannelFromFd(const grpc::string& target,
init_lib.init();
return CreateChannelInternal(
"", grpc_insecure_channel_create_from_fd(target.c_str(), fd, nullptr),
- nullptr);
+ std::vector<
+ std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>());
}
std::shared_ptr<Channel> CreateCustomInsecureChannelFromFd(
@@ -46,15 +47,16 @@ std::shared_ptr<Channel> CreateCustomInsecureChannelFromFd(
return CreateChannelInternal(
"",
grpc_insecure_channel_create_from_fd(target.c_str(), fd, &channel_args),
- nullptr);
+ std::vector<
+ std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>());
}
namespace experimental {
std::shared_ptr<Channel> CreateCustomInsecureChannelWithInterceptorsFromFd(
const grpc::string& target, int fd, const ChannelArguments& args,
- std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>
+ std::vector<
+ std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators) {
internal::GrpcLibrary init_lib;
init_lib.init();
diff --git a/src/cpp/client/cronet_credentials.cc b/src/cpp/client/cronet_credentials.cc
index 09a76b428c..b2801764f2 100644
--- a/src/cpp/client/cronet_credentials.cc
+++ b/src/cpp/client/cronet_credentials.cc
@@ -31,7 +31,10 @@ class CronetChannelCredentialsImpl final : public ChannelCredentials {
std::shared_ptr<grpc::Channel> CreateChannel(
const string& target, const grpc::ChannelArguments& args) override {
- return CreateChannelWithInterceptors(target, args, nullptr);
+ return CreateChannelWithInterceptors(
+ target, args,
+ std::vector<std::unique_ptr<
+ experimental::ClientInterceptorFactoryInterface>>());
}
SecureChannelCredentials* AsSecureCredentials() override { return nullptr; }
@@ -39,8 +42,8 @@ class CronetChannelCredentialsImpl final : public ChannelCredentials {
private:
std::shared_ptr<grpc::Channel> CreateChannelWithInterceptors(
const string& target, const grpc::ChannelArguments& args,
- std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>
+ std::vector<
+ std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators) override {
grpc_channel_args channel_args;
args.SetChannelArgs(&channel_args);
diff --git a/src/cpp/client/insecure_credentials.cc b/src/cpp/client/insecure_credentials.cc
index b816e0c59a..241ce91803 100644
--- a/src/cpp/client/insecure_credentials.cc
+++ b/src/cpp/client/insecure_credentials.cc
@@ -32,13 +32,16 @@ class InsecureChannelCredentialsImpl final : public ChannelCredentials {
public:
std::shared_ptr<grpc::Channel> CreateChannel(
const string& target, const grpc::ChannelArguments& args) override {
- return CreateChannelWithInterceptors(target, args, nullptr);
+ return CreateChannelWithInterceptors(
+ target, args,
+ std::vector<std::unique_ptr<
+ experimental::ClientInterceptorFactoryInterface>>());
}
std::shared_ptr<grpc::Channel> CreateChannelWithInterceptors(
const string& target, const grpc::ChannelArguments& args,
- std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>
+ std::vector<
+ std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators) override {
grpc_channel_args channel_args;
args.SetChannelArgs(&channel_args);
diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc
index 7faaa20e78..d0abe441a6 100644
--- a/src/cpp/client/secure_credentials.cc
+++ b/src/cpp/client/secure_credentials.cc
@@ -36,14 +36,17 @@ SecureChannelCredentials::SecureChannelCredentials(
std::shared_ptr<grpc::Channel> SecureChannelCredentials::CreateChannel(
const string& target, const grpc::ChannelArguments& args) {
- return CreateChannelWithInterceptors(target, args, nullptr);
+ return CreateChannelWithInterceptors(
+ target, args,
+ std::vector<
+ std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>());
}
std::shared_ptr<grpc::Channel>
SecureChannelCredentials::CreateChannelWithInterceptors(
const string& target, const grpc::ChannelArguments& args,
- std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>
+ std::vector<
+ std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators) {
grpc_channel_args channel_args;
args.SetChannelArgs(&channel_args);
diff --git a/src/cpp/client/secure_credentials.h b/src/cpp/client/secure_credentials.h
index bfb6e17ee9..613f1d6dc2 100644
--- a/src/cpp/client/secure_credentials.h
+++ b/src/cpp/client/secure_credentials.h
@@ -42,8 +42,8 @@ class SecureChannelCredentials final : public ChannelCredentials {
private:
std::shared_ptr<grpc::Channel> CreateChannelWithInterceptors(
const string& target, const grpc::ChannelArguments& args,
- std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>
+ std::vector<
+ std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators) override;
grpc_channel_credentials* const c_creds_;
};
diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc
index 8abd45efb7..55da89e6c8 100644
--- a/src/cpp/common/version_cc.cc
+++ b/src/cpp/common/version_cc.cc
@@ -22,5 +22,5 @@
#include <grpcpp/grpcpp.h>
namespace grpc {
-grpc::string Version() { return "1.17.0-dev"; }
+grpc::string Version() { return "1.18.0-dev"; }
} // namespace grpc
diff --git a/src/cpp/server/server_cc.cc b/src/cpp/server/server_cc.cc
index c031528a8f..0a51cf5626 100644
--- a/src/cpp/server/server_cc.cc
+++ b/src/cpp/server/server_cc.cc
@@ -58,6 +58,9 @@ namespace {
// max-threads set) to the server builder.
#define DEFAULT_MAX_SYNC_SERVER_THREADS INT_MAX
+// How many callback requests of each method should we pre-register at start
+#define DEFAULT_CALLBACK_REQS_PER_METHOD 32
+
class DefaultGlobalCallbacks final : public Server::GlobalCallbacks {
public:
~DefaultGlobalCallbacks() override {}
@@ -81,10 +84,7 @@ class ShutdownTag : public internal::CompletionQueueTag {
class DummyTag : public internal::CompletionQueueTag {
public:
- bool FinalizeResult(void** tag, bool* status) {
- *status = true;
- return true;
- }
+ bool FinalizeResult(void** tag, bool* status) { return true; }
};
class UnimplementedAsyncRequestContext {
@@ -199,9 +199,21 @@ class Server::SyncRequest final : public internal::CompletionQueueTag {
}
}
+ void PostShutdownCleanup() {
+ if (call_) {
+ grpc_call_unref(call_);
+ call_ = nullptr;
+ }
+ if (cq_) {
+ grpc_completion_queue_destroy(cq_);
+ cq_ = nullptr;
+ }
+ }
+
bool FinalizeResult(void** tag, bool* status) override {
if (!*status) {
grpc_completion_queue_destroy(cq_);
+ cq_ = nullptr;
}
if (call_details_) {
deadline_ = call_details_->deadline;
@@ -586,7 +598,17 @@ class Server::SyncRequestThreadManager : public ThreadManager {
void* tag;
bool ok;
while (server_cq_->Next(&tag, &ok)) {
- // Do nothing
+ if (ok) {
+ // If a request was pulled off the queue, it means that the thread
+ // handling the request added it to the completion queue after shutdown
+ // was called - because the thread had already started and checked the
+ // shutdown flag before shutdown was called. In this case, we simply
+ // clean it up here, *after* calling wait on all the worker threads, at
+ // which point we are certain no in-flight requests will add more to the
+ // queue. This fixes an intermittent memory leak on shutdown.
+ SyncRequest* sync_req = static_cast<SyncRequest*>(tag);
+ sync_req->PostShutdownCleanup();
+ }
}
}
@@ -707,14 +729,15 @@ std::shared_ptr<Channel> Server::InProcessChannel(
grpc_channel_args channel_args = args.c_channel_args();
return CreateChannelInternal(
"inproc", grpc_inproc_channel_create(server_, &channel_args, nullptr),
- nullptr);
+ std::vector<
+ std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>());
}
std::shared_ptr<Channel>
Server::experimental_type::InProcessChannelWithInterceptors(
const ChannelArguments& args,
- std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>
+ std::vector<
+ std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
interceptor_creators) {
grpc_channel_args channel_args = args.c_channel_args();
return CreateChannelInternal(
@@ -769,9 +792,12 @@ bool Server::RegisterService(const grpc::string* host, Service* service) {
(*it)->AddSyncMethod(method, method_registration_tag);
}
} else {
- // a callback method
- auto* req = new CallbackRequest(this, method, method_registration_tag);
- callback_reqs_.emplace_back(req);
+ // a callback method. Register at least some callback requests
+ // TODO(vjpai): Register these dynamically based on need
+ for (int i = 0; i < DEFAULT_CALLBACK_REQS_PER_METHOD; i++) {
+ auto* req = new CallbackRequest(this, method, method_registration_tag);
+ callback_reqs_.emplace_back(req);
+ }
// Enqueue it so that it will be Request'ed later once
// all request matchers are created at core server startup
}
diff --git a/src/cpp/server/server_context.cc b/src/cpp/server/server_context.cc
index 396996e5bc..9c01f896e6 100644
--- a/src/cpp/server/server_context.cc
+++ b/src/cpp/server/server_context.cc
@@ -247,6 +247,10 @@ void ServerContext::BindDeadlineAndMetadata(gpr_timespec deadline,
ServerContext::~ServerContext() { Clear(); }
void ServerContext::Clear() {
+ auth_context_.reset();
+ initial_metadata_.clear();
+ trailing_metadata_.clear();
+ client_metadata_.Reset();
if (call_) {
grpc_call_unref(call_);
}
diff --git a/src/csharp/Grpc.Core.Tests/Internal/AsyncCallServerTest.cs b/src/csharp/Grpc.Core.Tests/Internal/AsyncCallServerTest.cs
index e7d8939978..5c7d48f786 100644
--- a/src/csharp/Grpc.Core.Tests/Internal/AsyncCallServerTest.cs
+++ b/src/csharp/Grpc.Core.Tests/Internal/AsyncCallServerTest.cs
@@ -49,7 +49,7 @@ namespace Grpc.Core.Internal.Tests
fakeCall = new FakeNativeCall();
asyncCallServer = new AsyncCallServer<string, string>(
- Marshallers.StringMarshaller.Serializer, Marshallers.StringMarshaller.Deserializer,
+ Marshallers.StringMarshaller.ContextualSerializer, Marshallers.StringMarshaller.ContextualDeserializer,
server);
asyncCallServer.InitializeForTesting(fakeCall);
}
diff --git a/src/csharp/Grpc.Core.Tests/MarshallerTest.cs b/src/csharp/Grpc.Core.Tests/MarshallerTest.cs
index 97f64a0575..ad3e81d61f 100644
--- a/src/csharp/Grpc.Core.Tests/MarshallerTest.cs
+++ b/src/csharp/Grpc.Core.Tests/MarshallerTest.cs
@@ -69,11 +69,8 @@ namespace Grpc.Core.Tests
Assert.AreSame(contextualSerializer, marshaller.ContextualSerializer);
Assert.AreSame(contextualDeserializer, marshaller.ContextualDeserializer);
-
- // test that emulated serializer and deserializer work
- var origMsg = "abc";
- var serialized = marshaller.Serializer(origMsg);
- Assert.AreEqual(origMsg, marshaller.Deserializer(serialized));
+ Assert.Throws(typeof(NotImplementedException), () => marshaller.Serializer("abc"));
+ Assert.Throws(typeof(NotImplementedException), () => marshaller.Deserializer(new byte[] {1, 2, 3}));
}
class FakeSerializationContext : SerializationContext
diff --git a/src/csharp/Grpc.Core/DeserializationContext.cs b/src/csharp/Grpc.Core/DeserializationContext.cs
index 5b6372ef85..d69e0db5bd 100644
--- a/src/csharp/Grpc.Core/DeserializationContext.cs
+++ b/src/csharp/Grpc.Core/DeserializationContext.cs
@@ -16,6 +16,8 @@
#endregion
+using System;
+
namespace Grpc.Core
{
/// <summary>
@@ -41,6 +43,9 @@ namespace Grpc.Core
/// (as there is no practical reason for doing so) and <c>DeserializationContext</c> implementations are free to assume so.
/// </summary>
/// <returns>byte array containing the entire payload.</returns>
- public abstract byte[] PayloadAsNewBuffer();
+ public virtual byte[] PayloadAsNewBuffer()
+ {
+ throw new NotImplementedException();
+ }
}
}
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCall.cs b/src/csharp/Grpc.Core/Internal/AsyncCall.cs
index 4cdf0ee6a7..b6d687f71e 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCall.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCall.cs
@@ -54,7 +54,7 @@ namespace Grpc.Core.Internal
ClientSideStatus? finishedStatus;
public AsyncCall(CallInvocationDetails<TRequest, TResponse> callDetails)
- : base(callDetails.RequestMarshaller.Serializer, callDetails.ResponseMarshaller.Deserializer)
+ : base(callDetails.RequestMarshaller.ContextualSerializer, callDetails.ResponseMarshaller.ContextualDeserializer)
{
this.details = callDetails.WithOptions(callDetails.Options.Normalize());
this.initialMetadataSent = true; // we always send metadata at the very beginning of the call.
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs
index a93dc34620..39c9f7c616 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs
@@ -40,8 +40,8 @@ namespace Grpc.Core.Internal
static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<AsyncCallBase<TWrite, TRead>>();
protected static readonly Status DeserializeResponseFailureStatus = new Status(StatusCode.Internal, "Failed to deserialize response message.");
- readonly Func<TWrite, byte[]> serializer;
- readonly Func<byte[], TRead> deserializer;
+ readonly Action<TWrite, SerializationContext> serializer;
+ readonly Func<DeserializationContext, TRead> deserializer;
protected readonly object myLock = new object();
@@ -63,7 +63,7 @@ namespace Grpc.Core.Internal
protected bool initialMetadataSent;
protected long streamingWritesCounter; // Number of streaming send operations started so far.
- public AsyncCallBase(Func<TWrite, byte[]> serializer, Func<byte[], TRead> deserializer)
+ public AsyncCallBase(Action<TWrite, SerializationContext> serializer, Func<DeserializationContext, TRead> deserializer)
{
this.serializer = GrpcPreconditions.CheckNotNull(serializer);
this.deserializer = GrpcPreconditions.CheckNotNull(deserializer);
@@ -215,14 +215,26 @@ namespace Grpc.Core.Internal
protected byte[] UnsafeSerialize(TWrite msg)
{
- return serializer(msg);
+ DefaultSerializationContext context = null;
+ try
+ {
+ context = DefaultSerializationContext.GetInitializedThreadLocal();
+ serializer(msg, context);
+ return context.GetPayload();
+ }
+ finally
+ {
+ context?.Reset();
+ }
}
protected Exception TryDeserialize(byte[] payload, out TRead msg)
{
+ DefaultDeserializationContext context = null;
try
{
- msg = deserializer(payload);
+ context = DefaultDeserializationContext.GetInitializedThreadLocal(payload);
+ msg = deserializer(context);
return null;
}
catch (Exception e)
@@ -230,6 +242,11 @@ namespace Grpc.Core.Internal
msg = default(TRead);
return e;
}
+ finally
+ {
+ context?.Reset();
+
+ }
}
/// <summary>
diff --git a/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs b/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs
index 0ceca4abb8..0bf1fb3b7d 100644
--- a/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs
+++ b/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs
@@ -37,7 +37,7 @@ namespace Grpc.Core.Internal
readonly CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
readonly Server server;
- public AsyncCallServer(Func<TResponse, byte[]> serializer, Func<byte[], TRequest> deserializer, Server server) : base(serializer, deserializer)
+ public AsyncCallServer(Action<TResponse, SerializationContext> serializer, Func<DeserializationContext, TRequest> deserializer, Server server) : base(serializer, deserializer)
{
this.server = GrpcPreconditions.CheckNotNull(server);
}
diff --git a/src/csharp/Grpc.Core/Internal/DefaultDeserializationContext.cs b/src/csharp/Grpc.Core/Internal/DefaultDeserializationContext.cs
new file mode 100644
index 0000000000..7ace80e8d5
--- /dev/null
+++ b/src/csharp/Grpc.Core/Internal/DefaultDeserializationContext.cs
@@ -0,0 +1,66 @@
+#region Copyright notice and license
+
+// Copyright 2018 The gRPC Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#endregion
+
+using Grpc.Core.Utils;
+using System;
+using System.Threading;
+
+namespace Grpc.Core.Internal
+{
+ internal class DefaultDeserializationContext : DeserializationContext
+ {
+ static readonly ThreadLocal<DefaultDeserializationContext> threadLocalInstance =
+ new ThreadLocal<DefaultDeserializationContext>(() => new DefaultDeserializationContext(), false);
+
+ byte[] payload;
+ bool alreadyCalledPayloadAsNewBuffer;
+
+ public DefaultDeserializationContext()
+ {
+ Reset();
+ }
+
+ public override int PayloadLength => payload.Length;
+
+ public override byte[] PayloadAsNewBuffer()
+ {
+ GrpcPreconditions.CheckState(!alreadyCalledPayloadAsNewBuffer);
+ alreadyCalledPayloadAsNewBuffer = true;
+ return payload;
+ }
+
+ public void Initialize(byte[] payload)
+ {
+ this.payload = GrpcPreconditions.CheckNotNull(payload);
+ this.alreadyCalledPayloadAsNewBuffer = false;
+ }
+
+ public void Reset()
+ {
+ this.payload = null;
+ this.alreadyCalledPayloadAsNewBuffer = true; // mark payload as read
+ }
+
+ public static DefaultDeserializationContext GetInitializedThreadLocal(byte[] payload)
+ {
+ var instance = threadLocalInstance.Value;
+ instance.Initialize(payload);
+ return instance;
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Core/Internal/DefaultSerializationContext.cs b/src/csharp/Grpc.Core/Internal/DefaultSerializationContext.cs
new file mode 100644
index 0000000000..cceb194879
--- /dev/null
+++ b/src/csharp/Grpc.Core/Internal/DefaultSerializationContext.cs
@@ -0,0 +1,62 @@
+#region Copyright notice and license
+
+// Copyright 2018 The gRPC Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#endregion
+
+using Grpc.Core.Utils;
+using System.Threading;
+
+namespace Grpc.Core.Internal
+{
+ internal class DefaultSerializationContext : SerializationContext
+ {
+ static readonly ThreadLocal<DefaultSerializationContext> threadLocalInstance =
+ new ThreadLocal<DefaultSerializationContext>(() => new DefaultSerializationContext(), false);
+
+ bool isComplete;
+ byte[] payload;
+
+ public DefaultSerializationContext()
+ {
+ Reset();
+ }
+
+ public override void Complete(byte[] payload)
+ {
+ GrpcPreconditions.CheckState(!isComplete);
+ this.isComplete = true;
+ this.payload = payload;
+ }
+
+ internal byte[] GetPayload()
+ {
+ return this.payload;
+ }
+
+ public void Reset()
+ {
+ this.isComplete = false;
+ this.payload = null;
+ }
+
+ public static DefaultSerializationContext GetInitializedThreadLocal()
+ {
+ var instance = threadLocalInstance.Value;
+ instance.Reset();
+ return instance;
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs
index 81522cf8fe..ec732e8c7f 100644
--- a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs
+++ b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs
@@ -52,8 +52,8 @@ namespace Grpc.Core.Internal
public async Task HandleCall(ServerRpcNew newRpc, CompletionQueueSafeHandle cq)
{
var asyncCall = new AsyncCallServer<TRequest, TResponse>(
- method.ResponseMarshaller.Serializer,
- method.RequestMarshaller.Deserializer,
+ method.ResponseMarshaller.ContextualSerializer,
+ method.RequestMarshaller.ContextualDeserializer,
newRpc.Server);
asyncCall.Initialize(newRpc.Call, cq);
@@ -116,8 +116,8 @@ namespace Grpc.Core.Internal
public async Task HandleCall(ServerRpcNew newRpc, CompletionQueueSafeHandle cq)
{
var asyncCall = new AsyncCallServer<TRequest, TResponse>(
- method.ResponseMarshaller.Serializer,
- method.RequestMarshaller.Deserializer,
+ method.ResponseMarshaller.ContextualSerializer,
+ method.RequestMarshaller.ContextualDeserializer,
newRpc.Server);
asyncCall.Initialize(newRpc.Call, cq);
@@ -179,8 +179,8 @@ namespace Grpc.Core.Internal
public async Task HandleCall(ServerRpcNew newRpc, CompletionQueueSafeHandle cq)
{
var asyncCall = new AsyncCallServer<TRequest, TResponse>(
- method.ResponseMarshaller.Serializer,
- method.RequestMarshaller.Deserializer,
+ method.ResponseMarshaller.ContextualSerializer,
+ method.RequestMarshaller.ContextualDeserializer,
newRpc.Server);
asyncCall.Initialize(newRpc.Call, cq);
@@ -242,8 +242,8 @@ namespace Grpc.Core.Internal
public async Task HandleCall(ServerRpcNew newRpc, CompletionQueueSafeHandle cq)
{
var asyncCall = new AsyncCallServer<TRequest, TResponse>(
- method.ResponseMarshaller.Serializer,
- method.RequestMarshaller.Deserializer,
+ method.ResponseMarshaller.ContextualSerializer,
+ method.RequestMarshaller.ContextualDeserializer,
newRpc.Server);
asyncCall.Initialize(newRpc.Call, cq);
diff --git a/src/csharp/Grpc.Core/Marshaller.cs b/src/csharp/Grpc.Core/Marshaller.cs
index 0af9aa586b..34a1849cd7 100644
--- a/src/csharp/Grpc.Core/Marshaller.cs
+++ b/src/csharp/Grpc.Core/Marshaller.cs
@@ -41,6 +41,8 @@ namespace Grpc.Core
{
this.serializer = GrpcPreconditions.CheckNotNull(serializer, nameof(serializer));
this.deserializer = GrpcPreconditions.CheckNotNull(deserializer, nameof(deserializer));
+ // contextual serialization/deserialization is emulated to make the marshaller
+ // usable with the grpc library (required for backward compatibility).
this.contextualSerializer = EmulateContextualSerializer;
this.contextualDeserializer = EmulateContextualDeserializer;
}
@@ -57,10 +59,10 @@ namespace Grpc.Core
{
this.contextualSerializer = GrpcPreconditions.CheckNotNull(serializer, nameof(serializer));
this.contextualDeserializer = GrpcPreconditions.CheckNotNull(deserializer, nameof(deserializer));
- // TODO(jtattermusch): once gRPC C# library switches to using contextual (de)serializer,
- // emulating the simple (de)serializer will become unnecessary.
- this.serializer = EmulateSimpleSerializer;
- this.deserializer = EmulateSimpleDeserializer;
+ // gRPC only uses contextual serializer/deserializer internally, so emulating the legacy
+ // (de)serializer is not necessary.
+ this.serializer = (msg) => { throw new NotImplementedException(); };
+ this.deserializer = (payload) => { throw new NotImplementedException(); };
}
/// <summary>
@@ -85,25 +87,6 @@ namespace Grpc.Core
/// </summary>
public Func<DeserializationContext, T> ContextualDeserializer => this.contextualDeserializer;
- // for backward compatibility, emulate the simple serializer using the contextual one
- private byte[] EmulateSimpleSerializer(T msg)
- {
- // TODO(jtattermusch): avoid the allocation by passing a thread-local instance
- // This code will become unnecessary once gRPC C# library switches to using contextual (de)serializer.
- var context = new EmulatedSerializationContext();
- this.contextualSerializer(msg, context);
- return context.GetPayload();
- }
-
- // for backward compatibility, emulate the simple deserializer using the contextual one
- private T EmulateSimpleDeserializer(byte[] payload)
- {
- // TODO(jtattermusch): avoid the allocation by passing a thread-local instance
- // This code will become unnecessary once gRPC C# library switches to using contextual (de)serializer.
- var context = new EmulatedDeserializationContext(payload);
- return this.contextualDeserializer(context);
- }
-
// for backward compatibility, emulate the contextual serializer using the simple one
private void EmulateContextualSerializer(T message, SerializationContext context)
{
@@ -116,44 +99,6 @@ namespace Grpc.Core
{
return this.deserializer(context.PayloadAsNewBuffer());
}
-
- internal class EmulatedSerializationContext : SerializationContext
- {
- bool isComplete;
- byte[] payload;
-
- public override void Complete(byte[] payload)
- {
- GrpcPreconditions.CheckState(!isComplete);
- this.isComplete = true;
- this.payload = payload;
- }
-
- internal byte[] GetPayload()
- {
- return this.payload;
- }
- }
-
- internal class EmulatedDeserializationContext : DeserializationContext
- {
- readonly byte[] payload;
- bool alreadyCalledPayloadAsNewBuffer;
-
- public EmulatedDeserializationContext(byte[] payload)
- {
- this.payload = GrpcPreconditions.CheckNotNull(payload);
- }
-
- public override int PayloadLength => payload.Length;
-
- public override byte[] PayloadAsNewBuffer()
- {
- GrpcPreconditions.CheckState(!alreadyCalledPayloadAsNewBuffer);
- alreadyCalledPayloadAsNewBuffer = true;
- return payload;
- }
- }
}
/// <summary>
diff --git a/src/csharp/Grpc.Core/SerializationContext.cs b/src/csharp/Grpc.Core/SerializationContext.cs
index cf4d1595da..9aef2adbcd 100644
--- a/src/csharp/Grpc.Core/SerializationContext.cs
+++ b/src/csharp/Grpc.Core/SerializationContext.cs
@@ -16,6 +16,8 @@
#endregion
+using System;
+
namespace Grpc.Core
{
/// <summary>
@@ -29,6 +31,9 @@ namespace Grpc.Core
/// payload which must not be accessed afterwards.
/// </summary>
/// <param name="payload">the serialized form of current message</param>
- public abstract void Complete(byte[] payload);
+ public virtual void Complete(byte[] payload)
+ {
+ throw new NotImplementedException();
+ }
}
}
diff --git a/src/csharp/Grpc.Core/ServerServiceDefinition.cs b/src/csharp/Grpc.Core/ServerServiceDefinition.cs
index 07c6aa1796..b040ab379c 100644
--- a/src/csharp/Grpc.Core/ServerServiceDefinition.cs
+++ b/src/csharp/Grpc.Core/ServerServiceDefinition.cs
@@ -72,7 +72,7 @@ namespace Grpc.Core
}
/// <summary>
- /// Adds a definitions for a single request - single response method.
+ /// Adds a definition for a single request - single response method.
/// </summary>
/// <typeparam name="TRequest">The request message class.</typeparam>
/// <typeparam name="TResponse">The response message class.</typeparam>
@@ -90,7 +90,7 @@ namespace Grpc.Core
}
/// <summary>
- /// Adds a definitions for a client streaming method.
+ /// Adds a definition for a client streaming method.
/// </summary>
/// <typeparam name="TRequest">The request message class.</typeparam>
/// <typeparam name="TResponse">The response message class.</typeparam>
@@ -108,7 +108,7 @@ namespace Grpc.Core
}
/// <summary>
- /// Adds a definitions for a server streaming method.
+ /// Adds a definition for a server streaming method.
/// </summary>
/// <typeparam name="TRequest">The request message class.</typeparam>
/// <typeparam name="TResponse">The response message class.</typeparam>
@@ -126,7 +126,7 @@ namespace Grpc.Core
}
/// <summary>
- /// Adds a definitions for a bidirectional streaming method.
+ /// Adds a definition for a bidirectional streaming method.
/// </summary>
/// <typeparam name="TRequest">The request message class.</typeparam>
/// <typeparam name="TResponse">The response message class.</typeparam>
diff --git a/src/csharp/Grpc.Core/ServiceBinderBase.cs b/src/csharp/Grpc.Core/ServiceBinderBase.cs
new file mode 100644
index 0000000000..d4909f4a26
--- /dev/null
+++ b/src/csharp/Grpc.Core/ServiceBinderBase.cs
@@ -0,0 +1,101 @@
+#region Copyright notice and license
+
+// Copyright 2018 The gRPC Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using Grpc.Core.Interceptors;
+using Grpc.Core.Internal;
+using Grpc.Core.Utils;
+
+namespace Grpc.Core
+{
+ /// <summary>
+ /// Allows binding server-side method implementations in alternative serving stacks.
+ /// Instances of this class are usually populated by the <c>BindService</c> method
+ /// that is part of the autogenerated code for a protocol buffers service definition.
+ /// <seealso cref="ServerServiceDefinition"/>
+ /// </summary>
+ public class ServiceBinderBase
+ {
+ /// <summary>
+ /// Adds a definition for a single request - single response method.
+ /// </summary>
+ /// <typeparam name="TRequest">The request message class.</typeparam>
+ /// <typeparam name="TResponse">The response message class.</typeparam>
+ /// <param name="method">The method.</param>
+ /// <param name="handler">The method handler.</param>
+ public virtual void AddMethod<TRequest, TResponse>(
+ Method<TRequest, TResponse> method,
+ UnaryServerMethod<TRequest, TResponse> handler)
+ where TRequest : class
+ where TResponse : class
+ {
+ throw new NotImplementedException();
+ }
+
+ /// <summary>
+ /// Adds a definition for a client streaming method.
+ /// </summary>
+ /// <typeparam name="TRequest">The request message class.</typeparam>
+ /// <typeparam name="TResponse">The response message class.</typeparam>
+ /// <param name="method">The method.</param>
+ /// <param name="handler">The method handler.</param>
+ public virtual void AddMethod<TRequest, TResponse>(
+ Method<TRequest, TResponse> method,
+ ClientStreamingServerMethod<TRequest, TResponse> handler)
+ where TRequest : class
+ where TResponse : class
+ {
+ throw new NotImplementedException();
+ }
+
+ /// <summary>
+ /// Adds a definition for a server streaming method.
+ /// </summary>
+ /// <typeparam name="TRequest">The request message class.</typeparam>
+ /// <typeparam name="TResponse">The response message class.</typeparam>
+ /// <param name="method">The method.</param>
+ /// <param name="handler">The method handler.</param>
+ public virtual void AddMethod<TRequest, TResponse>(
+ Method<TRequest, TResponse> method,
+ ServerStreamingServerMethod<TRequest, TResponse> handler)
+ where TRequest : class
+ where TResponse : class
+ {
+ throw new NotImplementedException();
+ }
+
+ /// <summary>
+ /// Adds a definition for a bidirectional streaming method.
+ /// </summary>
+ /// <typeparam name="TRequest">The request message class.</typeparam>
+ /// <typeparam name="TResponse">The response message class.</typeparam>
+ /// <param name="method">The method.</param>
+ /// <param name="handler">The method handler.</param>
+ public virtual void AddMethod<TRequest, TResponse>(
+ Method<TRequest, TResponse> method,
+ DuplexStreamingServerMethod<TRequest, TResponse> handler)
+ where TRequest : class
+ where TResponse : class
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/src/csharp/Grpc.Core/Version.csproj.include b/src/csharp/Grpc.Core/Version.csproj.include
index ed0d884365..4fffe4f644 100755
--- a/src/csharp/Grpc.Core/Version.csproj.include
+++ b/src/csharp/Grpc.Core/Version.csproj.include
@@ -1,7 +1,7 @@
<!-- This file is generated -->
<Project>
<PropertyGroup>
- <GrpcCsharpVersion>1.17.0-dev</GrpcCsharpVersion>
+ <GrpcCsharpVersion>1.18.0-dev</GrpcCsharpVersion>
<GoogleProtobufVersion>3.6.1</GoogleProtobufVersion>
</PropertyGroup>
</Project>
diff --git a/src/csharp/Grpc.Core/VersionInfo.cs b/src/csharp/Grpc.Core/VersionInfo.cs
index 14714c8c4a..633880189c 100644
--- a/src/csharp/Grpc.Core/VersionInfo.cs
+++ b/src/csharp/Grpc.Core/VersionInfo.cs
@@ -33,11 +33,11 @@ namespace Grpc.Core
/// <summary>
/// Current <c>AssemblyFileVersion</c> of gRPC C# assemblies
/// </summary>
- public const string CurrentAssemblyFileVersion = "1.17.0.0";
+ public const string CurrentAssemblyFileVersion = "1.18.0.0";
/// <summary>
/// Current version of gRPC C#
/// </summary>
- public const string CurrentVersion = "1.17.0-dev";
+ public const string CurrentVersion = "1.18.0-dev";
}
}
diff --git a/src/csharp/Grpc.Examples/MathGrpc.cs b/src/csharp/Grpc.Examples/MathGrpc.cs
index 9578bb4d81..e5be387e67 100644
--- a/src/csharp/Grpc.Examples/MathGrpc.cs
+++ b/src/csharp/Grpc.Examples/MathGrpc.cs
@@ -287,6 +287,18 @@ namespace Math {
.AddMethod(__Method_Sum, serviceImpl.Sum).Build();
}
+ /// <summary>Register service method implementations with a service binder. Useful when customizing the service binding logic.
+ /// Note: this method is part of an experimental API that can change or be removed without any prior notice.</summary>
+ /// <param name="serviceBinder">Service methods will be bound by calling <c>AddMethod</c> on this object.</param>
+ /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
+ public static void BindService(grpc::ServiceBinderBase serviceBinder, MathBase serviceImpl)
+ {
+ serviceBinder.AddMethod(__Method_Div, serviceImpl.Div);
+ serviceBinder.AddMethod(__Method_DivMany, serviceImpl.DivMany);
+ serviceBinder.AddMethod(__Method_Fib, serviceImpl.Fib);
+ serviceBinder.AddMethod(__Method_Sum, serviceImpl.Sum);
+ }
+
}
}
#endregion
diff --git a/src/csharp/Grpc.HealthCheck/Health.cs b/src/csharp/Grpc.HealthCheck/Health.cs
index a90f261d28..2c3bb45c3c 100644
--- a/src/csharp/Grpc.HealthCheck/Health.cs
+++ b/src/csharp/Grpc.HealthCheck/Health.cs
@@ -25,15 +25,17 @@ namespace Grpc.Health.V1 {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
"ChtncnBjL2hlYWx0aC92MS9oZWFsdGgucHJvdG8SDmdycGMuaGVhbHRoLnYx",
- "IiUKEkhlYWx0aENoZWNrUmVxdWVzdBIPCgdzZXJ2aWNlGAEgASgJIpQBChNI",
+ "IiUKEkhlYWx0aENoZWNrUmVxdWVzdBIPCgdzZXJ2aWNlGAEgASgJIqkBChNI",
"ZWFsdGhDaGVja1Jlc3BvbnNlEkEKBnN0YXR1cxgBIAEoDjIxLmdycGMuaGVh",
- "bHRoLnYxLkhlYWx0aENoZWNrUmVzcG9uc2UuU2VydmluZ1N0YXR1cyI6Cg1T",
+ "bHRoLnYxLkhlYWx0aENoZWNrUmVzcG9uc2UuU2VydmluZ1N0YXR1cyJPCg1T",
"ZXJ2aW5nU3RhdHVzEgsKB1VOS05PV04QABILCgdTRVJWSU5HEAESDwoLTk9U",
- "X1NFUlZJTkcQAjJaCgZIZWFsdGgSUAoFQ2hlY2sSIi5ncnBjLmhlYWx0aC52",
- "MS5IZWFsdGhDaGVja1JlcXVlc3QaIy5ncnBjLmhlYWx0aC52MS5IZWFsdGhD",
- "aGVja1Jlc3BvbnNlQmEKEWlvLmdycGMuaGVhbHRoLnYxQgtIZWFsdGhQcm90",
- "b1ABWixnb29nbGUuZ29sYW5nLm9yZy9ncnBjL2hlYWx0aC9ncnBjX2hlYWx0",
- "aF92MaoCDkdycGMuSGVhbHRoLlYxYgZwcm90bzM="));
+ "X1NFUlZJTkcQAhITCg9TRVJWSUNFX1VOS05PV04QAzKuAQoGSGVhbHRoElAK",
+ "BUNoZWNrEiIuZ3JwYy5oZWFsdGgudjEuSGVhbHRoQ2hlY2tSZXF1ZXN0GiMu",
+ "Z3JwYy5oZWFsdGgudjEuSGVhbHRoQ2hlY2tSZXNwb25zZRJSCgVXYXRjaBIi",
+ "LmdycGMuaGVhbHRoLnYxLkhlYWx0aENoZWNrUmVxdWVzdBojLmdycGMuaGVh",
+ "bHRoLnYxLkhlYWx0aENoZWNrUmVzcG9uc2UwAUJhChFpby5ncnBjLmhlYWx0",
+ "aC52MUILSGVhbHRoUHJvdG9QAVosZ29vZ2xlLmdvbGFuZy5vcmcvZ3JwYy9o",
+ "ZWFsdGgvZ3JwY19oZWFsdGhfdjGqAg5HcnBjLkhlYWx0aC5WMWIGcHJvdG8z"));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
@@ -309,6 +311,10 @@ namespace Grpc.Health.V1 {
[pbr::OriginalName("UNKNOWN")] Unknown = 0,
[pbr::OriginalName("SERVING")] Serving = 1,
[pbr::OriginalName("NOT_SERVING")] NotServing = 2,
+ /// <summary>
+ /// Used only by the Watch method.
+ /// </summary>
+ [pbr::OriginalName("SERVICE_UNKNOWN")] ServiceUnknown = 3,
}
}
diff --git a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
index 5e79c04d2a..51956f2f23 100644
--- a/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
+++ b/src/csharp/Grpc.HealthCheck/HealthGrpc.cs
@@ -40,6 +40,13 @@ namespace Grpc.Health.V1 {
__Marshaller_grpc_health_v1_HealthCheckRequest,
__Marshaller_grpc_health_v1_HealthCheckResponse);
+ static readonly grpc::Method<global::Grpc.Health.V1.HealthCheckRequest, global::Grpc.Health.V1.HealthCheckResponse> __Method_Watch = new grpc::Method<global::Grpc.Health.V1.HealthCheckRequest, global::Grpc.Health.V1.HealthCheckResponse>(
+ grpc::MethodType.ServerStreaming,
+ __ServiceName,
+ "Watch",
+ __Marshaller_grpc_health_v1_HealthCheckRequest,
+ __Marshaller_grpc_health_v1_HealthCheckResponse);
+
/// <summary>Service descriptor</summary>
public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
{
@@ -49,11 +56,44 @@ namespace Grpc.Health.V1 {
/// <summary>Base class for server-side implementations of Health</summary>
public abstract partial class HealthBase
{
+ /// <summary>
+ /// If the requested service is unknown, the call will fail with status
+ /// NOT_FOUND.
+ /// </summary>
+ /// <param name="request">The request received from the client.</param>
+ /// <param name="context">The context of the server-side call handler being invoked.</param>
+ /// <returns>The response to send back to the client (wrapped by a task).</returns>
public virtual global::System.Threading.Tasks.Task<global::Grpc.Health.V1.HealthCheckResponse> Check(global::Grpc.Health.V1.HealthCheckRequest request, grpc::ServerCallContext context)
{
throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
}
+ /// <summary>
+ /// Performs a watch for the serving status of the requested service.
+ /// The server will immediately send back a message indicating the current
+ /// serving status. It will then subsequently send a new message whenever
+ /// the service's serving status changes.
+ ///
+ /// If the requested service is unknown when the call is received, the
+ /// server will send a message setting the serving status to
+ /// SERVICE_UNKNOWN but will *not* terminate the call. If at some
+ /// future point, the serving status of the service becomes known, the
+ /// server will send a new message with the service's serving status.
+ ///
+ /// If the call terminates with status UNIMPLEMENTED, then clients
+ /// should assume this method is not supported and should not retry the
+ /// call. If the call terminates with any other status (including OK),
+ /// clients should retry the call with appropriate exponential backoff.
+ /// </summary>
+ /// <param name="request">The request received from the client.</param>
+ /// <param name="responseStream">Used for sending responses back to the client.</param>
+ /// <param name="context">The context of the server-side call handler being invoked.</param>
+ /// <returns>A task indicating completion of the handler.</returns>
+ public virtual global::System.Threading.Tasks.Task Watch(global::Grpc.Health.V1.HealthCheckRequest request, grpc::IServerStreamWriter<global::Grpc.Health.V1.HealthCheckResponse> responseStream, grpc::ServerCallContext context)
+ {
+ throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+ }
+
}
/// <summary>Client for Health</summary>
@@ -79,22 +119,104 @@ namespace Grpc.Health.V1 {
{
}
+ /// <summary>
+ /// If the requested service is unknown, the call will fail with status
+ /// NOT_FOUND.
+ /// </summary>
+ /// <param name="request">The request to send to the server.</param>
+ /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+ /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+ /// <param name="cancellationToken">An optional token for canceling the call.</param>
+ /// <returns>The response received from the server.</returns>
public virtual global::Grpc.Health.V1.HealthCheckResponse Check(global::Grpc.Health.V1.HealthCheckRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return Check(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
+ /// <summary>
+ /// If the requested service is unknown, the call will fail with status
+ /// NOT_FOUND.
+ /// </summary>
+ /// <param name="request">The request to send to the server.</param>
+ /// <param name="options">The options for the call.</param>
+ /// <returns>The response received from the server.</returns>
public virtual global::Grpc.Health.V1.HealthCheckResponse Check(global::Grpc.Health.V1.HealthCheckRequest request, grpc::CallOptions options)
{
return CallInvoker.BlockingUnaryCall(__Method_Check, null, options, request);
}
+ /// <summary>
+ /// If the requested service is unknown, the call will fail with status
+ /// NOT_FOUND.
+ /// </summary>
+ /// <param name="request">The request to send to the server.</param>
+ /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+ /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+ /// <param name="cancellationToken">An optional token for canceling the call.</param>
+ /// <returns>The call object.</returns>
public virtual grpc::AsyncUnaryCall<global::Grpc.Health.V1.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1.HealthCheckRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
{
return CheckAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
}
+ /// <summary>
+ /// If the requested service is unknown, the call will fail with status
+ /// NOT_FOUND.
+ /// </summary>
+ /// <param name="request">The request to send to the server.</param>
+ /// <param name="options">The options for the call.</param>
+ /// <returns>The call object.</returns>
public virtual grpc::AsyncUnaryCall<global::Grpc.Health.V1.HealthCheckResponse> CheckAsync(global::Grpc.Health.V1.HealthCheckRequest request, grpc::CallOptions options)
{
return CallInvoker.AsyncUnaryCall(__Method_Check, null, options, request);
}
+ /// <summary>
+ /// Performs a watch for the serving status of the requested service.
+ /// The server will immediately send back a message indicating the current
+ /// serving status. It will then subsequently send a new message whenever
+ /// the service's serving status changes.
+ ///
+ /// If the requested service is unknown when the call is received, the
+ /// server will send a message setting the serving status to
+ /// SERVICE_UNKNOWN but will *not* terminate the call. If at some
+ /// future point, the serving status of the service becomes known, the
+ /// server will send a new message with the service's serving status.
+ ///
+ /// If the call terminates with status UNIMPLEMENTED, then clients
+ /// should assume this method is not supported and should not retry the
+ /// call. If the call terminates with any other status (including OK),
+ /// clients should retry the call with appropriate exponential backoff.
+ /// </summary>
+ /// <param name="request">The request to send to the server.</param>
+ /// <param name="headers">The initial metadata to send with the call. This parameter is optional.</param>
+ /// <param name="deadline">An optional deadline for the call. The call will be cancelled if deadline is hit.</param>
+ /// <param name="cancellationToken">An optional token for canceling the call.</param>
+ /// <returns>The call object.</returns>
+ public virtual grpc::AsyncServerStreamingCall<global::Grpc.Health.V1.HealthCheckResponse> Watch(global::Grpc.Health.V1.HealthCheckRequest request, grpc::Metadata headers = null, global::System.DateTime? deadline = null, global::System.Threading.CancellationToken cancellationToken = default(global::System.Threading.CancellationToken))
+ {
+ return Watch(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+ }
+ /// <summary>
+ /// Performs a watch for the serving status of the requested service.
+ /// The server will immediately send back a message indicating the current
+ /// serving status. It will then subsequently send a new message whenever
+ /// the service's serving status changes.
+ ///
+ /// If the requested service is unknown when the call is received, the
+ /// server will send a message setting the serving status to
+ /// SERVICE_UNKNOWN but will *not* terminate the call. If at some
+ /// future point, the serving status of the service becomes known, the
+ /// server will send a new message with the service's serving status.
+ ///
+ /// If the call terminates with status UNIMPLEMENTED, then clients
+ /// should assume this method is not supported and should not retry the
+ /// call. If the call terminates with any other status (including OK),
+ /// clients should retry the call with appropriate exponential backoff.
+ /// </summary>
+ /// <param name="request">The request to send to the server.</param>
+ /// <param name="options">The options for the call.</param>
+ /// <returns>The call object.</returns>
+ public virtual grpc::AsyncServerStreamingCall<global::Grpc.Health.V1.HealthCheckResponse> Watch(global::Grpc.Health.V1.HealthCheckRequest request, grpc::CallOptions options)
+ {
+ return CallInvoker.AsyncServerStreamingCall(__Method_Watch, null, options, request);
+ }
/// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
protected override HealthClient NewInstance(ClientBaseConfiguration configuration)
{
@@ -107,7 +229,18 @@ namespace Grpc.Health.V1 {
public static grpc::ServerServiceDefinition BindService(HealthBase serviceImpl)
{
return grpc::ServerServiceDefinition.CreateBuilder()
- .AddMethod(__Method_Check, serviceImpl.Check).Build();
+ .AddMethod(__Method_Check, serviceImpl.Check)
+ .AddMethod(__Method_Watch, serviceImpl.Watch).Build();
+ }
+
+ /// <summary>Register service method implementations with a service binder. Useful when customizing the service binding logic.
+ /// Note: this method is part of an experimental API that can change or be removed without any prior notice.</summary>
+ /// <param name="serviceBinder">Service methods will be bound by calling <c>AddMethod</c> on this object.</param>
+ /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
+ public static void BindService(grpc::ServiceBinderBase serviceBinder, HealthBase serviceImpl)
+ {
+ serviceBinder.AddMethod(__Method_Check, serviceImpl.Check);
+ serviceBinder.AddMethod(__Method_Watch, serviceImpl.Watch);
}
}
diff --git a/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs
index b5738593f2..3431b5fa18 100644
--- a/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/BenchmarkServiceGrpc.cs
@@ -324,6 +324,19 @@ namespace Grpc.Testing {
.AddMethod(__Method_StreamingBothWays, serviceImpl.StreamingBothWays).Build();
}
+ /// <summary>Register service method implementations with a service binder. Useful when customizing the service binding logic.
+ /// Note: this method is part of an experimental API that can change or be removed without any prior notice.</summary>
+ /// <param name="serviceBinder">Service methods will be bound by calling <c>AddMethod</c> on this object.</param>
+ /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
+ public static void BindService(grpc::ServiceBinderBase serviceBinder, BenchmarkServiceBase serviceImpl)
+ {
+ serviceBinder.AddMethod(__Method_UnaryCall, serviceImpl.UnaryCall);
+ serviceBinder.AddMethod(__Method_StreamingCall, serviceImpl.StreamingCall);
+ serviceBinder.AddMethod(__Method_StreamingFromClient, serviceImpl.StreamingFromClient);
+ serviceBinder.AddMethod(__Method_StreamingFromServer, serviceImpl.StreamingFromServer);
+ serviceBinder.AddMethod(__Method_StreamingBothWays, serviceImpl.StreamingBothWays);
+ }
+
}
}
#endregion
diff --git a/src/csharp/Grpc.IntegrationTesting/Control.cs b/src/csharp/Grpc.IntegrationTesting/Control.cs
index 6e00348451..368b86659a 100644
--- a/src/csharp/Grpc.IntegrationTesting/Control.cs
+++ b/src/csharp/Grpc.IntegrationTesting/Control.cs
@@ -34,7 +34,7 @@ namespace Grpc.Testing {
"U2VjdXJpdHlQYXJhbXMSEwoLdXNlX3Rlc3RfY2EYASABKAgSHAoUc2VydmVy",
"X2hvc3Rfb3ZlcnJpZGUYAiABKAkSEQoJY3JlZF90eXBlGAMgASgJIk0KCkNo",
"YW5uZWxBcmcSDAoEbmFtZRgBIAEoCRITCglzdHJfdmFsdWUYAiABKAlIABIT",
- "CglpbnRfdmFsdWUYAyABKAVIAEIHCgV2YWx1ZSLvBAoMQ2xpZW50Q29uZmln",
+ "CglpbnRfdmFsdWUYAyABKAVIAEIHCgV2YWx1ZSKiBQoMQ2xpZW50Q29uZmln",
"EhYKDnNlcnZlcl90YXJnZXRzGAEgAygJEi0KC2NsaWVudF90eXBlGAIgASgO",
"MhguZ3JwYy50ZXN0aW5nLkNsaWVudFR5cGUSNQoPc2VjdXJpdHlfcGFyYW1z",
"GAMgASgLMhwuZ3JwYy50ZXN0aW5nLlNlY3VyaXR5UGFyYW1zEiQKHG91dHN0",
@@ -48,59 +48,60 @@ namespace Grpc.Testing {
"GA4gASgFEhgKEG90aGVyX2NsaWVudF9hcGkYDyABKAkSLgoMY2hhbm5lbF9h",
"cmdzGBAgAygLMhguZ3JwYy50ZXN0aW5nLkNoYW5uZWxBcmcSFgoOdGhyZWFk",
"c19wZXJfY3EYESABKAUSGwoTbWVzc2FnZXNfcGVyX3N0cmVhbRgSIAEoBRIY",
- "ChB1c2VfY29hbGVzY2VfYXBpGBMgASgIIjgKDENsaWVudFN0YXR1cxIoCgVz",
- "dGF0cxgBIAEoCzIZLmdycGMudGVzdGluZy5DbGllbnRTdGF0cyIVCgRNYXJr",
- "Eg0KBXJlc2V0GAEgASgIImgKCkNsaWVudEFyZ3MSKwoFc2V0dXAYASABKAsy",
- "Gi5ncnBjLnRlc3RpbmcuQ2xpZW50Q29uZmlnSAASIgoEbWFyaxgCIAEoCzIS",
- "LmdycGMudGVzdGluZy5NYXJrSABCCQoHYXJndHlwZSL9AgoMU2VydmVyQ29u",
- "ZmlnEi0KC3NlcnZlcl90eXBlGAEgASgOMhguZ3JwYy50ZXN0aW5nLlNlcnZl",
- "clR5cGUSNQoPc2VjdXJpdHlfcGFyYW1zGAIgASgLMhwuZ3JwYy50ZXN0aW5n",
- "LlNlY3VyaXR5UGFyYW1zEgwKBHBvcnQYBCABKAUSHAoUYXN5bmNfc2VydmVy",
- "X3RocmVhZHMYByABKAUSEgoKY29yZV9saW1pdBgIIAEoBRIzCg5wYXlsb2Fk",
- "X2NvbmZpZxgJIAEoCzIbLmdycGMudGVzdGluZy5QYXlsb2FkQ29uZmlnEhEK",
- "CWNvcmVfbGlzdBgKIAMoBRIYChBvdGhlcl9zZXJ2ZXJfYXBpGAsgASgJEhYK",
- "DnRocmVhZHNfcGVyX2NxGAwgASgFEhwKE3Jlc291cmNlX3F1b3RhX3NpemUY",
- "6QcgASgFEi8KDGNoYW5uZWxfYXJncxjqByADKAsyGC5ncnBjLnRlc3Rpbmcu",
- "Q2hhbm5lbEFyZyJoCgpTZXJ2ZXJBcmdzEisKBXNldHVwGAEgASgLMhouZ3Jw",
- "Yy50ZXN0aW5nLlNlcnZlckNvbmZpZ0gAEiIKBG1hcmsYAiABKAsyEi5ncnBj",
- "LnRlc3RpbmcuTWFya0gAQgkKB2FyZ3R5cGUiVQoMU2VydmVyU3RhdHVzEigK",
- "BXN0YXRzGAEgASgLMhkuZ3JwYy50ZXN0aW5nLlNlcnZlclN0YXRzEgwKBHBv",
- "cnQYAiABKAUSDQoFY29yZXMYAyABKAUiDQoLQ29yZVJlcXVlc3QiHQoMQ29y",
- "ZVJlc3BvbnNlEg0KBWNvcmVzGAEgASgFIgYKBFZvaWQi/QEKCFNjZW5hcmlv",
- "EgwKBG5hbWUYASABKAkSMQoNY2xpZW50X2NvbmZpZxgCIAEoCzIaLmdycGMu",
- "dGVzdGluZy5DbGllbnRDb25maWcSEwoLbnVtX2NsaWVudHMYAyABKAUSMQoN",
- "c2VydmVyX2NvbmZpZxgEIAEoCzIaLmdycGMudGVzdGluZy5TZXJ2ZXJDb25m",
- "aWcSEwoLbnVtX3NlcnZlcnMYBSABKAUSFgoOd2FybXVwX3NlY29uZHMYBiAB",
- "KAUSGQoRYmVuY2htYXJrX3NlY29uZHMYByABKAUSIAoYc3Bhd25fbG9jYWxf",
- "d29ya2VyX2NvdW50GAggASgFIjYKCVNjZW5hcmlvcxIpCglzY2VuYXJpb3MY",
- "ASADKAsyFi5ncnBjLnRlc3RpbmcuU2NlbmFyaW8ihAQKFVNjZW5hcmlvUmVz",
- "dWx0U3VtbWFyeRILCgNxcHMYASABKAESGwoTcXBzX3Blcl9zZXJ2ZXJfY29y",
- "ZRgCIAEoARIaChJzZXJ2ZXJfc3lzdGVtX3RpbWUYAyABKAESGAoQc2VydmVy",
- "X3VzZXJfdGltZRgEIAEoARIaChJjbGllbnRfc3lzdGVtX3RpbWUYBSABKAES",
- "GAoQY2xpZW50X3VzZXJfdGltZRgGIAEoARISCgpsYXRlbmN5XzUwGAcgASgB",
- "EhIKCmxhdGVuY3lfOTAYCCABKAESEgoKbGF0ZW5jeV85NRgJIAEoARISCgps",
- "YXRlbmN5Xzk5GAogASgBEhMKC2xhdGVuY3lfOTk5GAsgASgBEhgKEHNlcnZl",
- "cl9jcHVfdXNhZ2UYDCABKAESJgoec3VjY2Vzc2Z1bF9yZXF1ZXN0c19wZXJf",
- "c2Vjb25kGA0gASgBEiIKGmZhaWxlZF9yZXF1ZXN0c19wZXJfc2Vjb25kGA4g",
- "ASgBEiAKGGNsaWVudF9wb2xsc19wZXJfcmVxdWVzdBgPIAEoARIgChhzZXJ2",
- "ZXJfcG9sbHNfcGVyX3JlcXVlc3QYECABKAESIgoac2VydmVyX3F1ZXJpZXNf",
- "cGVyX2NwdV9zZWMYESABKAESIgoaY2xpZW50X3F1ZXJpZXNfcGVyX2NwdV9z",
- "ZWMYEiABKAEigwMKDlNjZW5hcmlvUmVzdWx0EigKCHNjZW5hcmlvGAEgASgL",
- "MhYuZ3JwYy50ZXN0aW5nLlNjZW5hcmlvEi4KCWxhdGVuY2llcxgCIAEoCzIb",
- "LmdycGMudGVzdGluZy5IaXN0b2dyYW1EYXRhEi8KDGNsaWVudF9zdGF0cxgD",
- "IAMoCzIZLmdycGMudGVzdGluZy5DbGllbnRTdGF0cxIvCgxzZXJ2ZXJfc3Rh",
- "dHMYBCADKAsyGS5ncnBjLnRlc3RpbmcuU2VydmVyU3RhdHMSFAoMc2VydmVy",
- "X2NvcmVzGAUgAygFEjQKB3N1bW1hcnkYBiABKAsyIy5ncnBjLnRlc3Rpbmcu",
- "U2NlbmFyaW9SZXN1bHRTdW1tYXJ5EhYKDmNsaWVudF9zdWNjZXNzGAcgAygI",
- "EhYKDnNlcnZlcl9zdWNjZXNzGAggAygIEjkKD3JlcXVlc3RfcmVzdWx0cxgJ",
- "IAMoCzIgLmdycGMudGVzdGluZy5SZXF1ZXN0UmVzdWx0Q291bnQqQQoKQ2xp",
- "ZW50VHlwZRIPCgtTWU5DX0NMSUVOVBAAEhAKDEFTWU5DX0NMSUVOVBABEhAK",
- "DE9USEVSX0NMSUVOVBACKlsKClNlcnZlclR5cGUSDwoLU1lOQ19TRVJWRVIQ",
- "ABIQCgxBU1lOQ19TRVJWRVIQARIYChRBU1lOQ19HRU5FUklDX1NFUlZFUhAC",
- "EhAKDE9USEVSX1NFUlZFUhADKnIKB1JwY1R5cGUSCQoFVU5BUlkQABINCglT",
- "VFJFQU1JTkcQARIZChVTVFJFQU1JTkdfRlJPTV9DTElFTlQQAhIZChVTVFJF",
- "QU1JTkdfRlJPTV9TRVJWRVIQAxIXChNTVFJFQU1JTkdfQk9USF9XQVlTEARi",
- "BnByb3RvMw=="));
+ "ChB1c2VfY29hbGVzY2VfYXBpGBMgASgIEjEKKW1lZGlhbl9sYXRlbmN5X2Nv",
+ "bGxlY3Rpb25faW50ZXJ2YWxfbWlsbGlzGBQgASgFIjgKDENsaWVudFN0YXR1",
+ "cxIoCgVzdGF0cxgBIAEoCzIZLmdycGMudGVzdGluZy5DbGllbnRTdGF0cyIV",
+ "CgRNYXJrEg0KBXJlc2V0GAEgASgIImgKCkNsaWVudEFyZ3MSKwoFc2V0dXAY",
+ "ASABKAsyGi5ncnBjLnRlc3RpbmcuQ2xpZW50Q29uZmlnSAASIgoEbWFyaxgC",
+ "IAEoCzISLmdycGMudGVzdGluZy5NYXJrSABCCQoHYXJndHlwZSL9AgoMU2Vy",
+ "dmVyQ29uZmlnEi0KC3NlcnZlcl90eXBlGAEgASgOMhguZ3JwYy50ZXN0aW5n",
+ "LlNlcnZlclR5cGUSNQoPc2VjdXJpdHlfcGFyYW1zGAIgASgLMhwuZ3JwYy50",
+ "ZXN0aW5nLlNlY3VyaXR5UGFyYW1zEgwKBHBvcnQYBCABKAUSHAoUYXN5bmNf",
+ "c2VydmVyX3RocmVhZHMYByABKAUSEgoKY29yZV9saW1pdBgIIAEoBRIzCg5w",
+ "YXlsb2FkX2NvbmZpZxgJIAEoCzIbLmdycGMudGVzdGluZy5QYXlsb2FkQ29u",
+ "ZmlnEhEKCWNvcmVfbGlzdBgKIAMoBRIYChBvdGhlcl9zZXJ2ZXJfYXBpGAsg",
+ "ASgJEhYKDnRocmVhZHNfcGVyX2NxGAwgASgFEhwKE3Jlc291cmNlX3F1b3Rh",
+ "X3NpemUY6QcgASgFEi8KDGNoYW5uZWxfYXJncxjqByADKAsyGC5ncnBjLnRl",
+ "c3RpbmcuQ2hhbm5lbEFyZyJoCgpTZXJ2ZXJBcmdzEisKBXNldHVwGAEgASgL",
+ "MhouZ3JwYy50ZXN0aW5nLlNlcnZlckNvbmZpZ0gAEiIKBG1hcmsYAiABKAsy",
+ "Ei5ncnBjLnRlc3RpbmcuTWFya0gAQgkKB2FyZ3R5cGUiVQoMU2VydmVyU3Rh",
+ "dHVzEigKBXN0YXRzGAEgASgLMhkuZ3JwYy50ZXN0aW5nLlNlcnZlclN0YXRz",
+ "EgwKBHBvcnQYAiABKAUSDQoFY29yZXMYAyABKAUiDQoLQ29yZVJlcXVlc3Qi",
+ "HQoMQ29yZVJlc3BvbnNlEg0KBWNvcmVzGAEgASgFIgYKBFZvaWQi/QEKCFNj",
+ "ZW5hcmlvEgwKBG5hbWUYASABKAkSMQoNY2xpZW50X2NvbmZpZxgCIAEoCzIa",
+ "LmdycGMudGVzdGluZy5DbGllbnRDb25maWcSEwoLbnVtX2NsaWVudHMYAyAB",
+ "KAUSMQoNc2VydmVyX2NvbmZpZxgEIAEoCzIaLmdycGMudGVzdGluZy5TZXJ2",
+ "ZXJDb25maWcSEwoLbnVtX3NlcnZlcnMYBSABKAUSFgoOd2FybXVwX3NlY29u",
+ "ZHMYBiABKAUSGQoRYmVuY2htYXJrX3NlY29uZHMYByABKAUSIAoYc3Bhd25f",
+ "bG9jYWxfd29ya2VyX2NvdW50GAggASgFIjYKCVNjZW5hcmlvcxIpCglzY2Vu",
+ "YXJpb3MYASADKAsyFi5ncnBjLnRlc3RpbmcuU2NlbmFyaW8ihAQKFVNjZW5h",
+ "cmlvUmVzdWx0U3VtbWFyeRILCgNxcHMYASABKAESGwoTcXBzX3Blcl9zZXJ2",
+ "ZXJfY29yZRgCIAEoARIaChJzZXJ2ZXJfc3lzdGVtX3RpbWUYAyABKAESGAoQ",
+ "c2VydmVyX3VzZXJfdGltZRgEIAEoARIaChJjbGllbnRfc3lzdGVtX3RpbWUY",
+ "BSABKAESGAoQY2xpZW50X3VzZXJfdGltZRgGIAEoARISCgpsYXRlbmN5XzUw",
+ "GAcgASgBEhIKCmxhdGVuY3lfOTAYCCABKAESEgoKbGF0ZW5jeV85NRgJIAEo",
+ "ARISCgpsYXRlbmN5Xzk5GAogASgBEhMKC2xhdGVuY3lfOTk5GAsgASgBEhgK",
+ "EHNlcnZlcl9jcHVfdXNhZ2UYDCABKAESJgoec3VjY2Vzc2Z1bF9yZXF1ZXN0",
+ "c19wZXJfc2Vjb25kGA0gASgBEiIKGmZhaWxlZF9yZXF1ZXN0c19wZXJfc2Vj",
+ "b25kGA4gASgBEiAKGGNsaWVudF9wb2xsc19wZXJfcmVxdWVzdBgPIAEoARIg",
+ "ChhzZXJ2ZXJfcG9sbHNfcGVyX3JlcXVlc3QYECABKAESIgoac2VydmVyX3F1",
+ "ZXJpZXNfcGVyX2NwdV9zZWMYESABKAESIgoaY2xpZW50X3F1ZXJpZXNfcGVy",
+ "X2NwdV9zZWMYEiABKAEigwMKDlNjZW5hcmlvUmVzdWx0EigKCHNjZW5hcmlv",
+ "GAEgASgLMhYuZ3JwYy50ZXN0aW5nLlNjZW5hcmlvEi4KCWxhdGVuY2llcxgC",
+ "IAEoCzIbLmdycGMudGVzdGluZy5IaXN0b2dyYW1EYXRhEi8KDGNsaWVudF9z",
+ "dGF0cxgDIAMoCzIZLmdycGMudGVzdGluZy5DbGllbnRTdGF0cxIvCgxzZXJ2",
+ "ZXJfc3RhdHMYBCADKAsyGS5ncnBjLnRlc3RpbmcuU2VydmVyU3RhdHMSFAoM",
+ "c2VydmVyX2NvcmVzGAUgAygFEjQKB3N1bW1hcnkYBiABKAsyIy5ncnBjLnRl",
+ "c3RpbmcuU2NlbmFyaW9SZXN1bHRTdW1tYXJ5EhYKDmNsaWVudF9zdWNjZXNz",
+ "GAcgAygIEhYKDnNlcnZlcl9zdWNjZXNzGAggAygIEjkKD3JlcXVlc3RfcmVz",
+ "dWx0cxgJIAMoCzIgLmdycGMudGVzdGluZy5SZXF1ZXN0UmVzdWx0Q291bnQq",
+ "VgoKQ2xpZW50VHlwZRIPCgtTWU5DX0NMSUVOVBAAEhAKDEFTWU5DX0NMSUVO",
+ "VBABEhAKDE9USEVSX0NMSUVOVBACEhMKD0NBTExCQUNLX0NMSUVOVBADKlsK",
+ "ClNlcnZlclR5cGUSDwoLU1lOQ19TRVJWRVIQABIQCgxBU1lOQ19TRVJWRVIQ",
+ "ARIYChRBU1lOQ19HRU5FUklDX1NFUlZFUhACEhAKDE9USEVSX1NFUlZFUhAD",
+ "KnIKB1JwY1R5cGUSCQoFVU5BUlkQABINCglTVFJFQU1JTkcQARIZChVTVFJF",
+ "QU1JTkdfRlJPTV9DTElFTlQQAhIZChVTVFJFQU1JTkdfRlJPTV9TRVJWRVIQ",
+ "AxIXChNTVFJFQU1JTkdfQk9USF9XQVlTEARiBnByb3RvMw=="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { global::Grpc.Testing.PayloadsReflection.Descriptor, global::Grpc.Testing.StatsReflection.Descriptor, },
new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Grpc.Testing.ClientType), typeof(global::Grpc.Testing.ServerType), typeof(global::Grpc.Testing.RpcType), }, new pbr::GeneratedClrTypeInfo[] {
@@ -109,7 +110,7 @@ namespace Grpc.Testing {
new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.LoadParams), global::Grpc.Testing.LoadParams.Parser, new[]{ "ClosedLoop", "Poisson" }, new[]{ "Load" }, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.SecurityParams), global::Grpc.Testing.SecurityParams.Parser, new[]{ "UseTestCa", "ServerHostOverride", "CredType" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ChannelArg), global::Grpc.Testing.ChannelArg.Parser, new[]{ "Name", "StrValue", "IntValue" }, new[]{ "Value" }, null, null),
- new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ClientConfig), global::Grpc.Testing.ClientConfig.Parser, new[]{ "ServerTargets", "ClientType", "SecurityParams", "OutstandingRpcsPerChannel", "ClientChannels", "AsyncClientThreads", "RpcType", "LoadParams", "PayloadConfig", "HistogramParams", "CoreList", "CoreLimit", "OtherClientApi", "ChannelArgs", "ThreadsPerCq", "MessagesPerStream", "UseCoalesceApi" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ClientConfig), global::Grpc.Testing.ClientConfig.Parser, new[]{ "ServerTargets", "ClientType", "SecurityParams", "OutstandingRpcsPerChannel", "ClientChannels", "AsyncClientThreads", "RpcType", "LoadParams", "PayloadConfig", "HistogramParams", "CoreList", "CoreLimit", "OtherClientApi", "ChannelArgs", "ThreadsPerCq", "MessagesPerStream", "UseCoalesceApi", "MedianLatencyCollectionIntervalMillis" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ClientStatus), global::Grpc.Testing.ClientStatus.Parser, new[]{ "Stats" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.Mark), global::Grpc.Testing.Mark.Parser, new[]{ "Reset" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Grpc.Testing.ClientArgs), global::Grpc.Testing.ClientArgs.Parser, new[]{ "Setup", "Mark" }, new[]{ "Argtype" }, null, null),
@@ -140,6 +141,7 @@ namespace Grpc.Testing {
/// used for some language-specific variants
/// </summary>
[pbr::OriginalName("OTHER_CLIENT")] OtherClient = 2,
+ [pbr::OriginalName("CALLBACK_CLIENT")] CallbackClient = 3,
}
public enum ServerType {
@@ -1054,6 +1056,7 @@ namespace Grpc.Testing {
threadsPerCq_ = other.threadsPerCq_;
messagesPerStream_ = other.messagesPerStream_;
useCoalesceApi_ = other.useCoalesceApi_;
+ medianLatencyCollectionIntervalMillis_ = other.medianLatencyCollectionIntervalMillis_;
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
@@ -1278,6 +1281,21 @@ namespace Grpc.Testing {
}
}
+ /// <summary>Field number for the "median_latency_collection_interval_millis" field.</summary>
+ public const int MedianLatencyCollectionIntervalMillisFieldNumber = 20;
+ private int medianLatencyCollectionIntervalMillis_;
+ /// <summary>
+ /// If 0, disabled. Else, specifies the period between gathering latency
+ /// medians in milliseconds.
+ /// </summary>
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int MedianLatencyCollectionIntervalMillis {
+ get { return medianLatencyCollectionIntervalMillis_; }
+ set {
+ medianLatencyCollectionIntervalMillis_ = value;
+ }
+ }
+
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as ClientConfig);
@@ -1308,6 +1326,7 @@ namespace Grpc.Testing {
if (ThreadsPerCq != other.ThreadsPerCq) return false;
if (MessagesPerStream != other.MessagesPerStream) return false;
if (UseCoalesceApi != other.UseCoalesceApi) return false;
+ if (MedianLatencyCollectionIntervalMillis != other.MedianLatencyCollectionIntervalMillis) return false;
return Equals(_unknownFields, other._unknownFields);
}
@@ -1331,6 +1350,7 @@ namespace Grpc.Testing {
if (ThreadsPerCq != 0) hash ^= ThreadsPerCq.GetHashCode();
if (MessagesPerStream != 0) hash ^= MessagesPerStream.GetHashCode();
if (UseCoalesceApi != false) hash ^= UseCoalesceApi.GetHashCode();
+ if (MedianLatencyCollectionIntervalMillis != 0) hash ^= MedianLatencyCollectionIntervalMillis.GetHashCode();
if (_unknownFields != null) {
hash ^= _unknownFields.GetHashCode();
}
@@ -1403,6 +1423,10 @@ namespace Grpc.Testing {
output.WriteRawTag(152, 1);
output.WriteBool(UseCoalesceApi);
}
+ if (MedianLatencyCollectionIntervalMillis != 0) {
+ output.WriteRawTag(160, 1);
+ output.WriteInt32(MedianLatencyCollectionIntervalMillis);
+ }
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}
@@ -1456,6 +1480,9 @@ namespace Grpc.Testing {
if (UseCoalesceApi != false) {
size += 2 + 1;
}
+ if (MedianLatencyCollectionIntervalMillis != 0) {
+ size += 2 + pb::CodedOutputStream.ComputeInt32Size(MedianLatencyCollectionIntervalMillis);
+ }
if (_unknownFields != null) {
size += _unknownFields.CalculateSize();
}
@@ -1524,6 +1551,9 @@ namespace Grpc.Testing {
if (other.UseCoalesceApi != false) {
UseCoalesceApi = other.UseCoalesceApi;
}
+ if (other.MedianLatencyCollectionIntervalMillis != 0) {
+ MedianLatencyCollectionIntervalMillis = other.MedianLatencyCollectionIntervalMillis;
+ }
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}
@@ -1616,6 +1646,10 @@ namespace Grpc.Testing {
UseCoalesceApi = input.ReadBool();
break;
}
+ case 160: {
+ MedianLatencyCollectionIntervalMillis = input.ReadInt32();
+ break;
+ }
}
}
}
diff --git a/src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs
index 2d233fbdc0..7e77f8d114 100644
--- a/src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/EmptyServiceGrpc.cs
@@ -80,6 +80,14 @@ namespace Grpc.Testing {
return grpc::ServerServiceDefinition.CreateBuilder().Build();
}
+ /// <summary>Register service method implementations with a service binder. Useful when customizing the service binding logic.
+ /// Note: this method is part of an experimental API that can change or be removed without any prior notice.</summary>
+ /// <param name="serviceBinder">Service methods will be bound by calling <c>AddMethod</c> on this object.</param>
+ /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
+ public static void BindService(grpc::ServiceBinderBase serviceBinder, EmptyServiceBase serviceImpl)
+ {
+ }
+
}
}
#endregion
diff --git a/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs b/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs
index 9f16f41ac1..c66a9a9161 100644
--- a/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/MetricsGrpc.cs
@@ -193,6 +193,16 @@ namespace Grpc.Testing {
.AddMethod(__Method_GetGauge, serviceImpl.GetGauge).Build();
}
+ /// <summary>Register service method implementations with a service binder. Useful when customizing the service binding logic.
+ /// Note: this method is part of an experimental API that can change or be removed without any prior notice.</summary>
+ /// <param name="serviceBinder">Service methods will be bound by calling <c>AddMethod</c> on this object.</param>
+ /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
+ public static void BindService(grpc::ServiceBinderBase serviceBinder, MetricsServiceBase serviceImpl)
+ {
+ serviceBinder.AddMethod(__Method_GetAllGauges, serviceImpl.GetAllGauges);
+ serviceBinder.AddMethod(__Method_GetGauge, serviceImpl.GetGauge);
+ }
+
}
}
#endregion
diff --git a/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs
index 1da0548cb4..954c172272 100644
--- a/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/ReportQpsScenarioServiceGrpc.cs
@@ -143,6 +143,15 @@ namespace Grpc.Testing {
.AddMethod(__Method_ReportScenario, serviceImpl.ReportScenario).Build();
}
+ /// <summary>Register service method implementations with a service binder. Useful when customizing the service binding logic.
+ /// Note: this method is part of an experimental API that can change or be removed without any prior notice.</summary>
+ /// <param name="serviceBinder">Service methods will be bound by calling <c>AddMethod</c> on this object.</param>
+ /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
+ public static void BindService(grpc::ServiceBinderBase serviceBinder, ReportQpsScenarioServiceBase serviceImpl)
+ {
+ serviceBinder.AddMethod(__Method_ReportScenario, serviceImpl.ReportScenario);
+ }
+
}
}
#endregion
diff --git a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
index 2176916b43..d125fd5627 100644
--- a/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/TestGrpc.cs
@@ -539,6 +539,22 @@ namespace Grpc.Testing {
.AddMethod(__Method_UnimplementedCall, serviceImpl.UnimplementedCall).Build();
}
+ /// <summary>Register service method implementations with a service binder. Useful when customizing the service binding logic.
+ /// Note: this method is part of an experimental API that can change or be removed without any prior notice.</summary>
+ /// <param name="serviceBinder">Service methods will be bound by calling <c>AddMethod</c> on this object.</param>
+ /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
+ public static void BindService(grpc::ServiceBinderBase serviceBinder, TestServiceBase serviceImpl)
+ {
+ serviceBinder.AddMethod(__Method_EmptyCall, serviceImpl.EmptyCall);
+ serviceBinder.AddMethod(__Method_UnaryCall, serviceImpl.UnaryCall);
+ serviceBinder.AddMethod(__Method_CacheableUnaryCall, serviceImpl.CacheableUnaryCall);
+ serviceBinder.AddMethod(__Method_StreamingOutputCall, serviceImpl.StreamingOutputCall);
+ serviceBinder.AddMethod(__Method_StreamingInputCall, serviceImpl.StreamingInputCall);
+ serviceBinder.AddMethod(__Method_FullDuplexCall, serviceImpl.FullDuplexCall);
+ serviceBinder.AddMethod(__Method_HalfDuplexCall, serviceImpl.HalfDuplexCall);
+ serviceBinder.AddMethod(__Method_UnimplementedCall, serviceImpl.UnimplementedCall);
+ }
+
}
/// <summary>
/// A simple service NOT implemented at servers so clients can test for
@@ -661,6 +677,15 @@ namespace Grpc.Testing {
.AddMethod(__Method_UnimplementedCall, serviceImpl.UnimplementedCall).Build();
}
+ /// <summary>Register service method implementations with a service binder. Useful when customizing the service binding logic.
+ /// Note: this method is part of an experimental API that can change or be removed without any prior notice.</summary>
+ /// <param name="serviceBinder">Service methods will be bound by calling <c>AddMethod</c> on this object.</param>
+ /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
+ public static void BindService(grpc::ServiceBinderBase serviceBinder, UnimplementedServiceBase serviceImpl)
+ {
+ serviceBinder.AddMethod(__Method_UnimplementedCall, serviceImpl.UnimplementedCall);
+ }
+
}
/// <summary>
/// A service used to control reconnect server.
@@ -779,6 +804,16 @@ namespace Grpc.Testing {
.AddMethod(__Method_Stop, serviceImpl.Stop).Build();
}
+ /// <summary>Register service method implementations with a service binder. Useful when customizing the service binding logic.
+ /// Note: this method is part of an experimental API that can change or be removed without any prior notice.</summary>
+ /// <param name="serviceBinder">Service methods will be bound by calling <c>AddMethod</c> on this object.</param>
+ /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
+ public static void BindService(grpc::ServiceBinderBase serviceBinder, ReconnectServiceBase serviceImpl)
+ {
+ serviceBinder.AddMethod(__Method_Start, serviceImpl.Start);
+ serviceBinder.AddMethod(__Method_Stop, serviceImpl.Stop);
+ }
+
}
}
#endregion
diff --git a/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs b/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs
index b9e8f91231..5b22337d53 100644
--- a/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs
+++ b/src/csharp/Grpc.IntegrationTesting/WorkerServiceGrpc.cs
@@ -321,6 +321,18 @@ namespace Grpc.Testing {
.AddMethod(__Method_QuitWorker, serviceImpl.QuitWorker).Build();
}
+ /// <summary>Register service method implementations with a service binder. Useful when customizing the service binding logic.
+ /// Note: this method is part of an experimental API that can change or be removed without any prior notice.</summary>
+ /// <param name="serviceBinder">Service methods will be bound by calling <c>AddMethod</c> on this object.</param>
+ /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
+ public static void BindService(grpc::ServiceBinderBase serviceBinder, WorkerServiceBase serviceImpl)
+ {
+ serviceBinder.AddMethod(__Method_RunServer, serviceImpl.RunServer);
+ serviceBinder.AddMethod(__Method_RunClient, serviceImpl.RunClient);
+ serviceBinder.AddMethod(__Method_CoreCount, serviceImpl.CoreCount);
+ serviceBinder.AddMethod(__Method_QuitWorker, serviceImpl.QuitWorker);
+ }
+
}
}
#endregion
diff --git a/src/csharp/Grpc.Reflection/ReflectionGrpc.cs b/src/csharp/Grpc.Reflection/ReflectionGrpc.cs
index c00075b7c6..ed55c2f584 100644
--- a/src/csharp/Grpc.Reflection/ReflectionGrpc.cs
+++ b/src/csharp/Grpc.Reflection/ReflectionGrpc.cs
@@ -123,6 +123,15 @@ namespace Grpc.Reflection.V1Alpha {
.AddMethod(__Method_ServerReflectionInfo, serviceImpl.ServerReflectionInfo).Build();
}
+ /// <summary>Register service method implementations with a service binder. Useful when customizing the service binding logic.
+ /// Note: this method is part of an experimental API that can change or be removed without any prior notice.</summary>
+ /// <param name="serviceBinder">Service methods will be bound by calling <c>AddMethod</c> on this object.</param>
+ /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
+ public static void BindService(grpc::ServiceBinderBase serviceBinder, ServerReflectionBase serviceImpl)
+ {
+ serviceBinder.AddMethod(__Method_ServerReflectionInfo, serviceImpl.ServerReflectionInfo);
+ }
+
}
}
#endregion
diff --git a/src/csharp/build_packages_dotnetcli.bat b/src/csharp/build_packages_dotnetcli.bat
index 27688360e9..76d4f14390 100755
--- a/src/csharp/build_packages_dotnetcli.bat
+++ b/src/csharp/build_packages_dotnetcli.bat
@@ -13,7 +13,7 @@
@rem limitations under the License.
@rem Current package versions
-set VERSION=1.17.0-dev
+set VERSION=1.18.0-dev
@rem Adjust the location of nuget.exe
set NUGET=C:\nuget\nuget.exe
diff --git a/src/csharp/build_unitypackage.bat b/src/csharp/build_unitypackage.bat
index dd74de0491..3334d24c11 100644
--- a/src/csharp/build_unitypackage.bat
+++ b/src/csharp/build_unitypackage.bat
@@ -13,7 +13,7 @@
@rem limitations under the License.
@rem Current package versions
-set VERSION=1.17.0-dev
+set VERSION=1.18.0-dev
@rem Adjust the location of nuget.exe
set NUGET=C:\nuget\nuget.exe
diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec
index a95a120d21..55ca6048bc 100644
--- a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec
+++ b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec
@@ -42,7 +42,7 @@ Pod::Spec.new do |s|
# exclamation mark ensures that other "regular" pods will be able to find it as it'll be installed
# before them.
s.name = '!ProtoCompiler-gRPCPlugin'
- v = '1.17.0-dev'
+ v = '1.18.0-dev'
s.version = v
s.summary = 'The gRPC ProtoC plugin generates Objective-C files from .proto services.'
s.description = <<-DESC
diff --git a/src/objective-c/GRPCClient/private/version.h b/src/objective-c/GRPCClient/private/version.h
index d5463c0b4c..0be0e3c9a0 100644
--- a/src/objective-c/GRPCClient/private/version.h
+++ b/src/objective-c/GRPCClient/private/version.h
@@ -22,4 +22,4 @@
// instead. This file can be regenerated from the template by running
// `tools/buildgen/generate_projects.sh`.
-#define GRPC_OBJC_VERSION_STRING @"1.17.0-dev"
+#define GRPC_OBJC_VERSION_STRING @"1.18.0-dev"
diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h
index ca27c03b3c..f2fd692070 100644
--- a/src/objective-c/tests/version.h
+++ b/src/objective-c/tests/version.h
@@ -22,5 +22,5 @@
// instead. This file can be regenerated from the template by running
// `tools/buildgen/generate_projects.sh`.
-#define GRPC_OBJC_VERSION_STRING @"1.17.0-dev"
+#define GRPC_OBJC_VERSION_STRING @"1.18.0-dev"
#define GRPC_C_VERSION_STRING @"7.0.0-dev"
diff --git a/src/php/composer.json b/src/php/composer.json
index d54db91b5f..9c298c0e85 100644
--- a/src/php/composer.json
+++ b/src/php/composer.json
@@ -2,7 +2,7 @@
"name": "grpc/grpc-dev",
"description": "gRPC library for PHP - for Developement use only",
"license": "Apache-2.0",
- "version": "1.17.0",
+ "version": "1.18.0",
"require": {
"php": ">=5.5.0",
"google/protobuf": "^v3.3.0"
diff --git a/src/php/ext/grpc/channel.c b/src/php/ext/grpc/channel.c
index b17f3d9a61..c06bdea7fe 100644
--- a/src/php/ext/grpc/channel.c
+++ b/src/php/ext/grpc/channel.c
@@ -393,6 +393,8 @@ PHP_METHOD(Channel, __construct) {
channel->wrapper->target = strdup(target);
channel->wrapper->args_hashstr = strdup(sha1str);
channel->wrapper->creds_hashstr = NULL;
+ channel->wrapper->creds = creds;
+ channel->wrapper->args = args;
if (creds != NULL && creds->hashstr != NULL) {
php_grpc_int creds_hashstr_len = strlen(creds->hashstr);
char *channel_creds_hashstr = malloc(creds_hashstr_len + 1);
diff --git a/src/php/ext/grpc/channel.h b/src/php/ext/grpc/channel.h
index 27752c9a3f..ce17c4a58a 100644
--- a/src/php/ext/grpc/channel.h
+++ b/src/php/ext/grpc/channel.h
@@ -19,6 +19,7 @@
#ifndef NET_GRPC_PHP_GRPC_CHANNEL_H_
#define NET_GRPC_PHP_GRPC_CHANNEL_H_
+#include "channel_credentials.h"
#include "php_grpc.h"
/* Class entry for the PHP Channel class */
@@ -32,6 +33,8 @@ typedef struct _grpc_channel_wrapper {
char *creds_hashstr;
size_t ref_count;
gpr_mu mu;
+ grpc_channel_args args;
+ wrapped_grpc_channel_credentials *creds;
} grpc_channel_wrapper;
/* Wrapper struct for grpc_channel that can be associated with a PHP object */
diff --git a/src/php/ext/grpc/config.m4 b/src/php/ext/grpc/config.m4
index fa54ebd920..9ec2c7cf04 100755
--- a/src/php/ext/grpc/config.m4
+++ b/src/php/ext/grpc/config.m4
@@ -103,7 +103,7 @@ if test "$PHP_COVERAGE" = "yes"; then
AC_MSG_ERROR([ccache must be disabled when --enable-coverage option is used. You can disable ccache by setting environment variable CCACHE_DISABLE=1.])
fi
- lcov_version_list="1.5 1.6 1.7 1.9 1.10 1.11"
+ lcov_version_list="1.5 1.6 1.7 1.9 1.10 1.11 1.12 1.13"
AC_CHECK_PROG(LCOV, lcov, lcov)
AC_CHECK_PROG(GENHTML, genhtml, genhtml)
diff --git a/src/php/ext/grpc/php_grpc.c b/src/php/ext/grpc/php_grpc.c
index fabd98975d..111c6f4867 100644
--- a/src/php/ext/grpc/php_grpc.c
+++ b/src/php/ext/grpc/php_grpc.c
@@ -26,6 +26,8 @@
#include "call_credentials.h"
#include "server_credentials.h"
#include "completion_queue.h"
+#include <ext/spl/spl_exceptions.h>
+#include <zend_exceptions.h>
ZEND_DECLARE_MODULE_GLOBALS(grpc)
static PHP_GINIT_FUNCTION(grpc);
@@ -86,6 +88,125 @@ ZEND_GET_MODULE(grpc)
}
*/
/* }}} */
+void create_new_channel(
+ wrapped_grpc_channel *channel,
+ char *target,
+ grpc_channel_args args,
+ wrapped_grpc_channel_credentials *creds) {
+ if (creds == NULL) {
+ channel->wrapper->wrapped = grpc_insecure_channel_create(target, &args,
+ NULL);
+ } else {
+ channel->wrapper->wrapped =
+ grpc_secure_channel_create(creds->wrapped, target, &args, NULL);
+ }
+}
+
+void acquire_persistent_locks() {
+ zval *data;
+ PHP_GRPC_HASH_FOREACH_VAL_START(&grpc_persistent_list, data)
+ php_grpc_zend_resource *rsrc =
+ (php_grpc_zend_resource*) PHP_GRPC_HASH_VALPTR_TO_VAL(data)
+ if (rsrc == NULL) {
+ break;
+ }
+ channel_persistent_le_t* le = rsrc->ptr;
+
+ gpr_mu_lock(&le->channel->mu);
+ PHP_GRPC_HASH_FOREACH_END()
+}
+
+void release_persistent_locks() {
+ zval *data;
+ PHP_GRPC_HASH_FOREACH_VAL_START(&grpc_persistent_list, data)
+ php_grpc_zend_resource *rsrc =
+ (php_grpc_zend_resource*) PHP_GRPC_HASH_VALPTR_TO_VAL(data)
+ if (rsrc == NULL) {
+ break;
+ }
+ channel_persistent_le_t* le = rsrc->ptr;
+
+ gpr_mu_unlock(&le->channel->mu);
+ PHP_GRPC_HASH_FOREACH_END()
+}
+
+void destroy_grpc_channels() {
+ zval *data;
+ PHP_GRPC_HASH_FOREACH_VAL_START(&grpc_persistent_list, data)
+ php_grpc_zend_resource *rsrc =
+ (php_grpc_zend_resource*) PHP_GRPC_HASH_VALPTR_TO_VAL(data)
+ if (rsrc == NULL) {
+ break;
+ }
+ channel_persistent_le_t* le = rsrc->ptr;
+
+ wrapped_grpc_channel wrapped_channel;
+ wrapped_channel.wrapper = le->channel;
+ grpc_channel_wrapper *channel = wrapped_channel.wrapper;
+ grpc_channel_destroy(channel->wrapped);
+ PHP_GRPC_HASH_FOREACH_END()
+}
+
+void restart_channels() {
+ zval *data;
+ PHP_GRPC_HASH_FOREACH_VAL_START(&grpc_persistent_list, data)
+ php_grpc_zend_resource *rsrc =
+ (php_grpc_zend_resource*) PHP_GRPC_HASH_VALPTR_TO_VAL(data)
+ if (rsrc == NULL) {
+ break;
+ }
+ channel_persistent_le_t* le = rsrc->ptr;
+
+ wrapped_grpc_channel wrapped_channel;
+ wrapped_channel.wrapper = le->channel;
+ grpc_channel_wrapper *channel = wrapped_channel.wrapper;
+ create_new_channel(&wrapped_channel, channel->target, channel->args,
+ channel->creds);
+ gpr_mu_unlock(&channel->mu);
+ PHP_GRPC_HASH_FOREACH_END()
+}
+
+void prefork() {
+ acquire_persistent_locks();
+}
+
+void postfork_child() {
+ TSRMLS_FETCH();
+
+ // loop through persistant list and destroy all underlying grpc_channel objs
+ destroy_grpc_channels();
+
+ // clear completion queue
+ grpc_php_shutdown_completion_queue(TSRMLS_C);
+
+ // clean-up grpc_core
+ grpc_shutdown();
+ if (grpc_is_initialized() > 0) {
+ zend_throw_exception(spl_ce_UnexpectedValueException,
+ "Oops, failed to shutdown gRPC Core after fork()",
+ 1 TSRMLS_CC);
+ }
+
+ // restart grpc_core
+ grpc_init();
+ grpc_php_init_completion_queue(TSRMLS_C);
+
+ // re-create grpc_channel and point wrapped to it
+ // unlock wrapped grpc channel mutex
+ restart_channels();
+}
+
+void postfork_parent() {
+ release_persistent_locks();
+}
+
+void register_fork_handlers() {
+ if (getenv("GRPC_ENABLE_FORK_SUPPORT")) {
+#ifdef GRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK
+ pthread_atfork(&prefork, &postfork_parent, &postfork_child);
+#endif // GRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK
+ }
+}
/* {{{ PHP_MINIT_FUNCTION
*/
@@ -265,6 +386,7 @@ PHP_MINFO_FUNCTION(grpc) {
PHP_RINIT_FUNCTION(grpc) {
if (!GRPC_G(initialized)) {
grpc_init();
+ register_fork_handlers();
grpc_php_init_completion_queue(TSRMLS_C);
GRPC_G(initialized) = 1;
}
diff --git a/src/php/ext/grpc/version.h b/src/php/ext/grpc/version.h
index 70f8bbbf40..1ddf90a667 100644
--- a/src/php/ext/grpc/version.h
+++ b/src/php/ext/grpc/version.h
@@ -20,6 +20,6 @@
#ifndef VERSION_H
#define VERSION_H
-#define PHP_GRPC_VERSION "1.17.0dev"
+#define PHP_GRPC_VERSION "1.18.0dev"
#endif /* VERSION_H */
diff --git a/src/proto/grpc/channelz/BUILD b/src/proto/grpc/channelz/BUILD
index bdb03d5e2d..b6b485e3e8 100644
--- a/src/proto/grpc/channelz/BUILD
+++ b/src/proto/grpc/channelz/BUILD
@@ -24,3 +24,10 @@ grpc_proto_library(
has_services = True,
well_known_protos = True,
)
+
+filegroup(
+ name = "channelz_proto_file",
+ srcs = [
+ "channelz.proto",
+ ],
+)
diff --git a/src/proto/grpc/health/v1/BUILD b/src/proto/grpc/health/v1/BUILD
index 97642985c9..38a7d992e0 100644
--- a/src/proto/grpc/health/v1/BUILD
+++ b/src/proto/grpc/health/v1/BUILD
@@ -29,4 +29,3 @@ filegroup(
"health.proto",
],
)
-
diff --git a/src/proto/grpc/testing/compiler_test.proto b/src/proto/grpc/testing/compiler_test.proto
index db5ca48331..9fa5590a59 100644
--- a/src/proto/grpc/testing/compiler_test.proto
+++ b/src/proto/grpc/testing/compiler_test.proto
@@ -20,6 +20,9 @@
syntax = "proto3";
// Ignored detached comment
+// The comments in this file are not meant for readability
+// but rather to test to make sure that the code generator
+// properly preserves comments on files, services, and RPCs
// Ignored package leading comment
package grpc.testing;
diff --git a/src/python/grpcio/grpc/BUILD.bazel b/src/python/grpcio/grpc/BUILD.bazel
index 2e6839ef2d..6958ccdfb6 100644
--- a/src/python/grpcio/grpc/BUILD.bazel
+++ b/src/python/grpcio/grpc/BUILD.bazel
@@ -13,7 +13,6 @@ py_library(
":interceptor",
":server",
"//src/python/grpcio/grpc/_cython:cygrpc",
- "//src/python/grpcio/grpc/beta",
"//src/python/grpcio/grpc/experimental",
"//src/python/grpcio/grpc/framework",
requirement('enum34'),
diff --git a/src/python/grpcio/grpc/__init__.py b/src/python/grpcio/grpc/__init__.py
index df98dd10ad..6022fc3ef2 100644
--- a/src/python/grpcio/grpc/__init__.py
+++ b/src/python/grpcio/grpc/__init__.py
@@ -15,12 +15,14 @@
import abc
import enum
+import logging
import sys
-
import six
from grpc._cython import cygrpc as _cygrpc
+logging.getLogger(__name__).addHandler(logging.NullHandler())
+
############################## Future Interface ###############################
@@ -387,7 +389,8 @@ class ClientCallDetails(six.with_metaclass(abc.ABCMeta)):
metadata: Optional :term:`metadata` to be transmitted to
the service-side of the RPC.
credentials: An optional CallCredentials for the RPC.
- wait_for_ready: An optional flag to enable wait for ready mechanism.
+ wait_for_ready: This is an EXPERIMENTAL argument. An optional flag t
+ enable wait for ready mechanism.
"""
@@ -654,8 +657,8 @@ class UnaryUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)):
metadata: Optional :term:`metadata` to be transmitted to the
service-side of the RPC.
credentials: An optional CallCredentials for the RPC.
- wait_for_ready: An optional flag to enable wait for ready
- mechanism
+ wait_for_ready: This is an EXPERIMENTAL argument. An optional
+ flag to enable wait for ready mechanism
Returns:
The response value for the RPC.
@@ -683,8 +686,8 @@ class UnaryUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)):
metadata: Optional :term:`metadata` to be transmitted to the
service-side of the RPC.
credentials: An optional CallCredentials for the RPC.
- wait_for_ready: An optional flag to enable wait for ready
- mechanism
+ wait_for_ready: This is an EXPERIMENTAL argument. An optional
+ flag to enable wait for ready mechanism
Returns:
The response value for the RPC and a Call value for the RPC.
@@ -712,8 +715,8 @@ class UnaryUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)):
metadata: Optional :term:`metadata` to be transmitted to the
service-side of the RPC.
credentials: An optional CallCredentials for the RPC.
- wait_for_ready: An optional flag to enable wait for ready
- mechanism
+ wait_for_ready: This is an EXPERIMENTAL argument. An optional
+ flag to enable wait for ready mechanism
Returns:
An object that is both a Call for the RPC and a Future.
@@ -744,8 +747,8 @@ class UnaryStreamMultiCallable(six.with_metaclass(abc.ABCMeta)):
metadata: An optional :term:`metadata` to be transmitted to the
service-side of the RPC.
credentials: An optional CallCredentials for the RPC.
- wait_for_ready: An optional flag to enable wait for ready
- mechanism
+ wait_for_ready: This is an EXPERIMENTAL argument. An optional
+ flag to enable wait for ready mechanism
Returns:
An object that is both a Call for the RPC and an iterator of
@@ -776,8 +779,8 @@ class StreamUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)):
metadata: Optional :term:`metadata` to be transmitted to the
service-side of the RPC.
credentials: An optional CallCredentials for the RPC.
- wait_for_ready: An optional flag to enable wait for ready
- mechanism
+ wait_for_ready: This is an EXPERIMENTAL argument. An optional
+ flag to enable wait for ready mechanism
Returns:
The response value for the RPC.
@@ -806,8 +809,8 @@ class StreamUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)):
metadata: Optional :term:`metadata` to be transmitted to the
service-side of the RPC.
credentials: An optional CallCredentials for the RPC.
- wait_for_ready: An optional flag to enable wait for ready
- mechanism
+ wait_for_ready: This is an EXPERIMENTAL argument. An optional
+ flag to enable wait for ready mechanism
Returns:
The response value for the RPC and a Call object for the RPC.
@@ -835,8 +838,8 @@ class StreamUnaryMultiCallable(six.with_metaclass(abc.ABCMeta)):
metadata: Optional :term:`metadata` to be transmitted to the
service-side of the RPC.
credentials: An optional CallCredentials for the RPC.
- wait_for_ready: An optional flag to enable wait for ready
- mechanism
+ wait_for_ready: This is an EXPERIMENTAL argument. An optional
+ flag to enable wait for ready mechanism
Returns:
An object that is both a Call for the RPC and a Future.
@@ -867,8 +870,8 @@ class StreamStreamMultiCallable(six.with_metaclass(abc.ABCMeta)):
metadata: Optional :term:`metadata` to be transmitted to the
service-side of the RPC.
credentials: An optional CallCredentials for the RPC.
- wait_for_ready: An optional flag to enable wait for ready
- mechanism
+ wait_for_ready: This is an EXPERIMENTAL argument. An optional
+ flag to enable wait for ready mechanism
Returns:
An object that is both a Call for the RPC and an iterator of
@@ -1720,7 +1723,7 @@ def server(thread_pool,
handlers. The interceptors are given control in the order they are
specified. This is an EXPERIMENTAL API.
options: An optional list of key-value pairs (channel args in gRPC runtime)
- to configure the channel.
+ to configure the channel.
maximum_concurrent_rpcs: The maximum number of concurrent RPCs this server
will service before returning RESOURCE_EXHAUSTED status, or None to
indicate no limit.
diff --git a/src/python/grpcio/grpc/_channel.py b/src/python/grpcio/grpc/_channel.py
index 3ff7658748..ab154d8512 100644
--- a/src/python/grpcio/grpc/_channel.py
+++ b/src/python/grpcio/grpc/_channel.py
@@ -25,7 +25,6 @@ from grpc._cython import cygrpc
from grpc.framework.foundation import callable_util
_LOGGER = logging.getLogger(__name__)
-_LOGGER.addHandler(logging.NullHandler())
_USER_AGENT = 'grpc-python/{}'.format(_grpcio_metadata.__version__)
diff --git a/src/python/grpcio/grpc/_common.py b/src/python/grpcio/grpc/_common.py
index 42f3a4e614..f69127e38e 100644
--- a/src/python/grpcio/grpc/_common.py
+++ b/src/python/grpcio/grpc/_common.py
@@ -21,7 +21,6 @@ import grpc
from grpc._cython import cygrpc
_LOGGER = logging.getLogger(__name__)
-_LOGGER.addHandler(logging.NullHandler())
CYGRPC_CONNECTIVITY_STATE_TO_CHANNEL_CONNECTIVITY = {
cygrpc.ConnectivityState.idle:
diff --git a/src/python/grpcio/grpc/_cython/BUILD.bazel b/src/python/grpcio/grpc/_cython/BUILD.bazel
index cfd3a51d9b..e318298d0a 100644
--- a/src/python/grpcio/grpc/_cython/BUILD.bazel
+++ b/src/python/grpcio/grpc/_cython/BUILD.bazel
@@ -12,6 +12,7 @@ pyx_library(
"_cygrpc/grpc_string.pyx.pxi",
"_cygrpc/arguments.pyx.pxi",
"_cygrpc/call.pyx.pxi",
+ "_cygrpc/channelz.pyx.pxi",
"_cygrpc/channel.pyx.pxi",
"_cygrpc/credentials.pyx.pxi",
"_cygrpc/completion_queue.pyx.pxi",
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channelz.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/channelz.pyx.pxi
new file mode 100644
index 0000000000..113f7976dd
--- /dev/null
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/channelz.pyx.pxi
@@ -0,0 +1,69 @@
+# Copyright 2018 The gRPC Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+def channelz_get_top_channels(start_channel_id):
+ cdef char *c_returned_str = grpc_channelz_get_top_channels(
+ start_channel_id,
+ )
+ if c_returned_str == NULL:
+ raise ValueError('Failed to get top channels, please ensure your' \
+ ' start_channel_id==%s is valid' % start_channel_id)
+ return c_returned_str
+
+def channelz_get_servers(start_server_id):
+ cdef char *c_returned_str = grpc_channelz_get_servers(start_server_id)
+ if c_returned_str == NULL:
+ raise ValueError('Failed to get servers, please ensure your' \
+ ' start_server_id==%s is valid' % start_server_id)
+ return c_returned_str
+
+def channelz_get_server(server_id):
+ cdef char *c_returned_str = grpc_channelz_get_server(server_id)
+ if c_returned_str == NULL:
+ raise ValueError('Failed to get the server, please ensure your' \
+ ' server_id==%s is valid' % server_id)
+ return c_returned_str
+
+def channelz_get_server_sockets(server_id, start_socket_id):
+ cdef char *c_returned_str = grpc_channelz_get_server_sockets(
+ server_id,
+ start_socket_id,
+ )
+ if c_returned_str == NULL:
+ raise ValueError('Failed to get server sockets, please ensure your' \
+ ' server_id==%s and start_socket_id==%s is valid' %
+ (server_id, start_socket_id))
+ return c_returned_str
+
+def channelz_get_channel(channel_id):
+ cdef char *c_returned_str = grpc_channelz_get_channel(channel_id)
+ if c_returned_str == NULL:
+ raise ValueError('Failed to get the channel, please ensure your' \
+ ' channel_id==%s is valid' % (channel_id))
+ return c_returned_str
+
+def channelz_get_subchannel(subchannel_id):
+ cdef char *c_returned_str = grpc_channelz_get_subchannel(subchannel_id)
+ if c_returned_str == NULL:
+ raise ValueError('Failed to get the subchannel, please ensure your' \
+ ' subchannel_id==%s is valid' % (subchannel_id))
+ return c_returned_str
+
+def channelz_get_socket(socket_id):
+ cdef char *c_returned_str = grpc_channelz_get_socket(socket_id)
+ if c_returned_str == NULL:
+ raise ValueError('Failed to get the socket, please ensure your' \
+ ' socket_id==%s is valid' % (socket_id))
+ return c_returned_str
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi
index 63048e8da0..ff523fb256 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi
@@ -129,6 +129,8 @@ cdef class SSLSessionCacheLRU:
cdef class SSLChannelCredentials(ChannelCredentials):
def __cinit__(self, pem_root_certificates, private_key, certificate_chain):
+ if pem_root_certificates is not None and not isinstance(pem_root_certificates, bytes):
+ raise TypeError('expected certificate to be bytes, got %s' % (type(pem_root_certificates)))
self._pem_root_certificates = pem_root_certificates
self._private_key = private_key
self._certificate_chain = certificate_chain
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
index 23428f0b0c..5bbc10af25 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi
@@ -13,6 +13,7 @@
# limitations under the License.
cimport libc.time
+from libc.stdint cimport intptr_t
# Typedef types with approximately the same semantics to provide their names to
@@ -121,7 +122,6 @@ cdef extern from "grpc/grpc.h":
GRPC_STATUS_DATA_LOSS
GRPC_STATUS__DO_NOT_USE
- const char *GRPC_ARG_PRIMARY_USER_AGENT_STRING
const char *GRPC_ARG_ENABLE_CENSUS
const char *GRPC_ARG_MAX_CONCURRENT_STREAMS
const char *GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH
@@ -190,12 +190,6 @@ cdef extern from "grpc/grpc.h":
size_t arguments_length "num_args"
grpc_arg *arguments "args"
- ctypedef enum grpc_compression_level:
- GRPC_COMPRESS_LEVEL_NONE
- GRPC_COMPRESS_LEVEL_LOW
- GRPC_COMPRESS_LEVEL_MED
- GRPC_COMPRESS_LEVEL_HIGH
-
ctypedef enum grpc_stream_compression_level:
GRPC_STREAM_COMPRESS_LEVEL_NONE
GRPC_STREAM_COMPRESS_LEVEL_LOW
@@ -391,6 +385,15 @@ cdef extern from "grpc/grpc.h":
void grpc_server_cancel_all_calls(grpc_server *server) nogil
void grpc_server_destroy(grpc_server *server) nogil
+ char* grpc_channelz_get_top_channels(intptr_t start_channel_id)
+ char* grpc_channelz_get_servers(intptr_t start_server_id)
+ char* grpc_channelz_get_server(intptr_t server_id)
+ char* grpc_channelz_get_server_sockets(intptr_t server_id,
+ intptr_t start_socket_id)
+ char* grpc_channelz_get_channel(intptr_t channel_id)
+ char* grpc_channelz_get_subchannel(intptr_t subchannel_id)
+ char* grpc_channelz_get_socket(intptr_t socket_id)
+
cdef extern from "grpc/grpc_security.h":
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_string.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_string.pyx.pxi
index fa356d913e..00a1b23a67 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc_string.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc_string.pyx.pxi
@@ -15,7 +15,6 @@
import logging
_LOGGER = logging.getLogger(__name__)
-_LOGGER.addHandler(logging.NullHandler())
# This function will ascii encode unicode string inputs if neccesary.
# In Python3, unicode strings are the default str type.
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi
index f9d1e863ca..ce701724fd 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi
@@ -19,7 +19,6 @@ import time
import grpc
_LOGGER = logging.getLogger(__name__)
-_LOGGER.addHandler(logging.NullHandler())
cdef class Server:
diff --git a/src/python/grpcio/grpc/_cython/cygrpc.pyx b/src/python/grpcio/grpc/_cython/cygrpc.pyx
index ae5c07bfc8..9ab919375c 100644
--- a/src/python/grpcio/grpc/_cython/cygrpc.pyx
+++ b/src/python/grpcio/grpc/_cython/cygrpc.pyx
@@ -35,6 +35,7 @@ include "_cygrpc/server.pyx.pxi"
include "_cygrpc/tag.pyx.pxi"
include "_cygrpc/time.pyx.pxi"
include "_cygrpc/_hooks.pyx.pxi"
+include "_cygrpc/channelz.pyx.pxi"
include "_cygrpc/grpc_gevent.pyx.pxi"
diff --git a/src/python/grpcio/grpc/_grpcio_metadata.py b/src/python/grpcio/grpc/_grpcio_metadata.py
index 42b3a1ad49..7a9f173947 100644
--- a/src/python/grpcio/grpc/_grpcio_metadata.py
+++ b/src/python/grpcio/grpc/_grpcio_metadata.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc/_grpcio_metadata.py.template`!!!
-__version__ = """1.17.0.dev0"""
+__version__ = """1.18.0.dev0"""
diff --git a/src/python/grpcio/grpc/_interceptor.py b/src/python/grpcio/grpc/_interceptor.py
index 4345114026..2a8ddd8ce4 100644
--- a/src/python/grpcio/grpc/_interceptor.py
+++ b/src/python/grpcio/grpc/_interceptor.py
@@ -232,8 +232,8 @@ class _UnaryUnaryMultiCallable(grpc.UnaryUnaryMultiCallable):
credentials=new_credentials,
wait_for_ready=new_wait_for_ready)
return _UnaryOutcome(response, call)
- except grpc.RpcError:
- raise
+ except grpc.RpcError as rpc_error:
+ return rpc_error
except Exception as exception: # pylint:disable=broad-except
return _FailureOutcome(exception, sys.exc_info()[2])
@@ -354,8 +354,8 @@ class _StreamUnaryMultiCallable(grpc.StreamUnaryMultiCallable):
credentials=new_credentials,
wait_for_ready=new_wait_for_ready)
return _UnaryOutcome(response, call)
- except grpc.RpcError:
- raise
+ except grpc.RpcError as rpc_error:
+ return rpc_error
except Exception as exception: # pylint:disable=broad-except
return _FailureOutcome(exception, sys.exc_info()[2])
diff --git a/src/python/grpcio/grpc/_plugin_wrapping.py b/src/python/grpcio/grpc/_plugin_wrapping.py
index 53af2ff913..916ee080b6 100644
--- a/src/python/grpcio/grpc/_plugin_wrapping.py
+++ b/src/python/grpcio/grpc/_plugin_wrapping.py
@@ -21,7 +21,6 @@ from grpc import _common
from grpc._cython import cygrpc
_LOGGER = logging.getLogger(__name__)
-_LOGGER.addHandler(logging.NullHandler())
class _AuthMetadataContext(
diff --git a/src/python/grpcio/grpc/beta/BUILD.bazel b/src/python/grpcio/grpc/beta/BUILD.bazel
deleted file mode 100644
index 731be5cb25..0000000000
--- a/src/python/grpcio/grpc/beta/BUILD.bazel
+++ /dev/null
@@ -1,58 +0,0 @@
-load("@grpc_python_dependencies//:requirements.bzl", "requirement")
-package(default_visibility = ["//visibility:public"])
-
-py_library(
- name = "beta",
- srcs = ["__init__.py",],
- deps = [
- ":client_adaptations",
- ":metadata",
- ":server_adaptations",
- ":implementations",
- ":interfaces",
- ":utilities",
- ],
-)
-
-py_library(
- name = "client_adaptations",
- srcs = ["_client_adaptations.py"],
- imports=["../../",]
-)
-
-py_library(
- name = "metadata",
- srcs = ["_metadata.py"],
-)
-
-py_library(
- name = "server_adaptations",
- srcs = ["_server_adaptations.py"],
- imports=["../../",],
-)
-
-py_library(
- name = "implementations",
- srcs = ["implementations.py"],
- imports=["../../",],
-)
-
-py_library(
- name = "interfaces",
- srcs = ["interfaces.py"],
- deps = [
- requirement("six"),
- ],
- imports=["../../",],
-)
-
-py_library(
- name = "utilities",
- srcs = ["utilities.py"],
- deps = [
- ":implementations",
- ":interfaces",
- "//src/python/grpcio/grpc/framework/foundation",
- ],
-)
-
diff --git a/src/python/grpcio/grpc/framework/foundation/callable_util.py b/src/python/grpcio/grpc/framework/foundation/callable_util.py
index 36066e19df..24daf3406f 100644
--- a/src/python/grpcio/grpc/framework/foundation/callable_util.py
+++ b/src/python/grpcio/grpc/framework/foundation/callable_util.py
@@ -22,7 +22,6 @@ import logging
import six
_LOGGER = logging.getLogger(__name__)
-_LOGGER.addHandler(logging.NullHandler())
class Outcome(six.with_metaclass(abc.ABCMeta)):
diff --git a/src/python/grpcio/grpc/framework/foundation/logging_pool.py b/src/python/grpcio/grpc/framework/foundation/logging_pool.py
index dfb8dbdc30..216e3990db 100644
--- a/src/python/grpcio/grpc/framework/foundation/logging_pool.py
+++ b/src/python/grpcio/grpc/framework/foundation/logging_pool.py
@@ -18,7 +18,6 @@ import logging
from concurrent import futures
_LOGGER = logging.getLogger(__name__)
-_LOGGER.addHandler(logging.NullHandler())
def _wrap(behavior):
diff --git a/src/python/grpcio/grpc/framework/foundation/stream_util.py b/src/python/grpcio/grpc/framework/foundation/stream_util.py
index e03130cced..1faaf29bd7 100644
--- a/src/python/grpcio/grpc/framework/foundation/stream_util.py
+++ b/src/python/grpcio/grpc/framework/foundation/stream_util.py
@@ -20,7 +20,6 @@ from grpc.framework.foundation import stream
_NO_VALUE = object()
_LOGGER = logging.getLogger(__name__)
-_LOGGER.addHandler(logging.NullHandler())
class TransformingConsumer(stream.Consumer):
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index 42a4a7aa04..ce65c594fe 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -215,6 +215,7 @@ CORE_SOURCE_FILES = [
'src/core/ext/transport/chttp2/transport/bin_encoder.cc',
'src/core/ext/transport/chttp2/transport/chttp2_plugin.cc',
'src/core/ext/transport/chttp2/transport/chttp2_transport.cc',
+ 'src/core/ext/transport/chttp2/transport/context_list.cc',
'src/core/ext/transport/chttp2/transport/flow_control.cc',
'src/core/ext/transport/chttp2/transport/frame_data.cc',
'src/core/ext/transport/chttp2/transport/frame_goaway.cc',
@@ -323,18 +324,17 @@ CORE_SOURCE_FILES = [
'src/core/ext/filters/client_channel/lb_policy.cc',
'src/core/ext/filters/client_channel/lb_policy_factory.cc',
'src/core/ext/filters/client_channel/lb_policy_registry.cc',
- 'src/core/ext/filters/client_channel/method_params.cc',
'src/core/ext/filters/client_channel/parse_address.cc',
'src/core/ext/filters/client_channel/proxy_mapper.cc',
'src/core/ext/filters/client_channel/proxy_mapper_registry.cc',
'src/core/ext/filters/client_channel/resolver.cc',
'src/core/ext/filters/client_channel/resolver_registry.cc',
+ 'src/core/ext/filters/client_channel/resolver_result_parsing.cc',
'src/core/ext/filters/client_channel/retry_throttle.cc',
'src/core/ext/filters/client_channel/subchannel.cc',
'src/core/ext/filters/client_channel/subchannel_index.cc',
'src/core/ext/filters/deadline/deadline_filter.cc',
'src/core/ext/filters/client_channel/health/health.pb.c',
- 'src/core/tsi/alts_transport_security.cc',
'src/core/tsi/fake_transport_security.cc',
'src/core/tsi/local_transport_security.cc',
'src/core/tsi/ssl/session_cache/ssl_session_boringssl.cc',
diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py
index 71113e68d9..2e91818d2c 100644
--- a/src/python/grpcio/grpc_version.py
+++ b/src/python/grpcio/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio/grpc_version.py.template`!!!
-VERSION = '1.17.0.dev0'
+VERSION = '1.18.0.dev0'
diff --git a/src/python/grpcio_channelz/.gitignore b/src/python/grpcio_channelz/.gitignore
new file mode 100644
index 0000000000..0c5da6b5af
--- /dev/null
+++ b/src/python/grpcio_channelz/.gitignore
@@ -0,0 +1,6 @@
+*.proto
+*_pb2.py
+*_pb2_grpc.py
+build/
+grpcio_channelz.egg-info/
+dist/
diff --git a/src/python/grpcio_channelz/MANIFEST.in b/src/python/grpcio_channelz/MANIFEST.in
new file mode 100644
index 0000000000..5597f375ba
--- /dev/null
+++ b/src/python/grpcio_channelz/MANIFEST.in
@@ -0,0 +1,3 @@
+include grpc_version.py
+recursive-include grpc_channelz *.py
+global-exclude *.pyc
diff --git a/src/python/grpcio_channelz/README.rst b/src/python/grpcio_channelz/README.rst
new file mode 100644
index 0000000000..efeaa56064
--- /dev/null
+++ b/src/python/grpcio_channelz/README.rst
@@ -0,0 +1,9 @@
+gRPC Python Channelz package
+==============================
+
+Channelz is a live debug tool in gRPC Python.
+
+Dependencies
+------------
+
+Depends on the `grpcio` package, available from PyPI via `pip install grpcio`.
diff --git a/src/python/grpcio_channelz/channelz_commands.py b/src/python/grpcio_channelz/channelz_commands.py
new file mode 100644
index 0000000000..e9ad355034
--- /dev/null
+++ b/src/python/grpcio_channelz/channelz_commands.py
@@ -0,0 +1,63 @@
+# Copyright 2018 The gRPC Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""Provides distutils command classes for the GRPC Python setup process."""
+
+import os
+import shutil
+
+import setuptools
+
+ROOT_DIR = os.path.abspath(os.path.dirname(os.path.abspath(__file__)))
+CHANNELZ_PROTO = os.path.join(ROOT_DIR,
+ '../../proto/grpc/channelz/channelz.proto')
+
+
+class CopyProtoModules(setuptools.Command):
+ """Command to copy proto modules from grpc/src/proto."""
+
+ description = ''
+ user_options = []
+
+ def initialize_options(self):
+ pass
+
+ def finalize_options(self):
+ pass
+
+ def run(self):
+ if os.path.isfile(CHANNELZ_PROTO):
+ shutil.copyfile(CHANNELZ_PROTO,
+ os.path.join(ROOT_DIR,
+ 'grpc_channelz/v1/channelz.proto'))
+
+
+class BuildPackageProtos(setuptools.Command):
+ """Command to generate project *_pb2.py modules from proto files."""
+
+ description = 'build grpc protobuf modules'
+ user_options = []
+
+ def initialize_options(self):
+ pass
+
+ def finalize_options(self):
+ pass
+
+ def run(self):
+ # due to limitations of the proto generator, we require that only *one*
+ # directory is provided as an 'include' directory. We assume it's the '' key
+ # to `self.distribution.package_dir` (and get a key error if it's not
+ # there).
+ from grpc_tools import command
+ command.build_package_protos(self.distribution.package_dir[''])
diff --git a/src/python/grpcio_channelz/grpc_channelz/__init__.py b/src/python/grpcio_channelz/grpc_channelz/__init__.py
new file mode 100644
index 0000000000..38fdfc9c5c
--- /dev/null
+++ b/src/python/grpcio_channelz/grpc_channelz/__init__.py
@@ -0,0 +1,13 @@
+# Copyright 2018 The gRPC Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
diff --git a/src/python/grpcio_channelz/grpc_channelz/v1/BUILD.bazel b/src/python/grpcio_channelz/grpc_channelz/v1/BUILD.bazel
new file mode 100644
index 0000000000..aae8cedb76
--- /dev/null
+++ b/src/python/grpcio_channelz/grpc_channelz/v1/BUILD.bazel
@@ -0,0 +1,38 @@
+load("@grpc_python_dependencies//:requirements.bzl", "requirement")
+load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library")
+
+package(default_visibility = ["//visibility:public"])
+
+genrule(
+ name = "mv_channelz_proto",
+ srcs = [
+ "//src/proto/grpc/channelz:channelz_proto_file",
+ ],
+ outs = ["channelz.proto",],
+ cmd = "cp $< $@",
+)
+
+py_proto_library(
+ name = "py_channelz_proto",
+ protos = ["mv_channelz_proto",],
+ imports = [
+ "external/com_google_protobuf/src/",
+ ],
+ inputs = [
+ "@com_google_protobuf//:well_known_protos",
+ ],
+ with_grpc = True,
+ deps = [
+ requirement('protobuf'),
+ ],
+)
+
+py_library(
+ name = "grpc_channelz",
+ srcs = ["channelz.py",],
+ deps = [
+ ":py_channelz_proto",
+ "//src/python/grpcio/grpc:grpcio",
+ ],
+ imports=["../../",],
+)
diff --git a/src/python/grpcio_channelz/grpc_channelz/v1/__init__.py b/src/python/grpcio_channelz/grpc_channelz/v1/__init__.py
new file mode 100644
index 0000000000..38fdfc9c5c
--- /dev/null
+++ b/src/python/grpcio_channelz/grpc_channelz/v1/__init__.py
@@ -0,0 +1,13 @@
+# Copyright 2018 The gRPC Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
diff --git a/src/python/grpcio_channelz/grpc_channelz/v1/channelz.py b/src/python/grpcio_channelz/grpc_channelz/v1/channelz.py
new file mode 100644
index 0000000000..573b9d0d5a
--- /dev/null
+++ b/src/python/grpcio_channelz/grpc_channelz/v1/channelz.py
@@ -0,0 +1,141 @@
+# Copyright 2018 The gRPC Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""Channelz debug service implementation in gRPC Python."""
+
+import grpc
+from grpc._cython import cygrpc
+
+import grpc_channelz.v1.channelz_pb2 as _channelz_pb2
+import grpc_channelz.v1.channelz_pb2_grpc as _channelz_pb2_grpc
+
+from google.protobuf import json_format
+
+
+class ChannelzServicer(_channelz_pb2_grpc.ChannelzServicer):
+ """Servicer handling RPCs for service statuses."""
+
+ @staticmethod
+ def GetTopChannels(request, context):
+ try:
+ return json_format.Parse(
+ cygrpc.channelz_get_top_channels(request.start_channel_id),
+ _channelz_pb2.GetTopChannelsResponse(),
+ )
+ except (ValueError, json_format.ParseError) as e:
+ context.set_code(grpc.StatusCode.INTERNAL)
+ context.set_details(str(e))
+
+ @staticmethod
+ def GetServers(request, context):
+ try:
+ return json_format.Parse(
+ cygrpc.channelz_get_servers(request.start_server_id),
+ _channelz_pb2.GetServersResponse(),
+ )
+ except (ValueError, json_format.ParseError) as e:
+ context.set_code(grpc.StatusCode.INTERNAL)
+ context.set_details(str(e))
+
+ @staticmethod
+ def GetServer(request, context):
+ try:
+ return json_format.Parse(
+ cygrpc.channelz_get_server(request.server_id),
+ _channelz_pb2.GetServerResponse(),
+ )
+ except ValueError as e:
+ context.set_code(grpc.StatusCode.NOT_FOUND)
+ context.set_details(str(e))
+ except json_format.ParseError as e:
+ context.set_code(grpc.StatusCode.INTERNAL)
+ context.set_details(str(e))
+
+ @staticmethod
+ def GetServerSockets(request, context):
+ try:
+ return json_format.Parse(
+ cygrpc.channelz_get_server_sockets(request.server_id,
+ request.start_socket_id),
+ _channelz_pb2.GetServerSocketsResponse(),
+ )
+ except ValueError as e:
+ context.set_code(grpc.StatusCode.NOT_FOUND)
+ context.set_details(str(e))
+ except json_format.ParseError as e:
+ context.set_code(grpc.StatusCode.INTERNAL)
+ context.set_details(str(e))
+
+ @staticmethod
+ def GetChannel(request, context):
+ try:
+ return json_format.Parse(
+ cygrpc.channelz_get_channel(request.channel_id),
+ _channelz_pb2.GetChannelResponse(),
+ )
+ except ValueError as e:
+ context.set_code(grpc.StatusCode.NOT_FOUND)
+ context.set_details(str(e))
+ except json_format.ParseError as e:
+ context.set_code(grpc.StatusCode.INTERNAL)
+ context.set_details(str(e))
+
+ @staticmethod
+ def GetSubchannel(request, context):
+ try:
+ return json_format.Parse(
+ cygrpc.channelz_get_subchannel(request.subchannel_id),
+ _channelz_pb2.GetSubchannelResponse(),
+ )
+ except ValueError as e:
+ context.set_code(grpc.StatusCode.NOT_FOUND)
+ context.set_details(str(e))
+ except json_format.ParseError as e:
+ context.set_code(grpc.StatusCode.INTERNAL)
+ context.set_details(str(e))
+
+ @staticmethod
+ def GetSocket(request, context):
+ try:
+ return json_format.Parse(
+ cygrpc.channelz_get_socket(request.socket_id),
+ _channelz_pb2.GetSocketResponse(),
+ )
+ except ValueError as e:
+ context.set_code(grpc.StatusCode.NOT_FOUND)
+ context.set_details(str(e))
+ except json_format.ParseError as e:
+ context.set_code(grpc.StatusCode.INTERNAL)
+ context.set_details(str(e))
+
+
+def add_channelz_servicer(server):
+ """Add Channelz servicer to a server. Channelz servicer is in charge of
+ pulling information from C-Core for entire process. It will allow the
+ server to response to Channelz queries.
+
+ The Channelz statistic is enabled by default inside C-Core. Whether the
+ statistic is enabled or not is isolated from adding Channelz servicer.
+ That means you can query Channelz info with a Channelz-disabled channel,
+ and you can add Channelz servicer to a Channelz-disabled server.
+
+ The Channelz statistic can be enabled or disabled by channel option
+ 'grpc.enable_channelz'. Set to 1 to enable, set to 0 to disable.
+
+ This is an EXPERIMENTAL API.
+
+ Args:
+ server: grpc.Server to which Channelz service will be added.
+ """
+ _channelz_pb2_grpc.add_ChannelzServicer_to_server(ChannelzServicer(),
+ server)
diff --git a/src/python/grpcio_channelz/grpc_version.py b/src/python/grpcio_channelz/grpc_version.py
new file mode 100644
index 0000000000..16356ea402
--- /dev/null
+++ b/src/python/grpcio_channelz/grpc_version.py
@@ -0,0 +1,17 @@
+# Copyright 2018 The gRPC Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_channelz/grpc_version.py.template`!!!
+
+VERSION = '1.18.0.dev0'
diff --git a/src/python/grpcio_channelz/setup.py b/src/python/grpcio_channelz/setup.py
new file mode 100644
index 0000000000..a495052376
--- /dev/null
+++ b/src/python/grpcio_channelz/setup.py
@@ -0,0 +1,96 @@
+# Copyright 2018 The gRPC Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""Setup module for the GRPC Python package's Channelz."""
+
+import os
+import sys
+
+import setuptools
+
+# Ensure we're in the proper directory whether or not we're being used by pip.
+os.chdir(os.path.dirname(os.path.abspath(__file__)))
+
+# Break import-style to ensure we can actually find our local modules.
+import grpc_version
+
+
+class _NoOpCommand(setuptools.Command):
+ """No-op command."""
+
+ description = ''
+ user_options = []
+
+ def initialize_options(self):
+ pass
+
+ def finalize_options(self):
+ pass
+
+ def run(self):
+ pass
+
+
+CLASSIFIERS = [
+ 'Development Status :: 5 - Production/Stable',
+ 'Programming Language :: Python',
+ 'Programming Language :: Python :: 2',
+ 'Programming Language :: Python :: 2.7',
+ 'Programming Language :: Python :: 3',
+ 'Programming Language :: Python :: 3.4',
+ 'Programming Language :: Python :: 3.5',
+ 'Programming Language :: Python :: 3.6',
+ 'License :: OSI Approved :: Apache Software License',
+]
+
+PACKAGE_DIRECTORIES = {
+ '': '.',
+}
+
+INSTALL_REQUIRES = (
+ 'protobuf>=3.6.0',
+ 'grpcio>={version}'.format(version=grpc_version.VERSION),
+)
+
+try:
+ import channelz_commands as _channelz_commands
+ # we are in the build environment, otherwise the above import fails
+ SETUP_REQUIRES = (
+ 'grpcio-tools=={version}'.format(version=grpc_version.VERSION),)
+ COMMAND_CLASS = {
+ # Run preprocess from the repository *before* doing any packaging!
+ 'preprocess': _channelz_commands.CopyProtoModules,
+ 'build_package_protos': _channelz_commands.BuildPackageProtos,
+ }
+except ImportError:
+ SETUP_REQUIRES = ()
+ COMMAND_CLASS = {
+ # wire up commands to no-op not to break the external dependencies
+ 'preprocess': _NoOpCommand,
+ 'build_package_protos': _NoOpCommand,
+ }
+
+setuptools.setup(
+ name='grpcio-channelz',
+ version=grpc_version.VERSION,
+ license='Apache License 2.0',
+ description='Channel Level Live Debug Information Service for gRPC',
+ author='The gRPC Authors',
+ author_email='grpc-io@googlegroups.com',
+ classifiers=CLASSIFIERS,
+ url='https://grpc.io',
+ package_dir=PACKAGE_DIRECTORIES,
+ packages=setuptools.find_packages('.'),
+ install_requires=INSTALL_REQUIRES,
+ setup_requires=SETUP_REQUIRES,
+ cmdclass=COMMAND_CLASS)
diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py
index a30aac2e0b..85fa762f7e 100644
--- a/src/python/grpcio_health_checking/grpc_version.py
+++ b/src/python/grpcio_health_checking/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_health_checking/grpc_version.py.template`!!!
-VERSION = '1.17.0.dev0'
+VERSION = '1.18.0.dev0'
diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py
index aafea9fe76..e62ab169a2 100644
--- a/src/python/grpcio_reflection/grpc_version.py
+++ b/src/python/grpcio_reflection/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_reflection/grpc_version.py.template`!!!
-VERSION = '1.17.0.dev0'
+VERSION = '1.18.0.dev0'
diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py
index 876acd3142..7b4c1695fa 100644
--- a/src/python/grpcio_testing/grpc_version.py
+++ b/src/python/grpcio_testing/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_testing/grpc_version.py.template`!!!
-VERSION = '1.17.0.dev0'
+VERSION = '1.18.0.dev0'
diff --git a/src/python/grpcio_tests/commands.py b/src/python/grpcio_tests/commands.py
index d163f6fb68..65e9a99950 100644
--- a/src/python/grpcio_tests/commands.py
+++ b/src/python/grpcio_tests/commands.py
@@ -132,7 +132,12 @@ class TestGevent(setuptools.Command):
'unit.beta._beta_features_test',
# TODO(https://github.com/grpc/grpc/issues/15411) unpin gevent version
# This test will stuck while running higher version of gevent
- 'unit._auth_context_test.AuthContextTest.testSessionResumption')
+ 'unit._auth_context_test.AuthContextTest.testSessionResumption',
+ # TODO(https://github.com/grpc/grpc/issues/17330) enable these three tests
+ 'channelz._channelz_servicer_test.ChannelzServicerTest.test_many_subchannels',
+ 'channelz._channelz_servicer_test.ChannelzServicerTest.test_many_subchannels_and_sockets',
+ 'channelz._channelz_servicer_test.ChannelzServicerTest.test_streaming_rpc'
+ )
description = 'run tests with gevent. Assumes grpc/gevent are installed'
user_options = []
diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py
index cc9b41587c..2fcd1ad617 100644
--- a/src/python/grpcio_tests/grpc_version.py
+++ b/src/python/grpcio_tests/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_tests/grpc_version.py.template`!!!
-VERSION = '1.17.0.dev0'
+VERSION = '1.18.0.dev0'
diff --git a/src/python/grpcio_tests/setup.py b/src/python/grpcio_tests/setup.py
index 61c98fa038..f56425ac6d 100644
--- a/src/python/grpcio_tests/setup.py
+++ b/src/python/grpcio_tests/setup.py
@@ -39,6 +39,7 @@ PACKAGE_DIRECTORIES = {
INSTALL_REQUIRES = (
'coverage>=4.0', 'enum34>=1.0.4',
'grpcio>={version}'.format(version=grpc_version.VERSION),
+ 'grpcio-channelz>={version}'.format(version=grpc_version.VERSION),
'grpcio-tools>={version}'.format(version=grpc_version.VERSION),
'grpcio-health-checking>={version}'.format(version=grpc_version.VERSION),
'oauth2client>=1.4.7', 'protobuf>=3.6.0', 'six>=1.10', 'google-auth>=1.0.0',
diff --git a/src/python/grpcio_tests/tests/channelz/BUILD.bazel b/src/python/grpcio_tests/tests/channelz/BUILD.bazel
new file mode 100644
index 0000000000..63513616e7
--- /dev/null
+++ b/src/python/grpcio_tests/tests/channelz/BUILD.bazel
@@ -0,0 +1,15 @@
+package(default_visibility = ["//visibility:public"])
+
+py_test(
+ name = "channelz_servicer_test",
+ srcs = ["_channelz_servicer_test.py"],
+ main = "_channelz_servicer_test.py",
+ size = "small",
+ deps = [
+ "//src/python/grpcio/grpc:grpcio",
+ "//src/python/grpcio_channelz/grpc_channelz/v1:grpc_channelz",
+ "//src/python/grpcio_tests/tests/unit:test_common",
+ "//src/python/grpcio_tests/tests/unit/framework/common:common",
+ ],
+ imports = ["../../",],
+)
diff --git a/src/python/grpcio_tests/tests/channelz/__init__.py b/src/python/grpcio_tests/tests/channelz/__init__.py
new file mode 100644
index 0000000000..38fdfc9c5c
--- /dev/null
+++ b/src/python/grpcio_tests/tests/channelz/__init__.py
@@ -0,0 +1,13 @@
+# Copyright 2018 The gRPC Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
diff --git a/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py b/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py
new file mode 100644
index 0000000000..84f8594689
--- /dev/null
+++ b/src/python/grpcio_tests/tests/channelz/_channelz_servicer_test.py
@@ -0,0 +1,494 @@
+# Copyright 2018 The gRPC Authors
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""Tests of grpc_channelz.v1.channelz."""
+
+import unittest
+
+from concurrent import futures
+
+import grpc
+from grpc_channelz.v1 import channelz
+from grpc_channelz.v1 import channelz_pb2
+from grpc_channelz.v1 import channelz_pb2_grpc
+
+from tests.unit import test_common
+from tests.unit.framework.common import test_constants
+
+_SUCCESSFUL_UNARY_UNARY = '/test/SuccessfulUnaryUnary'
+_FAILED_UNARY_UNARY = '/test/FailedUnaryUnary'
+_SUCCESSFUL_STREAM_STREAM = '/test/SuccessfulStreamStream'
+
+_REQUEST = b'\x00\x00\x00'
+_RESPONSE = b'\x01\x01\x01'
+
+_DISABLE_REUSE_PORT = (('grpc.so_reuseport', 0),)
+_ENABLE_CHANNELZ = (('grpc.enable_channelz', 1),)
+_DISABLE_CHANNELZ = (('grpc.enable_channelz', 0),)
+
+
+def _successful_unary_unary(request, servicer_context):
+ return _RESPONSE
+
+
+def _failed_unary_unary(request, servicer_context):
+ servicer_context.set_code(grpc.StatusCode.INTERNAL)
+ servicer_context.set_details("Channelz Test Intended Failure")
+
+
+def _successful_stream_stream(request_iterator, servicer_context):
+ for _ in request_iterator:
+ yield _RESPONSE
+
+
+class _GenericHandler(grpc.GenericRpcHandler):
+
+ def service(self, handler_call_details):
+ if handler_call_details.method == _SUCCESSFUL_UNARY_UNARY:
+ return grpc.unary_unary_rpc_method_handler(_successful_unary_unary)
+ elif handler_call_details.method == _FAILED_UNARY_UNARY:
+ return grpc.unary_unary_rpc_method_handler(_failed_unary_unary)
+ elif handler_call_details.method == _SUCCESSFUL_STREAM_STREAM:
+ return grpc.stream_stream_rpc_method_handler(
+ _successful_stream_stream)
+ else:
+ return None
+
+
+class _ChannelServerPair(object):
+
+ def __init__(self):
+ # Server will enable channelz service
+ # Bind as attribute, so its `del` can be called explicitly, during
+ # the destruction process. Otherwise, if the removal of server
+ # rely on gc cycle, the test will become non-deterministic.
+ self._server = grpc.server(
+ futures.ThreadPoolExecutor(max_workers=3),
+ options=_DISABLE_REUSE_PORT + _ENABLE_CHANNELZ)
+ port = self._server.add_insecure_port('[::]:0')
+ self._server.add_generic_rpc_handlers((_GenericHandler(),))
+ self._server.start()
+
+ # Channel will enable channelz service...
+ self.channel = grpc.insecure_channel('localhost:%d' % port,
+ _ENABLE_CHANNELZ)
+
+ def __del__(self):
+ self._server.__del__()
+ self.channel.close()
+
+
+def _generate_channel_server_pairs(n):
+ return [_ChannelServerPair() for i in range(n)]
+
+
+def _clean_channel_server_pairs(pairs):
+ for pair in pairs:
+ pair.__del__()
+
+
+class ChannelzServicerTest(unittest.TestCase):
+
+ def _send_successful_unary_unary(self, idx):
+ _, r = self._pairs[idx].channel.unary_unary(
+ _SUCCESSFUL_UNARY_UNARY).with_call(_REQUEST)
+ self.assertEqual(r.code(), grpc.StatusCode.OK)
+
+ def _send_failed_unary_unary(self, idx):
+ try:
+ self._pairs[idx].channel.unary_unary(_FAILED_UNARY_UNARY).with_call(
+ _REQUEST)
+ except grpc.RpcError:
+ return
+ else:
+ self.fail("This call supposed to fail")
+
+ def _send_successful_stream_stream(self, idx):
+ response_iterator = self._pairs[idx].channel.stream_stream(
+ _SUCCESSFUL_STREAM_STREAM).__call__(
+ iter([_REQUEST] * test_constants.STREAM_LENGTH))
+ cnt = 0
+ for _ in response_iterator:
+ cnt += 1
+ self.assertEqual(cnt, test_constants.STREAM_LENGTH)
+
+ def _get_channel_id(self, idx):
+ """Channel id may not be consecutive"""
+ resp = self._channelz_stub.GetTopChannels(
+ channelz_pb2.GetTopChannelsRequest(start_channel_id=0))
+ self.assertGreater(len(resp.channel), idx)
+ return resp.channel[idx].ref.channel_id
+
+ def setUp(self):
+ self._pairs = []
+ # This server is for Channelz info fetching only
+ # It self should not enable Channelz
+ self._server = grpc.server(
+ futures.ThreadPoolExecutor(max_workers=3),
+ options=_DISABLE_REUSE_PORT + _DISABLE_CHANNELZ)
+ port = self._server.add_insecure_port('[::]:0')
+ channelz.add_channelz_servicer(self._server)
+ self._server.start()
+
+ # This channel is used to fetch Channelz info only
+ # Channelz should not be enabled
+ self._channel = grpc.insecure_channel('localhost:%d' % port,
+ _DISABLE_CHANNELZ)
+ self._channelz_stub = channelz_pb2_grpc.ChannelzStub(self._channel)
+
+ def tearDown(self):
+ self._server.__del__()
+ self._channel.close()
+ _clean_channel_server_pairs(self._pairs)
+
+ def test_get_top_channels_basic(self):
+ self._pairs = _generate_channel_server_pairs(1)
+ resp = self._channelz_stub.GetTopChannels(
+ channelz_pb2.GetTopChannelsRequest(start_channel_id=0))
+ self.assertEqual(len(resp.channel), 1)
+ self.assertEqual(resp.end, True)
+
+ def test_get_top_channels_high_start_id(self):
+ self._pairs = _generate_channel_server_pairs(1)
+ resp = self._channelz_stub.GetTopChannels(
+ channelz_pb2.GetTopChannelsRequest(start_channel_id=10000))
+ self.assertEqual(len(resp.channel), 0)
+ self.assertEqual(resp.end, True)
+
+ def test_successful_request(self):
+ self._pairs = _generate_channel_server_pairs(1)
+ self._send_successful_unary_unary(0)
+ resp = self._channelz_stub.GetChannel(
+ channelz_pb2.GetChannelRequest(channel_id=self._get_channel_id(0)))
+ self.assertEqual(resp.channel.data.calls_started, 1)
+ self.assertEqual(resp.channel.data.calls_succeeded, 1)
+ self.assertEqual(resp.channel.data.calls_failed, 0)
+
+ def test_failed_request(self):
+ self._pairs = _generate_channel_server_pairs(1)
+ self._send_failed_unary_unary(0)
+ resp = self._channelz_stub.GetChannel(
+ channelz_pb2.GetChannelRequest(channel_id=self._get_channel_id(0)))
+ self.assertEqual(resp.channel.data.calls_started, 1)
+ self.assertEqual(resp.channel.data.calls_succeeded, 0)
+ self.assertEqual(resp.channel.data.calls_failed, 1)
+
+ def test_many_requests(self):
+ self._pairs = _generate_channel_server_pairs(1)
+ k_success = 7
+ k_failed = 9
+ for i in range(k_success):
+ self._send_successful_unary_unary(0)
+ for i in range(k_failed):
+ self._send_failed_unary_unary(0)
+ resp = self._channelz_stub.GetChannel(
+ channelz_pb2.GetChannelRequest(channel_id=self._get_channel_id(0)))
+ self.assertEqual(resp.channel.data.calls_started, k_success + k_failed)
+ self.assertEqual(resp.channel.data.calls_succeeded, k_success)
+ self.assertEqual(resp.channel.data.calls_failed, k_failed)
+
+ def test_many_channel(self):
+ k_channels = 4
+ self._pairs = _generate_channel_server_pairs(k_channels)
+ resp = self._channelz_stub.GetTopChannels(
+ channelz_pb2.GetTopChannelsRequest(start_channel_id=0))
+ self.assertEqual(len(resp.channel), k_channels)
+
+ def test_many_requests_many_channel(self):
+ k_channels = 4
+ self._pairs = _generate_channel_server_pairs(k_channels)
+ k_success = 11
+ k_failed = 13
+ for i in range(k_success):
+ self._send_successful_unary_unary(0)
+ self._send_successful_unary_unary(2)
+ for i in range(k_failed):
+ self._send_failed_unary_unary(1)
+ self._send_failed_unary_unary(2)
+
+ # The first channel saw only successes
+ resp = self._channelz_stub.GetChannel(
+ channelz_pb2.GetChannelRequest(channel_id=self._get_channel_id(0)))
+ self.assertEqual(resp.channel.data.calls_started, k_success)
+ self.assertEqual(resp.channel.data.calls_succeeded, k_success)
+ self.assertEqual(resp.channel.data.calls_failed, 0)
+
+ # The second channel saw only failures
+ resp = self._channelz_stub.GetChannel(
+ channelz_pb2.GetChannelRequest(channel_id=self._get_channel_id(1)))
+ self.assertEqual(resp.channel.data.calls_started, k_failed)
+ self.assertEqual(resp.channel.data.calls_succeeded, 0)
+ self.assertEqual(resp.channel.data.calls_failed, k_failed)
+
+ # The third channel saw both successes and failures
+ resp = self._channelz_stub.GetChannel(
+ channelz_pb2.GetChannelRequest(channel_id=self._get_channel_id(2)))
+ self.assertEqual(resp.channel.data.calls_started, k_success + k_failed)
+ self.assertEqual(resp.channel.data.calls_succeeded, k_success)
+ self.assertEqual(resp.channel.data.calls_failed, k_failed)
+
+ # The fourth channel saw nothing
+ resp = self._channelz_stub.GetChannel(
+ channelz_pb2.GetChannelRequest(channel_id=self._get_channel_id(3)))
+ self.assertEqual(resp.channel.data.calls_started, 0)
+ self.assertEqual(resp.channel.data.calls_succeeded, 0)
+ self.assertEqual(resp.channel.data.calls_failed, 0)
+
+ def test_many_subchannels(self):
+ k_channels = 4
+ self._pairs = _generate_channel_server_pairs(k_channels)
+ k_success = 17
+ k_failed = 19
+ for i in range(k_success):
+ self._send_successful_unary_unary(0)
+ self._send_successful_unary_unary(2)
+ for i in range(k_failed):
+ self._send_failed_unary_unary(1)
+ self._send_failed_unary_unary(2)
+
+ gtc_resp = self._channelz_stub.GetTopChannels(
+ channelz_pb2.GetTopChannelsRequest(start_channel_id=0))
+ self.assertEqual(len(gtc_resp.channel), k_channels)
+ for i in range(k_channels):
+ # If no call performed in the channel, there shouldn't be any subchannel
+ if gtc_resp.channel[i].data.calls_started == 0:
+ self.assertEqual(len(gtc_resp.channel[i].subchannel_ref), 0)
+ continue
+
+ # Otherwise, the subchannel should exist
+ self.assertGreater(len(gtc_resp.channel[i].subchannel_ref), 0)
+ gsc_resp = self._channelz_stub.GetSubchannel(
+ channelz_pb2.GetSubchannelRequest(
+ subchannel_id=gtc_resp.channel[i].subchannel_ref[
+ 0].subchannel_id))
+ self.assertEqual(gtc_resp.channel[i].data.calls_started,
+ gsc_resp.subchannel.data.calls_started)
+ self.assertEqual(gtc_resp.channel[i].data.calls_succeeded,
+ gsc_resp.subchannel.data.calls_succeeded)
+ self.assertEqual(gtc_resp.channel[i].data.calls_failed,
+ gsc_resp.subchannel.data.calls_failed)
+
+ @unittest.skip('Servers in core are not guaranteed to be destroyed ' \
+ 'immediately when the reference goes out of scope, so ' \
+ 'servers from multiple test cases are not hermetic. ' \
+ 'TODO(https://github.com/grpc/grpc/issues/17258)')
+ def test_server_basic(self):
+ self._pairs = _generate_channel_server_pairs(1)
+ resp = self._channelz_stub.GetServers(
+ channelz_pb2.GetServersRequest(start_server_id=0))
+ self.assertEqual(len(resp.server), 1)
+
+ @unittest.skip('Servers in core are not guaranteed to be destroyed ' \
+ 'immediately when the reference goes out of scope, so ' \
+ 'servers from multiple test cases are not hermetic. ' \
+ 'TODO(https://github.com/grpc/grpc/issues/17258)')
+ def test_get_one_server(self):
+ self._pairs = _generate_channel_server_pairs(1)
+ gss_resp = self._channelz_stub.GetServers(
+ channelz_pb2.GetServersRequest(start_server_id=0))
+ self.assertEqual(len(gss_resp.server), 1)
+ gs_resp = self._channelz_stub.GetServer(
+ channelz_pb2.GetServerRequest(
+ server_id=gss_resp.server[0].ref.server_id))
+ self.assertEqual(gss_resp.server[0].ref.server_id,
+ gs_resp.server.ref.server_id)
+
+ @unittest.skip('Servers in core are not guaranteed to be destroyed ' \
+ 'immediately when the reference goes out of scope, so ' \
+ 'servers from multiple test cases are not hermetic. ' \
+ 'TODO(https://github.com/grpc/grpc/issues/17258)')
+ def test_server_call(self):
+ self._pairs = _generate_channel_server_pairs(1)
+ k_success = 23
+ k_failed = 29
+ for i in range(k_success):
+ self._send_successful_unary_unary(0)
+ for i in range(k_failed):
+ self._send_failed_unary_unary(0)
+
+ resp = self._channelz_stub.GetServers(
+ channelz_pb2.GetServersRequest(start_server_id=0))
+ self.assertEqual(len(resp.server), 1)
+ self.assertEqual(resp.server[0].data.calls_started,
+ k_success + k_failed)
+ self.assertEqual(resp.server[0].data.calls_succeeded, k_success)
+ self.assertEqual(resp.server[0].data.calls_failed, k_failed)
+
+ def test_many_subchannels_and_sockets(self):
+ k_channels = 4
+ self._pairs = _generate_channel_server_pairs(k_channels)
+ k_success = 3
+ k_failed = 5
+ for i in range(k_success):
+ self._send_successful_unary_unary(0)
+ self._send_successful_unary_unary(2)
+ for i in range(k_failed):
+ self._send_failed_unary_unary(1)
+ self._send_failed_unary_unary(2)
+
+ gtc_resp = self._channelz_stub.GetTopChannels(
+ channelz_pb2.GetTopChannelsRequest(start_channel_id=0))
+ self.assertEqual(len(gtc_resp.channel), k_channels)
+ for i in range(k_channels):
+ # If no call performed in the channel, there shouldn't be any subchannel
+ if gtc_resp.channel[i].data.calls_started == 0:
+ self.assertEqual(len(gtc_resp.channel[i].subchannel_ref), 0)
+ continue
+
+ # Otherwise, the subchannel should exist
+ self.assertGreater(len(gtc_resp.channel[i].subchannel_ref), 0)
+ gsc_resp = self._channelz_stub.GetSubchannel(
+ channelz_pb2.GetSubchannelRequest(
+ subchannel_id=gtc_resp.channel[i].subchannel_ref[
+ 0].subchannel_id))
+ self.assertEqual(len(gsc_resp.subchannel.socket_ref), 1)
+
+ gs_resp = self._channelz_stub.GetSocket(
+ channelz_pb2.GetSocketRequest(
+ socket_id=gsc_resp.subchannel.socket_ref[0].socket_id))
+ self.assertEqual(gsc_resp.subchannel.data.calls_started,
+ gs_resp.socket.data.streams_started)
+ self.assertEqual(gsc_resp.subchannel.data.calls_started,
+ gs_resp.socket.data.streams_succeeded)
+ # Calls started == messages sent, only valid for unary calls
+ self.assertEqual(gsc_resp.subchannel.data.calls_started,
+ gs_resp.socket.data.messages_sent)
+ # Only receive responses when the RPC was successful
+ self.assertEqual(gsc_resp.subchannel.data.calls_succeeded,
+ gs_resp.socket.data.messages_received)
+
+ def test_streaming_rpc(self):
+ self._pairs = _generate_channel_server_pairs(1)
+ # In C++, the argument for _send_successful_stream_stream is message length.
+ # Here the argument is still channel idx, to be consistent with the other two.
+ self._send_successful_stream_stream(0)
+
+ gc_resp = self._channelz_stub.GetChannel(
+ channelz_pb2.GetChannelRequest(channel_id=self._get_channel_id(0)))
+ self.assertEqual(gc_resp.channel.data.calls_started, 1)
+ self.assertEqual(gc_resp.channel.data.calls_succeeded, 1)
+ self.assertEqual(gc_resp.channel.data.calls_failed, 0)
+ # Subchannel exists
+ self.assertGreater(len(gc_resp.channel.subchannel_ref), 0)
+
+ gsc_resp = self._channelz_stub.GetSubchannel(
+ channelz_pb2.GetSubchannelRequest(
+ subchannel_id=gc_resp.channel.subchannel_ref[0].subchannel_id))
+ self.assertEqual(gsc_resp.subchannel.data.calls_started, 1)
+ self.assertEqual(gsc_resp.subchannel.data.calls_succeeded, 1)
+ self.assertEqual(gsc_resp.subchannel.data.calls_failed, 0)
+ # Socket exists
+ self.assertEqual(len(gsc_resp.subchannel.socket_ref), 1)
+
+ gs_resp = self._channelz_stub.GetSocket(
+ channelz_pb2.GetSocketRequest(
+ socket_id=gsc_resp.subchannel.socket_ref[0].socket_id))
+ self.assertEqual(gs_resp.socket.data.streams_started, 1)
+ self.assertEqual(gs_resp.socket.data.streams_succeeded, 1)
+ self.assertEqual(gs_resp.socket.data.streams_failed, 0)
+ self.assertEqual(gs_resp.socket.data.messages_sent,
+ test_constants.STREAM_LENGTH)
+ self.assertEqual(gs_resp.socket.data.messages_received,
+ test_constants.STREAM_LENGTH)
+
+ @unittest.skip('Servers in core are not guaranteed to be destroyed ' \
+ 'immediately when the reference goes out of scope, so ' \
+ 'servers from multiple test cases are not hermetic. ' \
+ 'TODO(https://github.com/grpc/grpc/issues/17258)')
+ def test_server_sockets(self):
+ self._pairs = _generate_channel_server_pairs(1)
+ self._send_successful_unary_unary(0)
+ self._send_failed_unary_unary(0)
+
+ gs_resp = self._channelz_stub.GetServers(
+ channelz_pb2.GetServersRequest(start_server_id=0))
+ self.assertEqual(len(gs_resp.server), 1)
+ self.assertEqual(gs_resp.server[0].data.calls_started, 2)
+ self.assertEqual(gs_resp.server[0].data.calls_succeeded, 1)
+ self.assertEqual(gs_resp.server[0].data.calls_failed, 1)
+
+ gss_resp = self._channelz_stub.GetServerSockets(
+ channelz_pb2.GetServerSocketsRequest(
+ server_id=gs_resp.server[0].ref.server_id, start_socket_id=0))
+ # If the RPC call failed, it will raise a grpc.RpcError
+ # So, if there is no exception raised, considered pass
+
+ @unittest.skip('Servers in core are not guaranteed to be destroyed ' \
+ 'immediately when the reference goes out of scope, so ' \
+ 'servers from multiple test cases are not hermetic. ' \
+ 'TODO(https://github.com/grpc/grpc/issues/17258)')
+ def test_server_listen_sockets(self):
+ self._pairs = _generate_channel_server_pairs(1)
+
+ gss_resp = self._channelz_stub.GetServers(
+ channelz_pb2.GetServersRequest(start_server_id=0))
+ self.assertEqual(len(gss_resp.server), 1)
+ self.assertEqual(len(gss_resp.server[0].listen_socket), 1)
+
+ gs_resp = self._channelz_stub.GetSocket(
+ channelz_pb2.GetSocketRequest(
+ socket_id=gss_resp.server[0].listen_socket[0].socket_id))
+ # If the RPC call failed, it will raise a grpc.RpcError
+ # So, if there is no exception raised, considered pass
+
+ def test_invalid_query_get_server(self):
+ try:
+ self._channelz_stub.GetServer(
+ channelz_pb2.GetServerRequest(server_id=10000))
+ except BaseException as e:
+ self.assertIn('StatusCode.NOT_FOUND', str(e))
+ else:
+ self.fail('Invalid query not detected')
+
+ def test_invalid_query_get_channel(self):
+ try:
+ self._channelz_stub.GetChannel(
+ channelz_pb2.GetChannelRequest(channel_id=10000))
+ except BaseException as e:
+ self.assertIn('StatusCode.NOT_FOUND', str(e))
+ else:
+ self.fail('Invalid query not detected')
+
+ def test_invalid_query_get_subchannel(self):
+ try:
+ self._channelz_stub.GetSubchannel(
+ channelz_pb2.GetSubchannelRequest(subchannel_id=10000))
+ except BaseException as e:
+ self.assertIn('StatusCode.NOT_FOUND', str(e))
+ else:
+ self.fail('Invalid query not detected')
+
+ def test_invalid_query_get_socket(self):
+ try:
+ self._channelz_stub.GetSocket(
+ channelz_pb2.GetSocketRequest(socket_id=10000))
+ except BaseException as e:
+ self.assertIn('StatusCode.NOT_FOUND', str(e))
+ else:
+ self.fail('Invalid query not detected')
+
+ def test_invalid_query_get_server_sockets(self):
+ try:
+ self._channelz_stub.GetServerSockets(
+ channelz_pb2.GetServerSocketsRequest(
+ server_id=10000,
+ start_socket_id=0,
+ ))
+ except BaseException as e:
+ self.assertIn('StatusCode.NOT_FOUND', str(e))
+ else:
+ self.fail('Invalid query not detected')
+
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/interop/BUILD.bazel b/src/python/grpcio_tests/tests/interop/BUILD.bazel
index a39f30d32a..aebdbf67eb 100644
--- a/src/python/grpcio_tests/tests/interop/BUILD.bazel
+++ b/src/python/grpcio_tests/tests/interop/BUILD.bazel
@@ -35,6 +35,10 @@ py_library(
requirement('google-auth'),
requirement('requests'),
requirement('enum34'),
+ requirement('urllib3'),
+ requirement('chardet'),
+ requirement('certifi'),
+ requirement('idna'),
],
imports=["../../",],
)
diff --git a/src/python/grpcio_tests/tests/interop/methods.py b/src/python/grpcio_tests/tests/interop/methods.py
index 721dedf0b7..c11f6c8fad 100644
--- a/src/python/grpcio_tests/tests/interop/methods.py
+++ b/src/python/grpcio_tests/tests/interop/methods.py
@@ -23,7 +23,6 @@ from google.auth import environment_vars as google_auth_environment_vars
from google.auth.transport import grpc as google_auth_transport_grpc
from google.auth.transport import requests as google_auth_transport_requests
import grpc
-from grpc.beta import implementations
from src.proto.grpc.testing import empty_pb2
from src.proto.grpc.testing import messages_pb2
@@ -377,7 +376,7 @@ def _unimplemented_service(unimplemented_service_stub):
def _custom_metadata(stub):
initial_metadata_value = "test_initial_metadata_value"
- trailing_metadata_value = "\x0a\x0b\x0a\x0b\x0a\x0b"
+ trailing_metadata_value = b"\x0a\x0b\x0a\x0b\x0a\x0b"
metadata = ((_INITIAL_METADATA_KEY, initial_metadata_value),
(_TRAILING_METADATA_KEY, trailing_metadata_value))
@@ -391,7 +390,7 @@ def _custom_metadata(stub):
if trailing_metadata[_TRAILING_METADATA_KEY] != trailing_metadata_value:
raise ValueError('expected trailing metadata %s, got %s' %
(trailing_metadata_value,
- initial_metadata[_TRAILING_METADATA_KEY]))
+ trailing_metadata[_TRAILING_METADATA_KEY]))
# Testing with UnaryCall
request = messages_pb2.SimpleRequest(
@@ -422,7 +421,7 @@ def _compute_engine_creds(stub, args):
def _oauth2_auth_token(stub, args):
json_key_filename = os.environ[google_auth_environment_vars.CREDENTIALS]
- wanted_email = json.load(open(json_key_filename, 'rb'))['client_email']
+ wanted_email = json.load(open(json_key_filename, 'r'))['client_email']
response = _large_unary_common_behavior(stub, True, True, None)
if wanted_email != response.username:
raise ValueError('expected username %s, got %s' % (wanted_email,
@@ -435,7 +434,7 @@ def _oauth2_auth_token(stub, args):
def _jwt_token_creds(stub, args):
json_key_filename = os.environ[google_auth_environment_vars.CREDENTIALS]
- wanted_email = json.load(open(json_key_filename, 'rb'))['client_email']
+ wanted_email = json.load(open(json_key_filename, 'r'))['client_email']
response = _large_unary_common_behavior(stub, True, False, None)
if wanted_email != response.username:
raise ValueError('expected username %s, got %s' % (wanted_email,
@@ -444,7 +443,7 @@ def _jwt_token_creds(stub, args):
def _per_rpc_creds(stub, args):
json_key_filename = os.environ[google_auth_environment_vars.CREDENTIALS]
- wanted_email = json.load(open(json_key_filename, 'rb'))['client_email']
+ wanted_email = json.load(open(json_key_filename, 'r'))['client_email']
google_credentials, unused_project_id = google_auth.default(
scopes=[args.oauth_scope])
call_credentials = grpc.metadata_call_credentials(
diff --git a/src/python/grpcio_tests/tests/tests.json b/src/python/grpcio_tests/tests/tests.json
index a3006d9afc..9cffd3df19 100644
--- a/src/python/grpcio_tests/tests/tests.json
+++ b/src/python/grpcio_tests/tests/tests.json
@@ -1,5 +1,6 @@
[
"_sanity._sanity_test.SanityTest",
+ "channelz._channelz_servicer_test.ChannelzServicerTest",
"health_check._health_servicer_test.HealthServicerTest",
"interop._insecure_intraop_test.InsecureIntraopTest",
"interop._secure_intraop_test.SecureIntraopTest",
diff --git a/src/python/grpcio_tests/tests/unit/_credentials_test.py b/src/python/grpcio_tests/tests/unit/_credentials_test.py
index be7378ecbc..187a6f0388 100644
--- a/src/python/grpcio_tests/tests/unit/_credentials_test.py
+++ b/src/python/grpcio_tests/tests/unit/_credentials_test.py
@@ -15,6 +15,7 @@
import unittest
import logging
+import six
import grpc
@@ -53,6 +54,16 @@ class CredentialsTest(unittest.TestCase):
self.assertIsInstance(channel_first_second_and_third,
grpc.ChannelCredentials)
+ @unittest.skipIf(six.PY2, 'only invalid in Python3')
+ def test_invalid_string_certificate(self):
+ self.assertRaises(
+ TypeError,
+ grpc.ssl_channel_credentials,
+ root_certificates='A Certificate',
+ private_key=None,
+ certificate_chain=None,
+ )
+
if __name__ == '__main__':
logging.basicConfig()
diff --git a/src/python/grpcio_tests/tests/unit/_logging_test.py b/src/python/grpcio_tests/tests/unit/_logging_test.py
index 80b1f1b3c1..631b9de9db 100644
--- a/src/python/grpcio_tests/tests/unit/_logging_test.py
+++ b/src/python/grpcio_tests/tests/unit/_logging_test.py
@@ -68,6 +68,13 @@ class LoggingTest(unittest.TestCase):
self.assertEqual(1, len(logging.getLogger().handlers))
self.assertIs(logging.getLogger().handlers[0].stream, intended_stream)
+ @isolated_logging
+ def test_grpc_logger(self):
+ self.assertIn("grpc", logging.Logger.manager.loggerDict)
+ root_logger = logging.getLogger("grpc")
+ self.assertEqual(1, len(root_logger.handlers))
+ self.assertIsInstance(root_logger.handlers[0], logging.NullHandler)
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/src/python/grpcio_tests/tests/unit/_server_ssl_cert_config_test.py b/src/python/grpcio_tests/tests/unit/_server_ssl_cert_config_test.py
index e733a59a5b..9e4bd61816 100644
--- a/src/python/grpcio_tests/tests/unit/_server_ssl_cert_config_test.py
+++ b/src/python/grpcio_tests/tests/unit/_server_ssl_cert_config_test.py
@@ -70,18 +70,11 @@ SERVER_CERT_CHAIN_2_PEM = (resources.cert_hier_2_server_1_cert() +
Call = collections.namedtuple('Call', ['did_raise', 'returned_cert_config'])
-def _create_client_stub(
- port,
- expect_success,
- root_certificates=None,
- private_key=None,
- certificate_chain=None,
-):
- channel = grpc.secure_channel('localhost:{}'.format(port),
- grpc.ssl_channel_credentials(
- root_certificates=root_certificates,
- private_key=private_key,
- certificate_chain=certificate_chain))
+def _create_channel(port, credentials):
+ return grpc.secure_channel('localhost:{}'.format(port), credentials)
+
+
+def _create_client_stub(channel, expect_success):
if expect_success:
# per Nathaniel: there's some robustness issue if we start
# using a channel without waiting for it to be actually ready
@@ -176,14 +169,13 @@ class _ServerSSLCertReloadTest(
root_certificates=None,
private_key=None,
certificate_chain=None):
- client_stub = _create_client_stub(
- self.port,
- expect_success,
+ credentials = grpc.ssl_channel_credentials(
root_certificates=root_certificates,
private_key=private_key,
certificate_chain=certificate_chain)
- self._perform_rpc(client_stub, expect_success)
- del client_stub
+ with _create_channel(self.port, credentials) as client_channel:
+ client_stub = _create_client_stub(client_channel, expect_success)
+ self._perform_rpc(client_stub, expect_success)
def _test(self):
# things should work...
@@ -259,12 +251,13 @@ class _ServerSSLCertReloadTest(
# now create the "persistent" clients
self.cert_config_fetcher.reset()
self.cert_config_fetcher.configure(False, None)
- persistent_client_stub_A = _create_client_stub(
+ channel_A = _create_channel(
self.port,
- True,
- root_certificates=CA_1_PEM,
- private_key=CLIENT_KEY_2_PEM,
- certificate_chain=CLIENT_CERT_CHAIN_2_PEM)
+ grpc.ssl_channel_credentials(
+ root_certificates=CA_1_PEM,
+ private_key=CLIENT_KEY_2_PEM,
+ certificate_chain=CLIENT_CERT_CHAIN_2_PEM))
+ persistent_client_stub_A = _create_client_stub(channel_A, True)
self._perform_rpc(persistent_client_stub_A, True)
actual_calls = self.cert_config_fetcher.getCalls()
self.assertEqual(len(actual_calls), 1)
@@ -273,12 +266,13 @@ class _ServerSSLCertReloadTest(
self.cert_config_fetcher.reset()
self.cert_config_fetcher.configure(False, None)
- persistent_client_stub_B = _create_client_stub(
+ channel_B = _create_channel(
self.port,
- True,
- root_certificates=CA_1_PEM,
- private_key=CLIENT_KEY_2_PEM,
- certificate_chain=CLIENT_CERT_CHAIN_2_PEM)
+ grpc.ssl_channel_credentials(
+ root_certificates=CA_1_PEM,
+ private_key=CLIENT_KEY_2_PEM,
+ certificate_chain=CLIENT_CERT_CHAIN_2_PEM))
+ persistent_client_stub_B = _create_client_stub(channel_B, True)
self._perform_rpc(persistent_client_stub_B, True)
actual_calls = self.cert_config_fetcher.getCalls()
self.assertEqual(len(actual_calls), 1)
@@ -359,6 +353,9 @@ class _ServerSSLCertReloadTest(
actual_calls = self.cert_config_fetcher.getCalls()
self.assertEqual(len(actual_calls), 0)
+ channel_A.close()
+ channel_B.close()
+
class ServerSSLCertConfigFetcherParamsChecks(unittest.TestCase):
diff --git a/src/python/grpcio_tests/tests/unit/beta/BUILD.bazel b/src/python/grpcio_tests/tests/unit/beta/BUILD.bazel
deleted file mode 100644
index d3e0fe20eb..0000000000
--- a/src/python/grpcio_tests/tests/unit/beta/BUILD.bazel
+++ /dev/null
@@ -1,75 +0,0 @@
-load("@grpc_python_dependencies//:requirements.bzl", "requirement")
-
-package(default_visibility = ["//visibility:public"])
-
-py_library(
- name = "test_utilities",
- srcs = ["test_utilities.py"],
- deps = [
- "//src/python/grpcio/grpc:grpcio",
- ],
-)
-
-py_test(
- name = "_beta_features_test",
- srcs = ["_beta_features_test.py"],
- main = "_beta_features_test.py",
- size = "small",
- deps = [
- "//src/python/grpcio/grpc:grpcio",
- "//src/python/grpcio_tests/tests/unit:resources",
- "//src/python/grpcio_tests/tests/unit/framework/common",
- ":test_utilities",
- ],
- imports=["../../../",],
-)
-
-py_test(
- name = "_connectivity_channel_test",
- srcs = ["_connectivity_channel_test.py"],
- main = "_connectivity_channel_test.py",
- size = "small",
- deps = [
- "//src/python/grpcio/grpc:grpcio",
- ],
-)
-
-# TODO(ghostwriternr): To be added later.
-#py_test(
-# name = "_implementations_test",
-# srcs = ["_implementations_test.py"],
-# main = "_implementations_test.py",
-# size = "small",
-# deps = [
-# "//src/python/grpcio/grpc:grpcio",
-# "//src/python/grpcio_tests/tests/unit:resources",
-# requirement('oauth2client'),
-# ],
-# imports=["../../../",],
-#)
-
-py_test(
- name = "_not_found_test",
- srcs = ["_not_found_test.py"],
- main = "_not_found_test.py",
- size = "small",
- deps = [
- "//src/python/grpcio/grpc:grpcio",
- "//src/python/grpcio_tests/tests/unit/framework/common",
- ],
- imports=["../../../",],
-)
-
-py_test(
- name = "_utilities_test",
- srcs = ["_utilities_test.py"],
- main = "_utilities_test.py",
- size = "small",
- deps = [
- "//src/python/grpcio/grpc:grpcio",
- "//src/python/grpcio_tests/tests/unit/framework/common",
- ],
- imports=["../../../",],
-)
-
-
diff --git a/src/ruby/lib/grpc/generic/service.rb b/src/ruby/lib/grpc/generic/service.rb
index 4764217406..169a62f11d 100644
--- a/src/ruby/lib/grpc/generic/service.rb
+++ b/src/ruby/lib/grpc/generic/service.rb
@@ -95,7 +95,7 @@ module GRPC
rpc_descs[name] = RpcDesc.new(name, input, output,
marshal_class_method,
unmarshal_class_method)
- define_method(GenericService.underscore(name.to_s).to_sym) do |_, _|
+ define_method(GenericService.underscore(name.to_s).to_sym) do |*|
fail GRPC::BadStatus.new_status_exception(
GRPC::Core::StatusCodes::UNIMPLEMENTED)
end
diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb
index 243d566645..a4ed052d85 100644
--- a/src/ruby/lib/grpc/version.rb
+++ b/src/ruby/lib/grpc/version.rb
@@ -14,5 +14,5 @@
# GRPC contains the General RPC module.
module GRPC
- VERSION = '1.17.0.dev'
+ VERSION = '1.18.0.dev'
end
diff --git a/src/ruby/spec/generic/rpc_server_spec.rb b/src/ruby/spec/generic/rpc_server_spec.rb
index 44a6134086..924d747a79 100644
--- a/src/ruby/spec/generic/rpc_server_spec.rb
+++ b/src/ruby/spec/generic/rpc_server_spec.rb
@@ -342,6 +342,28 @@ describe GRPC::RpcServer do
t.join
end
+ it 'should return UNIMPLEMENTED on unimplemented ' \
+ 'methods for client_streamer', server: true do
+ @srv.handle(EchoService)
+ t = Thread.new { @srv.run }
+ @srv.wait_till_running
+ blk = proc do
+ stub = EchoStub.new(@host, :this_channel_is_insecure, **client_opts)
+ requests = [EchoMsg.new, EchoMsg.new]
+ stub.a_client_streaming_rpc_unimplemented(requests)
+ end
+
+ begin
+ expect(&blk).to raise_error do |error|
+ expect(error).to be_a(GRPC::BadStatus)
+ expect(error.code).to eq(GRPC::Core::StatusCodes::UNIMPLEMENTED)
+ end
+ ensure
+ @srv.stop # should be call not to crash
+ t.join
+ end
+ end
+
it 'should handle multiple sequential requests', server: true do
@srv.handle(EchoService)
t = Thread.new { @srv.run }
diff --git a/src/ruby/spec/support/services.rb b/src/ruby/spec/support/services.rb
index 6e693f1cde..438459dfd7 100644
--- a/src/ruby/spec/support/services.rb
+++ b/src/ruby/spec/support/services.rb
@@ -33,6 +33,7 @@ class EchoService
rpc :a_client_streaming_rpc, stream(EchoMsg), EchoMsg
rpc :a_server_streaming_rpc, EchoMsg, stream(EchoMsg)
rpc :a_bidi_rpc, stream(EchoMsg), stream(EchoMsg)
+ rpc :a_client_streaming_rpc_unimplemented, stream(EchoMsg), EchoMsg
attr_reader :received_md
def initialize(**kw)
diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb
index 92e85eb882..389fb70684 100644
--- a/src/ruby/tools/version.rb
+++ b/src/ruby/tools/version.rb
@@ -14,6 +14,6 @@
module GRPC
module Tools
- VERSION = '1.17.0.dev'
+ VERSION = '1.18.0.dev'
end
end
diff --git a/templates/Makefile.template b/templates/Makefile.template
index 0b67416d3e..8bb06176bf 100644
--- a/templates/Makefile.template
+++ b/templates/Makefile.template
@@ -1370,7 +1370,7 @@
ifeq ($(SYSTEM),MINGW32)
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/lib${lib.name}$(SHARED_VERSION_${lang_to_var[lib.language]})-dll.a $(prefix)/lib/lib${lib.name}.a
else ifneq ($(SYSTEM),Darwin)
- $(Q) ln -sf $(SHARED_PREFIX)${lib.name}$(SHARED_VERSION_${lang_to_var[lib.language]}).$(SHARED_EXT_${lang_to_var[lib.language]}) $(prefix)/lib/lib${lib.name}.so.${settings.core_version.major}
+ $(Q) ln -sf $(SHARED_PREFIX)${lib.name}$(SHARED_VERSION_${lang_to_var[lib.language]}).$(SHARED_EXT_${lang_to_var[lib.language]}) $(prefix)/lib/lib${lib.name}.so.${settings.get(lang_to_var[lib.language].lower() + '_version').major}
$(Q) ln -sf $(SHARED_PREFIX)${lib.name}$(SHARED_VERSION_${lang_to_var[lib.language]}).$(SHARED_EXT_${lang_to_var[lib.language]}) $(prefix)/lib/lib${lib.name}.so
endif
% endif
diff --git a/templates/config.m4.template b/templates/config.m4.template
index 19f9904911..18378cfc34 100644
--- a/templates/config.m4.template
+++ b/templates/config.m4.template
@@ -45,7 +45,8 @@
% endfor
, $ext_shared, , -fvisibility=hidden ${"\\"}
-DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN ${"\\"}
- -D_HAS_EXCEPTIONS=0 -DNOMINMAX -DGRPC_ARES=0)
+ -D_HAS_EXCEPTIONS=0 -DNOMINMAX -DGRPC_ARES=0 ${"\\"}
+ -DGRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK=1)
PHP_ADD_BUILD_DIR($ext_builddir/src/php/ext/grpc)
<%
diff --git a/templates/gRPC-C++.podspec.template b/templates/gRPC-C++.podspec.template
index ed69a1ed4c..ab330415af 100644
--- a/templates/gRPC-C++.podspec.template
+++ b/templates/gRPC-C++.podspec.template
@@ -132,7 +132,7 @@
s.name = 'gRPC-C++'
# TODO (mxyan): use version that match gRPC version when pod is stabilized
# version = '${settings.version}'
- version = '0.0.3'
+ version = '0.0.4'
s.version = version
s.summary = 'gRPC C++ library'
s.homepage = 'https://grpc.io'
diff --git a/templates/src/python/grpcio_channelz/grpc_version.py.template b/templates/src/python/grpcio_channelz/grpc_version.py.template
new file mode 100644
index 0000000000..75d510cd17
--- /dev/null
+++ b/templates/src/python/grpcio_channelz/grpc_version.py.template
@@ -0,0 +1,19 @@
+%YAML 1.2
+--- |
+ # Copyright 2018 The gRPC Authors
+ #
+ # Licensed under the Apache License, Version 2.0 (the "License");
+ # you may not use this file except in compliance with the License.
+ # You may obtain a copy of the License at
+ #
+ # http://www.apache.org/licenses/LICENSE-2.0
+ #
+ # Unless required by applicable law or agreed to in writing, software
+ # distributed under the License is distributed on an "AS IS" BASIS,
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ # See the License for the specific language governing permissions and
+ # limitations under the License.
+
+ # AUTO-GENERATED FROM `$REPO_ROOT/templates/src/python/grpcio_channelz/grpc_version.py.template`!!!
+
+ VERSION = '${settings.python_version.pep440()}'
diff --git a/templates/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile.template b/templates/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile.template
index bf28796de3..f584a2378e 100644
--- a/templates/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile.template
+++ b/templates/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile.template
@@ -14,15 +14,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
- FROM debian:jessie
-
- <%include file="../../apt_get_basic.include"/>
- <%include file="../../python_deps.include"/>
- # Install pip and virtualenv for Python 3.4
- RUN curl https://bootstrap.pypa.io/get-pip.py | python3.4
- RUN python3.4 -m pip install virtualenv
+ <%include file="../../python_stretch.include"/>
- <%include file="../../run_tests_addons.include"/>
- # Define the default command.
- CMD ["bash"]
-
+ RUN apt-get update && apt-get -t testing install -y python3.7 python3-all-dev
+ RUN curl https://bootstrap.pypa.io/get-pip.py | python3.7
diff --git a/templates/tools/dockerfile/test/multilang_jessie_x64/Dockerfile.template b/templates/tools/dockerfile/test/multilang_jessie_x64/Dockerfile.template
deleted file mode 100644
index ac687b710f..0000000000
--- a/templates/tools/dockerfile/test/multilang_jessie_x64/Dockerfile.template
+++ /dev/null
@@ -1,41 +0,0 @@
-%YAML 1.2
---- |
- # Copyright 2016 gRPC authors.
- #
- # Licensed under the Apache License, Version 2.0 (the "License");
- # you may not use this file except in compliance with the License.
- # You may obtain a copy of the License at
- #
- # http://www.apache.org/licenses/LICENSE-2.0
- #
- # Unless required by applicable law or agreed to in writing, software
- # distributed under the License is distributed on an "AS IS" BASIS,
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- # See the License for the specific language governing permissions and
- # limitations under the License.
-
- FROM debian:jessie
-
- <%include file="../../apt_get_basic.include"/>
- <%include file="../../gcp_api_libraries.include"/>
- <%include file="../../csharp_deps.include"/>
- <%include file="../../csharp_dotnetcli_deps.include"/>
- <%include file="../../cxx_deps.include"/>
- <%include file="../../node_deps.include"/>
- <%include file="../../php_deps.include"/>
- <%include file="../../ruby_deps.include"/>
- <%include file="../../python_deps.include"/>
- # Install pip and virtualenv for Python 3.4
- RUN curl https://bootstrap.pypa.io/get-pip.py | python3.4
- RUN python3.4 -m pip install virtualenv
-
- # Install coverage for Python test coverage reporting
- RUN pip install coverage
- ENV PATH ~/.local/bin:$PATH
-
- # Install Mako to generate files in grpc/grpc-node
- RUN pip install Mako
-
- <%include file="../../run_tests_addons.include"/>
- # Define the default command.
- CMD ["bash"]
diff --git a/templates/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile.template b/templates/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile.template
index ff342db493..c3602f6c51 100644
--- a/templates/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile.template
+++ b/templates/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile.template
@@ -18,3 +18,6 @@
RUN apt-get update && apt-get -t testing install -y python3.7 python3-all-dev
RUN curl https://bootstrap.pypa.io/get-pip.py | python3.7
+
+ # for Python test coverage reporting
+ RUN pip install coverage
diff --git a/test/core/end2end/fuzzers/hpack.dictionary b/test/core/end2end/fuzzers/hpack.dictionary
index a79fe5ad95..0469421c97 100644
--- a/test/core/end2end/fuzzers/hpack.dictionary
+++ b/test/core/end2end/fuzzers/hpack.dictionary
@@ -35,6 +35,7 @@
"\x1Fgrpc.max_response_message_bytes"
"$/grpc.lb.v1.LoadBalancer/BalanceLoad"
"\x1C/grpc.health.v1.Health/Watch"
+"P/envoy.service.discovery.v2.AggregatedDiscoveryService/StreamAggregatedResources"
"\x07deflate"
"\x04gzip"
"\x0Bstream/gzip"
diff --git a/test/core/gpr/BUILD b/test/core/gpr/BUILD
index d58d4f2a14..67657ee1ce 100644
--- a/test/core/gpr/BUILD
+++ b/test/core/gpr/BUILD
@@ -81,12 +81,12 @@ grpc_cc_test(
grpc_cc_test(
name = "mpscq_test",
srcs = ["mpscq_test.cc"],
+ exec_compatible_with = ["//third_party/toolchains/machine_size:large"],
language = "C++",
deps = [
"//:gpr",
"//test/core/util:gpr_test_util",
],
- data = ["//third_party/toolchains:RBE_USE_MACHINE_TYPE_LARGE"],
)
grpc_cc_test(
diff --git a/test/core/gprpp/inlined_vector_test.cc b/test/core/gprpp/inlined_vector_test.cc
index 73e0773b31..6abd2e7dfa 100644
--- a/test/core/gprpp/inlined_vector_test.cc
+++ b/test/core/gprpp/inlined_vector_test.cc
@@ -116,7 +116,7 @@ typedef InlinedVector<int, kInlinedLength> IntVec8;
const size_t kInlinedFillSize = kInlinedLength - 1;
const size_t kAllocatedFillSize = kInlinedLength + 1;
-TEST(InlinedVectorTest, CopyConstructerInlined) {
+TEST(InlinedVectorTest, CopyConstructorInlined) {
IntVec8 original;
FillVector(&original, kInlinedFillSize);
IntVec8 copy_constructed(original);
@@ -125,7 +125,7 @@ TEST(InlinedVectorTest, CopyConstructerInlined) {
}
}
-TEST(InlinedVectorTest, CopyConstructerAllocated) {
+TEST(InlinedVectorTest, CopyConstructorAllocated) {
IntVec8 original;
FillVector(&original, kAllocatedFillSize);
IntVec8 copy_constructed(original);
@@ -264,6 +264,166 @@ TEST(InlinedVectorTest, MoveAssignmentAllocatedAllocated) {
EXPECT_EQ(move_assigned.data(), old_data);
}
+// A copyable and movable value class, used to test that elements' copy
+// and move methods are called correctly.
+class Value {
+ public:
+ explicit Value(int v) : value_(MakeUnique<int>(v)) {}
+
+ // copyable
+ Value(const Value& v) {
+ value_ = MakeUnique<int>(*v.value_);
+ copied_ = true;
+ }
+ Value& operator=(const Value& v) {
+ value_ = MakeUnique<int>(*v.value_);
+ copied_ = true;
+ return *this;
+ }
+
+ // movable
+ Value(Value&& v) {
+ value_ = std::move(v.value_);
+ moved_ = true;
+ }
+ Value& operator=(Value&& v) {
+ value_ = std::move(v.value_);
+ moved_ = true;
+ return *this;
+ }
+
+ const UniquePtr<int>& value() const { return value_; }
+ bool copied() const { return copied_; }
+ bool moved() const { return moved_; }
+
+ private:
+ UniquePtr<int> value_;
+ bool copied_ = false;
+ bool moved_ = false;
+};
+
+TEST(InlinedVectorTest, CopyConstructorCopiesElementsInlined) {
+ InlinedVector<Value, 1> v1;
+ v1.emplace_back(3);
+ InlinedVector<Value, 1> v2(v1);
+ EXPECT_EQ(v2.size(), 1UL);
+ EXPECT_EQ(*v2[0].value(), 3);
+ // Addresses should differ.
+ EXPECT_NE(v1[0].value().get(), v2[0].value().get());
+ EXPECT_TRUE(v2[0].copied());
+}
+
+TEST(InlinedVectorTest, CopyConstructorCopiesElementsAllocated) {
+ InlinedVector<Value, 1> v1;
+ v1.reserve(2);
+ v1.emplace_back(3);
+ v1.emplace_back(5);
+ InlinedVector<Value, 1> v2(v1);
+ EXPECT_EQ(v2.size(), 2UL);
+ EXPECT_EQ(*v2[0].value(), 3);
+ EXPECT_EQ(*v2[1].value(), 5);
+ // Addresses should differ.
+ EXPECT_NE(v1[0].value().get(), v2[0].value().get());
+ EXPECT_NE(v1[1].value().get(), v2[1].value().get());
+ EXPECT_TRUE(v2[0].copied());
+ EXPECT_TRUE(v2[1].copied());
+}
+
+TEST(InlinedVectorTest, CopyAssignmentCopiesElementsInlined) {
+ InlinedVector<Value, 1> v1;
+ v1.emplace_back(3);
+ InlinedVector<Value, 1> v2;
+ EXPECT_EQ(v2.size(), 0UL);
+ v2 = v1;
+ EXPECT_EQ(v2.size(), 1UL);
+ EXPECT_EQ(*v2[0].value(), 3);
+ // Addresses should differ.
+ EXPECT_NE(v1[0].value().get(), v2[0].value().get());
+ EXPECT_TRUE(v2[0].copied());
+}
+
+TEST(InlinedVectorTest, CopyAssignmentCopiesElementsAllocated) {
+ InlinedVector<Value, 1> v1;
+ v1.reserve(2);
+ v1.emplace_back(3);
+ v1.emplace_back(5);
+ InlinedVector<Value, 1> v2;
+ EXPECT_EQ(v2.size(), 0UL);
+ v2 = v1;
+ EXPECT_EQ(v2.size(), 2UL);
+ EXPECT_EQ(*v2[0].value(), 3);
+ EXPECT_EQ(*v2[1].value(), 5);
+ // Addresses should differ.
+ EXPECT_NE(v1[0].value().get(), v2[0].value().get());
+ EXPECT_NE(v1[1].value().get(), v2[1].value().get());
+ EXPECT_TRUE(v2[0].copied());
+ EXPECT_TRUE(v2[1].copied());
+}
+
+TEST(InlinedVectorTest, MoveConstructorMovesElementsInlined) {
+ InlinedVector<Value, 1> v1;
+ v1.emplace_back(3);
+ int* addr = v1[0].value().get();
+ InlinedVector<Value, 1> v2(std::move(v1));
+ EXPECT_EQ(v2.size(), 1UL);
+ EXPECT_EQ(*v2[0].value(), 3);
+ EXPECT_EQ(addr, v2[0].value().get());
+ EXPECT_TRUE(v2[0].moved());
+}
+
+TEST(InlinedVectorTest, MoveConstructorMovesElementsAllocated) {
+ InlinedVector<Value, 1> v1;
+ v1.reserve(2);
+ v1.emplace_back(3);
+ v1.emplace_back(5);
+ int* addr1 = v1[0].value().get();
+ int* addr2 = v1[1].value().get();
+ Value* data1 = v1.data();
+ InlinedVector<Value, 1> v2(std::move(v1));
+ EXPECT_EQ(v2.size(), 2UL);
+ EXPECT_EQ(*v2[0].value(), 3);
+ EXPECT_EQ(*v2[1].value(), 5);
+ EXPECT_EQ(addr1, v2[0].value().get());
+ EXPECT_EQ(addr2, v2[1].value().get());
+ // In this case, elements won't be moved, because we have just stolen
+ // the underlying storage.
+ EXPECT_EQ(data1, v2.data());
+}
+
+TEST(InlinedVectorTest, MoveAssignmentMovesElementsInlined) {
+ InlinedVector<Value, 1> v1;
+ v1.emplace_back(3);
+ int* addr = v1[0].value().get();
+ InlinedVector<Value, 1> v2;
+ EXPECT_EQ(v2.size(), 0UL);
+ v2 = std::move(v1);
+ EXPECT_EQ(v2.size(), 1UL);
+ EXPECT_EQ(*v2[0].value(), 3);
+ EXPECT_EQ(addr, v2[0].value().get());
+ EXPECT_TRUE(v2[0].moved());
+}
+
+TEST(InlinedVectorTest, MoveAssignmentMovesElementsAllocated) {
+ InlinedVector<Value, 1> v1;
+ v1.reserve(2);
+ v1.emplace_back(3);
+ v1.emplace_back(5);
+ int* addr1 = v1[0].value().get();
+ int* addr2 = v1[1].value().get();
+ Value* data1 = v1.data();
+ InlinedVector<Value, 1> v2;
+ EXPECT_EQ(v2.size(), 0UL);
+ v2 = std::move(v1);
+ EXPECT_EQ(v2.size(), 2UL);
+ EXPECT_EQ(*v2[0].value(), 3);
+ EXPECT_EQ(*v2[1].value(), 5);
+ EXPECT_EQ(addr1, v2[0].value().get());
+ EXPECT_EQ(addr2, v2[1].value().get());
+ // In this case, elements won't be moved, because we have just stolen
+ // the underlying storage.
+ EXPECT_EQ(data1, v2.data());
+}
+
TEST(InlinedVectorTest, PopBackInlined) {
InlinedVector<UniquePtr<int>, 2> v;
// Add two elements, pop one out
diff --git a/test/core/gprpp/ref_counted_test.cc b/test/core/gprpp/ref_counted_test.cc
index f85a2e4675..62a3ea4d53 100644
--- a/test/core/gprpp/ref_counted_test.cc
+++ b/test/core/gprpp/ref_counted_test.cc
@@ -29,7 +29,10 @@ namespace {
class Foo : public RefCounted<Foo> {
public:
- Foo() {}
+ Foo() {
+ static_assert(std::has_virtual_destructor<Foo>::value,
+ "PolymorphicRefCount doesn't have a virtual dtor");
+ }
};
TEST(RefCounted, Basic) {
@@ -45,6 +48,28 @@ TEST(RefCounted, ExtraRef) {
foo->Unref();
}
+class FooNonPolymorphic
+ : public RefCounted<FooNonPolymorphic, NonPolymorphicRefCount> {
+ public:
+ FooNonPolymorphic() {
+ static_assert(!std::has_virtual_destructor<FooNonPolymorphic>::value,
+ "NonPolymorphicRefCount has a virtual dtor");
+ }
+};
+
+TEST(RefCountedNonPolymorphic, Basic) {
+ FooNonPolymorphic* foo = New<FooNonPolymorphic>();
+ foo->Unref();
+}
+
+TEST(RefCountedNonPolymorphic, ExtraRef) {
+ FooNonPolymorphic* foo = New<FooNonPolymorphic>();
+ RefCountedPtr<FooNonPolymorphic> foop = foo->Ref();
+ foop.release();
+ foo->Unref();
+ foo->Unref();
+}
+
// Note: We use DebugOnlyTraceFlag instead of TraceFlag to ensure that
// things build properly in both debug and non-debug cases.
DebugOnlyTraceFlag foo_tracer(true, "foo");
@@ -66,6 +91,26 @@ TEST(RefCountedWithTracing, Basic) {
foo->Unref(DEBUG_LOCATION, "original_ref");
}
+class FooNonPolymorphicWithTracing
+ : public RefCountedWithTracing<FooNonPolymorphicWithTracing,
+ NonPolymorphicRefCount> {
+ public:
+ FooNonPolymorphicWithTracing() : RefCountedWithTracing(&foo_tracer) {}
+};
+
+TEST(RefCountedNonPolymorphicWithTracing, Basic) {
+ FooNonPolymorphicWithTracing* foo = New<FooNonPolymorphicWithTracing>();
+ RefCountedPtr<FooNonPolymorphicWithTracing> foop =
+ foo->Ref(DEBUG_LOCATION, "extra_ref");
+ foop.release();
+ foo->Unref(DEBUG_LOCATION, "extra_ref");
+ // Can use the no-argument methods, too.
+ foop = foo->Ref();
+ foop.release();
+ foo->Unref();
+ foo->Unref(DEBUG_LOCATION, "original_ref");
+}
+
} // namespace
} // namespace testing
} // namespace grpc_core
diff --git a/test/core/iomgr/BUILD b/test/core/iomgr/BUILD
index 70ee83acd2..e278632e50 100644
--- a/test/core/iomgr/BUILD
+++ b/test/core/iomgr/BUILD
@@ -40,7 +40,7 @@ grpc_cc_library(
grpc_cc_test(
name = "combiner_test",
srcs = ["combiner_test.cc"],
- data = ["//third_party/toolchains:RBE_USE_MACHINE_TYPE_LARGE"],
+ exec_compatible_with = ["//third_party/toolchains/machine_size:large"],
language = "C++",
deps = [
"//:gpr",
diff --git a/test/core/iomgr/buffer_list_test.cc b/test/core/iomgr/buffer_list_test.cc
index c7f30fa092..e104e8e91a 100644
--- a/test/core/iomgr/buffer_list_test.cc
+++ b/test/core/iomgr/buffer_list_test.cc
@@ -50,7 +50,7 @@ static void TestShutdownFlushesList() {
grpc_core::TracedBuffer::AddNewEntry(
&list, i, static_cast<void*>(&verifier_called[i]));
}
- grpc_core::TracedBuffer::Shutdown(&list, GRPC_ERROR_NONE);
+ grpc_core::TracedBuffer::Shutdown(&list, nullptr, GRPC_ERROR_NONE);
GPR_ASSERT(list == nullptr);
for (auto i = 0; i < NUM_ELEM; i++) {
GPR_ASSERT(gpr_atm_acq_load(&verifier_called[i]) ==
@@ -88,7 +88,7 @@ static void TestVerifierCalledOnAck() {
grpc_core::TracedBuffer::ProcessTimestamp(&list, &serr, &tss);
GPR_ASSERT(gpr_atm_acq_load(&verifier_called) == static_cast<gpr_atm>(1));
GPR_ASSERT(list == nullptr);
- grpc_core::TracedBuffer::Shutdown(&list, GRPC_ERROR_NONE);
+ grpc_core::TracedBuffer::Shutdown(&list, nullptr, GRPC_ERROR_NONE);
}
static void TestTcpBufferList() {
diff --git a/test/core/transport/chttp2/BUILD b/test/core/transport/chttp2/BUILD
index 6eff716b01..33437373e4 100644
--- a/test/core/transport/chttp2/BUILD
+++ b/test/core/transport/chttp2/BUILD
@@ -67,6 +67,22 @@ grpc_cc_test(
)
grpc_cc_test(
+ name = "context_list_test",
+ srcs = ["context_list_test.cc"],
+ external_deps = [
+ "gtest",
+ ],
+ language = "C++",
+ deps = [
+ "//:gpr",
+ "//:grpc",
+ "//test/core/util:gpr_test_util",
+ "//test/core/util:grpc_test_util",
+ ],
+)
+
+
+grpc_cc_test(
name = "hpack_encoder_test",
srcs = ["hpack_encoder_test.cc"],
language = "C++",
diff --git a/test/core/transport/chttp2/context_list_test.cc b/test/core/transport/chttp2/context_list_test.cc
new file mode 100644
index 0000000000..e64f1532ec
--- /dev/null
+++ b/test/core/transport/chttp2/context_list_test.cc
@@ -0,0 +1,102 @@
+/*
+ *
+ * Copyright 2018 gRPC authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include "src/core/lib/iomgr/port.h"
+
+#include <gtest/gtest.h>
+#include <new>
+#include <vector>
+
+#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
+#include "src/core/ext/transport/chttp2/transport/context_list.h"
+#include "src/core/lib/transport/transport.h"
+#include "test/core/util/mock_endpoint.h"
+#include "test/core/util/test_config.h"
+
+#include <grpc/grpc.h>
+
+namespace grpc_core {
+namespace testing {
+namespace {
+
+const uint32_t kByteOffset = 123;
+
+void TestExecuteFlushesListVerifier(void* arg, grpc_core::Timestamps* ts) {
+ ASSERT_NE(arg, nullptr);
+ EXPECT_EQ(ts->byte_offset, kByteOffset);
+ gpr_atm* done = reinterpret_cast<gpr_atm*>(arg);
+ gpr_atm_rel_store(done, static_cast<gpr_atm>(1));
+}
+
+void discard_write(grpc_slice slice) {}
+
+/** Tests that all ContextList elements in the list are flushed out on
+ * execute.
+ * Also tests that arg and byte_counter are passed correctly.
+ */
+TEST(ContextList, ExecuteFlushesList) {
+ grpc_core::ContextList* list = nullptr;
+ grpc_http2_set_write_timestamps_callback(TestExecuteFlushesListVerifier);
+ const int kNumElems = 5;
+ grpc_core::ExecCtx exec_ctx;
+ grpc_stream_refcount ref;
+ GRPC_STREAM_REF_INIT(&ref, 1, nullptr, nullptr, "dummy ref");
+ grpc_resource_quota* resource_quota =
+ grpc_resource_quota_create("context_list_test");
+ grpc_endpoint* mock_endpoint =
+ grpc_mock_endpoint_create(discard_write, resource_quota);
+ grpc_transport* t =
+ grpc_create_chttp2_transport(nullptr, mock_endpoint, true);
+ std::vector<grpc_chttp2_stream*> s;
+ s.reserve(kNumElems);
+ gpr_atm verifier_called[kNumElems];
+ for (auto i = 0; i < kNumElems; i++) {
+ s.push_back(static_cast<grpc_chttp2_stream*>(
+ gpr_malloc(grpc_transport_stream_size(t))));
+ grpc_transport_init_stream(reinterpret_cast<grpc_transport*>(t),
+ reinterpret_cast<grpc_stream*>(s[i]), &ref,
+ nullptr, nullptr);
+ s[i]->context = &verifier_called[i];
+ s[i]->byte_counter = kByteOffset;
+ gpr_atm_rel_store(&verifier_called[i], static_cast<gpr_atm>(0));
+ grpc_core::ContextList::Append(&list, s[i]);
+ }
+ grpc_core::Timestamps ts;
+ grpc_core::ContextList::Execute(list, &ts, GRPC_ERROR_NONE);
+ for (auto i = 0; i < kNumElems; i++) {
+ EXPECT_EQ(gpr_atm_acq_load(&verifier_called[i]), static_cast<gpr_atm>(1));
+ grpc_transport_destroy_stream(reinterpret_cast<grpc_transport*>(t),
+ reinterpret_cast<grpc_stream*>(s[i]),
+ nullptr);
+ exec_ctx.Flush();
+ gpr_free(s[i]);
+ }
+ grpc_transport_destroy(t);
+ grpc_resource_quota_unref(resource_quota);
+ exec_ctx.Flush();
+}
+} // namespace
+} // namespace testing
+} // namespace grpc_core
+
+int main(int argc, char** argv) {
+ grpc_test_init(argc, argv);
+ grpc_init();
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/test/core/util/mock_endpoint.cc b/test/core/util/mock_endpoint.cc
index ef6fd62b51..e5867cd526 100644
--- a/test/core/util/mock_endpoint.cc
+++ b/test/core/util/mock_endpoint.cc
@@ -103,18 +103,19 @@ static grpc_resource_user* me_get_resource_user(grpc_endpoint* ep) {
static int me_get_fd(grpc_endpoint* ep) { return -1; }
-static const grpc_endpoint_vtable vtable = {
- me_read,
- me_write,
- me_add_to_pollset,
- me_add_to_pollset_set,
- me_delete_from_pollset_set,
- me_shutdown,
- me_destroy,
- me_get_resource_user,
- me_get_peer,
- me_get_fd,
-};
+static bool me_can_track_err(grpc_endpoint* ep) { return false; }
+
+static const grpc_endpoint_vtable vtable = {me_read,
+ me_write,
+ me_add_to_pollset,
+ me_add_to_pollset_set,
+ me_delete_from_pollset_set,
+ me_shutdown,
+ me_destroy,
+ me_get_resource_user,
+ me_get_peer,
+ me_get_fd,
+ me_can_track_err};
grpc_endpoint* grpc_mock_endpoint_create(void (*on_write)(grpc_slice slice),
grpc_resource_quota* resource_quota) {
diff --git a/test/core/util/passthru_endpoint.cc b/test/core/util/passthru_endpoint.cc
index 3cc8ad6fe1..51b6de4695 100644
--- a/test/core/util/passthru_endpoint.cc
+++ b/test/core/util/passthru_endpoint.cc
@@ -155,6 +155,8 @@ static char* me_get_peer(grpc_endpoint* ep) {
static int me_get_fd(grpc_endpoint* ep) { return -1; }
+static bool me_can_track_err(grpc_endpoint* ep) { return false; }
+
static grpc_resource_user* me_get_resource_user(grpc_endpoint* ep) {
half* m = reinterpret_cast<half*>(ep);
return m->resource_user;
@@ -171,6 +173,7 @@ static const grpc_endpoint_vtable vtable = {
me_get_resource_user,
me_get_peer,
me_get_fd,
+ me_can_track_err,
};
static void half_init(half* m, passthru_endpoint* parent,
diff --git a/test/core/util/trickle_endpoint.cc b/test/core/util/trickle_endpoint.cc
index 62ed72a629..b0da735e57 100644
--- a/test/core/util/trickle_endpoint.cc
+++ b/test/core/util/trickle_endpoint.cc
@@ -131,6 +131,8 @@ static int te_get_fd(grpc_endpoint* ep) {
return grpc_endpoint_get_fd(te->wrapped);
}
+static bool te_can_track_err(grpc_endpoint* ep) { return false; }
+
static void te_finish_write(void* arg, grpc_error* error) {
trickle_endpoint* te = static_cast<trickle_endpoint*>(arg);
gpr_mu_lock(&te->mu);
@@ -148,7 +150,8 @@ static const grpc_endpoint_vtable vtable = {te_read,
te_destroy,
te_get_resource_user,
te_get_peer,
- te_get_fd};
+ te_get_fd,
+ te_can_track_err};
grpc_endpoint* grpc_trickle_endpoint_create(grpc_endpoint* wrap,
double bytes_per_second) {
diff --git a/test/cpp/end2end/client_callback_end2end_test.cc b/test/cpp/end2end/client_callback_end2end_test.cc
index 7ffc610ce2..a35991396a 100644
--- a/test/cpp/end2end/client_callback_end2end_test.cc
+++ b/test/cpp/end2end/client_callback_end2end_test.cc
@@ -34,6 +34,7 @@
#include "test/core/util/test_config.h"
#include "test/cpp/end2end/test_service_impl.h"
#include "test/cpp/util/byte_buffer_proto_helper.h"
+#include "test/cpp/util/string_ref_helper.h"
#include <gtest/gtest.h>
@@ -100,11 +101,13 @@ class ClientCallbackEnd2endTest
test_string += "Hello world. ";
request.set_message(test_string);
-
+ grpc::string val;
if (with_binary_metadata) {
+ request.mutable_param()->set_echo_metadata(true);
char bytes[8] = {'\0', '\1', '\2', '\3',
'\4', '\5', '\6', static_cast<char>(i)};
- cli_ctx.AddMetadata("custom-bin", grpc::string(bytes, 8));
+ val = grpc::string(bytes, 8);
+ cli_ctx.AddMetadata("custom-bin", val);
}
cli_ctx.set_compression_algorithm(GRPC_COMPRESS_GZIP);
@@ -114,10 +117,18 @@ class ClientCallbackEnd2endTest
bool done = false;
stub_->experimental_async()->Echo(
&cli_ctx, &request, &response,
- [&request, &response, &done, &mu, &cv](Status s) {
+ [&cli_ctx, &request, &response, &done, &mu, &cv, val,
+ with_binary_metadata](Status s) {
GPR_ASSERT(s.ok());
EXPECT_EQ(request.message(), response.message());
+ if (with_binary_metadata) {
+ EXPECT_EQ(
+ 1u, cli_ctx.GetServerTrailingMetadata().count("custom-bin"));
+ EXPECT_EQ(val, ToString(cli_ctx.GetServerTrailingMetadata()
+ .find("custom-bin")
+ ->second));
+ }
std::lock_guard<std::mutex> l(mu);
done = true;
cv.notify_one();
diff --git a/test/cpp/end2end/client_interceptors_end2end_test.cc b/test/cpp/end2end/client_interceptors_end2end_test.cc
index 0b34ec93ae..60e8b051ab 100644
--- a/test/cpp/end2end/client_interceptors_end2end_test.cc
+++ b/test/cpp/end2end/client_interceptors_end2end_test.cc
@@ -361,15 +361,13 @@ class ClientInterceptorsEnd2endTest : public ::testing::Test {
TEST_F(ClientInterceptorsEnd2endTest, ClientInterceptorLoggingTest) {
ChannelArguments args;
DummyInterceptor::Reset();
- auto creators = std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>(
- new std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>());
- creators->push_back(std::unique_ptr<LoggingInterceptorFactory>(
+ std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
+ creators;
+ creators.push_back(std::unique_ptr<LoggingInterceptorFactory>(
new LoggingInterceptorFactory()));
// Add 20 dummy interceptors
for (auto i = 0; i < 20; i++) {
- creators->push_back(std::unique_ptr<DummyInterceptorFactory>(
+ creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
new DummyInterceptorFactory()));
}
auto channel = experimental::CreateCustomChannelWithInterceptors(
@@ -382,20 +380,18 @@ TEST_F(ClientInterceptorsEnd2endTest, ClientInterceptorLoggingTest) {
TEST_F(ClientInterceptorsEnd2endTest, ClientInterceptorHijackingTest) {
ChannelArguments args;
DummyInterceptor::Reset();
- auto creators = std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>(
- new std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>());
+ std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
+ creators;
// Add 20 dummy interceptors before hijacking interceptor
for (auto i = 0; i < 20; i++) {
- creators->push_back(std::unique_ptr<DummyInterceptorFactory>(
+ creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
new DummyInterceptorFactory()));
}
- creators->push_back(std::unique_ptr<HijackingInterceptorFactory>(
+ creators.push_back(std::unique_ptr<HijackingInterceptorFactory>(
new HijackingInterceptorFactory()));
// Add 20 dummy interceptors after hijacking interceptor
for (auto i = 0; i < 20; i++) {
- creators->push_back(std::unique_ptr<DummyInterceptorFactory>(
+ creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
new DummyInterceptorFactory()));
}
auto channel = experimental::CreateCustomChannelWithInterceptors(
@@ -408,13 +404,11 @@ TEST_F(ClientInterceptorsEnd2endTest, ClientInterceptorHijackingTest) {
TEST_F(ClientInterceptorsEnd2endTest, ClientInterceptorLogThenHijackTest) {
ChannelArguments args;
- auto creators = std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>(
- new std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>());
- creators->push_back(std::unique_ptr<LoggingInterceptorFactory>(
+ std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
+ creators;
+ creators.push_back(std::unique_ptr<LoggingInterceptorFactory>(
new LoggingInterceptorFactory()));
- creators->push_back(std::unique_ptr<HijackingInterceptorFactory>(
+ creators.push_back(std::unique_ptr<HijackingInterceptorFactory>(
new HijackingInterceptorFactory()));
auto channel = experimental::CreateCustomChannelWithInterceptors(
server_address_, InsecureChannelCredentials(), args, std::move(creators));
@@ -426,21 +420,19 @@ TEST_F(ClientInterceptorsEnd2endTest,
ClientInterceptorHijackingMakesAnotherCallTest) {
ChannelArguments args;
DummyInterceptor::Reset();
- auto creators = std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>(
- new std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>());
+ std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
+ creators;
// Add 5 dummy interceptors before hijacking interceptor
for (auto i = 0; i < 5; i++) {
- creators->push_back(std::unique_ptr<DummyInterceptorFactory>(
+ creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
new DummyInterceptorFactory()));
}
- creators->push_back(
+ creators.push_back(
std::unique_ptr<experimental::ClientInterceptorFactoryInterface>(
new HijackingInterceptorMakesAnotherCallFactory()));
// Add 7 dummy interceptors after hijacking interceptor
for (auto i = 0; i < 7; i++) {
- creators->push_back(std::unique_ptr<DummyInterceptorFactory>(
+ creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
new DummyInterceptorFactory()));
}
auto channel = server_->experimental().InProcessChannelWithInterceptors(
@@ -456,15 +448,13 @@ TEST_F(ClientInterceptorsEnd2endTest,
ClientInterceptorLoggingTestWithCallback) {
ChannelArguments args;
DummyInterceptor::Reset();
- auto creators = std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>(
- new std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>());
- creators->push_back(std::unique_ptr<LoggingInterceptorFactory>(
+ std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
+ creators;
+ creators.push_back(std::unique_ptr<LoggingInterceptorFactory>(
new LoggingInterceptorFactory()));
// Add 20 dummy interceptors
for (auto i = 0; i < 20; i++) {
- creators->push_back(std::unique_ptr<DummyInterceptorFactory>(
+ creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
new DummyInterceptorFactory()));
}
auto channel = server_->experimental().InProcessChannelWithInterceptors(
@@ -496,15 +486,13 @@ class ClientInterceptorsStreamingEnd2endTest : public ::testing::Test {
TEST_F(ClientInterceptorsStreamingEnd2endTest, ClientStreamingTest) {
ChannelArguments args;
DummyInterceptor::Reset();
- auto creators = std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>(
- new std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>());
- creators->push_back(std::unique_ptr<LoggingInterceptorFactory>(
+ std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
+ creators;
+ creators.push_back(std::unique_ptr<LoggingInterceptorFactory>(
new LoggingInterceptorFactory()));
// Add 20 dummy interceptors
for (auto i = 0; i < 20; i++) {
- creators->push_back(std::unique_ptr<DummyInterceptorFactory>(
+ creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
new DummyInterceptorFactory()));
}
auto channel = experimental::CreateCustomChannelWithInterceptors(
@@ -517,15 +505,13 @@ TEST_F(ClientInterceptorsStreamingEnd2endTest, ClientStreamingTest) {
TEST_F(ClientInterceptorsStreamingEnd2endTest, ServerStreamingTest) {
ChannelArguments args;
DummyInterceptor::Reset();
- auto creators = std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>(
- new std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>());
- creators->push_back(std::unique_ptr<LoggingInterceptorFactory>(
+ std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
+ creators;
+ creators.push_back(std::unique_ptr<LoggingInterceptorFactory>(
new LoggingInterceptorFactory()));
// Add 20 dummy interceptors
for (auto i = 0; i < 20; i++) {
- creators->push_back(std::unique_ptr<DummyInterceptorFactory>(
+ creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
new DummyInterceptorFactory()));
}
auto channel = experimental::CreateCustomChannelWithInterceptors(
@@ -538,15 +524,13 @@ TEST_F(ClientInterceptorsStreamingEnd2endTest, ServerStreamingTest) {
TEST_F(ClientInterceptorsStreamingEnd2endTest, BidiStreamingTest) {
ChannelArguments args;
DummyInterceptor::Reset();
- auto creators = std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>(
- new std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>());
- creators->push_back(std::unique_ptr<LoggingInterceptorFactory>(
+ std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
+ creators;
+ creators.push_back(std::unique_ptr<LoggingInterceptorFactory>(
new LoggingInterceptorFactory()));
// Add 20 dummy interceptors
for (auto i = 0; i < 20; i++) {
- creators->push_back(std::unique_ptr<DummyInterceptorFactory>(
+ creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
new DummyInterceptorFactory()));
}
auto channel = experimental::CreateCustomChannelWithInterceptors(
@@ -583,13 +567,11 @@ TEST_F(ClientGlobalInterceptorEnd2endTest, DummyGlobalInterceptor) {
experimental::RegisterGlobalClientInterceptorFactory(&global_factory);
ChannelArguments args;
DummyInterceptor::Reset();
- auto creators = std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>(
- new std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>());
+ std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
+ creators;
// Add 20 dummy interceptors
for (auto i = 0; i < 20; i++) {
- creators->push_back(std::unique_ptr<DummyInterceptorFactory>(
+ creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
new DummyInterceptorFactory()));
}
auto channel = experimental::CreateCustomChannelWithInterceptors(
@@ -610,13 +592,11 @@ TEST_F(ClientGlobalInterceptorEnd2endTest, LoggingGlobalInterceptor) {
experimental::RegisterGlobalClientInterceptorFactory(&global_factory);
ChannelArguments args;
DummyInterceptor::Reset();
- auto creators = std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>(
- new std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>());
+ std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
+ creators;
// Add 20 dummy interceptors
for (auto i = 0; i < 20; i++) {
- creators->push_back(std::unique_ptr<DummyInterceptorFactory>(
+ creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
new DummyInterceptorFactory()));
}
auto channel = experimental::CreateCustomChannelWithInterceptors(
@@ -637,13 +617,11 @@ TEST_F(ClientGlobalInterceptorEnd2endTest, HijackingGlobalInterceptor) {
experimental::RegisterGlobalClientInterceptorFactory(&global_factory);
ChannelArguments args;
DummyInterceptor::Reset();
- auto creators = std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>(
- new std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>());
+ std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
+ creators;
// Add 20 dummy interceptors
for (auto i = 0; i < 20; i++) {
- creators->push_back(std::unique_ptr<DummyInterceptorFactory>(
+ creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
new DummyInterceptorFactory()));
}
auto channel = experimental::CreateCustomChannelWithInterceptors(
diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc
index 9218c85717..312065a2df 100644
--- a/test/cpp/end2end/client_lb_end2end_test.cc
+++ b/test/cpp/end2end/client_lb_end2end_test.cc
@@ -149,7 +149,7 @@ class ClientLbEnd2endTest : public ::testing::Test {
void StartServers(size_t num_servers,
std::vector<int> ports = std::vector<int>()) {
- CreateServers(num_servers, ports);
+ CreateServers(num_servers, std::move(ports));
for (size_t i = 0; i < num_servers; ++i) {
StartServer(i);
}
@@ -191,6 +191,11 @@ class ClientLbEnd2endTest : public ::testing::Test {
grpc_channel_args_destroy(fake_results);
}
+ void SetFailureOnReresolution() {
+ grpc_core::ExecCtx exec_ctx;
+ response_generator_->SetFailureOnReresolution();
+ }
+
std::vector<int> GetServersPorts() {
std::vector<int> ports;
for (const auto& server : servers_) ports.push_back(server->port_);
@@ -728,6 +733,23 @@ TEST_F(ClientLbEnd2endTest, PickFirstCheckStateBeforeStartWatch) {
EXPECT_EQ("pick_first", channel_2->GetLoadBalancingPolicyName());
}
+TEST_F(ClientLbEnd2endTest, PickFirstIdleOnDisconnect) {
+ // Start server, send RPC, and make sure channel is READY.
+ const int kNumServers = 1;
+ StartServers(kNumServers);
+ auto channel = BuildChannel(""); // pick_first is the default.
+ auto stub = BuildStub(channel);
+ SetNextResolution(GetServersPorts());
+ CheckRpcSendOk(stub, DEBUG_LOCATION);
+ EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY);
+ // Stop server. Channel should go into state IDLE.
+ SetFailureOnReresolution();
+ servers_[0]->Shutdown();
+ EXPECT_TRUE(WaitForChannelNotReady(channel.get()));
+ EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_IDLE);
+ servers_.clear();
+}
+
TEST_F(ClientLbEnd2endTest, RoundRobin) {
// Start servers and send one RPC per server.
const int kNumServers = 3;
diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc
index 4558437102..03291e1785 100644
--- a/test/cpp/end2end/end2end_test.cc
+++ b/test/cpp/end2end/end2end_test.cc
@@ -272,6 +272,7 @@ class End2endTest : public ::testing::TestWithParam<TestScenario> {
std::unique_ptr<experimental::ServerInterceptorFactoryInterface>>
creators;
// Add 20 dummy server interceptors
+ creators.reserve(20);
for (auto i = 0; i < 20; i++) {
creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
new DummyInterceptorFactory()));
diff --git a/test/cpp/end2end/grpclb_end2end_test.cc b/test/cpp/end2end/grpclb_end2end_test.cc
index 6ce0696114..5b304dc16b 100644
--- a/test/cpp/end2end/grpclb_end2end_test.cc
+++ b/test/cpp/end2end/grpclb_end2end_test.cc
@@ -553,10 +553,11 @@ class GrpclbEnd2endTest : public ::testing::Test {
return status;
}
- void CheckRpcSendOk(const size_t times = 1, const int timeout_ms = 1000) {
+ void CheckRpcSendOk(const size_t times = 1, const int timeout_ms = 1000,
+ bool wait_for_ready = false) {
for (size_t i = 0; i < times; ++i) {
EchoResponse response;
- const Status status = SendRpc(&response, timeout_ms);
+ const Status status = SendRpc(&response, timeout_ms, wait_for_ready);
EXPECT_TRUE(status.ok()) << "code=" << status.error_code()
<< " message=" << status.error_message();
EXPECT_EQ(response.message(), kRequestMessage_);
@@ -717,10 +718,9 @@ TEST_F(SingleBalancerTest, InitiallyEmptyServerlist) {
ScheduleResponseForBalancer(
0, BalancerServiceImpl::BuildResponseForBackends(GetBackendPorts(), {}),
kServerlistDelayMs);
-
const auto t0 = system_clock::now();
// Client will block: LB will initially send empty serverlist.
- CheckRpcSendOk(1, kCallDeadlineMs);
+ CheckRpcSendOk(1, kCallDeadlineMs, true /* wait_for_ready */);
const auto ellapsed_ms =
std::chrono::duration_cast<std::chrono::milliseconds>(
system_clock::now() - t0);
diff --git a/test/cpp/end2end/interceptors_util.cc b/test/cpp/end2end/interceptors_util.cc
index 602d1695a3..5d59c1a4b7 100644
--- a/test/cpp/end2end/interceptors_util.cc
+++ b/test/cpp/end2end/interceptors_util.cc
@@ -132,16 +132,13 @@ bool CheckMetadata(const std::multimap<grpc::string_ref, grpc::string_ref>& map,
return false;
}
-std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>
+std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
CreateDummyClientInterceptors() {
- auto creators = std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>(
- new std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>());
+ std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
+ creators;
// Add 20 dummy interceptors before hijacking interceptor
for (auto i = 0; i < 20; i++) {
- creators->push_back(std::unique_ptr<DummyInterceptorFactory>(
+ creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
new DummyInterceptorFactory()));
}
return creators;
diff --git a/test/cpp/end2end/interceptors_util.h b/test/cpp/end2end/interceptors_util.h
index b4c4791fca..d886e32494 100644
--- a/test/cpp/end2end/interceptors_util.h
+++ b/test/cpp/end2end/interceptors_util.h
@@ -149,8 +149,7 @@ void MakeCallbackCall(const std::shared_ptr<Channel>& channel);
bool CheckMetadata(const std::multimap<grpc::string_ref, grpc::string_ref>& map,
const string& key, const string& value);
-std::unique_ptr<std::vector<
- std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>
+std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
CreateDummyClientInterceptors();
inline void* tag(int i) { return (void*)static_cast<intptr_t>(i); }
diff --git a/test/cpp/end2end/server_interceptors_end2end_test.cc b/test/cpp/end2end/server_interceptors_end2end_test.cc
index 4ae086ea76..295d63516b 100644
--- a/test/cpp/end2end/server_interceptors_end2end_test.cc
+++ b/test/cpp/end2end/server_interceptors_end2end_test.cc
@@ -391,6 +391,7 @@ TEST_F(ServerInterceptorsAsyncEnd2endTest, GenericRPCTest) {
builder.RegisterAsyncGenericService(&service);
std::vector<std::unique_ptr<experimental::ServerInterceptorFactoryInterface>>
creators;
+ creators.reserve(20);
for (auto i = 0; i < 20; i++) {
creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
new DummyInterceptorFactory()));
@@ -486,6 +487,7 @@ TEST_F(ServerInterceptorsAsyncEnd2endTest, UnimplementedRpcTest) {
builder.AddListeningPort(server_address, InsecureServerCredentials());
std::vector<std::unique_ptr<experimental::ServerInterceptorFactoryInterface>>
creators;
+ creators.reserve(20);
for (auto i = 0; i < 20; i++) {
creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
new DummyInterceptorFactory()));
@@ -539,6 +541,7 @@ TEST_F(ServerInterceptorsSyncUnimplementedEnd2endTest, UnimplementedRpcTest) {
builder.AddListeningPort(server_address, InsecureServerCredentials());
std::vector<std::unique_ptr<experimental::ServerInterceptorFactoryInterface>>
creators;
+ creators.reserve(20);
for (auto i = 0; i < 20; i++) {
creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
new DummyInterceptorFactory()));
diff --git a/test/cpp/interop/interop_client.cc b/test/cpp/interop/interop_client.cc
index a99cf8122f..4ff153f980 100644
--- a/test/cpp/interop/interop_client.cc
+++ b/test/cpp/interop/interop_client.cc
@@ -76,7 +76,7 @@ void UnaryCompressionChecks(const InteropClientContextInspector& inspector,
InteropClient::ServiceStub::ServiceStub(
ChannelCreationFunc channel_creation_func, bool new_stub_every_call)
- : channel_creation_func_(channel_creation_func),
+ : channel_creation_func_(std::move(channel_creation_func)),
channel_(channel_creation_func_()),
new_stub_every_call_(new_stub_every_call) {
// If new_stub_every_call is false, then this is our chance to initialize
@@ -112,7 +112,7 @@ void InteropClient::ServiceStub::ResetChannel() {
InteropClient::InteropClient(ChannelCreationFunc channel_creation_func,
bool new_stub_every_test_case,
bool do_not_abort_on_transient_failures)
- : serviceStub_(channel_creation_func, new_stub_every_test_case),
+ : serviceStub_(std::move(channel_creation_func), new_stub_every_test_case),
do_not_abort_on_transient_failures_(do_not_abort_on_transient_failures) {}
bool InteropClient::AssertStatusOk(const Status& s,
diff --git a/test/cpp/interop/stress_interop_client.cc b/test/cpp/interop/stress_interop_client.cc
index 7dc1956f78..5bbe913365 100644
--- a/test/cpp/interop/stress_interop_client.cc
+++ b/test/cpp/interop/stress_interop_client.cc
@@ -73,7 +73,7 @@ StressTestInteropClient::StressTestInteropClient(
long sleep_duration_ms, bool do_not_abort_on_transient_failures)
: test_id_(test_id),
server_address_(server_address),
- channel_creation_func_(channel_creation_func),
+ channel_creation_func_(std::move(channel_creation_func)),
interop_client_(new InteropClient(channel_creation_func_, false,
do_not_abort_on_transient_failures)),
test_selector_(test_selector),
diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc
index 446dc93edb..8d12606434 100644
--- a/test/cpp/microbenchmarks/bm_call_create.cc
+++ b/test/cpp/microbenchmarks/bm_call_create.cc
@@ -135,7 +135,8 @@ static void BM_LameChannelCallCreateCpp(benchmark::State& state) {
"",
grpc_lame_client_channel_create("localhost:1234",
GRPC_STATUS_UNAUTHENTICATED, "blah"),
- nullptr));
+ std::vector<std::unique_ptr<
+ grpc::experimental::ClientInterceptorFactoryInterface>>()));
grpc::CompletionQueue cq;
grpc::testing::EchoRequest send_request;
grpc::testing::EchoResponse recv_response;
diff --git a/test/cpp/microbenchmarks/bm_chttp2_transport.cc b/test/cpp/microbenchmarks/bm_chttp2_transport.cc
index f7ae16e61d..650152ecc0 100644
--- a/test/cpp/microbenchmarks/bm_chttp2_transport.cc
+++ b/test/cpp/microbenchmarks/bm_chttp2_transport.cc
@@ -54,7 +54,8 @@ class DummyEndpoint : public grpc_endpoint {
destroy,
get_resource_user,
get_peer,
- get_fd};
+ get_fd,
+ can_track_err};
grpc_endpoint::vtable = &my_vtable;
ru_ = grpc_resource_user_create(Library::get().rq(), "dummy_endpoint");
}
@@ -125,6 +126,7 @@ class DummyEndpoint : public grpc_endpoint {
}
static char* get_peer(grpc_endpoint* ep) { return gpr_strdup("test"); }
static int get_fd(grpc_endpoint* ep) { return 0; }
+ static bool can_track_err(grpc_endpoint* ep) { return false; }
};
class Fixture {
diff --git a/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc b/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc
index 85767c8758..dca97c85b1 100644
--- a/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc
+++ b/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc
@@ -94,6 +94,7 @@ static const grpc_event_engine_vtable* init_engine_vtable(bool) {
g_vtable.pollset_destroy = pollset_destroy;
g_vtable.pollset_work = pollset_work;
g_vtable.pollset_kick = pollset_kick;
+ g_vtable.shutdown_background_closure = [] {};
g_vtable.shutdown_engine = [] {};
return &g_vtable;
diff --git a/test/cpp/microbenchmarks/fullstack_fixtures.h b/test/cpp/microbenchmarks/fullstack_fixtures.h
index e57eb6ddd1..71e8d9972b 100644
--- a/test/cpp/microbenchmarks/fullstack_fixtures.h
+++ b/test/cpp/microbenchmarks/fullstack_fixtures.h
@@ -218,7 +218,10 @@ class EndpointPairFixture : public BaseFixture {
"target", &c_args, GRPC_CLIENT_DIRECT_CHANNEL, client_transport_);
grpc_chttp2_transport_start_reading(client_transport_, nullptr, nullptr);
- channel_ = CreateChannelInternal("", channel, nullptr);
+ channel_ = CreateChannelInternal(
+ "", channel,
+ std::vector<std::unique_ptr<
+ experimental::ClientInterceptorFactoryInterface>>());
}
}
diff --git a/test/cpp/performance/writes_per_rpc_test.cc b/test/cpp/performance/writes_per_rpc_test.cc
index 32eab1fc44..baeede34ea 100644
--- a/test/cpp/performance/writes_per_rpc_test.cc
+++ b/test/cpp/performance/writes_per_rpc_test.cc
@@ -118,7 +118,10 @@ class EndpointPairFixture {
"target", &c_args, GRPC_CLIENT_DIRECT_CHANNEL, transport);
grpc_chttp2_transport_start_reading(transport, nullptr, nullptr);
- channel_ = CreateChannelInternal("", channel, nullptr);
+ channel_ = CreateChannelInternal(
+ "", channel,
+ std::vector<std::unique_ptr<
+ experimental::ClientInterceptorFactoryInterface>>());
}
}
diff --git a/test/cpp/qps/BUILD b/test/cpp/qps/BUILD
index 26f43284a6..626ac5f3f2 100644
--- a/test/cpp/qps/BUILD
+++ b/test/cpp/qps/BUILD
@@ -170,7 +170,7 @@ grpc_cc_test(
grpc_cc_test(
name = "qps_openloop_test",
srcs = ["qps_openloop_test.cc"],
- data = ["//third_party/toolchains:RBE_USE_MACHINE_TYPE_LARGE"],
+ exec_compatible_with = ["//third_party/toolchains/machine_size:large"],
deps = [
":benchmark_config",
":driver_impl",
diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc
index 11cfb4aa05..181e11f12b 100644
--- a/test/cpp/qps/driver.cc
+++ b/test/cpp/qps/driver.cc
@@ -95,6 +95,17 @@ static deque<string> get_workers(const string& env_name) {
return out;
}
+std::string GetCredType(
+ const std::string& worker_addr,
+ const std::map<std::string, std::string>& per_worker_credential_types,
+ const std::string& credential_type) {
+ auto it = per_worker_credential_types.find(worker_addr);
+ if (it != per_worker_credential_types.end()) {
+ return it->second;
+ }
+ return credential_type;
+}
+
// helpers for postprocess_scenario_result
static double WallTime(const ClientStats& s) { return s.time_elapsed(); }
static double SystemTime(const ClientStats& s) { return s.time_system(); }
@@ -198,8 +209,9 @@ std::unique_ptr<ScenarioResult> RunScenario(
const ServerConfig& initial_server_config, size_t num_servers,
int warmup_seconds, int benchmark_seconds, int spawn_local_worker_count,
const grpc::string& qps_server_target_override,
- const grpc::string& credential_type, bool run_inproc,
- int32_t median_latency_collection_interval_millis) {
+ const grpc::string& credential_type,
+ const std::map<std::string, std::string>& per_worker_credential_types,
+ bool run_inproc, int32_t median_latency_collection_interval_millis) {
if (run_inproc) {
g_inproc_servers = new std::vector<grpc::testing::Server*>;
}
@@ -278,7 +290,9 @@ std::unique_ptr<ScenarioResult> RunScenario(
if (!run_inproc) {
servers[i].stub = WorkerService::NewStub(CreateChannel(
workers[i], GetCredentialsProvider()->GetChannelCredentials(
- credential_type, &channel_args)));
+ GetCredType(workers[i], per_worker_credential_types,
+ credential_type),
+ &channel_args)));
} else {
servers[i].stub = WorkerService::NewStub(
local_workers[i]->InProcessChannel(channel_args));
@@ -335,9 +349,11 @@ std::unique_ptr<ScenarioResult> RunScenario(
gpr_log(GPR_INFO, "Starting client on %s (worker #%" PRIuPTR ")",
worker.c_str(), i + num_servers);
if (!run_inproc) {
- clients[i].stub = WorkerService::NewStub(
- CreateChannel(worker, GetCredentialsProvider()->GetChannelCredentials(
- credential_type, &channel_args)));
+ clients[i].stub = WorkerService::NewStub(CreateChannel(
+ worker,
+ GetCredentialsProvider()->GetChannelCredentials(
+ GetCredType(worker, per_worker_credential_types, credential_type),
+ &channel_args)));
} else {
clients[i].stub = WorkerService::NewStub(
local_workers[i + num_servers]->InProcessChannel(channel_args));
@@ -529,7 +545,9 @@ std::unique_ptr<ScenarioResult> RunScenario(
return result;
}
-bool RunQuit(const grpc::string& credential_type) {
+bool RunQuit(
+ const grpc::string& credential_type,
+ const std::map<std::string, std::string>& per_worker_credential_types) {
// Get client, server lists
bool result = true;
auto workers = get_workers("QPS_WORKERS");
@@ -541,7 +559,9 @@ bool RunQuit(const grpc::string& credential_type) {
for (size_t i = 0; i < workers.size(); i++) {
auto stub = WorkerService::NewStub(CreateChannel(
workers[i], GetCredentialsProvider()->GetChannelCredentials(
- credential_type, &channel_args)));
+ GetCredType(workers[i], per_worker_credential_types,
+ credential_type),
+ &channel_args)));
Void dummy;
grpc::ClientContext ctx;
ctx.set_wait_for_ready(true);
diff --git a/test/cpp/qps/driver.h b/test/cpp/qps/driver.h
index cda89f7ddf..568871d2da 100644
--- a/test/cpp/qps/driver.h
+++ b/test/cpp/qps/driver.h
@@ -32,10 +32,13 @@ std::unique_ptr<ScenarioResult> RunScenario(
const grpc::testing::ServerConfig& server_config, size_t num_servers,
int warmup_seconds, int benchmark_seconds, int spawn_local_worker_count,
const grpc::string& qps_server_target_override,
- const grpc::string& credential_type, bool run_inproc,
- int32_t median_latency_collection_interval_millis);
+ const grpc::string& credential_type,
+ const std::map<std::string, std::string>& per_worker_credential_types,
+ bool run_inproc, int32_t median_latency_collection_interval_millis);
-bool RunQuit(const grpc::string& credential_type);
+bool RunQuit(
+ const grpc::string& credential_type,
+ const std::map<std::string, std::string>& per_worker_credential_types);
} // namespace testing
} // namespace grpc
diff --git a/test/cpp/qps/inproc_sync_unary_ping_pong_test.cc b/test/cpp/qps/inproc_sync_unary_ping_pong_test.cc
index 56d1730252..6257e42ebf 100644
--- a/test/cpp/qps/inproc_sync_unary_ping_pong_test.cc
+++ b/test/cpp/qps/inproc_sync_unary_ping_pong_test.cc
@@ -48,7 +48,7 @@ static void RunSynchronousUnaryPingPong() {
const auto result =
RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2, "",
- kInsecureCredentialsType, true, 0);
+ kInsecureCredentialsType, {}, true, 0);
GetReporter()->ReportQPS(*result);
GetReporter()->ReportLatency(*result);
diff --git a/test/cpp/qps/qps_json_driver.cc b/test/cpp/qps/qps_json_driver.cc
index eaa0dd992c..1d67e79b86 100644
--- a/test/cpp/qps/qps_json_driver.cc
+++ b/test/cpp/qps/qps_json_driver.cc
@@ -65,6 +65,16 @@ DEFINE_string(json_file_out, "", "File to write the JSON output to.");
DEFINE_string(credential_type, grpc::testing::kInsecureCredentialsType,
"Credential type for communication with workers");
+DEFINE_string(
+ per_worker_credential_types, "",
+ "A map of QPS worker addresses to credential types. When creating a "
+ "channel to a QPS worker's driver port, the qps_json_driver first checks "
+ "if the 'name:port' string is in the map, and it uses the corresponding "
+ "credential type if so. If the QPS worker's 'name:port' string is not "
+ "in the map, then the driver -> worker channel will be created with "
+ "the credentials specified in --credential_type. The value of this flag "
+ "is a semicolon-separated list of map entries, where each map entry is "
+ "a comma-separated pair.");
DEFINE_bool(run_inproc, false, "Perform an in-process transport test");
DEFINE_int32(
median_latency_collection_interval_millis, 0,
@@ -75,16 +85,53 @@ DEFINE_int32(
namespace grpc {
namespace testing {
-static std::unique_ptr<ScenarioResult> RunAndReport(const Scenario& scenario,
- bool* success) {
+static std::map<std::string, std::string>
+ConstructPerWorkerCredentialTypesMap() {
+ // Parse a list of the form: "addr1,cred_type1;addr2,cred_type2;..." into
+ // a map.
+ std::string remaining = FLAGS_per_worker_credential_types;
+ std::map<std::string, std::string> out;
+ while (!remaining.empty()) {
+ size_t next_semicolon = remaining.find(';');
+ std::string next_entry = remaining.substr(0, next_semicolon);
+ if (next_semicolon == std::string::npos) {
+ remaining = "";
+ } else {
+ remaining = remaining.substr(next_semicolon + 1, std::string::npos);
+ }
+ size_t comma = next_entry.find(',');
+ if (comma == std::string::npos) {
+ gpr_log(GPR_ERROR,
+ "Expectd --per_worker_credential_types to be a list "
+ "of the form: 'addr1,cred_type1;addr2,cred_type2;...' "
+ "into.");
+ abort();
+ }
+ std::string addr = next_entry.substr(0, comma);
+ std::string cred_type = next_entry.substr(comma + 1, std::string::npos);
+ if (out.find(addr) != out.end()) {
+ gpr_log(GPR_ERROR,
+ "Found duplicate addr in per_worker_credential_types.");
+ abort();
+ }
+ out[addr] = cred_type;
+ }
+ return out;
+}
+
+static std::unique_ptr<ScenarioResult> RunAndReport(
+ const Scenario& scenario,
+ const std::map<std::string, std::string>& per_worker_credential_types,
+ bool* success) {
std::cerr << "RUNNING SCENARIO: " << scenario.name() << "\n";
- auto result = RunScenario(
- scenario.client_config(), scenario.num_clients(),
- scenario.server_config(), scenario.num_servers(),
- scenario.warmup_seconds(), scenario.benchmark_seconds(),
- !FLAGS_run_inproc ? scenario.spawn_local_worker_count() : -2,
- FLAGS_qps_server_target_override, FLAGS_credential_type, FLAGS_run_inproc,
- FLAGS_median_latency_collection_interval_millis);
+ auto result =
+ RunScenario(scenario.client_config(), scenario.num_clients(),
+ scenario.server_config(), scenario.num_servers(),
+ scenario.warmup_seconds(), scenario.benchmark_seconds(),
+ !FLAGS_run_inproc ? scenario.spawn_local_worker_count() : -2,
+ FLAGS_qps_server_target_override, FLAGS_credential_type,
+ per_worker_credential_types, FLAGS_run_inproc,
+ FLAGS_median_latency_collection_interval_millis);
// Amend the result with scenario config. Eventually we should adjust
// RunScenario contract so we don't need to touch the result here.
@@ -115,21 +162,26 @@ static std::unique_ptr<ScenarioResult> RunAndReport(const Scenario& scenario,
return result;
}
-static double GetCpuLoad(Scenario* scenario, double offered_load,
- bool* success) {
+static double GetCpuLoad(
+ Scenario* scenario, double offered_load,
+ const std::map<std::string, std::string>& per_worker_credential_types,
+ bool* success) {
scenario->mutable_client_config()
->mutable_load_params()
->mutable_poisson()
->set_offered_load(offered_load);
- auto result = RunAndReport(*scenario, success);
+ auto result = RunAndReport(*scenario, per_worker_credential_types, success);
return result->summary().server_cpu_usage();
}
-static double BinarySearch(Scenario* scenario, double targeted_cpu_load,
- double low, double high, bool* success) {
+static double BinarySearch(
+ Scenario* scenario, double targeted_cpu_load, double low, double high,
+ const std::map<std::string, std::string>& per_worker_credential_types,
+ bool* success) {
while (low <= high * (1 - FLAGS_error_tolerance)) {
double mid = low + (high - low) / 2;
- double current_cpu_load = GetCpuLoad(scenario, mid, success);
+ double current_cpu_load =
+ GetCpuLoad(scenario, mid, per_worker_credential_types, success);
gpr_log(GPR_DEBUG, "Binary Search: current_offered_load %.0f", mid);
if (!*success) {
gpr_log(GPR_ERROR, "Client/Server Failure");
@@ -145,12 +197,14 @@ static double BinarySearch(Scenario* scenario, double targeted_cpu_load,
return low;
}
-static double SearchOfferedLoad(double initial_offered_load,
- double targeted_cpu_load, Scenario* scenario,
- bool* success) {
+static double SearchOfferedLoad(
+ double initial_offered_load, double targeted_cpu_load, Scenario* scenario,
+ const std::map<std::string, std::string>& per_worker_credential_types,
+ bool* success) {
std::cerr << "RUNNING SCENARIO: " << scenario->name() << "\n";
double current_offered_load = initial_offered_load;
- double current_cpu_load = GetCpuLoad(scenario, current_offered_load, success);
+ double current_cpu_load = GetCpuLoad(scenario, current_offered_load,
+ per_worker_credential_types, success);
if (current_cpu_load > targeted_cpu_load) {
gpr_log(GPR_ERROR, "Initial offered load too high");
return -1;
@@ -158,14 +212,15 @@ static double SearchOfferedLoad(double initial_offered_load,
while (*success && (current_cpu_load < targeted_cpu_load)) {
current_offered_load *= 2;
- current_cpu_load = GetCpuLoad(scenario, current_offered_load, success);
+ current_cpu_load = GetCpuLoad(scenario, current_offered_load,
+ per_worker_credential_types, success);
gpr_log(GPR_DEBUG, "Binary Search: current_offered_load %.0f",
current_offered_load);
}
double targeted_offered_load =
BinarySearch(scenario, targeted_cpu_load, current_offered_load / 2,
- current_offered_load, success);
+ current_offered_load, per_worker_credential_types, success);
return targeted_offered_load;
}
@@ -183,6 +238,7 @@ static bool QpsDriver() {
abort();
}
+ auto per_worker_credential_types = ConstructPerWorkerCredentialTypesMap();
if (scfile) {
// Read the json data from disk
FILE* json_file = fopen(FLAGS_scenarios_file.c_str(), "r");
@@ -198,7 +254,7 @@ static bool QpsDriver() {
} else if (scjson) {
json = FLAGS_scenarios_json.c_str();
} else if (FLAGS_quit) {
- return RunQuit(FLAGS_credential_type);
+ return RunQuit(FLAGS_credential_type, per_worker_credential_types);
}
// Parse into an array of scenarios
@@ -212,15 +268,16 @@ static bool QpsDriver() {
for (int i = 0; i < scenarios.scenarios_size(); i++) {
if (FLAGS_search_param == "") {
const Scenario& scenario = scenarios.scenarios(i);
- RunAndReport(scenario, &success);
+ RunAndReport(scenario, per_worker_credential_types, &success);
} else {
if (FLAGS_search_param == "offered_load") {
Scenario* scenario = scenarios.mutable_scenarios(i);
- double targeted_offered_load =
- SearchOfferedLoad(FLAGS_initial_search_value,
- FLAGS_targeted_cpu_load, scenario, &success);
+ double targeted_offered_load = SearchOfferedLoad(
+ FLAGS_initial_search_value, FLAGS_targeted_cpu_load, scenario,
+ per_worker_credential_types, &success);
gpr_log(GPR_INFO, "targeted_offered_load %f", targeted_offered_load);
- GetCpuLoad(scenario, targeted_offered_load, &success);
+ GetCpuLoad(scenario, targeted_offered_load, per_worker_credential_types,
+ &success);
} else {
gpr_log(GPR_ERROR, "Unimplemented search param");
}
diff --git a/test/cpp/qps/qps_openloop_test.cc b/test/cpp/qps/qps_openloop_test.cc
index 6044f4265a..68062e66f2 100644
--- a/test/cpp/qps/qps_openloop_test.cc
+++ b/test/cpp/qps/qps_openloop_test.cc
@@ -52,7 +52,7 @@ static void RunQPS() {
const auto result =
RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2, "",
- kInsecureCredentialsType, false, 0);
+ kInsecureCredentialsType, {}, false, 0);
GetReporter()->ReportQPSPerCore(*result);
GetReporter()->ReportLatency(*result);
diff --git a/test/cpp/qps/secure_sync_unary_ping_pong_test.cc b/test/cpp/qps/secure_sync_unary_ping_pong_test.cc
index a559c82cc8..422bd617eb 100644
--- a/test/cpp/qps/secure_sync_unary_ping_pong_test.cc
+++ b/test/cpp/qps/secure_sync_unary_ping_pong_test.cc
@@ -55,7 +55,7 @@ static void RunSynchronousUnaryPingPong() {
const auto result =
RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2, "",
- kInsecureCredentialsType, false, 0);
+ kInsecureCredentialsType, {}, false, 0);
GetReporter()->ReportQPS(*result);
GetReporter()->ReportLatency(*result);
diff --git a/test/cpp/util/BUILD b/test/cpp/util/BUILD
index c8d4333ef0..57eaf3baf2 100644
--- a/test/cpp/util/BUILD
+++ b/test/cpp/util/BUILD
@@ -185,6 +185,7 @@ grpc_cc_test(
external_deps = [
"gtest",
],
+ tags = ["nomsan"], # death tests seem to be incompatible with msan
deps = [
":grpc_cli_libs",
":test_util",
diff --git a/third_party/data-plane-api b/third_party/data-plane-api
new file mode 160000
+Subproject 911001cdca003337bdb93fab32740cde61bafee
diff --git a/third_party/googleapis b/third_party/googleapis
new file mode 160000
+Subproject 80ed4d0bbf65d57cc267dfc63bd2584557f11f9
diff --git a/third_party/protoc-gen-validate b/third_party/protoc-gen-validate
new file mode 160000
+Subproject e143189bf6f37b3957fb31743df6a1bcf4a8c68
diff --git a/third_party/toolchains/BUILD b/third_party/toolchains/BUILD
index 02cd87a7b9..e213461acc 100644
--- a/third_party/toolchains/BUILD
+++ b/third_party/toolchains/BUILD
@@ -16,37 +16,72 @@ licenses(["notice"]) # Apache v2
package(default_visibility = ["//visibility:public"])
-exports_files(["RBE_USE_MACHINE_TYPE_LARGE",])
-
# Latest RBE Ubuntu16_04 container
# Update every time when a new container is released.
alias(
name = "rbe_ubuntu1604",
- actual = ":rbe_ubuntu1604_r328903",
+ actual = ":rbe_ubuntu1604_r342117",
+)
+
+alias(
+ name = "rbe_ubuntu1604_large",
+ actual = ":rbe_ubuntu1604_r342117_large",
)
-# RBE Ubuntu16_04 r328903
+# RBE Ubuntu16_04 r342117
platform(
- name = "rbe_ubuntu1604_r328903",
+ name = "rbe_ubuntu1604_r342117",
constraint_values = [
"@bazel_tools//platforms:x86_64",
"@bazel_tools//platforms:linux",
"@bazel_tools//tools/cpp:clang",
"@com_github_bazelbuild_bazeltoolchains//constraints:xenial",
"@com_github_bazelbuild_bazeltoolchains//constraints/sanitizers:support_msan",
+ "//third_party/toolchains/machine_size:standard",
],
remote_execution_properties = """
properties: {
name: "container-image"
- value:"docker://gcr.io/cloud-marketplace/google/rbe-ubuntu16-04@sha256:59bf0e191a6b5cc1ab62c2224c810681d1326bad5a27b1d36c9f40113e79da7f"
+ value:"docker://gcr.io/cloud-marketplace/google/rbe-ubuntu16-04@sha256:f3120a030a19d67626ababdac79cc787e699a1aa924081431285118f87e7b375"
}
properties: {
name: "gceMachineType" # Small machines for majority of tests.
value: "n1-highmem-2"
}
+ """,
+)
+
+# RBE Ubuntu16_04 r342117 large
+platform(
+ name = "rbe_ubuntu1604_r342117_large",
+ constraint_values = [
+ "@bazel_tools//platforms:x86_64",
+ "@bazel_tools//platforms:linux",
+ "@bazel_tools//tools/cpp:clang",
+ "@com_github_bazelbuild_bazeltoolchains//constraints:xenial",
+ "@com_github_bazelbuild_bazeltoolchains//constraints/sanitizers:support_msan",
+ "//third_party/toolchains/machine_size:large",
+ ],
+ remote_execution_properties = """
+ properties: {
+ name: "container-image"
+ value:"docker://gcr.io/cloud-marketplace/google/rbe-ubuntu16-04@sha256:f3120a030a19d67626ababdac79cc787e699a1aa924081431285118f87e7b375"
+ }
properties: {
- name: "gceMachineType_LARGE" # Large machines for a small set of resource-consuming tests such as combiner_tests under TSAN.
+ name: "gceMachineType" # Large machines for some resource demanding tests (TSAN).
value: "n1-standard-8"
}
- """,
+ """,
+)
+
+# This target is auto-generated from release/cpp.tpl and should not be
+# modified directly.
+toolchain(
+ name = "cc-toolchain-clang-x86_64-default",
+ exec_compatible_with = [
+ ],
+ target_compatible_with = [
+ ],
+ toolchain = "@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/default:cc-compiler-k8",
+ toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
)
diff --git a/third_party/toolchains/RBE_USE_MACHINE_TYPE_LARGE b/third_party/toolchains/RBE_USE_MACHINE_TYPE_LARGE
deleted file mode 100644
index b1120238d7..0000000000
--- a/third_party/toolchains/RBE_USE_MACHINE_TYPE_LARGE
+++ /dev/null
@@ -1 +0,0 @@
-# This file is a sentinel and is meant to be empty.
diff --git a/third_party/toolchains/machine_size/BUILD b/third_party/toolchains/machine_size/BUILD
new file mode 100644
index 0000000000..cc962946c3
--- /dev/null
+++ b/third_party/toolchains/machine_size/BUILD
@@ -0,0 +1,31 @@
+# Copyright 2018 gRPC authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+licenses(["notice"]) # Apache v2
+
+package(default_visibility = ["//visibility:public"])
+
+constraint_setting(name = "machine_size")
+
+constraint_value(
+ name = "large",
+ constraint_setting = ":machine_size",
+)
+
+constraint_value(
+ name = "standard",
+ constraint_setting = ":machine_size",
+)
+
+# Add other constraint values as needed (tiny, huge, etc.) in the future.
diff --git a/third_party/upb b/third_party/upb
new file mode 160000
+Subproject 9ce4a77f61c134bbed28bfd5be5cd7dc0e80f5e
diff --git a/tools/bazel.rc b/tools/bazel.rc
index d33e6e086b..59e597b472 100644
--- a/tools/bazel.rc
+++ b/tools/bazel.rc
@@ -6,13 +6,17 @@
build --client_env=CC=clang
build --copt=-DGRPC_BAZEL_BUILD
+build:opt --compilation_mode=opt
build:opt --copt=-Wframe-larger-than=16384
+build:dbg --compilation_mode=dbg
+
build:asan --strip=never
build:asan --copt=-fsanitize=address
build:asan --copt=-O0
build:asan --copt=-fno-omit-frame-pointer
build:asan --copt=-DGPR_NO_DIRECT_SYSCALLS
+build:asan --copt=-DADDRESS_SANITIZER # used by absl
build:asan --linkopt=-fsanitize=address
build:asan --action_env=ASAN_OPTIONS=detect_leaks=1:color=always
build:asan --action_env=LSAN_OPTIONS=suppressions=test/core/util/lsan_suppressions.txt:report_objects=1
@@ -24,6 +28,7 @@ build:msan --copt=-fsanitize-memory-track-origins
build:msan --copt=-fsanitize-memory-use-after-dtor
build:msan --copt=-fno-omit-frame-pointer
build:msan --copt=-DGPR_NO_DIRECT_SYSCALLS
+build:msan --copt=-DMEMORY_SANITIZER # used by absl
build:msan --linkopt=-fsanitize=memory
build:msan --action_env=MSAN_OPTIONS=poison_in_dtor=1
@@ -32,6 +37,8 @@ build:tsan --copt=-fsanitize=thread
build:tsan --copt=-fno-omit-frame-pointer
build:tsan --copt=-DGPR_NO_DIRECT_SYSCALLS
build:tsan --copt=-DGRPC_TSAN
+# TODO(jtattermusch): ideally we would set --copt=-DTHREAD_SANITIZER (used by absl)
+# but it seems to do more harm than good and triggers #17175
build:tsan --linkopt=-fsanitize=thread
build:tsan --action_env=TSAN_OPTIONS=suppressions=test/core/util/tsan_suppressions.txt:halt_on_error=1:second_deadlock_stack=1
@@ -40,6 +47,7 @@ build:ubsan --copt=-fsanitize=undefined
build:ubsan --copt=-fno-omit-frame-pointer
build:ubsan --copt=-DGRPC_UBSAN
build:ubsan --copt=-DNDEBUG
+build:ubsan --copt=-DUNDEFINED_BEHAVIOR_SANITIZER # used by absl
build:ubsan --copt=-fno-sanitize=function,vptr
build:ubsan --linkopt=-fsanitize=undefined
build:ubsan --action_env=UBSAN_OPTIONS=halt_on_error=1:print_stacktrace=1:suppressions=test/core/util/ubsan_suppressions.txt
diff --git a/tools/codegen/core/gen_static_metadata.py b/tools/codegen/core/gen_static_metadata.py
index adfd4a24f9..ab288a0090 100755
--- a/tools/codegen/core/gen_static_metadata.py
+++ b/tools/codegen/core/gen_static_metadata.py
@@ -64,6 +64,7 @@ CONFIG = [
# well known method names
'/grpc.lb.v1.LoadBalancer/BalanceLoad',
'/grpc.health.v1.Health/Watch',
+ '/envoy.service.discovery.v2.AggregatedDiscoveryService/StreamAggregatedResources',
# compression algorithm names
'deflate',
'gzip',
diff --git a/tools/distrib/pylint_code.sh b/tools/distrib/pylint_code.sh
index 82a818cce5..d17eb9fdb8 100755
--- a/tools/distrib/pylint_code.sh
+++ b/tools/distrib/pylint_code.sh
@@ -20,6 +20,7 @@ cd "$(dirname "$0")/../.."
DIRS=(
'src/python/grpcio/grpc'
+ 'src/python/grpcio_channelz/grpc_channelz'
'src/python/grpcio_health_checking/grpc_health'
'src/python/grpcio_reflection/grpc_reflection'
'src/python/grpcio_testing/grpc_testing'
diff --git a/tools/distrib/python/docgen.py b/tools/distrib/python/docgen.py
index 732d948bbc..de47c00618 100755
--- a/tools/distrib/python/docgen.py
+++ b/tools/distrib/python/docgen.py
@@ -32,12 +32,10 @@ parser.add_argument(
help='GRPC/GPR libraries build configuration',
default='opt')
parser.add_argument('--submit', action='store_true')
-parser.add_argument('--gh-user', type=str, help='GitHub user to push as.')
parser.add_argument(
- '--gh-repo-owner',
+ '--repo-owner',
type=str,
- help=('Owner of the GitHub repository to be pushed; '
- 'defaults to --gh-user.'))
+ help=('Owner of the GitHub repository to be pushed'))
parser.add_argument('--doc-branch', type=str)
args = parser.parse_args()
@@ -70,7 +68,7 @@ subprocess_arguments_list = [
'env': environment
},
{
- 'args': [VIRTUALENV_PIP_PATH, 'install', '--upgrade', 'pip==10.0.1'],
+ 'args': [VIRTUALENV_PIP_PATH, 'install', '--upgrade', 'pip==18.1'],
'env': environment
},
{
@@ -78,7 +76,7 @@ subprocess_arguments_list = [
'env': environment
},
{
- 'args': [VIRTUALENV_PYTHON_PATH, SETUP_PATH, 'build'],
+ 'args': [VIRTUALENV_PIP_PATH, 'install', 'Sphinx~=1.8.1'],
'env': environment
},
{
@@ -91,12 +89,12 @@ for subprocess_arguments in subprocess_arguments_list:
print('Running command: {}'.format(subprocess_arguments['args']))
subprocess.check_call(**subprocess_arguments)
-if args.submit:
- assert args.gh_user
+if not args.submit:
+ print('Please check generated Python doc inside doc/build')
+elif args.submit:
+ assert args.repo_owner
assert args.doc_branch
- github_user = args.gh_user
- github_repository_owner = (args.gh_repo_owner
- if args.gh_repo_owner else args.gh_user)
+ github_repository_owner = args.repo_owner
# Create a temporary directory out of tree, checkout gh-pages from the
# specified repository, edit it, and push it. It's up to the user to then go
# onto GitHub and make a PR against grpc/grpc:gh-pages.
@@ -109,16 +107,19 @@ if args.submit:
print('Cloning your repository...')
subprocess.check_call(
[
- 'git', 'clone', 'https://{}@github.com/{}/grpc'.format(
- github_user, github_repository_owner)
+ 'git',
+ 'clone',
+ '--branch',
+ 'gh-pages',
+ 'https://github.com/grpc/grpc',
],
cwd=repo_parent_dir)
+ subprocess.check_call(['git', 'checkout', '-b', doc_branch], cwd=repo_dir)
subprocess.check_call(
- ['git', 'remote', 'add', 'upstream', 'https://github.com/grpc/grpc'],
- cwd=repo_dir)
- subprocess.check_call(['git', 'fetch', 'upstream'], cwd=repo_dir)
- subprocess.check_call(
- ['git', 'checkout', 'upstream/gh-pages', '-b', doc_branch],
+ [
+ 'git', 'remote', 'add', 'ssh-origin',
+ 'git@github.com:%s/grpc.git' % (github_repository_owner)
+ ],
cwd=repo_dir)
print('Updating documentation...')
shutil.rmtree(python_doc_dir, ignore_errors=True)
@@ -130,7 +131,7 @@ if args.submit:
['git', 'commit', '-m', 'Auto-update Python documentation'],
cwd=repo_dir)
subprocess.check_call(
- ['git', 'push', '--set-upstream', 'origin', doc_branch],
+ ['git', 'push', '--set-upstream', 'ssh-origin', doc_branch],
cwd=repo_dir)
except subprocess.CalledProcessError:
print('Failed to push documentation. Examine this directory and push '
diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py
index 4b775e667e..29b2127960 100644
--- a/tools/distrib/python/grpcio_tools/grpc_version.py
+++ b/tools/distrib/python/grpcio_tools/grpc_version.py
@@ -14,4 +14,4 @@
# AUTO-GENERATED FROM `$REPO_ROOT/templates/tools/distrib/python/grpcio_tools/grpc_version.py.template`!!!
-VERSION = '1.17.0.dev0'
+VERSION = '1.18.0.dev0'
diff --git a/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile b/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile
index dadd856740..acad500f90 100644
--- a/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile
+++ b/tools/dockerfile/interoptest/grpc_interop_python/Dockerfile
@@ -12,8 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-FROM debian:jessie
-
+FROM debian:stretch
+
# Install Git and basic packages.
RUN apt-get update && apt-get install -y \
autoconf \
@@ -49,27 +49,24 @@ RUN apt-get update && apt-get install -y \
# Build profiling
RUN apt-get update && apt-get install -y time && apt-get clean
-#====================
-# Python dependencies
-
-# Install dependencies
-
-RUN apt-get update && apt-get install -y \
- python-all-dev \
- python3-all-dev \
- python-pip
+# Google Cloud platform API libraries
+RUN apt-get update && apt-get install -y python-pip && apt-get clean
+RUN pip install --upgrade google-api-python-client oauth2client
-# Install Python packages from PyPI
-RUN pip install --upgrade pip==10.0.1
-RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0
+# Install Python 2.7
+RUN apt-get update && apt-get install -y python2.7 python-all-dev
+RUN curl https://bootstrap.pypa.io/get-pip.py | python2.7
-# Install pip and virtualenv for Python 3.4
-RUN curl https://bootstrap.pypa.io/get-pip.py | python3.4
-RUN python3.4 -m pip install virtualenv
+# Add Debian 'testing' repository
+RUN echo 'deb http://ftp.de.debian.org/debian testing main' >> /etc/apt/sources.list
+RUN echo 'APT::Default-Release "stable";' | tee -a /etc/apt/apt.conf.d/00local
RUN mkdir /var/local/jenkins
# Define the default command.
CMD ["bash"]
+
+
+RUN apt-get update && apt-get -t testing install -y python3.7 python3-all-dev
+RUN curl https://bootstrap.pypa.io/get-pip.py | python3.7
diff --git a/tools/dockerfile/interoptest/grpc_interop_python/build_interop.sh b/tools/dockerfile/interoptest/grpc_interop_python/build_interop.sh
index 7917e1cd60..468aa20e3f 100755
--- a/tools/dockerfile/interoptest/grpc_interop_python/build_interop.sh
+++ b/tools/dockerfile/interoptest/grpc_interop_python/build_interop.sh
@@ -28,5 +28,5 @@ cp -r /var/local/jenkins/service_account $HOME || true
cd /var/local/git/grpc
-# interop tests only run using python2.7 currently (and python build is slow)
-tools/run_tests/run_tests.py -l python --compiler python2.7 -c opt --build_only
+# interop tests only run using python3.7 currently (and python build is slow)
+tools/run_tests/run_tests.py -l python --compiler python3.7 -c opt --build_only
diff --git a/tools/dockerfile/test/multilang_jessie_x64/Dockerfile b/tools/dockerfile/test/multilang_jessie_x64/Dockerfile
deleted file mode 100644
index 3c95554b02..0000000000
--- a/tools/dockerfile/test/multilang_jessie_x64/Dockerfile
+++ /dev/null
@@ -1,170 +0,0 @@
-# Copyright 2016 gRPC authors.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-FROM debian:jessie
-
-# Install Git and basic packages.
-RUN apt-get update && apt-get install -y \
- autoconf \
- autotools-dev \
- build-essential \
- bzip2 \
- ccache \
- curl \
- dnsutils \
- gcc \
- gcc-multilib \
- git \
- golang \
- gyp \
- lcov \
- libc6 \
- libc6-dbg \
- libc6-dev \
- libgtest-dev \
- libtool \
- make \
- perl \
- strace \
- python-dev \
- python-setuptools \
- python-yaml \
- telnet \
- unzip \
- wget \
- zip && apt-get clean
-
-#================
-# Build profiling
-RUN apt-get update && apt-get install -y time && apt-get clean
-
-# Google Cloud platform API libraries
-RUN apt-get update && apt-get install -y python-pip && apt-get clean
-RUN pip install --upgrade google-api-python-client oauth2client
-
-#================
-# C# dependencies
-
-# Update to a newer version of mono
-RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF
-RUN echo "deb http://download.mono-project.com/repo/debian jessie main" | tee /etc/apt/sources.list.d/mono-official.list
-RUN echo "deb http://download.mono-project.com/repo/debian wheezy-apache24-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
-RUN echo "deb http://download.mono-project.com/repo/debian wheezy-libjpeg62-compat main" | tee -a /etc/apt/sources.list.d/mono-xamarin.list
-
-# Install dependencies
-RUN apt-get update && apt-get -y dist-upgrade && apt-get install -y \
- mono-devel \
- ca-certificates-mono \
- nuget \
- && apt-get clean
-
-RUN nuget update -self
-
-#=================
-# Use cmake 3.6 from jessie-backports
-# needed to build grpc_csharp_ext with cmake
-
-RUN echo "deb http://ftp.debian.org/debian jessie-backports main" | tee /etc/apt/sources.list.d/jessie-backports.list
-RUN apt-get update && apt-get install -t jessie-backports -y cmake && apt-get clean
-
-# Install dotnet SDK based on https://www.microsoft.com/net/core#debian
-RUN apt-get update && apt-get install -y curl libunwind8 gettext
-# dotnet-dev-1.0.0-preview2-003131
-RUN curl -sSL -o dotnet100.tar.gz https://go.microsoft.com/fwlink/?LinkID=827530
-RUN mkdir -p /opt/dotnet && tar zxf dotnet100.tar.gz -C /opt/dotnet
-# dotnet-dev-1.0.1
-RUN curl -sSL -o dotnet101.tar.gz https://go.microsoft.com/fwlink/?LinkID=843453
-RUN mkdir -p /opt/dotnet && tar zxf dotnet101.tar.gz -C /opt/dotnet
-RUN ln -s /opt/dotnet/dotnet /usr/local/bin
-
-# Trigger the population of the local package cache
-ENV NUGET_XMLDOC_MODE skip
-RUN mkdir warmup \
- && cd warmup \
- && dotnet new \
- && cd .. \
- && rm -rf warmup
-
-#=================
-# C++ dependencies
-RUN apt-get update && apt-get -y install libgflags-dev libgtest-dev libc++-dev clang && apt-get clean
-
-#==================
-# Node dependencies
-
-# Install nvm
-RUN touch .profile
-RUN curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.25.4/install.sh | bash
-# Install all versions of node that we want to test
-RUN /bin/bash -l -c "nvm install 4 && npm config set cache /tmp/npm-cache"
-RUN /bin/bash -l -c "nvm install 5 && npm config set cache /tmp/npm-cache"
-RUN /bin/bash -l -c "nvm install 6 && npm config set cache /tmp/npm-cache"
-RUN /bin/bash -l -c "nvm install 8 && npm config set cache /tmp/npm-cache"
-RUN /bin/bash -l -c "nvm install 9 && npm config set cache /tmp/npm-cache"
-RUN /bin/bash -l -c "nvm install 10 && npm config set cache /tmp/npm-cache"
-RUN /bin/bash -l -c "nvm alias default 10"
-#=================
-# PHP dependencies
-
-# Install dependencies
-
-RUN apt-get update && apt-get install -y \
- git php5 php5-dev phpunit unzip
-
-#==================
-# Ruby dependencies
-
-# Install rvm
-RUN gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3
-RUN \curl -sSL https://get.rvm.io | bash -s stable
-
-# Install Ruby 2.1
-RUN /bin/bash -l -c "rvm install ruby-2.1"
-RUN /bin/bash -l -c "rvm use --default ruby-2.1"
-RUN /bin/bash -l -c "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc"
-RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc"
-RUN /bin/bash -l -c "echo 'rvm --default use ruby-2.1' >> ~/.bashrc"
-RUN /bin/bash -l -c "gem install bundler --no-ri --no-rdoc"
-
-#====================
-# Python dependencies
-
-# Install dependencies
-
-RUN apt-get update && apt-get install -y \
- python-all-dev \
- python3-all-dev \
- python-pip
-
-# Install Python packages from PyPI
-RUN pip install --upgrade pip==10.0.1
-RUN pip install virtualenv
-RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.2.post1 six==1.10.0 twisted==17.5.0
-
-# Install pip and virtualenv for Python 3.4
-RUN curl https://bootstrap.pypa.io/get-pip.py | python3.4
-RUN python3.4 -m pip install virtualenv
-
-# Install coverage for Python test coverage reporting
-RUN pip install coverage
-ENV PATH ~/.local/bin:$PATH
-
-# Install Mako to generate files in grpc/grpc-node
-RUN pip install Mako
-
-
-RUN mkdir /var/local/jenkins
-
-# Define the default command.
-CMD ["bash"]
diff --git a/tools/dockerfile/test/python_alpine_x64/Dockerfile b/tools/dockerfile/test/python_alpine_x64/Dockerfile
index 6e06e2d52c..3001bf43ff 100644
--- a/tools/dockerfile/test/python_alpine_x64/Dockerfile
+++ b/tools/dockerfile/test/python_alpine_x64/Dockerfile
@@ -42,13 +42,7 @@ RUN pip install virtualenv
RUN pip install futures==2.2.0 enum34==1.0.4 protobuf==3.5.0.post1 six==1.10.0
# Google Cloud platform API libraries
-RUN pip install --upgrade google-api-python-client
-
-# Prepare ccache
-RUN ln -s /usr/bin/ccache /usr/local/bin/gcc
-RUN ln -s /usr/bin/ccache /usr/local/bin/g++
-RUN ln -s /usr/bin/ccache /usr/local/bin/cc
-RUN ln -s /usr/bin/ccache /usr/local/bin/c++
+RUN pip install --upgrade google-api-python-client oauth2client
RUN mkdir -p /var/local/jenkins
diff --git a/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile b/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile
index add1cc509d..45291ffdcf 100644
--- a/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile
+++ b/tools/dockerfile/test/python_stretch_3.7_x64/Dockerfile
@@ -70,3 +70,6 @@ CMD ["bash"]
RUN apt-get update && apt-get -t testing install -y python3.7 python3-all-dev
RUN curl https://bootstrap.pypa.io/get-pip.py | python3.7
+
+# for Python test coverage reporting
+RUN pip install coverage
diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++
index 392113c284..5c19711ee9 100644
--- a/tools/doxygen/Doxyfile.c++
+++ b/tools/doxygen/Doxyfile.c++
@@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++"
# could be handy for archiving the generated documentation or if some version
# control system is used.
-PROJECT_NUMBER = 1.17.0-dev
+PROJECT_NUMBER = 1.18.0-dev
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
@@ -777,6 +777,7 @@ doc/environment_variables.md \
doc/fail_fast.md \
doc/fork_support.md \
doc/g_stands_for.md \
+doc/grpc_release_schedule.md \
doc/health-checking.md \
doc/http-grpc-status-mapping.md \
doc/http2-interop-test-descriptions.md \
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index a96683883c..72b247c48d 100644
--- a/tools/doxygen/Doxyfile.c++.internal
+++ b/tools/doxygen/Doxyfile.c++.internal
@@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC C++"
# could be handy for archiving the generated documentation or if some version
# control system is used.
-PROJECT_NUMBER = 1.17.0-dev
+PROJECT_NUMBER = 1.18.0-dev
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
@@ -777,6 +777,7 @@ doc/environment_variables.md \
doc/fail_fast.md \
doc/fork_support.md \
doc/g_stands_for.md \
+doc/grpc_release_schedule.md \
doc/health-checking.md \
doc/http-grpc-status-mapping.md \
doc/http2-interop-test-descriptions.md \
diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core
index b78fb607ad..8c557383b2 100644
--- a/tools/doxygen/Doxyfile.core
+++ b/tools/doxygen/Doxyfile.core
@@ -784,6 +784,7 @@ doc/environment_variables.md \
doc/fail_fast.md \
doc/fork_support.md \
doc/g_stands_for.md \
+doc/grpc_release_schedule.md \
doc/health-checking.md \
doc/http-grpc-status-mapping.md \
doc/http2-interop-test-descriptions.md \
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index 791318bf36..0f1943de25 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -784,6 +784,7 @@ doc/environment_variables.md \
doc/fail_fast.md \
doc/fork_support.md \
doc/g_stands_for.md \
+doc/grpc_release_schedule.md \
doc/health-checking.md \
doc/http-grpc-status-mapping.md \
doc/http2-interop-test-descriptions.md \
@@ -926,8 +927,6 @@ src/core/ext/filters/client_channel/lb_policy_factory.cc \
src/core/ext/filters/client_channel/lb_policy_factory.h \
src/core/ext/filters/client_channel/lb_policy_registry.cc \
src/core/ext/filters/client_channel/lb_policy_registry.h \
-src/core/ext/filters/client_channel/method_params.cc \
-src/core/ext/filters/client_channel/method_params.h \
src/core/ext/filters/client_channel/parse_address.cc \
src/core/ext/filters/client_channel/parse_address.h \
src/core/ext/filters/client_channel/proxy_mapper.cc \
@@ -956,6 +955,8 @@ src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc \
src/core/ext/filters/client_channel/resolver_factory.h \
src/core/ext/filters/client_channel/resolver_registry.cc \
src/core/ext/filters/client_channel/resolver_registry.h \
+src/core/ext/filters/client_channel/resolver_result_parsing.cc \
+src/core/ext/filters/client_channel/resolver_result_parsing.h \
src/core/ext/filters/client_channel/retry_throttle.cc \
src/core/ext/filters/client_channel/retry_throttle.h \
src/core/ext/filters/client_channel/subchannel.cc \
@@ -1009,6 +1010,8 @@ src/core/ext/transport/chttp2/transport/bin_encoder.h \
src/core/ext/transport/chttp2/transport/chttp2_plugin.cc \
src/core/ext/transport/chttp2/transport/chttp2_transport.cc \
src/core/ext/transport/chttp2/transport/chttp2_transport.h \
+src/core/ext/transport/chttp2/transport/context_list.cc \
+src/core/ext/transport/chttp2/transport/context_list.h \
src/core/ext/transport/chttp2/transport/flow_control.cc \
src/core/ext/transport/chttp2/transport/flow_control.h \
src/core/ext/transport/chttp2/transport/frame.h \
@@ -1527,8 +1530,6 @@ src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.cc \
src/core/tsi/alts/zero_copy_frame_protector/alts_iovec_record_protocol.h \
src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.cc \
src/core/tsi/alts/zero_copy_frame_protector/alts_zero_copy_grpc_protector.h \
-src/core/tsi/alts_transport_security.cc \
-src/core/tsi/alts_transport_security.h \
src/core/tsi/fake_transport_security.cc \
src/core/tsi/fake_transport_security.h \
src/core/tsi/grpc_shadow_boringssl.h \
diff --git a/tools/internal_ci/helper_scripts/prepare_build_macos_rc b/tools/internal_ci/helper_scripts/prepare_build_macos_rc
index 2362b370d5..f5b0b764b1 100644
--- a/tools/internal_ci/helper_scripts/prepare_build_macos_rc
+++ b/tools/internal_ci/helper_scripts/prepare_build_macos_rc
@@ -15,14 +15,8 @@
# Source this rc script to prepare the environment for macos builds
-sudo launchctl limit maxfiles unlimited unlimited
-
-# show current maxfiles
+# show original open file limit values
launchctl limit maxfiles
-
-ulimit -n 10000
-
-# show current limits
ulimit -a
# synchronize the clock
@@ -97,3 +91,6 @@ mkdir -p /tmpfs/DerivedData
rm -rf ~/Library/Developer/Xcode/DerivedData
mkdir -p ~/Library/Developer/Xcode
ln -s /tmpfs/DerivedData ~/Library/Developer/Xcode/DerivedData
+
+# PHP tests currently require using an older version of PHPUnit
+ln -sf /usr/local/bin/phpunit-5.7 /usr/local/bin/phpunit
diff --git a/tools/internal_ci/linux/grpc_bazel_on_foundry_dbg.sh b/tools/internal_ci/linux/grpc_bazel_on_foundry_dbg.sh
index d3cd9c20cc..fdd5b2e4cd 100644
--- a/tools/internal_ci/linux/grpc_bazel_on_foundry_dbg.sh
+++ b/tools/internal_ci/linux/grpc_bazel_on_foundry_dbg.sh
@@ -16,5 +16,5 @@
set -ex
export UPLOAD_TEST_RESULTS=true
-EXTRA_FLAGS="-c dbg --test_timeout=300,450,1200,3600 --cache_test_results=no"
+EXTRA_FLAGS="--config=dbg --test_timeout=300,450,1200,3600 --cache_test_results=no"
github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}"
diff --git a/tools/internal_ci/linux/grpc_bazel_on_foundry_opt.sh b/tools/internal_ci/linux/grpc_bazel_on_foundry_opt.sh
index 48b3f9e674..30b2b17a67 100644
--- a/tools/internal_ci/linux/grpc_bazel_on_foundry_opt.sh
+++ b/tools/internal_ci/linux/grpc_bazel_on_foundry_opt.sh
@@ -16,5 +16,5 @@
set -ex
export UPLOAD_TEST_RESULTS=true
-EXTRA_FLAGS="-c opt --test_timeout=300,450,1200,3600 --cache_test_results=no"
+EXTRA_FLAGS="--config=opt --test_timeout=300,450,1200,3600 --cache_test_results=no"
github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}"
diff --git a/tools/internal_ci/linux/grpc_coverage.sh b/tools/internal_ci/linux/grpc_coverage.sh
index 97166372ab..a91cffdf98 100755
--- a/tools/internal_ci/linux/grpc_coverage.sh
+++ b/tools/internal_ci/linux/grpc_coverage.sh
@@ -21,12 +21,20 @@ cd $(dirname $0)/../../..
source tools/internal_ci/helper_scripts/prepare_build_linux_rc
python tools/run_tests/run_tests.py \
- --use_docker \
- -t \
- -l all \
- -c gcov \
- -x sponge_log.xml \
- -j 16 || FAILED="true"
+ -l c c++ -x coverage_cpp/sponge_log.xml \
+ --use_docker -t -c gcov -j 2 || FAILED="true"
+
+python tools/run_tests/run_tests.py \
+ -l python -x coverage_python/sponge_log.xml \
+ --use_docker -t -c gcov -j 2 || FAILED="true"
+
+python tools/run_tests/run_tests.py \
+ -l ruby -x coverage_ruby/sponge_log.xml \
+ --use_docker -t -c gcov -j 2 || FAILED="true"
+
+python tools/run_tests/run_tests.py \
+ -l php -x coverage_php/sponge_log.xml \
+ --use_docker -t -c gcov -j 2 || FAILED="true"
# HTML reports can't be easily displayed in GCS, so create a zip archive
# and put it under reports directory to get it uploaded as an artifact.
diff --git a/tools/internal_ci/linux/grpc_python_bazel_test_in_docker.sh b/tools/internal_ci/linux/grpc_python_bazel_test_in_docker.sh
index 4f98d0a93a..156d65955a 100755
--- a/tools/internal_ci/linux/grpc_python_bazel_test_in_docker.sh
+++ b/tools/internal_ci/linux/grpc_python_bazel_test_in_docker.sh
@@ -24,4 +24,4 @@ git clone /var/local/jenkins/grpc /var/local/git/grpc
&& git submodule update --init --reference /var/local/jenkins/grpc/${name} \
${name}')
cd /var/local/git/grpc/test
-bazel test --spawn_strategy=standalone --genrule_strategy=standalone //src/python/...
+bazel test --spawn_strategy=standalone --genrule_strategy=standalone --test_output=errors //src/python/...
diff --git a/tools/internal_ci/linux/pull_request/grpc_bazel_on_foundry_dbg.sh b/tools/internal_ci/linux/pull_request/grpc_bazel_on_foundry_dbg.sh
index eb1c7320a7..f1e6588517 100644
--- a/tools/internal_ci/linux/pull_request/grpc_bazel_on_foundry_dbg.sh
+++ b/tools/internal_ci/linux/pull_request/grpc_bazel_on_foundry_dbg.sh
@@ -15,5 +15,5 @@
set -ex
-EXTRA_FLAGS="-c dbg --test_timeout=300,450,1200,3600"
+EXTRA_FLAGS="--config=dbg --test_timeout=300,450,1200,3600"
github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}"
diff --git a/tools/internal_ci/linux/pull_request/grpc_bazel_on_foundry_opt.sh b/tools/internal_ci/linux/pull_request/grpc_bazel_on_foundry_opt.sh
index f179dc9483..77744de49f 100644
--- a/tools/internal_ci/linux/pull_request/grpc_bazel_on_foundry_opt.sh
+++ b/tools/internal_ci/linux/pull_request/grpc_bazel_on_foundry_opt.sh
@@ -15,5 +15,5 @@
set -ex
-EXTRA_FLAGS="-c opt --test_timeout=300,450,1200,3600"
+EXTRA_FLAGS="--config=opt --test_timeout=300,450,1200,3600"
github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh "${EXTRA_FLAGS}"
diff --git a/tools/run_tests/helper_scripts/run_lcov.sh b/tools/internal_ci/linux/pull_request/grpc_msan_on_foundry.sh
index 9d8b6793fc..c85a837a44 100755..100644
--- a/tools/run_tests/helper_scripts/run_lcov.sh
+++ b/tools/internal_ci/linux/pull_request/grpc_msan_on_foundry.sh
@@ -1,5 +1,5 @@
-#!/bin/bash
-# Copyright 2015 gRPC authors.
+#!/usr/bin/env bash
+# Copyright 2018 The gRPC Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -15,17 +15,4 @@
set -ex
-out=$(readlink -f "${1:-coverage}")
-
-root=$(readlink -f "$(dirname "$0")/../../..")
-shift || true
-tmp=$(mktemp)
-cd "$root"
-tools/run_tests/run_tests.py -c gcov -l c c++ "$@" || true
-lcov --capture --directory . --output-file "$tmp"
-genhtml "$tmp" --output-directory "$out"
-rm "$tmp"
-if which xdg-open > /dev/null
-then
- xdg-open "file://$out/index.html"
-fi
+github/grpc/tools/internal_ci/linux/grpc_bazel_on_foundry_base.sh --config=msan
diff --git a/tools/remote_build/README.md b/tools/remote_build/README.md
index c4d03547a2..19739e9ee1 100644
--- a/tools/remote_build/README.md
+++ b/tools/remote_build/README.md
@@ -17,10 +17,10 @@ and tests run by Kokoro CI.
## Running remote build manually from dev workstation
-Run from repository root:
+Run from repository root (opt, dbg):
```
# manual run of bazel tests remotely on Foundry
-bazel --bazelrc=tools/remote_build/manual.bazelrc test -c opt //test/...
+bazel --bazelrc=tools/remote_build/manual.bazelrc test --config=opt //test/...
```
Sanitizer runs (asan, msan, tsan, ubsan):
diff --git a/tools/remote_build/rbe_common.bazelrc b/tools/remote_build/rbe_common.bazelrc
index e8c7f0b9cb..aa3ddb050c 100644
--- a/tools/remote_build/rbe_common.bazelrc
+++ b/tools/remote_build/rbe_common.bazelrc
@@ -18,10 +18,10 @@
startup --host_jvm_args=-Dbazel.DigestFunction=SHA256
-build --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.16.1/default:toolchain
-build --extra_toolchains=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.16.1/cpp:cc-toolchain-clang-x86_64-default
+build --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/default:toolchain
+build --extra_toolchains=//third_party/toolchains:cc-toolchain-clang-x86_64-default
# Use custom execution platforms defined in third_party/toolchains
-build --extra_execution_platforms=//third_party/toolchains:rbe_ubuntu1604
+build --extra_execution_platforms=//third_party/toolchains:rbe_ubuntu1604,//third_party/toolchains:rbe_ubuntu1604_large
build --host_platform=//third_party/toolchains:rbe_ubuntu1604
build --platforms=//third_party/toolchains:rbe_ubuntu1604
@@ -48,27 +48,30 @@ test --test_env=GRPC_VERBOSITY=debug
build:asan --copt=-gmlt
# TODO(jtattermusch): use more reasonable test timeout
build:asan --test_timeout=3600
-build:asan --test_tag_filters=-qps_json_driver,-json_run_localhost
+build:asan --test_tag_filters=-qps_json_driver
# memory sanitizer: most settings are already in %workspace%/.bazelrc
# we only need a few additional ones that are Foundry specific
build:msan --copt=-gmlt
# TODO(jtattermusch): use more reasonable test timeout
build:msan --test_timeout=3600
+# TODO(jtattermusch): revisit the disabled tests
+build:msan --test_tag_filters=-nomsan,-json_run_localhost
build:msan --cxxopt=--stdlib=libc++
# setting LD_LIBRARY_PATH is necessary
# to avoid "libc++.so.1: cannot open shared object file"
build:msan --action_env=LD_LIBRARY_PATH=/usr/local/lib
-build:msan --host_crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.16.1/default:toolchain
+build:msan --host_crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/default:toolchain
# override the config-agnostic crosstool_top
-build:msan --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.0/bazel_0.16.1/msan:toolchain
+build:msan --crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/ubuntu16_04_clang/1.1/bazel_0.16.1/msan:toolchain
# thread sanitizer: most settings are already in %workspace%/.bazelrc
# we only need a few additional ones that are Foundry specific
build:tsan --copt=-gmlt
# TODO(jtattermusch): use more reasonable test timeout
build:tsan --test_timeout=3600
-build:tsan --test_tag_filters=-qps_json_driver,-json_run_localhost
+build:tsan --test_tag_filters=-qps_json_driver
+build:tsan --extra_execution_platforms=//third_party/toolchains:rbe_ubuntu1604,//third_party/toolchains:rbe_ubuntu1604_large
# undefined behavior sanitizer: most settings are already in %workspace%/.bazelrc
# we only need a few additional ones that are Foundry specific
@@ -76,7 +79,7 @@ build:ubsan --copt=-gmlt
# TODO(jtattermusch): use more reasonable test timeout
build:ubsan --test_timeout=3600
# override the config-agnostic crosstool_top
---crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/experimental/ubuntu16_04_clang/1.0/bazel_0.16.1/ubsan:toolchain
+--crosstool_top=@com_github_bazelbuild_bazeltoolchains//configs/experimental/ubuntu16_04_clang/1.1/bazel_0.16.1/ubsan:toolchain
# TODO(jtattermusch): remove this once Foundry adds the env to the docker image.
# ubsan needs symbolizer to work properly, otherwise the suppression file doesn't work
# and we get test failures.
diff --git a/tools/run_tests/artifacts/artifact_targets.py b/tools/run_tests/artifacts/artifact_targets.py
index d18ea2aca1..aa1d0c3bf2 100644
--- a/tools/run_tests/artifacts/artifact_targets.py
+++ b/tools/run_tests/artifacts/artifact_targets.py
@@ -124,6 +124,8 @@ class PythonArtifact:
# https://github.com/resin-io-projects/armv7hf-debian-qemu/issues/9
# A QEMU bug causes submodule update to hang, so we copy directly
environ['RELATIVE_COPY_PATH'] = '.'
+ # Parallel builds are counterproductive in emulated environment
+ environ['GRPC_PYTHON_BUILD_EXT_COMPILER_JOBS'] = '1'
extra_args = ' --entrypoint=/usr/bin/qemu-arm-static '
return create_docker_jobspec(
self.name,
diff --git a/tools/run_tests/artifacts/build_artifact_python.sh b/tools/run_tests/artifacts/build_artifact_python.sh
index 9a2e0f739f..bc6e558204 100755
--- a/tools/run_tests/artifacts/build_artifact_python.sh
+++ b/tools/run_tests/artifacts/build_artifact_python.sh
@@ -24,7 +24,8 @@ export AUDITWHEEL=${AUDITWHEEL:-auditwheel}
# Allow build_ext to build C/C++ files in parallel
# by enabling a monkeypatch. It speeds up the build a lot.
-export GRPC_PYTHON_BUILD_EXT_COMPILER_JOBS=2
+# Use externally provided GRPC_PYTHON_BUILD_EXT_COMPILER_JOBS value if set.
+export GRPC_PYTHON_BUILD_EXT_COMPILER_JOBS=${GRPC_PYTHON_BUILD_EXT_COMPILER_JOBS:-2}
mkdir -p "${ARTIFACTS_OUT}"
ARTIFACT_DIR="$PWD/${ARTIFACTS_OUT}"
@@ -107,6 +108,11 @@ then
${SETARCH_CMD} "${PYTHON}" src/python/grpcio_testing/setup.py sdist
cp -r src/python/grpcio_testing/dist/* "$ARTIFACT_DIR"
+ # Build grpcio_channelz source distribution
+ ${SETARCH_CMD} "${PYTHON}" src/python/grpcio_channelz/setup.py \
+ preprocess build_package_protos sdist
+ cp -r src/python/grpcio_channelz/dist/* "$ARTIFACT_DIR"
+
# Build grpcio_health_checking source distribution
${SETARCH_CMD} "${PYTHON}" src/python/grpcio_health_checking/setup.py \
preprocess build_package_protos sdist
diff --git a/tools/run_tests/dockerize/build_docker_and_run_tests.sh b/tools/run_tests/dockerize/build_docker_and_run_tests.sh
index 614049cae5..1741b3268b 100755
--- a/tools/run_tests/dockerize/build_docker_and_run_tests.sh
+++ b/tools/run_tests/dockerize/build_docker_and_run_tests.sh
@@ -22,9 +22,6 @@ cd "$(dirname "$0")/../../.."
git_root=$(pwd)
cd -
-# Ensure existence of ccache directory
-mkdir -p /tmp/ccache
-
# Inputs
# DOCKERFILE_DIR - Directory in which Dockerfile file is located.
# DOCKER_RUN_SCRIPT - Script to run under docker (relative to grpc repo root)
@@ -57,7 +54,6 @@ docker run \
-e "RUN_TESTS_COMMAND=$RUN_TESTS_COMMAND" \
-e "config=$config" \
-e "arch=$arch" \
- -e CCACHE_DIR=/tmp/ccache \
-e THIS_IS_REALLY_NEEDED='see https://github.com/docker/docker/issues/14203 for why docker is awful' \
-e HOST_GIT_ROOT="$git_root" \
-e LOCAL_GIT_ROOT=$docker_instance_git_root \
@@ -73,7 +69,6 @@ docker run \
--sysctl net.ipv6.conf.all.disable_ipv6=0 \
-v ~/.config/gcloud:/root/.config/gcloud \
-v "$git_root:$docker_instance_git_root" \
- -v /tmp/ccache:/tmp/ccache \
-v /tmp/npm-cache:/tmp/npm-cache \
-w /var/local/git/grpc \
--name="$CONTAINER_NAME" \
diff --git a/tools/run_tests/dockerize/build_interop_image.sh b/tools/run_tests/dockerize/build_interop_image.sh
index fcfcdeb4e4..126dd4065e 100755
--- a/tools/run_tests/dockerize/build_interop_image.sh
+++ b/tools/run_tests/dockerize/build_interop_image.sh
@@ -64,8 +64,6 @@ else
echo "WARNING: grpc-node not found, it won't be mounted to the docker container."
fi
-mkdir -p /tmp/ccache
-
# Mount service account dir if available.
# If service_directory does not contain the service account JSON file,
# some of the tests will fail.
@@ -105,14 +103,12 @@ CONTAINER_NAME="build_${BASE_NAME}_$(uuidgen)"
# shellcheck disable=SC2086
(docker run \
--cap-add SYS_PTRACE \
- -e CCACHE_DIR=/tmp/ccache \
-e THIS_IS_REALLY_NEEDED='see https://github.com/docker/docker/issues/14203 for why docker is awful' \
-e THIS_IS_REALLY_NEEDED_ONCE_AGAIN='For issue 4835. See https://github.com/docker/docker/issues/14203 for why docker is awful' \
-i \
$TTY_FLAG \
$MOUNT_ARGS \
$BUILD_INTEROP_DOCKER_EXTRA_ARGS \
- -v /tmp/ccache:/tmp/ccache \
--name="$CONTAINER_NAME" \
"$BASE_IMAGE" \
bash -l "/var/local/jenkins/grpc/tools/dockerfile/interoptest/$BASE_NAME/build_interop.sh" \
diff --git a/tools/run_tests/dockerize/docker_run_tests.sh b/tools/run_tests/dockerize/docker_run_tests.sh
index c41734c92d..b7686e48ba 100755
--- a/tools/run_tests/dockerize/docker_run_tests.sh
+++ b/tools/run_tests/dockerize/docker_run_tests.sh
@@ -38,16 +38,8 @@ exit_code=0
$RUN_TESTS_COMMAND || exit_code=$?
-cd reports
-echo '<html><head></head><body>' > index.html
-find . -maxdepth 1 -mindepth 1 -type d | sort | while read d ; do
- d=${d#*/}
- n=${d//_/ }
- echo "<a href='$d/index.html'>$n</a><br />" >> index.html
-done
-echo '</body></html>' >> index.html
-cd ..
-
+# The easiest way to copy all the reports files from inside of
+# the docker container is to zip them and then copy the zip.
zip -r reports.zip reports
find . -name report.xml -print0 | xargs -0 -r zip reports.zip
find . -name sponge_log.xml -print0 | xargs -0 -r zip reports.zip
diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json
index 47bc525f0d..4d9bbb0f09 100644
--- a/tools/run_tests/generated/sources_and_headers.json
+++ b/tools/run_tests/generated/sources_and_headers.json
@@ -3510,6 +3510,23 @@
{
"deps": [
"gpr",
+ "gpr_test_util",
+ "grpc",
+ "grpc_test_util"
+ ],
+ "headers": [],
+ "is_filegroup": false,
+ "language": "c++",
+ "name": "context_list_test",
+ "src": [
+ "test/core/transport/chttp2/context_list_test.cc"
+ ],
+ "third_party": false,
+ "type": "target"
+ },
+ {
+ "deps": [
+ "gpr",
"grpc",
"grpc++"
],
@@ -10035,13 +10052,13 @@
"src/core/ext/filters/client_channel/lb_policy.h",
"src/core/ext/filters/client_channel/lb_policy_factory.h",
"src/core/ext/filters/client_channel/lb_policy_registry.h",
- "src/core/ext/filters/client_channel/method_params.h",
"src/core/ext/filters/client_channel/parse_address.h",
"src/core/ext/filters/client_channel/proxy_mapper.h",
"src/core/ext/filters/client_channel/proxy_mapper_registry.h",
"src/core/ext/filters/client_channel/resolver.h",
"src/core/ext/filters/client_channel/resolver_factory.h",
"src/core/ext/filters/client_channel/resolver_registry.h",
+ "src/core/ext/filters/client_channel/resolver_result_parsing.h",
"src/core/ext/filters/client_channel/retry_throttle.h",
"src/core/ext/filters/client_channel/subchannel.h",
"src/core/ext/filters/client_channel/subchannel_index.h"
@@ -10074,8 +10091,6 @@
"src/core/ext/filters/client_channel/lb_policy_factory.h",
"src/core/ext/filters/client_channel/lb_policy_registry.cc",
"src/core/ext/filters/client_channel/lb_policy_registry.h",
- "src/core/ext/filters/client_channel/method_params.cc",
- "src/core/ext/filters/client_channel/method_params.h",
"src/core/ext/filters/client_channel/parse_address.cc",
"src/core/ext/filters/client_channel/parse_address.h",
"src/core/ext/filters/client_channel/proxy_mapper.cc",
@@ -10087,6 +10102,8 @@
"src/core/ext/filters/client_channel/resolver_factory.h",
"src/core/ext/filters/client_channel/resolver_registry.cc",
"src/core/ext/filters/client_channel/resolver_registry.h",
+ "src/core/ext/filters/client_channel/resolver_result_parsing.cc",
+ "src/core/ext/filters/client_channel/resolver_result_parsing.h",
"src/core/ext/filters/client_channel/retry_throttle.cc",
"src/core/ext/filters/client_channel/retry_throttle.h",
"src/core/ext/filters/client_channel/subchannel.cc",
@@ -10736,6 +10753,7 @@
"src/core/ext/transport/chttp2/transport/bin_decoder.h",
"src/core/ext/transport/chttp2/transport/bin_encoder.h",
"src/core/ext/transport/chttp2/transport/chttp2_transport.h",
+ "src/core/ext/transport/chttp2/transport/context_list.h",
"src/core/ext/transport/chttp2/transport/flow_control.h",
"src/core/ext/transport/chttp2/transport/frame.h",
"src/core/ext/transport/chttp2/transport/frame_data.h",
@@ -10765,6 +10783,8 @@
"src/core/ext/transport/chttp2/transport/chttp2_plugin.cc",
"src/core/ext/transport/chttp2/transport/chttp2_transport.cc",
"src/core/ext/transport/chttp2/transport/chttp2_transport.h",
+ "src/core/ext/transport/chttp2/transport/context_list.cc",
+ "src/core/ext/transport/chttp2/transport/context_list.h",
"src/core/ext/transport/chttp2/transport/flow_control.cc",
"src/core/ext/transport/chttp2/transport/flow_control.h",
"src/core/ext/transport/chttp2/transport/frame.h",
@@ -11111,7 +11131,6 @@
"tsi_interface"
],
"headers": [
- "src/core/tsi/alts_transport_security.h",
"src/core/tsi/fake_transport_security.h",
"src/core/tsi/local_transport_security.h",
"src/core/tsi/ssl/session_cache/ssl_session.h",
@@ -11124,8 +11143,6 @@
"language": "c",
"name": "tsi",
"src": [
- "src/core/tsi/alts_transport_security.cc",
- "src/core/tsi/alts_transport_security.h",
"src/core/tsi/fake_transport_security.cc",
"src/core/tsi/fake_transport_security.h",
"src/core/tsi/local_transport_security.cc",
diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json
index ef34cd6556..cc28e52ae2 100644
--- a/tools/run_tests/generated/tests.json
+++ b/tools/run_tests/generated/tests.json
@@ -3990,7 +3990,7 @@
"posix",
"windows"
],
- "cpu_cost": 1.0,
+ "cpu_cost": 10.0,
"exclude_configs": [],
"exclude_iomgrs": [],
"flaky": false,
@@ -4138,6 +4138,30 @@
"flaky": false,
"gtest": true,
"language": "c++",
+ "name": "context_list_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix",
+ "windows"
+ ],
+ "uses_polling": false
+ },
+ {
+ "args": [],
+ "benchmark": false,
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix",
+ "windows"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "gtest": true,
+ "language": "c++",
"name": "credentials_test",
"platforms": [
"linux",
diff --git a/tools/run_tests/helper_scripts/build_python.sh b/tools/run_tests/helper_scripts/build_python.sh
index 4c94c4c6d2..e43f1fb429 100755
--- a/tools/run_tests/helper_scripts/build_python.sh
+++ b/tools/run_tests/helper_scripts/build_python.sh
@@ -56,6 +56,12 @@ function is_linux() {
fi
}
+function inside_venv() {
+ if [[ -n "${VIRTUAL_ENV}" ]]; then
+ echo true
+ fi
+}
+
# Associated virtual environment name for the given python command.
function venv() {
$1 -c "import sys; print('py{}{}'.format(*sys.version_info[:2]))"
@@ -134,10 +140,14 @@ fi
# Perform build operations #
############################
-# Instantiate the virtualenv from the Python version passed in.
-$PYTHON -m pip install --user virtualenv
-$PYTHON -m virtualenv "$VENV"
-VENV_PYTHON=$(script_realpath "$VENV/$VENV_RELATIVE_PYTHON")
+if [[ "$(inside_venv)" ]]; then
+ VENV_PYTHON="$PYTHON"
+else
+ # Instantiate the virtualenv from the Python version passed in.
+ $PYTHON -m pip install --user virtualenv
+ $PYTHON -m virtualenv "$VENV"
+ VENV_PYTHON=$(script_realpath "$VENV/$VENV_RELATIVE_PYTHON")
+fi
# See https://github.com/grpc/grpc/issues/14815 for more context. We cannot rely
# on pip to upgrade itself because if pip is too old, it may not have the required
@@ -179,6 +189,11 @@ pip_install_dir "$ROOT"
$VENV_PYTHON "$ROOT/tools/distrib/python/make_grpcio_tools.py"
pip_install_dir "$ROOT/tools/distrib/python/grpcio_tools"
+# Build/install Channelz
+$VENV_PYTHON "$ROOT/src/python/grpcio_channelz/setup.py" preprocess
+$VENV_PYTHON "$ROOT/src/python/grpcio_channelz/setup.py" build_package_protos
+pip_install_dir "$ROOT/src/python/grpcio_channelz"
+
# Build/install health checking
$VENV_PYTHON "$ROOT/src/python/grpcio_health_checking/setup.py" preprocess
$VENV_PYTHON "$ROOT/src/python/grpcio_health_checking/setup.py" build_package_protos
diff --git a/tools/run_tests/run_interop_tests.py b/tools/run_tests/run_interop_tests.py
index ff6682c3cf..021f21dcd4 100755
--- a/tools/run_tests/run_interop_tests.py
+++ b/tools/run_tests/run_interop_tests.py
@@ -545,13 +545,13 @@ class PythonLanguage:
def client_cmd(self, args):
return [
- 'py27_native/bin/python', 'src/python/grpcio_tests/setup.py',
+ 'py37_native/bin/python', 'src/python/grpcio_tests/setup.py',
'run_interop', '--client', '--args="{}"'.format(' '.join(args))
]
def client_cmd_http2interop(self, args):
return [
- 'py27_native/bin/python',
+ 'py37_native/bin/python',
'src/python/grpcio_tests/tests/http2/negative_http2_client.py',
] + args
@@ -560,7 +560,7 @@ class PythonLanguage:
def server_cmd(self, args):
return [
- 'py27_native/bin/python', 'src/python/grpcio_tests/setup.py',
+ 'py37_native/bin/python', 'src/python/grpcio_tests/setup.py',
'run_interop', '--server', '--args="{}"'.format(' '.join(args))
]
diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index a1f2aaab2f..f71be2a65e 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -756,9 +756,10 @@ class PythonLanguage(object):
def dockerfile_dir(self):
return 'tools/dockerfile/test/python_%s_%s' % (
- self.python_manager_name(), _docker_arch_suffix(self.args.arch))
+ self._python_manager_name(), _docker_arch_suffix(self.args.arch))
- def python_manager_name(self):
+ def _python_manager_name(self):
+ """Choose the docker image to use based on python version."""
if self.args.compiler in [
'python2.7', 'python3.5', 'python3.6', 'python3.7'
]:
@@ -771,6 +772,7 @@ class PythonLanguage(object):
return 'stretch_3.7'
def _get_pythons(self, args):
+ """Get python runtimes to test with, based on current platform, architecture, compiler etc."""
if args.arch == 'x86':
bits = '32'
else:
@@ -1340,9 +1342,9 @@ argp.add_argument(
argp.add_argument(
'-l',
'--language',
- choices=['all'] + sorted(_LANGUAGES.keys()),
+ choices=sorted(_LANGUAGES.keys()),
nargs='+',
- default=['all'])
+ required=True)
argp.add_argument(
'-S', '--stop_on_failure', default=False, action='store_const', const=True)
argp.add_argument(
@@ -1513,17 +1515,7 @@ build_config = run_config.build_config
if args.travis:
_FORCE_ENVIRON_FOR_WRAPPERS = {'GRPC_TRACE': 'api'}
-if 'all' in args.language:
- lang_list = list(_LANGUAGES.keys())
-else:
- lang_list = args.language
-# We don't support code coverage on some languages
-if 'gcov' in args.config:
- for bad in ['csharp', 'grpc-node', 'objc', 'sanity']:
- if bad in lang_list:
- lang_list.remove(bad)
-
-languages = set(_LANGUAGES[l] for l in lang_list)
+languages = set(_LANGUAGES[l] for l in args.language)
for l in languages:
l.configure(run_config, args)
@@ -1535,7 +1527,7 @@ if any(language.make_options() for language in languages):
)
sys.exit(1)
else:
- # Combining make options is not clean and just happens to work. It allows C/C++ and C# to build
+ # Combining make options is not clean and just happens to work. It allows C & C++ to build
# together, and is only used under gcov. All other configs should build languages individually.
language_make_options = list(
set([
diff --git a/tools/run_tests/sanity/check_bazel_workspace.py b/tools/run_tests/sanity/check_bazel_workspace.py
index d562fffc8a..35da88d70e 100755
--- a/tools/run_tests/sanity/check_bazel_workspace.py
+++ b/tools/run_tests/sanity/check_bazel_workspace.py
@@ -42,6 +42,7 @@ _ZOPEFOUNDATION_ZOPE_INTERFACE_DEP_NAME = 'com_github_zopefoundation_zope_interf
_TWISTED_CONSTANTLY_DEP_NAME = 'com_github_twisted_constantly'
_GRPC_DEP_NAMES = [
+ 'upb',
'boringssl',
'com_github_madler_zlib',
'com_google_protobuf',
diff --git a/tools/run_tests/sanity/check_submodules.sh b/tools/run_tests/sanity/check_submodules.sh
index 8ea53dfec5..f1103596d5 100755
--- a/tools/run_tests/sanity/check_submodules.sh
+++ b/tools/run_tests/sanity/check_submodules.sh
@@ -32,11 +32,15 @@ cat << EOF | awk '{ print $1 }' | sort > "$want_submodules"
b29b21a81b32ec273f118f589f46d56ad3332420 third_party/boringssl (remotes/origin/chromium-stable)
afc30d43eef92979b05776ec0963c9cede5fb80f third_party/boringssl-with-bazel (fips-20180716-116-gafc30d43e)
3be1924221e1326df520f8498d704a5c4c8d0cce third_party/cares/cares (cares-1_13_0)
+ 911001cdca003337bdb93fab32740cde61bafee3 third_party/data-plane-api (heads/master)
30dbc81fb5ffdc98ea9b14b1918bfe4e8779b26e third_party/gflags (v2.2.0-5-g30dbc81)
+ 80ed4d0bbf65d57cc267dfc63bd2584557f11f9b third_party/googleapis (common-protos-1_3_1-915-g80ed4d0bb)
ec44c6c1675c25b9827aacd08c02433cccde7780 third_party/googletest (release-1.8.0)
6599cac0965be8e5a835ab7a5684bbef033d5ad0 third_party/libcxx (heads/release_60)
9245d481eb3e890f708ff2d7dadf2a10c04748ba third_party/libcxxabi (heads/release_60)
48cb18e5c419ddd23d9badcfe4e9df7bde1979b2 third_party/protobuf (v3.6.0.1-37-g48cb18e5)
+ e143189bf6f37b3957fb31743df6a1bcf4a8c685 third_party/protoc-gen-validate (v0.0.10)
+ 9ce4a77f61c134bbed28bfd5be5cd7dc0e80f5e3 third_party/upb (heads/upbc-cpp)
cacf7f1d4e3d44d871b605da3b647f07d718623f third_party/zlib (v1.2.11)
EOF
diff --git a/tools/run_tests/sanity/core_banned_functions.py b/tools/run_tests/sanity/core_banned_functions.py
index 2a5dcda5be..549ae14f5a 100755
--- a/tools/run_tests/sanity/core_banned_functions.py
+++ b/tools/run_tests/sanity/core_banned_functions.py
@@ -39,6 +39,7 @@ BANNED_EXCEPT = {
'grpc_wsa_error(': ['src/core/lib/iomgr/error.cc'],
'grpc_log_if_error(': ['src/core/lib/iomgr/error.cc'],
'grpc_slice_malloc(': ['src/core/lib/slice/slice.cc'],
+ 'grpc_call_cancel_internal(': ['src/core/lib/surface/call.cc'],
'grpc_closure_create(': ['src/core/lib/iomgr/closure.cc'],
'grpc_closure_init(': ['src/core/lib/iomgr/closure.cc'],
'grpc_closure_sched(': ['src/core/lib/iomgr/closure.cc'],