aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.github/mergeable.yml6
-rw-r--r--BUILD29
-rw-r--r--CMakeLists.txt163
-rw-r--r--Makefile200
-rw-r--r--README.md2
-rw-r--r--WORKSPACE41
-rw-r--r--bazel/cython_library.bzl74
-rw-r--r--build.yaml66
-rw-r--r--composer.json2
-rw-r--r--config.m43
-rw-r--r--config.w323
-rw-r--r--doc/csharp/server_reflection.md53
-rw-r--r--doc/g_stands_for.md3
-rw-r--r--doc/interop-test-descriptions.md45
-rw-r--r--doc/server-reflection.md13
-rw-r--r--doc/server_reflection_tutorial.md2
-rw-r--r--doc/statuscodes.md3
-rw-r--r--examples/csharp/Helloworld/Greeter.sln (renamed from examples/csharp/helloworld-from-cli/Greeter.sln)0
-rw-r--r--examples/csharp/Helloworld/Greeter/Greeter.csproj (renamed from examples/csharp/helloworld-from-cli/Greeter/Greeter.csproj)4
-rw-r--r--examples/csharp/Helloworld/Greeter/Helloworld.cs (renamed from examples/csharp/helloworld-from-cli/Greeter/Helloworld.cs)0
-rw-r--r--examples/csharp/Helloworld/Greeter/HelloworldGrpc.cs (renamed from examples/csharp/helloworld-from-cli/Greeter/HelloworldGrpc.cs)0
-rw-r--r--examples/csharp/Helloworld/GreeterClient/GreeterClient.csproj (renamed from examples/csharp/helloworld-from-cli/GreeterClient/GreeterClient.csproj)0
-rw-r--r--examples/csharp/Helloworld/GreeterClient/Program.cs (renamed from examples/csharp/helloworld-from-cli/GreeterClient/Program.cs)0
-rw-r--r--examples/csharp/Helloworld/GreeterServer/GreeterServer.csproj (renamed from examples/csharp/helloworld-from-cli/GreeterServer/GreeterServer.csproj)0
-rw-r--r--examples/csharp/Helloworld/GreeterServer/Program.cs (renamed from examples/csharp/helloworld-from-cli/GreeterServer/Program.cs)0
-rw-r--r--examples/csharp/Helloworld/README.md (renamed from examples/csharp/helloworld-from-cli/README.md)13
-rw-r--r--examples/csharp/Helloworld/generate_protos.bat (renamed from examples/csharp/helloworld-from-cli/generate_protos.bat)0
-rw-r--r--examples/csharp/HelloworldLegacyCsproj/Greeter.sln (renamed from examples/csharp/helloworld/Greeter.sln)0
-rw-r--r--examples/csharp/HelloworldLegacyCsproj/Greeter/.gitignore (renamed from examples/csharp/helloworld/Greeter/.gitignore)0
-rw-r--r--examples/csharp/HelloworldLegacyCsproj/Greeter/Greeter.csproj (renamed from examples/csharp/helloworld/Greeter/Greeter.csproj)16
-rw-r--r--examples/csharp/HelloworldLegacyCsproj/Greeter/Helloworld.cs (renamed from examples/csharp/helloworld/Greeter/Helloworld.cs)0
-rw-r--r--examples/csharp/HelloworldLegacyCsproj/Greeter/HelloworldGrpc.cs (renamed from examples/csharp/helloworld/Greeter/HelloworldGrpc.cs)0
-rw-r--r--examples/csharp/HelloworldLegacyCsproj/Greeter/Properties/AssemblyInfo.cs (renamed from examples/csharp/helloworld/Greeter/Properties/AssemblyInfo.cs)0
-rw-r--r--examples/csharp/HelloworldLegacyCsproj/Greeter/packages.config (renamed from examples/csharp/helloworld/Greeter/packages.config)6
-rw-r--r--examples/csharp/HelloworldLegacyCsproj/GreeterClient/.gitignore (renamed from examples/csharp/helloworld/GreeterClient/.gitignore)0
-rw-r--r--examples/csharp/HelloworldLegacyCsproj/GreeterClient/GreeterClient.csproj (renamed from examples/csharp/helloworld/GreeterClient/GreeterClient.csproj)16
-rw-r--r--examples/csharp/HelloworldLegacyCsproj/GreeterClient/Program.cs (renamed from examples/csharp/helloworld/GreeterClient/Program.cs)0
-rw-r--r--examples/csharp/HelloworldLegacyCsproj/GreeterClient/Properties/AssemblyInfo.cs (renamed from examples/csharp/helloworld/GreeterClient/Properties/AssemblyInfo.cs)0
-rw-r--r--examples/csharp/HelloworldLegacyCsproj/GreeterClient/packages.config (renamed from examples/csharp/helloworld/GreeterClient/packages.config)4
-rw-r--r--examples/csharp/HelloworldLegacyCsproj/GreeterServer/.gitignore (renamed from examples/csharp/helloworld/GreeterServer/.gitignore)0
-rw-r--r--examples/csharp/HelloworldLegacyCsproj/GreeterServer/GreeterServer.csproj (renamed from examples/csharp/helloworld/GreeterServer/GreeterServer.csproj)16
-rw-r--r--examples/csharp/HelloworldLegacyCsproj/GreeterServer/Program.cs (renamed from examples/csharp/helloworld/GreeterServer/Program.cs)0
-rw-r--r--examples/csharp/HelloworldLegacyCsproj/GreeterServer/Properties/AssemblyInfo.cs (renamed from examples/csharp/helloworld/GreeterServer/Properties/AssemblyInfo.cs)0
-rw-r--r--examples/csharp/HelloworldLegacyCsproj/GreeterServer/packages.config (renamed from examples/csharp/helloworld/GreeterServer/packages.config)4
-rw-r--r--examples/csharp/HelloworldLegacyCsproj/README.md (renamed from examples/csharp/helloworld/README.md)8
-rw-r--r--examples/csharp/HelloworldLegacyCsproj/generate_protos.bat (renamed from examples/csharp/helloworld/generate_protos.bat)0
-rw-r--r--examples/csharp/HelloworldXamarin/.gitignore41
-rw-r--r--examples/csharp/HelloworldXamarin/Droid/Assets/AboutAssets.txt19
-rw-r--r--examples/csharp/HelloworldXamarin/Droid/HelloworldXamarin.Droid.csproj83
-rw-r--r--examples/csharp/HelloworldXamarin/Droid/MainActivity.cs84
-rw-r--r--examples/csharp/HelloworldXamarin/Droid/Properties/AndroidManifest.xml6
-rw-r--r--examples/csharp/HelloworldXamarin/Droid/Properties/AssemblyInfo.cs45
-rw-r--r--examples/csharp/HelloworldXamarin/Droid/Resources/AboutResources.txt44
-rw-r--r--examples/csharp/HelloworldXamarin/Droid/Resources/Resource.designer.cs112
-rw-r--r--examples/csharp/HelloworldXamarin/Droid/Resources/layout/Main.axml4
-rw-r--r--examples/csharp/HelloworldXamarin/Droid/Resources/mipmap-hdpi/Icon.pngbin0 -> 2201 bytes
-rw-r--r--examples/csharp/HelloworldXamarin/Droid/Resources/mipmap-mdpi/Icon.pngbin0 -> 1410 bytes
-rw-r--r--examples/csharp/HelloworldXamarin/Droid/Resources/mipmap-xhdpi/Icon.pngbin0 -> 3237 bytes
-rw-r--r--examples/csharp/HelloworldXamarin/Droid/Resources/mipmap-xxhdpi/Icon.pngbin0 -> 5414 bytes
-rw-r--r--examples/csharp/HelloworldXamarin/Droid/Resources/mipmap-xxxhdpi/Icon.pngbin0 -> 7825 bytes
-rw-r--r--examples/csharp/HelloworldXamarin/Droid/Resources/values/Strings.xml5
-rw-r--r--examples/csharp/HelloworldXamarin/Droid/packages.config54
-rw-r--r--examples/csharp/HelloworldXamarin/HelloworldXamarin.sln45
-rw-r--r--examples/csharp/HelloworldXamarin/HelloworldXamarin/Helloworld.cs286
-rw-r--r--examples/csharp/HelloworldXamarin/HelloworldXamarin/HelloworldGrpc.cs150
-rw-r--r--examples/csharp/HelloworldXamarin/HelloworldXamarin/HelloworldXamarin.projitems15
-rw-r--r--examples/csharp/HelloworldXamarin/HelloworldXamarin/HelloworldXamarin.shproj11
-rw-r--r--examples/csharp/HelloworldXamarin/README.md37
-rw-r--r--examples/csharp/HelloworldXamarin/iOS/AppDelegate.cs77
-rw-r--r--examples/csharp/HelloworldXamarin/iOS/Assets.xcassets/AppIcon.appiconset/Contents.json202
-rw-r--r--examples/csharp/HelloworldXamarin/iOS/Assets.xcassets/Contents.json6
-rw-r--r--examples/csharp/HelloworldXamarin/iOS/Entitlements.plist6
-rw-r--r--examples/csharp/HelloworldXamarin/iOS/HelloworldXamarin.iOS.csproj126
-rw-r--r--examples/csharp/HelloworldXamarin/iOS/Info.plist48
-rw-r--r--examples/csharp/HelloworldXamarin/iOS/LaunchScreen.storyboard27
-rw-r--r--examples/csharp/HelloworldXamarin/iOS/Main.cs38
-rw-r--r--examples/csharp/HelloworldXamarin/iOS/Main.storyboard40
-rw-r--r--examples/csharp/HelloworldXamarin/iOS/ViewController.cs91
-rw-r--r--examples/csharp/HelloworldXamarin/iOS/ViewController.designer.cs25
-rw-r--r--examples/csharp/HelloworldXamarin/iOS/packages.config54
-rw-r--r--examples/csharp/RouteGuide/.gitignore (renamed from examples/csharp/route_guide/.gitignore)0
-rw-r--r--examples/csharp/RouteGuide/README.md (renamed from examples/csharp/route_guide/README.md)0
-rw-r--r--examples/csharp/RouteGuide/RouteGuide.sln (renamed from examples/csharp/route_guide/RouteGuide.sln)10
-rw-r--r--examples/csharp/RouteGuide/RouteGuide/RouteGuide.cs (renamed from examples/csharp/route_guide/RouteGuide/RouteGuide.cs)0
-rw-r--r--examples/csharp/RouteGuide/RouteGuide/RouteGuide.csproj25
-rw-r--r--examples/csharp/RouteGuide/RouteGuide/RouteGuideGrpc.cs (renamed from examples/csharp/route_guide/RouteGuide/RouteGuideGrpc.cs)0
-rw-r--r--examples/csharp/RouteGuide/RouteGuide/RouteGuideUtil.cs (renamed from examples/csharp/route_guide/RouteGuide/RouteGuideUtil.cs)0
-rw-r--r--examples/csharp/RouteGuide/RouteGuide/route_guide_db.json (renamed from examples/csharp/route_guide/RouteGuide/route_guide_db.json)2
-rw-r--r--examples/csharp/RouteGuide/RouteGuideClient/Program.cs (renamed from examples/csharp/route_guide/RouteGuideClient/Program.cs)0
-rw-r--r--examples/csharp/RouteGuide/RouteGuideClient/RouteGuideClient.csproj16
-rw-r--r--examples/csharp/RouteGuide/RouteGuideServer/Program.cs (renamed from examples/csharp/route_guide/RouteGuideServer/Program.cs)0
-rw-r--r--examples/csharp/RouteGuide/RouteGuideServer/RouteGuideImpl.cs (renamed from examples/csharp/route_guide/RouteGuideServer/RouteGuideImpl.cs)0
-rw-r--r--examples/csharp/RouteGuide/RouteGuideServer/RouteGuideServer.csproj16
-rw-r--r--examples/csharp/RouteGuide/generate_protos.bat (renamed from examples/csharp/route_guide/generate_protos.bat)0
-rw-r--r--examples/csharp/route_guide/RouteGuide/Properties/AssemblyInfo.cs54
-rw-r--r--examples/csharp/route_guide/RouteGuide/RouteGuide.csproj92
-rw-r--r--examples/csharp/route_guide/RouteGuide/packages.config8
-rw-r--r--examples/csharp/route_guide/RouteGuideClient/Properties/AssemblyInfo.cs54
-rw-r--r--examples/csharp/route_guide/RouteGuideClient/RouteGuideClient.csproj89
-rw-r--r--examples/csharp/route_guide/RouteGuideClient/packages.config8
-rw-r--r--examples/csharp/route_guide/RouteGuideServer/Properties/AssemblyInfo.cs54
-rw-r--r--examples/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj90
-rw-r--r--examples/csharp/route_guide/RouteGuideServer/packages.config9
-rw-r--r--examples/node/dynamic_codegen/greeter_client.js11
-rw-r--r--examples/node/dynamic_codegen/greeter_server.js11
-rw-r--r--examples/node/dynamic_codegen/route_guide/route_guide_client.js11
-rw-r--r--examples/node/dynamic_codegen/route_guide/route_guide_server.js11
-rw-r--r--examples/node/package.json3
-rw-r--r--examples/python/multiplex/helloworld_pb2.py145
-rw-r--r--examples/python/multiplex/helloworld_pb2_grpc.py3
-rw-r--r--examples/python/multiplex/route_guide_pb2.py310
-rw-r--r--examples/python/multiplex/route_guide_pb2_grpc.py3
-rw-r--r--examples/ruby/grpc-demo.gemspec2
-rw-r--r--gRPC-C++.podspec4
-rw-r--r--gRPC-Core.podspec5
-rw-r--r--gRPC-ProtoRPC.podspec2
-rw-r--r--gRPC-RxLibrary.podspec2
-rw-r--r--gRPC.podspec2
-rw-r--r--grpc.def2
-rw-r--r--grpc.gemspec3
-rw-r--r--grpc.gyp20
-rw-r--r--include/grpc/grpc.h28
-rw-r--r--include/grpc/grpc_security.h6
-rw-r--r--include/grpc/grpc_security_constants.h6
-rw-r--r--include/grpc/impl/codegen/port_platform.h4
-rw-r--r--include/grpcpp/ext/channelz_service_plugin.h41
-rw-r--r--include/grpcpp/impl/codegen/completion_queue.h2
-rw-r--r--include/grpcpp/security/credentials.h5
-rw-r--r--include/grpcpp/security/server_credentials.h4
-rw-r--r--package.xml11
-rw-r--r--requirements.bazel.txt10
-rw-r--r--setup.py6
-rw-r--r--src/android/test/interop/app/src/main/cpp/grpc-interop.cc5
-rw-r--r--src/core/ext/filters/client_channel/client_channel.cc38
-rw-r--r--src/core/ext/filters/client_channel/client_channel_channelz.cc20
-rw-r--r--src/core/ext/filters/client_channel/client_channel_channelz.h6
-rw-r--r--src/core/ext/filters/client_channel/lb_policy.h20
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc146
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc70
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc90
-rw-r--r--src/core/ext/filters/client_channel/lb_policy/subchannel_list.h13
-rw-r--r--src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc5
-rw-r--r--src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc6
-rw-r--r--src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc59
-rw-r--r--src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc9
-rw-r--r--src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h4
-rw-r--r--src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc29
-rw-r--r--src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc29
-rw-r--r--src/core/ext/filters/client_channel/subchannel.cc18
-rw-r--r--src/core/ext/transport/chttp2/transport/chttp2_transport.cc2
-rw-r--r--src/core/lib/channel/channel_stack.h2
-rw-r--r--src/core/lib/channel/channel_trace.cc2
-rw-r--r--src/core/lib/channel/channel_trace.h2
-rw-r--r--src/core/lib/channel/channelz.cc64
-rw-r--r--src/core/lib/channel/channelz.h17
-rw-r--r--src/core/lib/channel/channelz_registry.cc92
-rw-r--r--src/core/lib/channel/channelz_registry.h95
-rw-r--r--src/core/lib/gpr/arena.cc88
-rw-r--r--src/core/lib/gprpp/orphanable.h6
-rw-r--r--src/core/lib/gprpp/ref_counted.h6
-rw-r--r--src/core/lib/gprpp/ref_counted_ptr.h78
-rw-r--r--src/core/lib/iomgr/ev_epoll1_linux.cc22
-rw-r--r--src/core/lib/iomgr/ev_epollex_linux.cc31
-rw-r--r--src/core/lib/iomgr/ev_epollsig_linux.cc38
-rw-r--r--src/core/lib/iomgr/ev_poll_posix.cc67
-rw-r--r--src/core/lib/iomgr/ev_posix.cc6
-rw-r--r--src/core/lib/iomgr/ev_posix.h20
-rw-r--r--src/core/lib/iomgr/executor.cc220
-rw-r--r--src/core/lib/iomgr/executor.h45
-rw-r--r--src/core/lib/iomgr/lockfree_event.cc6
-rw-r--r--src/core/lib/iomgr/resolve_address_posix.cc5
-rw-r--r--src/core/lib/iomgr/resolve_address_windows.cc5
-rw-r--r--src/core/lib/iomgr/socket_windows.cc29
-rw-r--r--src/core/lib/iomgr/socket_windows.h4
-rw-r--r--src/core/lib/json/json.cc3
-rw-r--r--src/core/lib/security/credentials/alts/check_gcp_environment_linux.cc5
-rw-r--r--src/core/lib/security/security_connector/security_connector.cc9
-rw-r--r--src/core/lib/surface/call.cc3
-rw-r--r--src/core/lib/surface/channel.cc9
-rw-r--r--src/core/lib/surface/init.cc4
-rw-r--r--src/core/lib/surface/version.cc4
-rw-r--r--src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc8
-rw-r--r--src/cpp/client/secure_credentials.cc7
-rw-r--r--src/cpp/common/version_cc.cc2
-rw-r--r--src/cpp/server/channelz/channelz_service.cc57
-rw-r--r--src/cpp/server/channelz/channelz_service.h43
-rw-r--r--src/cpp/server/channelz/channelz_service_plugin.cc79
-rw-r--r--src/cpp/server/secure_server_credentials.cc6
-rwxr-xr-xsrc/csharp/Grpc.Core/Grpc.Core.csproj30
-rw-r--r--src/csharp/Grpc.Core/Internal/NativeExtension.cs24
-rw-r--r--src/csharp/Grpc.Core/Internal/NativeLogRedirector.cs19
-rw-r--r--src/csharp/Grpc.Core/Internal/PlatformApis.cs34
-rwxr-xr-xsrc/csharp/Grpc.Core/Version.csproj.include2
-rw-r--r--src/csharp/Grpc.Core/VersionInfo.cs4
-rw-r--r--src/csharp/Grpc.Core/build/MonoAndroid/Grpc.Core.targets28
-rw-r--r--src/csharp/Grpc.Core/build/Xamarin.iOS/Grpc.Core.targets15
-rw-r--r--src/csharp/Grpc.Core/build/net45/Grpc.Core.targets (renamed from src/csharp/Grpc.Core/Grpc.Core.targets)0
-rw-r--r--src/csharp/README.md8
-rwxr-xr-xsrc/csharp/build_packages_dotnetcli.bat10
-rwxr-xr-xsrc/csharp/build_packages_dotnetcli.sh52
-rw-r--r--src/csharp/build_unitypackage.bat78
-rw-r--r--src/csharp/doc/docfx.json2
-rw-r--r--src/csharp/experimental/README.md39
-rwxr-xr-xsrc/csharp/experimental/build_native_ext_for_android.sh25
-rwxr-xr-xsrc/csharp/experimental/build_native_ext_for_ios.sh62
-rw-r--r--src/csharp/unitypackage/README.md13
-rw-r--r--src/csharp/unitypackage/unitypackage_skeleton/Plugins/Google.Protobuf.meta8
-rw-r--r--src/csharp/unitypackage/unitypackage_skeleton/Plugins/Google.Protobuf/lib.meta8
-rw-r--r--src/csharp/unitypackage/unitypackage_skeleton/Plugins/Google.Protobuf/lib/net45.meta8
-rw-r--r--src/csharp/unitypackage/unitypackage_skeleton/Plugins/Google.Protobuf/lib/net45/Google.Protobuf.dll.meta30
-rw-r--r--src/csharp/unitypackage/unitypackage_skeleton/Plugins/Google.Protobuf/lib/net45/Google.Protobuf.xml.meta7
-rw-r--r--src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.meta10
-rw-r--r--src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/lib.meta10
-rw-r--r--src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/lib/net45.meta10
-rw-r--r--src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/lib/net45/Grpc.Core.dll.meta32
-rw-r--r--src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/lib/net45/Grpc.Core.pdb.meta9
-rw-r--r--src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/lib/net45/Grpc.Core.xml.meta9
-rw-r--r--src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes.meta10
-rw-r--r--src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/android.meta10
-rw-r--r--src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/android/arm64-v8a.meta8
-rw-r--r--src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/android/arm64-v8a/libgrpc_csharp_ext.so.meta102
-rw-r--r--src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/android/armeabi-v7a.meta10
-rw-r--r--src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/android/armeabi-v7a/libgrpc_csharp_ext.so.meta102
-rw-r--r--src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/android/x86.meta8
-rw-r--r--src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/android/x86/libgrpc_csharp_ext.so.meta102
-rw-r--r--src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/ios.meta10
-rw-r--r--src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/ios/libgrpc.a.meta95
-rw-r--r--src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/ios/libgrpc_csharp_ext.a.meta117
-rw-r--r--src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/linux.meta10
-rw-r--r--src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/linux/x64.meta10
-rw-r--r--src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/linux/x64/libgrpc_csharp_ext.so.meta117
-rw-r--r--src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/linux/x86.meta10
-rw-r--r--src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/linux/x86/libgrpc_csharp_ext.so.meta117
-rw-r--r--src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/osx.meta10
-rw-r--r--src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/osx/x64.meta10
-rw-r--r--src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/osx/x64/grpc_csharp_ext.bundle.meta117
-rw-r--r--src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/osx/x86.meta10
-rw-r--r--src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/osx/x86/grpc_csharp_ext.bundle.meta117
-rw-r--r--src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/win.meta10
-rw-r--r--src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/win/x64.meta10
-rw-r--r--src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/win/x64/grpc_csharp_ext.dll.meta117
-rw-r--r--src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/win/x86.meta10
-rw-r--r--src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/win/x86/grpc_csharp_ext.dll.meta117
-rw-r--r--src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Interactive.Async.meta10
-rw-r--r--src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Interactive.Async/lib.meta10
-rw-r--r--src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Interactive.Async/lib/net45.meta10
-rw-r--r--src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Interactive.Async/lib/net45/System.Interactive.Async.dll.meta32
-rw-r--r--src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Interactive.Async/lib/net45/System.Interactive.Async.xml.meta9
-rw-r--r--src/objective-c/!ProtoCompiler-gRPCPlugin.podspec2
-rw-r--r--src/objective-c/GRPCClient/private/version.h2
-rwxr-xr-xsrc/objective-c/tests/build_one_example.sh2
-rw-r--r--src/objective-c/tests/version.h4
-rw-r--r--src/php/composer.json4
-rw-r--r--src/php/ext/grpc/version.h2
-rw-r--r--src/php/lib/Grpc/BaseStub.php9
-rw-r--r--src/proto/grpc/testing/echo_messages.proto1
-rw-r--r--src/python/grpcio/grpc/BUILD.bazel82
-rw-r--r--src/python/grpcio/grpc/_cython/BUILD.bazel46
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pxd.pxi16
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pyx.pxi17
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/arguments.pxd.pxi8
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/arguments.pyx.pxi18
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi2
-rw-r--r--src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi2
-rw-r--r--src/python/grpcio/grpc/_cython/cygrpc.pxd1
-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/beta/BUILD.bazel58
-rw-r--r--src/python/grpcio/grpc/experimental/BUILD.bazel27
-rw-r--r--src/python/grpcio/grpc/framework/BUILD.bazel11
-rw-r--r--src/python/grpcio/grpc/framework/common/BUILD.bazel27
-rw-r--r--src/python/grpcio/grpc/framework/foundation/BUILD.bazel61
-rw-r--r--src/python/grpcio/grpc/framework/interfaces/BUILD.bazel10
-rw-r--r--src/python/grpcio/grpc/framework/interfaces/base/BUILD.bazel29
-rw-r--r--src/python/grpcio/grpc/framework/interfaces/face/BUILD.bazel32
-rw-r--r--src/python/grpcio/grpc_core_dependencies.py3
-rw-r--r--src/python/grpcio/grpc_version.py2
-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/grpc_version.py2
-rw-r--r--src/python/grpcio_tests/tests/unit/beta/_utilities_test.py1
-rw-r--r--src/python/grpcio_tests/tests/unit/framework/foundation/BUILD.bazel17
-rw-r--r--src/ruby/ext/grpc/extconf.rb27
-rw-r--r--src/ruby/ext/grpc/rb_grpc_imports.generated.c4
-rw-r--r--src/ruby/ext/grpc/rb_grpc_imports.generated.h6
-rw-r--r--src/ruby/lib/grpc/version.rb2
-rw-r--r--src/ruby/tools/version.rb2
-rw-r--r--templates/Makefile.template10
-rw-r--r--templates/composer.json.template2
-rwxr-xr-xtemplates/src/csharp/build_packages_dotnetcli.bat.template8
-rwxr-xr-xtemplates/src/csharp/build_packages_dotnetcli.sh.template54
-rwxr-xr-xtemplates/src/csharp/build_unitypackage.bat.template80
-rw-r--r--templates/src/php/composer.json.template2
-rw-r--r--test/core/channel/channel_trace_test.cc24
-rw-r--r--test/core/channel/channelz_registry_test.cc74
-rw-r--r--test/core/channel/channelz_test.cc100
-rw-r--r--test/core/end2end/tests/channelz.cc16
-rw-r--r--test/core/gprpp/ref_counted_ptr_test.cc63
-rw-r--r--test/core/iomgr/BUILD13
-rw-r--r--test/core/iomgr/grpc_ipv6_loopback_available_test.cc48
-rw-r--r--test/core/security/check_gcp_environment_linux_test.cc1
-rw-r--r--test/core/surface/public_headers_must_be_c89.c2
-rw-r--r--test/cpp/end2end/BUILD21
-rw-r--r--test/cpp/end2end/channelz_service_test.cc352
-rw-r--r--test/cpp/end2end/client_lb_end2end_test.cc40
-rw-r--r--test/cpp/interop/client.cc16
-rw-r--r--test/cpp/interop/interop_client.cc64
-rw-r--r--test/cpp/interop/interop_client.h20
-rw-r--r--test/cpp/interop/stress_interop_client.cc6
-rw-r--r--test/cpp/interop/stress_interop_client.h4
-rw-r--r--test/cpp/interop/stress_test.cc11
-rw-r--r--test/cpp/naming/address_sorting_test.cc160
-rwxr-xr-xtest/cpp/naming/gen_build_yaml.py2
-rw-r--r--test/cpp/qps/BUILD6
-rw-r--r--test/cpp/qps/benchmark_config.cc15
-rw-r--r--test/cpp/qps/client.h24
-rw-r--r--test/cpp/qps/qps_server_builder.cc45
-rw-r--r--test/cpp/qps/qps_server_builder.h46
-rw-r--r--test/cpp/qps/qps_worker.cc9
-rw-r--r--test/cpp/qps/server_async.cc15
-rw-r--r--test/cpp/qps/server_sync.cc13
-rw-r--r--test/cpp/server/load_reporter/load_reporter_test.cc4
-rw-r--r--test/cpp/util/BUILD1
-rw-r--r--test/cpp/util/channel_trace_proto_helper.cc19
-rw-r--r--test/cpp/util/channel_trace_proto_helper.h6
-rw-r--r--test/cpp/util/cli_credentials.cc14
-rw-r--r--test/cpp/util/cli_credentials.h1
-rw-r--r--test/cpp/util/grpc_tool.cc17
-rw-r--r--test/cpp/util/grpc_tool_test.cc52
-rw-r--r--third_party/BUILD1
-rw-r--r--third_party/address_sorting/address_sorting.c9
-rw-r--r--third_party/address_sorting/address_sorting_windows.c46
-rw-r--r--third_party/address_sorting/include/address_sorting/address_sorting.h3
-rw-r--r--third_party/cython.BUILD29
-rw-r--r--third_party/py/BUILD0
-rw-r--r--third_party/py/BUILD.tpl36
-rw-r--r--third_party/py/python_configure.bzl305
-rw-r--r--third_party/py/remote.BUILD.tpl10
-rw-r--r--third_party/toolchains/BUILD2
-rwxr-xr-xtools/distrib/check_copyright.py4
-rw-r--r--tools/distrib/python/grpcio_tools/grpc_version.py2
-rw-r--r--tools/dockerfile/grpc_artifact_android_ndk/Dockerfile31
-rw-r--r--tools/doxygen/Doxyfile.c++2
-rw-r--r--tools/doxygen/Doxyfile.c++.internal2
-rw-r--r--tools/doxygen/Doxyfile.core2
-rw-r--r--tools/doxygen/Doxyfile.core.internal5
-rw-r--r--tools/internal_ci/helper_scripts/prepare_build_macos_rc15
-rw-r--r--tools/internal_ci/linux/grpc_publish_packages.cfg26
-rwxr-xr-xtools/internal_ci/linux/grpc_publish_packages.sh235
-rwxr-xr-xtools/internal_ci/macos/grpc_ios_binary_size.sh27
-rw-r--r--tools/internal_ci/macos/pull_request/grpc_ios_binary_size.cfg26
-rw-r--r--tools/interop_matrix/client_matrix.py3
-rw-r--r--tools/package_hosting/404.html1
-rw-r--r--tools/package_hosting/build-201807.xsl114
-rw-r--r--tools/package_hosting/dirindex.css16
-rw-r--r--tools/package_hosting/home.xsl86
-rw-r--r--tools/package_hosting/style.css76
-rwxr-xr-xtools/package_hosting/upload_web_assets.sh30
-rwxr-xr-xtools/profiling/ios_bin/binary_size.py (renamed from tools/profiling/ios_bin/binary_diff.py)54
-rw-r--r--tools/run_tests/artifacts/artifact_targets.py20
-rwxr-xr-xtools/run_tests/artifacts/build_artifact_csharp_android.sh1
-rwxr-xr-xtools/run_tests/artifacts/build_artifact_csharp_ios.sh23
-rwxr-xr-xtools/run_tests/artifacts/build_package_php.sh3
-rwxr-xr-xtools/run_tests/artifacts/build_package_python.sh3
-rwxr-xr-xtools/run_tests/artifacts/build_package_ruby.sh10
-rw-r--r--tools/run_tests/artifacts/package_targets.py38
-rw-r--r--tools/run_tests/generated/sources_and_headers.json104
-rw-r--r--tools/run_tests/generated/tests.json62
-rw-r--r--tools/run_tests/performance/README.md28
370 files changed, 9081 insertions, 1994 deletions
diff --git a/.github/mergeable.yml b/.github/mergeable.yml
new file mode 100644
index 0000000000..660d8cb440
--- /dev/null
+++ b/.github/mergeable.yml
@@ -0,0 +1,6 @@
+mergeable:
+ pull_requests:
+ label:
+ must_include:
+ regex: "release notes: yes|release notes: no"
+ message: "Add release notes yes/no label. For yes, add lang label"
diff --git a/BUILD b/BUILD
index 783590a134..81390dd1aa 100644
--- a/BUILD
+++ b/BUILD
@@ -64,11 +64,11 @@ config_setting(
)
# This should be updated along with build.yaml
-g_stands_for = "gladiolus"
+g_stands_for = "glider"
-core_version = "6.0.0"
+core_version = "6.0.0-dev"
-version = "1.14.0"
+version = "1.15.0-dev"
GPR_PUBLIC_HDRS = [
"include/grpc/support/alloc.h",
@@ -1433,7 +1433,10 @@ grpc_cc_library(
"src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc",
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc",
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc",
+ "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc",
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc",
+ "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc",
+ "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc",
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc",
],
hdrs = [
@@ -2054,6 +2057,26 @@ grpc_cc_library(
)
grpc_cc_library(
+ name = "grpcpp_channelz",
+ srcs = [
+ "src/cpp/server/channelz/channelz_service.cc",
+ "src/cpp/server/channelz/channelz_service_plugin.cc",
+ ],
+ hdrs = [
+ "src/cpp/server/channelz/channelz_service.h",
+ ],
+ language = "c++",
+ public_hdrs = [
+ "include/grpcpp/ext/channelz_service_plugin.h",
+ ],
+ deps = [
+ ":grpc++",
+ "//src/proto/grpc/channelz:channelz_proto",
+ ],
+ alwayslink = 1,
+)
+
+grpc_cc_library(
name = "grpc++_test",
public_hdrs = [
"include/grpc++/test/mock_stream.h",
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8ea028b5a7..e8e65d4b71 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.14.0")
+set(PACKAGE_VERSION "1.15.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/")
@@ -298,6 +298,7 @@ add_dependencies(buildtests_c grpc_completion_queue_test)
add_dependencies(buildtests_c grpc_completion_queue_threading_test)
add_dependencies(buildtests_c grpc_credentials_test)
add_dependencies(buildtests_c grpc_fetch_oauth2)
+add_dependencies(buildtests_c grpc_ipv6_loopback_available_test)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_c grpc_json_token_test)
endif()
@@ -551,6 +552,7 @@ add_dependencies(buildtests_cxx channel_arguments_test)
add_dependencies(buildtests_cxx channel_filter_test)
add_dependencies(buildtests_cxx channel_trace_test)
add_dependencies(buildtests_cxx channelz_registry_test)
+add_dependencies(buildtests_cxx channelz_service_test)
add_dependencies(buildtests_cxx channelz_test)
add_dependencies(buildtests_cxx check_gcp_environment_linux_test)
add_dependencies(buildtests_cxx check_gcp_environment_windows_test)
@@ -670,12 +672,8 @@ endif()
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx resolver_component_tests_runner_invoker)
endif()
-if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx address_sorting_test_unsecure)
-endif()
-if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx address_sorting_test)
-endif()
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_dependencies(buildtests_cxx cancel_ares_query_test)
endif()
@@ -1235,8 +1233,11 @@ add_library(grpc
src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc
+ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc
+ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc
+ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc
src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc
src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc
src/cpp/ext/filters/census/grpc_context.cc
@@ -2537,8 +2538,11 @@ add_library(grpc_unsecure
src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc
+ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc
+ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc
+ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc
src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc
src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc
src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc
@@ -4690,6 +4694,73 @@ if (gRPC_INSTALL)
)
endif()
+
+if (gRPC_BUILD_CODEGEN)
+add_library(grpcpp_channelz
+ src/cpp/server/channelz/channelz_service.cc
+ src/cpp/server/channelz/channelz_service_plugin.cc
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/channelz/channelz.pb.cc
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/channelz/channelz.grpc.pb.cc
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/channelz/channelz.pb.h
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/channelz/channelz.grpc.pb.h
+)
+
+if(WIN32 AND MSVC)
+ set_target_properties(grpcpp_channelz PROPERTIES COMPILE_PDB_NAME "grpcpp_channelz"
+ COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
+ )
+ if (gRPC_INSTALL)
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/grpcpp_channelz.pdb
+ DESTINATION ${gRPC_INSTALL_LIBDIR} OPTIONAL
+ )
+ endif()
+endif()
+
+protobuf_generate_grpc_cpp(
+ src/proto/grpc/channelz/channelz.proto
+)
+
+target_include_directories(grpcpp_channelz
+ PUBLIC $<INSTALL_INTERFACE:${gRPC_INSTALL_INCLUDEDIR}> $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
+ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
+ 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 ${_gRPC_PROTO_GENS_DIR}
+)
+
+target_link_libraries(grpcpp_channelz
+ ${_gRPC_PROTOBUF_LIBRARIES}
+ ${_gRPC_ALLTARGETS_LIBRARIES}
+ grpc++
+ grpc
+)
+
+foreach(_hdr
+ include/grpcpp/ext/channelz_service_plugin.h
+)
+ string(REPLACE "include/" "" _path ${_hdr})
+ get_filename_component(_path ${_path} PATH)
+ install(FILES ${_hdr}
+ DESTINATION "${gRPC_INSTALL_INCLUDEDIR}/${_path}"
+ )
+endforeach()
+endif (gRPC_BUILD_CODEGEN)
+
+
+if (gRPC_INSTALL)
+ install(TARGETS grpcpp_channelz EXPORT gRPCTargets
+ RUNTIME DESTINATION ${gRPC_INSTALL_BINDIR}
+ LIBRARY DESTINATION ${gRPC_INSTALL_LIBDIR}
+ ARCHIVE DESTINATION ${gRPC_INSTALL_LIBDIR}
+ )
+endif()
+
if (gRPC_BUILD_TESTS)
if (gRPC_BUILD_CODEGEN)
@@ -5096,6 +5167,7 @@ add_library(qps
test/cpp/qps/client_sync.cc
test/cpp/qps/driver.cc
test/cpp/qps/parse_json.cc
+ test/cpp/qps/qps_server_builder.cc
test/cpp/qps/qps_worker.cc
test/cpp/qps/report.cc
test/cpp/qps/server_async.cc
@@ -7256,6 +7328,35 @@ target_link_libraries(grpc_fetch_oauth2
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
+
+add_executable(grpc_ipv6_loopback_available_test
+ test/core/iomgr/grpc_ipv6_loopback_available_test.cc
+)
+
+
+target_include_directories(grpc_ipv6_loopback_available_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}
+)
+
+target_link_libraries(grpc_ipv6_loopback_available_test
+ ${_gRPC_ALLTARGETS_LIBRARIES}
+ grpc_test_util
+ grpc
+ gpr_test_util
+ gpr
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_executable(grpc_json_token_test
@@ -10873,6 +10974,54 @@ target_link_libraries(channelz_registry_test
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
+add_executable(channelz_service_test
+ test/cpp/end2end/channelz_service_test.cc
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/channelz/channelz.pb.cc
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/channelz/channelz.grpc.pb.cc
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/channelz/channelz.pb.h
+ ${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/channelz/channelz.grpc.pb.h
+ third_party/googletest/googletest/src/gtest-all.cc
+ third_party/googletest/googlemock/src/gmock-all.cc
+)
+
+protobuf_generate_grpc_cpp(
+ src/proto/grpc/channelz/channelz.proto
+)
+
+target_include_directories(channelz_service_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(channelz_service_test
+ ${_gRPC_PROTOBUF_LIBRARIES}
+ ${_gRPC_ALLTARGETS_LIBRARIES}
+ grpcpp_channelz
+ grpc++_test_util
+ grpc_test_util
+ grpc++
+ grpc
+ gpr_test_util
+ gpr
+ ${_gRPC_GFLAGS_LIBRARIES}
+)
+
+endif (gRPC_BUILD_TESTS)
+if (gRPC_BUILD_TESTS)
+
add_executable(channelz_test
test/core/channel/channelz_test.cc
${_gRPC_PROTO_GENS_DIR}/src/proto/grpc/channelz/channelz.pb.cc
@@ -16234,7 +16383,6 @@ target_link_libraries(resolver_component_tests_runner_invoker
endif()
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
-if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_executable(address_sorting_test_unsecure
test/cpp/naming/address_sorting_test.cc
@@ -16274,10 +16422,8 @@ target_link_libraries(address_sorting_test_unsecure
${_gRPC_GFLAGS_LIBRARIES}
)
-endif()
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
-if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
add_executable(address_sorting_test
test/cpp/naming/address_sorting_test.cc
@@ -16317,7 +16463,6 @@ target_link_libraries(address_sorting_test
${_gRPC_GFLAGS_LIBRARIES}
)
-endif()
endif (gRPC_BUILD_TESTS)
if (gRPC_BUILD_TESTS)
if(_gRPC_PLATFORM_LINUX OR _gRPC_PLATFORM_MAC OR _gRPC_PLATFORM_POSIX)
diff --git a/Makefile b/Makefile
index 74c0169851..5174ab6719 100644
--- a/Makefile
+++ b/Makefile
@@ -436,9 +436,9 @@ E = @echo
Q = @
endif
-CORE_VERSION = 6.0.0
-CPP_VERSION = 1.14.0
-CSHARP_VERSION = 1.14.0
+CORE_VERSION = 6.0.0-dev
+CPP_VERSION = 1.15.0-dev
+CSHARP_VERSION = 1.15.0-dev
CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES))
CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS)
@@ -1022,6 +1022,7 @@ grpc_completion_queue_threading_test: $(BINDIR)/$(CONFIG)/grpc_completion_queue_
grpc_create_jwt: $(BINDIR)/$(CONFIG)/grpc_create_jwt
grpc_credentials_test: $(BINDIR)/$(CONFIG)/grpc_credentials_test
grpc_fetch_oauth2: $(BINDIR)/$(CONFIG)/grpc_fetch_oauth2
+grpc_ipv6_loopback_available_test: $(BINDIR)/$(CONFIG)/grpc_ipv6_loopback_available_test
grpc_json_token_test: $(BINDIR)/$(CONFIG)/grpc_json_token_test
grpc_jwt_verifier_test: $(BINDIR)/$(CONFIG)/grpc_jwt_verifier_test
grpc_print_google_default_creds_token: $(BINDIR)/$(CONFIG)/grpc_print_google_default_creds_token
@@ -1142,6 +1143,7 @@ channel_arguments_test: $(BINDIR)/$(CONFIG)/channel_arguments_test
channel_filter_test: $(BINDIR)/$(CONFIG)/channel_filter_test
channel_trace_test: $(BINDIR)/$(CONFIG)/channel_trace_test
channelz_registry_test: $(BINDIR)/$(CONFIG)/channelz_registry_test
+channelz_service_test: $(BINDIR)/$(CONFIG)/channelz_service_test
channelz_test: $(BINDIR)/$(CONFIG)/channelz_test
check_gcp_environment_linux_test: $(BINDIR)/$(CONFIG)/check_gcp_environment_linux_test
check_gcp_environment_windows_test: $(BINDIR)/$(CONFIG)/check_gcp_environment_windows_test
@@ -1378,12 +1380,14 @@ static: static_c static_cxx
static_c: pc_c pc_c_unsecure cache.mk $(LIBDIR)/$(CONFIG)/libaddress_sorting.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgrpc_cronet.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a
-static_cxx: pc_cxx pc_cxx_unsecure cache.mk $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc++_cronet.a $(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a
+static_cxx: pc_cxx pc_cxx_unsecure cache.mk $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc++_cronet.a $(LIBDIR)/$(CONFIG)/libgrpc++_error_details.a $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a
+
+static_csharp: static_c $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.a
shared: shared_c shared_cxx
shared_c: pc_c pc_c_unsecure cache.mk $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)address_sorting$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)gpr$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_cronet$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_unsecure$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE)
-shared_cxx: pc_cxx pc_cxx_unsecure cache.mk $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)
+shared_cxx: pc_cxx pc_cxx_unsecure cache.mk $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_cronet$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_error_details$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)
shared_csharp: shared_c $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc_csharp_ext$(SHARED_VERSION_CSHARP).$(SHARED_EXT_CSHARP)
grpc_csharp_ext: shared_csharp
@@ -1469,6 +1473,7 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/grpc_completion_queue_threading_test \
$(BINDIR)/$(CONFIG)/grpc_credentials_test \
$(BINDIR)/$(CONFIG)/grpc_fetch_oauth2 \
+ $(BINDIR)/$(CONFIG)/grpc_ipv6_loopback_available_test \
$(BINDIR)/$(CONFIG)/grpc_json_token_test \
$(BINDIR)/$(CONFIG)/grpc_jwt_verifier_test \
$(BINDIR)/$(CONFIG)/grpc_security_connector_test \
@@ -1640,6 +1645,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/channel_filter_test \
$(BINDIR)/$(CONFIG)/channel_trace_test \
$(BINDIR)/$(CONFIG)/channelz_registry_test \
+ $(BINDIR)/$(CONFIG)/channelz_service_test \
$(BINDIR)/$(CONFIG)/channelz_test \
$(BINDIR)/$(CONFIG)/check_gcp_environment_linux_test \
$(BINDIR)/$(CONFIG)/check_gcp_environment_windows_test \
@@ -1818,6 +1824,7 @@ buildtests_cxx: privatelibs_cxx \
$(BINDIR)/$(CONFIG)/channel_filter_test \
$(BINDIR)/$(CONFIG)/channel_trace_test \
$(BINDIR)/$(CONFIG)/channelz_registry_test \
+ $(BINDIR)/$(CONFIG)/channelz_service_test \
$(BINDIR)/$(CONFIG)/channelz_test \
$(BINDIR)/$(CONFIG)/check_gcp_environment_linux_test \
$(BINDIR)/$(CONFIG)/check_gcp_environment_windows_test \
@@ -2023,6 +2030,8 @@ test_c: buildtests_c
$(Q) $(BINDIR)/$(CONFIG)/grpc_completion_queue_threading_test || ( echo test grpc_completion_queue_threading_test failed ; exit 1 )
$(E) "[RUN] Testing grpc_credentials_test"
$(Q) $(BINDIR)/$(CONFIG)/grpc_credentials_test || ( echo test grpc_credentials_test failed ; exit 1 )
+ $(E) "[RUN] Testing grpc_ipv6_loopback_available_test"
+ $(Q) $(BINDIR)/$(CONFIG)/grpc_ipv6_loopback_available_test || ( echo test grpc_ipv6_loopback_available_test failed ; exit 1 )
$(E) "[RUN] Testing grpc_json_token_test"
$(Q) $(BINDIR)/$(CONFIG)/grpc_json_token_test || ( echo test grpc_json_token_test failed ; exit 1 )
$(E) "[RUN] Testing grpc_jwt_verifier_test"
@@ -2261,6 +2270,8 @@ test_cxx: buildtests_cxx
$(Q) $(BINDIR)/$(CONFIG)/channel_trace_test || ( echo test channel_trace_test failed ; exit 1 )
$(E) "[RUN] Testing channelz_registry_test"
$(Q) $(BINDIR)/$(CONFIG)/channelz_registry_test || ( echo test channelz_registry_test failed ; exit 1 )
+ $(E) "[RUN] Testing channelz_service_test"
+ $(Q) $(BINDIR)/$(CONFIG)/channelz_service_test || ( echo test channelz_service_test failed ; exit 1 )
$(E) "[RUN] Testing channelz_test"
$(Q) $(BINDIR)/$(CONFIG)/channelz_test || ( echo test channelz_test failed ; exit 1 )
$(E) "[RUN] Testing check_gcp_environment_linux_test"
@@ -2459,6 +2470,8 @@ ifeq ($(CONFIG),opt)
$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++_reflection.a
$(E) "[STRIP] Stripping libgrpc++_unsecure.a"
$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a
+ $(E) "[STRIP] Stripping libgrpcpp_channelz.a"
+ $(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a
endif
strip-shared_c: shared_c
@@ -2487,6 +2500,8 @@ ifeq ($(CONFIG),opt)
$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_reflection$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)
$(E) "[STRIP] Stripping $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)"
$(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)
+ $(E) "[STRIP] Stripping $(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)"
+ $(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)
endif
strip-shared_csharp: shared_csharp
@@ -2946,6 +2961,9 @@ install-static_cxx: static_cxx strip-static_cxx install-pkg-config_cxx
$(E) "[INSTALL] Installing libgrpc++_unsecure.a"
$(Q) $(INSTALL) -d $(prefix)/lib
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(prefix)/lib/libgrpc++_unsecure.a
+ $(E) "[INSTALL] Installing libgrpcpp_channelz.a"
+ $(Q) $(INSTALL) -d $(prefix)/lib
+ $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a $(prefix)/lib/libgrpcpp_channelz.a
@@ -3048,6 +3066,15 @@ else ifneq ($(SYSTEM),Darwin)
$(Q) ln -sf $(SHARED_PREFIX)grpc++_unsecure$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpc++_unsecure.so.6
$(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)"
+ $(Q) $(INSTALL) -d $(prefix)/lib
+ $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/$(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP)
+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.6
+ $(Q) ln -sf $(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(prefix)/lib/libgrpcpp_channelz.so
+endif
ifneq ($(SYSTEM),MINGW32)
ifneq ($(SYSTEM),Darwin)
$(Q) ldconfig || true
@@ -3681,8 +3708,11 @@ LIBGRPC_SRC = \
src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc \
+ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc \
+ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \
+ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \
src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \
src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc \
src/cpp/ext/filters/census/grpc_context.cc \
@@ -4949,8 +4979,11 @@ LIBGRPC_UNSECURE_SRC = \
src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc \
+ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc \
+ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \
+ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \
src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \
src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc \
src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc \
@@ -7021,6 +7054,79 @@ ifneq ($(NO_DEPS),true)
endif
+LIBGRPCPP_CHANNELZ_SRC = \
+ src/cpp/server/channelz/channelz_service.cc \
+ src/cpp/server/channelz/channelz_service_plugin.cc \
+ $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc \
+
+PUBLIC_HEADERS_CXX += \
+ include/grpcpp/ext/channelz_service_plugin.h \
+
+LIBGRPCPP_CHANNELZ_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPCPP_CHANNELZ_SRC))))
+
+
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure libraries if you don't have OpenSSL.
+
+$(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a: openssl_dep_error
+
+$(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): openssl_dep_error
+
+else
+
+ifeq ($(NO_PROTOBUF),true)
+
+# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay.
+
+$(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a: protobuf_dep_error
+
+$(LIBDIR)/$(CONFIG)/$(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): protobuf_dep_error
+
+else
+
+$(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBGRPCPP_CHANNELZ_OBJS)
+ $(E) "[AR] Creating $@"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a
+ $(Q) $(AR) $(AROPTS) $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a $(LIBGRPCPP_CHANNELZ_OBJS)
+ifeq ($(SYSTEM),Darwin)
+ $(Q) ranlib -no_warning_for_no_symbols $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a
+endif
+
+
+
+ifeq ($(SYSTEM),MINGW32)
+$(LIBDIR)/$(CONFIG)/grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPCPP_CHANNELZ_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/grpc++$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/grpc$(SHARED_VERSION_CORE).$(SHARED_EXT_CORE) $(OPENSSL_DEP)
+ $(E) "[LD] Linking $@"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpcpp_channelz$(SHARED_VERSION_CPP).def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpcpp_channelz$(SHARED_VERSION_CPP)-dll.a -o $(LIBDIR)/$(CONFIG)/grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPCPP_CHANNELZ_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++$(SHARED_VERSION_CPP)-dll -lgrpc$(SHARED_VERSION_CORE)-dll
+else
+$(LIBDIR)/$(CONFIG)/libgrpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP): $(LIBGRPCPP_CHANNELZ_OBJS) $(ZLIB_DEP) $(CARES_DEP) $(ADDRESS_SORTING_DEP) $(PROTOBUF_DEP) $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT_CORE) $(OPENSSL_DEP)
+ $(E) "[LD] Linking $@"
+ $(Q) mkdir -p `dirname $@`
+ifeq ($(SYSTEM),Darwin)
+ $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -install_name $(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPCPP_CHANNELZ_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++ -lgrpc
+else
+ $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpcpp_channelz.so.1 -o $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBGRPCPP_CHANNELZ_OBJS) $(ZLIB_MERGE_LIBS) $(CARES_MERGE_LIBS) $(ADDRESS_SORTING_MERGE_LIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) -lgrpc++ -lgrpc
+ $(Q) ln -sf $(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz$(SHARED_VERSION_CPP).so.1
+ $(Q) ln -sf $(SHARED_PREFIX)grpcpp_channelz$(SHARED_VERSION_CPP).$(SHARED_EXT_CPP) $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz$(SHARED_VERSION_CPP).so
+endif
+endif
+
+endif
+
+endif
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(LIBGRPCPP_CHANNELZ_OBJS:.o=.dep)
+endif
+endif
+$(OBJDIR)/$(CONFIG)/src/cpp/server/channelz/channelz_service.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/src/cpp/server/channelz/channelz_service_plugin.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc
+
+
LIBHTTP2_CLIENT_MAIN_SRC = \
$(GENDIR)/src/proto/grpc/testing/empty.pb.cc $(GENDIR)/src/proto/grpc/testing/empty.grpc.pb.cc \
$(GENDIR)/src/proto/grpc/testing/messages.pb.cc $(GENDIR)/src/proto/grpc/testing/messages.grpc.pb.cc \
@@ -7344,6 +7450,7 @@ LIBQPS_SRC = \
test/cpp/qps/client_sync.cc \
test/cpp/qps/driver.cc \
test/cpp/qps/parse_json.cc \
+ test/cpp/qps/qps_server_builder.cc \
test/cpp/qps/qps_worker.cc \
test/cpp/qps/report.cc \
test/cpp/qps/server_async.cc \
@@ -7399,6 +7506,7 @@ $(OBJDIR)/$(CONFIG)/test/cpp/qps/client_async.o: $(GENDIR)/src/proto/grpc/testin
$(OBJDIR)/$(CONFIG)/test/cpp/qps/client_sync.o: $(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/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.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
$(OBJDIR)/$(CONFIG)/test/cpp/qps/driver.o: $(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/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.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
$(OBJDIR)/$(CONFIG)/test/cpp/qps/parse_json.o: $(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/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.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
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/qps_server_builder.o: $(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/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.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
$(OBJDIR)/$(CONFIG)/test/cpp/qps/qps_worker.o: $(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/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.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
$(OBJDIR)/$(CONFIG)/test/cpp/qps/report.o: $(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/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.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
$(OBJDIR)/$(CONFIG)/test/cpp/qps/server_async.o: $(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/stats.pb.cc $(GENDIR)/src/proto/grpc/testing/stats.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/control.pb.cc $(GENDIR)/src/proto/grpc/testing/control.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
@@ -12267,6 +12375,38 @@ endif
endif
+GRPC_IPV6_LOOPBACK_AVAILABLE_TEST_SRC = \
+ test/core/iomgr/grpc_ipv6_loopback_available_test.cc \
+
+GRPC_IPV6_LOOPBACK_AVAILABLE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GRPC_IPV6_LOOPBACK_AVAILABLE_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/grpc_ipv6_loopback_available_test: openssl_dep_error
+
+else
+
+
+
+$(BINDIR)/$(CONFIG)/grpc_ipv6_loopback_available_test: $(GRPC_IPV6_LOOPBACK_AVAILABLE_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) $(LD) $(LDFLAGS) $(GRPC_IPV6_LOOPBACK_AVAILABLE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/grpc_ipv6_loopback_available_test
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/core/iomgr/grpc_ipv6_loopback_available_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_grpc_ipv6_loopback_available_test: $(GRPC_IPV6_LOOPBACK_AVAILABLE_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(GRPC_IPV6_LOOPBACK_AVAILABLE_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
GRPC_JSON_TOKEN_TEST_SRC = \
test/core/security/json_token_test.cc \
@@ -16562,6 +16702,53 @@ endif
endif
+CHANNELZ_SERVICE_TEST_SRC = \
+ test/cpp/end2end/channelz_service_test.cc \
+ $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc \
+
+CHANNELZ_SERVICE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CHANNELZ_SERVICE_TEST_SRC))))
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL.
+
+$(BINDIR)/$(CONFIG)/channelz_service_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)/channelz_service_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/channelz_service_test: $(PROTOBUF_DEP) $(CHANNELZ_SERVICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.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) $(CHANNELZ_SERVICE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.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)/channelz_service_test
+
+endif
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/cpp/end2end/channelz_service_test.o: $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+$(OBJDIR)/$(CONFIG)/src/proto/grpc/channelz/channelz.o: $(LIBDIR)/$(CONFIG)/libgrpcpp_channelz.a $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a
+
+deps_channelz_service_test: $(CHANNELZ_SERVICE_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(CHANNELZ_SERVICE_TEST_OBJS:.o=.dep)
+endif
+endif
+$(OBJDIR)/$(CONFIG)/test/cpp/end2end/channelz_service_test.o: $(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc
+
+
CHANNELZ_TEST_SRC = \
test/core/channel/channelz_test.cc \
$(GENDIR)/src/proto/grpc/channelz/channelz.pb.cc $(GENDIR)/src/proto/grpc/channelz/channelz.grpc.pb.cc \
@@ -24517,6 +24704,8 @@ src/cpp/common/secure_channel_arguments.cc: $(OPENSSL_DEP)
src/cpp/common/secure_create_auth_context.cc: $(OPENSSL_DEP)
src/cpp/ext/proto_server_reflection.cc: $(OPENSSL_DEP)
src/cpp/ext/proto_server_reflection_plugin.cc: $(OPENSSL_DEP)
+src/cpp/server/channelz/channelz_service.cc: $(OPENSSL_DEP)
+src/cpp/server/channelz/channelz_service_plugin.cc: $(OPENSSL_DEP)
src/cpp/server/secure_server_credentials.cc: $(OPENSSL_DEP)
src/cpp/util/core_stats.cc: $(OPENSSL_DEP)
src/cpp/util/error_details.cc: $(OPENSSL_DEP)
@@ -24548,6 +24737,7 @@ test/cpp/qps/client_async.cc: $(OPENSSL_DEP)
test/cpp/qps/client_sync.cc: $(OPENSSL_DEP)
test/cpp/qps/driver.cc: $(OPENSSL_DEP)
test/cpp/qps/parse_json.cc: $(OPENSSL_DEP)
+test/cpp/qps/qps_server_builder.cc: $(OPENSSL_DEP)
test/cpp/qps/qps_worker.cc: $(OPENSSL_DEP)
test/cpp/qps/report.cc: $(OPENSSL_DEP)
test/cpp/qps/server_async.cc: $(OPENSSL_DEP)
diff --git a/README.md b/README.md
index 1af9ec34f0..1960f44137 100644
--- a/README.md
+++ b/README.md
@@ -37,6 +37,8 @@ For instructions on how to use the language-specific gRPC runtime in your projec
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.
+Precompiled bleeding-edge package builds of gRPC `master` branch's `HEAD` are uploaded daily to [packages.grpc.io](https://packages.grpc.io).
+
# To start developing gRPC
Contributions are welcome!
diff --git a/WORKSPACE b/WORKSPACE
index 8b68c0d2b1..9a0c41977f 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -1,5 +1,44 @@
-workspace(name = "com_github_grpc_grpc")
+workspace(name="com_github_grpc_grpc")
load("//bazel:grpc_deps.bzl", "grpc_deps", "grpc_test_only_deps")
grpc_deps()
grpc_test_only_deps()
+
+new_http_archive(
+ name="cython",
+ sha256="d68138a2381afbdd0876c3cb2a22389043fa01c4badede1228ee073032b07a27",
+ 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")
+
+git_repository(
+ name="io_bazel_rules_python",
+ remote="https://github.com/bazelbuild/rules_python.git",
+ commit="8b5d0683a7d878b28fffe464779c8a53659fc645",
+)
+
+load("@io_bazel_rules_python//python:pip.bzl", "pip_repositories", "pip_import")
+
+pip_repositories()
+pip_import(
+ name="grpc_python_dependencies",
+ requirements="//:requirements.bazel.txt",
+)
+
+load("@grpc_python_dependencies//:requirements.bzl", "pip_install")
+pip_install()
+
+git_repository(
+ name="org_pubref_rules_protobuf",
+ remote="https://github.com/pubref/rules_protobuf",
+ tag="v0.8.2",
+)
+
+load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_repositories")
+py_proto_repositories()
diff --git a/bazel/cython_library.bzl b/bazel/cython_library.bzl
new file mode 100644
index 0000000000..48b41d74e8
--- /dev/null
+++ b/bazel/cython_library.bzl
@@ -0,0 +1,74 @@
+"""Custom rules for gRPC Python"""
+
+
+# Adapted with modifications from
+# tensorflow/tensorflow/core/platform/default/build_config.bzl
+# Native Bazel rules don't exist yet to compile Cython code, but rules have
+# been written at cython/cython and tensorflow/tensorflow. We branch from
+# Tensorflow's version as it is more actively maintained and works for gRPC
+# Python's needs.
+def pyx_library(name, deps=[], py_deps=[], srcs=[], **kwargs):
+ """Compiles a group of .pyx / .pxd / .py files.
+
+ First runs Cython to create .cpp files for each input .pyx or .py + .pxd
+ pair. Then builds a shared object for each, passing "deps" to each cc_binary
+ rule (includes Python headers by default). Finally, creates a py_library rule
+ with the shared objects and any pure Python "srcs", with py_deps as its
+ dependencies; the shared objects can be imported like normal Python files.
+
+ Args:
+ name: Name for the rule.
+ deps: C/C++ dependencies of the Cython (e.g. Numpy headers).
+ py_deps: Pure Python dependencies of the final library.
+ srcs: .py, .pyx, or .pxd files to either compile or pass through.
+ **kwargs: Extra keyword arguments passed to the py_library.
+ """
+ # First filter out files that should be run compiled vs. passed through.
+ py_srcs = []
+ pyx_srcs = []
+ pxd_srcs = []
+ for src in srcs:
+ if src.endswith(".pyx") or (src.endswith(".py") and
+ src[:-3] + ".pxd" in srcs):
+ pyx_srcs.append(src)
+ elif src.endswith(".py"):
+ py_srcs.append(src)
+ else:
+ pxd_srcs.append(src)
+ if src.endswith("__init__.py"):
+ pxd_srcs.append(src)
+
+ # Invoke cython to produce the shared object libraries.
+ for filename in pyx_srcs:
+ native.genrule(
+ name=filename + "_cython_translation",
+ srcs=[filename],
+ outs=[filename.split(".")[0] + ".cpp"],
+ # Optionally use PYTHON_BIN_PATH on Linux platforms so that python 3
+ # works. Windows has issues with cython_binary so skip PYTHON_BIN_PATH.
+ cmd=
+ "PYTHONHASHSEED=0 $(location @cython//:cython_binary) --cplus $(SRCS) --output-file $(OUTS)",
+ tools=["@cython//:cython_binary"] + pxd_srcs,
+ )
+
+ shared_objects = []
+ for src in pyx_srcs:
+ stem = src.split(".")[0]
+ shared_object_name = stem + ".so"
+ native.cc_binary(
+ name=shared_object_name,
+ srcs=[stem + ".cpp"],
+ deps=deps + ["@local_config_python//:python_headers"],
+ linkshared=1,
+ )
+ shared_objects.append(shared_object_name)
+
+ # Now create a py_library with these shared objects as data.
+ native.py_library(
+ name=name,
+ srcs=py_srcs,
+ deps=py_deps,
+ srcs_version="PY2AND3",
+ data=shared_objects,
+ **kwargs)
+
diff --git a/build.yaml b/build.yaml
index b9dbdc4186..70af96046c 100644
--- a/build.yaml
+++ b/build.yaml
@@ -12,9 +12,9 @@ settings:
'#08': Use "-preN" suffixes to identify pre-release versions
'#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: 6.0.0
- g_stands_for: gladiolus
- version: 1.14.0
+ core_version: 6.0.0-dev
+ g_stands_for: glider
+ version: 1.15.0-dev
filegroups:
- name: alts_proto
headers:
@@ -740,8 +740,11 @@ filegroups:
- src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc
- src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc
- src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc
+ - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc
- src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
- src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc
+ - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc
+ - src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc
plugin: grpc_resolver_dns_ares
uses:
- grpc_base
@@ -1111,10 +1114,6 @@ filegroups:
secure: true
uses:
- grpc_trace
-- name: grpc++_channelz_proto
- language: c++
- src:
- - src/proto/grpc/channelz/channelz.proto
- name: grpc++_codegen_base
language: c++
public_headers:
@@ -1359,6 +1358,10 @@ filegroups:
deps:
- grpc++
- grpc
+- name: grpcpp_channelz_proto
+ language: c++
+ src:
+ - src/proto/grpc/channelz/channelz.proto
libs:
- name: address_sorting
build: all
@@ -1851,6 +1854,21 @@ libs:
vs_project_guid: '{B6E81D84-2ACB-41B8-8781-493A944C7817}'
vs_props:
- protoc
+- name: grpcpp_channelz
+ build: all
+ language: c++
+ public_headers:
+ - include/grpcpp/ext/channelz_service_plugin.h
+ headers:
+ - src/cpp/server/channelz/channelz_service.h
+ src:
+ - src/cpp/server/channelz/channelz_service.cc
+ - src/cpp/server/channelz/channelz_service_plugin.cc
+ deps:
+ - grpc++
+ - grpc
+ filegroups:
+ - grpcpp_channelz_proto
- name: http2_client_main
build: private
language: c++
@@ -1948,6 +1966,7 @@ libs:
- test/cpp/qps/histogram.h
- test/cpp/qps/interarrival.h
- test/cpp/qps/parse_json.h
+ - test/cpp/qps/qps_server_builder.h
- test/cpp/qps/qps_worker.h
- test/cpp/qps/report.h
- test/cpp/qps/server.h
@@ -1966,6 +1985,7 @@ libs:
- test/cpp/qps/client_sync.cc
- test/cpp/qps/driver.cc
- test/cpp/qps/parse_json.cc
+ - test/cpp/qps/qps_server_builder.cc
- test/cpp/qps/qps_worker.cc
- test/cpp/qps/report.cc
- test/cpp/qps/server_async.cc
@@ -2713,6 +2733,18 @@ targets:
- grpc
- gpr_test_util
- gpr
+- name: grpc_ipv6_loopback_available_test
+ build: test
+ language: c
+ src:
+ - test/core/iomgr/grpc_ipv6_loopback_available_test.cc
+ deps:
+ - grpc_test_util
+ - grpc
+ - gpr_test_util
+ - gpr
+ exclude_iomgrs:
+ - uv
- name: grpc_json_token_test
build: test
language: c
@@ -4295,7 +4327,7 @@ targets:
- gpr_test_util
- gpr
filegroups:
- - grpc++_channelz_proto
+ - grpcpp_channelz_proto
uses:
- grpc++_test
- name: channelz_registry_test
@@ -4314,6 +4346,22 @@ targets:
uses:
- grpc++_test
uses_polling: false
+- name: channelz_service_test
+ gtest: true
+ build: test
+ language: c++
+ src:
+ - test/cpp/end2end/channelz_service_test.cc
+ deps:
+ - grpcpp_channelz
+ - grpc++_test_util
+ - grpc_test_util
+ - grpc++
+ - grpc
+ - gpr_test_util
+ - gpr
+ filegroups:
+ - grpcpp_channelz_proto
- name: channelz_test
gtest: true
build: test
@@ -4328,7 +4376,7 @@ targets:
- gpr_test_util
- gpr
filegroups:
- - grpc++_channelz_proto
+ - grpcpp_channelz_proto
uses:
- grpc++_test
- name: check_gcp_environment_linux_test
diff --git a/composer.json b/composer.json
index 3e31baaa64..b8f4346444 100644
--- a/composer.json
+++ b/composer.json
@@ -9,7 +9,7 @@
"php": ">=5.5.0"
},
"require-dev": {
- "google/auth": "v0.9"
+ "google/auth": "^v1.3.0"
},
"suggest": {
"ext-protobuf": "For better performance, install the protobuf C extension.",
diff --git a/config.m4 b/config.m4
index c277ccafc8..aa40a698a6 100644
--- a/config.m4
+++ b/config.m4
@@ -380,8 +380,11 @@ if test "$PHP_GRPC" != "no"; then
src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc \
+ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc \
+ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \
+ src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \
src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \
src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc \
src/cpp/ext/filters/census/grpc_context.cc \
diff --git a/config.w32 b/config.w32
index 2857781dd5..5afa4466ac 100644
--- a/config.w32
+++ b/config.w32
@@ -355,8 +355,11 @@ if (PHP_GRPC != "no") {
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\dns_resolver_ares.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_ev_driver.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_ev_driver_posix.cc " +
+ "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_ev_driver_windows.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_fallback.cc " +
+ "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_posix.cc " +
+ "src\\core\\ext\\filters\\client_channel\\resolver\\dns\\c_ares\\grpc_ares_wrapper_windows.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver\\dns\\native\\dns_resolver.cc " +
"src\\core\\ext\\filters\\client_channel\\resolver\\sockaddr\\sockaddr_resolver.cc " +
"src\\cpp\\ext\\filters\\census\\grpc_context.cc " +
diff --git a/doc/csharp/server_reflection.md b/doc/csharp/server_reflection.md
new file mode 100644
index 0000000000..9721680269
--- /dev/null
+++ b/doc/csharp/server_reflection.md
@@ -0,0 +1,53 @@
+# gRPC C# Server Reflection
+
+This document shows how to use gRPC Server Reflection in gRPC C#.
+Please see [C++ Server Reflection Tutorial](../server_reflection_tutorial.md)
+for general information and more examples how to use server reflection.
+
+## Enable server reflection in C# servers
+
+C# Server Reflection is an add-on library.
+To use it, first install the [Grpc.Reflection](https://www.nuget.org/packages/Grpc.Reflection/)
+Nuget package into your project.
+
+Note that with C# you need to manually register the service
+descriptors with the reflection service implementation when creating a server
+(this isn't necessary with e.g. C++ or Java)
+```csharp
+// the reflection service will be aware of "Greeter" and "ServerReflection" services.
+var reflectionServiceImpl = new ReflectionServiceImpl(Greeter.Descriptor, ServerReflection.Descriptor);
+server = new Server()
+{
+ Services =
+ {
+ // the server will serve 2 services, the Greeter and the ServerReflection
+ ServerReflection.BindService(new GreeterImpl()),
+ ServerReflection.BindService(reflectionServiceImpl)
+ },
+ Ports = { { "localhost", 50051, ServerCredentials.Insecure } }
+};
+server.Start();
+```
+
+After starting the server, you can verify that the server reflection
+is working properly by using the `grpc_cli` command line tool:
+
+ ```sh
+ $ grpc_cli ls localhost:50051
+ ```
+
+ output:
+ ```sh
+ helloworld.Greeter
+ grpc.reflection.v1alpha.ServerReflection
+ ```
+
+ For more examples and instructions how to use the `grpc_cli` tool,
+ please refer to the [`grpc_cli` documentation](../command_line_tool.md)
+ and the [C++ Server Reflection Tutorial](../server_reflection_tutorial.md).
+
+## Additional Resources
+
+The [Server Reflection Protocol](../server-reflection.md) provides detailed
+information about how the server reflection works and describes the server reflection
+protocol in detail.
diff --git a/doc/g_stands_for.md b/doc/g_stands_for.md
index f86bd76f32..b3ed9bd713 100644
--- a/doc/g_stands_for.md
+++ b/doc/g_stands_for.md
@@ -13,4 +13,5 @@
- 1.11 'g' stands for ['gorgeous'](https://github.com/grpc/grpc/tree/v1.11.x)
- 1.12 'g' stands for ['glorious'](https://github.com/grpc/grpc/tree/v1.12.x)
- 1.13 'g' stands for ['gloriosa'](https://github.com/grpc/grpc/tree/v1.13.x)
-- 1.14 'g' stands for ['gladiolus'](https://github.com/grpc/grpc/tree/master)
+- 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/master)
diff --git a/doc/interop-test-descriptions.md b/doc/interop-test-descriptions.md
index 0ee2cae2bd..3c33189196 100644
--- a/doc/interop-test-descriptions.md
+++ b/doc/interop-test-descriptions.md
@@ -784,6 +784,32 @@ Client asserts:
* received status message is the same as the sent message for both Procedure
steps 1 and 2
+### special_status_message
+
+This test verifies Unicode and whitespace is correctly processed in status
+message. "\t" is horizontal tab. "\r" is carriage return. "\n" is line feed.
+
+Server features:
+* [UnaryCall][]
+* [Echo Status][]
+
+Procedure:
+ 1. Client calls UnaryCall with:
+
+ ```
+ {
+ response_status:{
+ code: 2
+ message: "\t\ntest with whitespace\r\nand Unicode BMP ☺ and non-BMP 😈\t\n"
+ }
+ }
+ ```
+
+Client asserts:
+* received status code is the same as the sent code for Procedure step 1
+* received status message is the same as the sent message for Procedure step 1,
+ including all whitespace characters
+
### unimplemented_method
This test verifies that calling an unimplemented RPC method returns the
@@ -899,6 +925,25 @@ Status: TODO
This test verifies that a client sending faster than a server can drain sees
pushback (i.e., attempts to send succeed only after appropriate delays).
+### Experimental Tests
+
+These tests are not yet standardized, and are not yet implemented in all
+languages. Therefore they are not part of our interop matrix.
+
+#### rpc_soak
+
+The client performs many large_unary RPCs in sequence over the same channel.
+The number of RPCs is configured by the experimental flag, `soak_iterations`.
+
+#### channel_soak
+
+The client performs many large_unary RPCs in sequence. Before each RPC, it
+tears down and rebuilds the channel. The number of RPCs is configured by
+the experimental flag, `soak_iterations`.
+
+This tests puts stress on several gRPC components; the resolver, the load
+balancer, and the RPC hotpath.
+
### TODO Tests
#### High priority:
diff --git a/doc/server-reflection.md b/doc/server-reflection.md
index cceee1647f..c9b476599f 100644
--- a/doc/server-reflection.md
+++ b/doc/server-reflection.md
@@ -181,3 +181,16 @@ will need to index those FileDescriptorProtos by file and symbol and imports.
One issue is that some grpc implementations are very loosely coupled with
protobufs; in such implementations it probably makes sense to split apart these
reflection APIs so as not to take an additional proto dependency.
+
+## Known Implementations
+
+Enabling server reflection differs language-to-language. Here are links to docs relevant to
+each language:
+
+- [Java](https://github.com/grpc/grpc-java/blob/master/documentation/server-reflection-tutorial.md#enable-server-reflection)
+- [Go](https://github.com/grpc/grpc-go/blob/master/Documentation/server-reflection-tutorial.md#enable-server-reflection)
+- [C++](https://grpc.io/grpc/cpp/md_doc_server_reflection_tutorial.html)
+- [C#](https://github.com/grpc/grpc/blob/master/doc/csharp/server_reflection.md)
+- Python: (tutorial not yet written)
+- Ruby: not yet implemented [#2567](https://github.com/grpc/grpc/issues/2567)
+- Node: not yet implemented [#2568](https://github.com/grpc/grpc/issues/2568)
diff --git a/doc/server_reflection_tutorial.md b/doc/server_reflection_tutorial.md
index ecb176723c..06a257c1e8 100644
--- a/doc/server_reflection_tutorial.md
+++ b/doc/server_reflection_tutorial.md
@@ -10,7 +10,7 @@ RPCs.
### Enable server reflection in C++ servers
-C++ Server Reflection is an add-on library, `libgrpc++_reflction`. To enable C++
+C++ Server Reflection is an add-on library, `libgrpc++_reflection`. To enable C++
server reflection, you can link this library to your server binary.
Some platforms (e.g. Ubuntu 11.10 onwards) only link in libraries that directly
diff --git a/doc/statuscodes.md b/doc/statuscodes.md
index f2df9e00de..06fbe5c8fe 100644
--- a/doc/statuscodes.md
+++ b/doc/statuscodes.md
@@ -38,6 +38,7 @@ situations in which they are generated.
| Error parsing response proto | INTERNAL | Client|
| Error parsing request proto | INTERNAL | Server|
| Sent or received message was larger than configured limit | RESOURCE_EXHAUSTED | Both |
+| Keepalive watchdog times out | INTERNAL | Both |
The following status codes are never generated by the library:
- INVALID_ARGUMENT
@@ -47,3 +48,5 @@ The following status codes are never generated by the library:
- ABORTED
- OUT_OF_RANGE
- DATA_LOSS
+
+Applications that may wish to [retry](https://github.com/grpc/proposal/blob/master/A6-client-retries.md) failed RPCs must decide which status codes on which to retry. As shown in the table above, the gRPC library can generate the same status code for different cases. Server applications can also return those same status codes. Therefore, there is no fixed list of status codes on which it is appropriate to retry in all applications. As a result, individual applications must make their own determination as to which status codes should cause an RPC to be retried.
diff --git a/examples/csharp/helloworld-from-cli/Greeter.sln b/examples/csharp/Helloworld/Greeter.sln
index ca50470e66..ca50470e66 100644
--- a/examples/csharp/helloworld-from-cli/Greeter.sln
+++ b/examples/csharp/Helloworld/Greeter.sln
diff --git a/examples/csharp/helloworld-from-cli/Greeter/Greeter.csproj b/examples/csharp/Helloworld/Greeter/Greeter.csproj
index 3bff4a576b..3d4be5da6b 100644
--- a/examples/csharp/helloworld-from-cli/Greeter/Greeter.csproj
+++ b/examples/csharp/Helloworld/Greeter/Greeter.csproj
@@ -11,8 +11,8 @@
<ItemGroup>
<PackageReference Include="Google.Protobuf" Version="3.5.0" />
<PackageReference Include="Google.Protobuf.Tools" Version="3.5.0" />
- <PackageReference Include="Grpc" Version="1.8.0" />
- <PackageReference Include="Grpc.Tools" Version="1.8.0" />
+ <PackageReference Include="Grpc" Version="1.13.1" />
+ <PackageReference Include="Grpc.Tools" Version="1.13.1" />
</ItemGroup>
</Project>
diff --git a/examples/csharp/helloworld-from-cli/Greeter/Helloworld.cs b/examples/csharp/Helloworld/Greeter/Helloworld.cs
index ecfc8e131c..ecfc8e131c 100644
--- a/examples/csharp/helloworld-from-cli/Greeter/Helloworld.cs
+++ b/examples/csharp/Helloworld/Greeter/Helloworld.cs
diff --git a/examples/csharp/helloworld-from-cli/Greeter/HelloworldGrpc.cs b/examples/csharp/Helloworld/Greeter/HelloworldGrpc.cs
index c808884e57..c808884e57 100644
--- a/examples/csharp/helloworld-from-cli/Greeter/HelloworldGrpc.cs
+++ b/examples/csharp/Helloworld/Greeter/HelloworldGrpc.cs
diff --git a/examples/csharp/helloworld-from-cli/GreeterClient/GreeterClient.csproj b/examples/csharp/Helloworld/GreeterClient/GreeterClient.csproj
index d1ed040411..d1ed040411 100644
--- a/examples/csharp/helloworld-from-cli/GreeterClient/GreeterClient.csproj
+++ b/examples/csharp/Helloworld/GreeterClient/GreeterClient.csproj
diff --git a/examples/csharp/helloworld-from-cli/GreeterClient/Program.cs b/examples/csharp/Helloworld/GreeterClient/Program.cs
index 38e7625d14..38e7625d14 100644
--- a/examples/csharp/helloworld-from-cli/GreeterClient/Program.cs
+++ b/examples/csharp/Helloworld/GreeterClient/Program.cs
diff --git a/examples/csharp/helloworld-from-cli/GreeterServer/GreeterServer.csproj b/examples/csharp/Helloworld/GreeterServer/GreeterServer.csproj
index 159fbd8a23..159fbd8a23 100644
--- a/examples/csharp/helloworld-from-cli/GreeterServer/GreeterServer.csproj
+++ b/examples/csharp/Helloworld/GreeterServer/GreeterServer.csproj
diff --git a/examples/csharp/helloworld-from-cli/GreeterServer/Program.cs b/examples/csharp/Helloworld/GreeterServer/Program.cs
index 2b787ecf0f..2b787ecf0f 100644
--- a/examples/csharp/helloworld-from-cli/GreeterServer/Program.cs
+++ b/examples/csharp/Helloworld/GreeterServer/Program.cs
diff --git a/examples/csharp/helloworld-from-cli/README.md b/examples/csharp/Helloworld/README.md
index b780fa1b2f..e603179438 100644
--- a/examples/csharp/helloworld-from-cli/README.md
+++ b/examples/csharp/Helloworld/README.md
@@ -3,9 +3,6 @@ gRPC in 3 minutes (C#)
BACKGROUND
-------------
-This is a different version of the helloworld example, using the dotnet sdk
-tools to build and run.
-
For this sample, we've already generated the server and client stubs from [helloworld.proto][].
Example projects in this directory depend on the [Grpc](https://www.nuget.org/packages/Grpc/)
@@ -15,17 +12,19 @@ which have been already added to the project for you.
PREREQUISITES
-------------
-- The [.NET Core SDK](https://www.microsoft.com/net/core).
+- The [.NET Core SDK](https://www.microsoft.com/net/core) (version 2+ is recommended)
+
+You can also build the example directly using Visual Studio 2017, but it's not a requirement.
BUILD
-------
-From the `examples/csharp/helloworld-from-cli` directory:
-
-- `dotnet restore Greeter.sln`
+From the `examples/csharp/Helloworld` directory:
- `dotnet build Greeter.sln`
+(if you're using dotnet SDK 1.x you need to run `dotnet restore Greeter.sln` first)
+
Try it!
-------
diff --git a/examples/csharp/helloworld-from-cli/generate_protos.bat b/examples/csharp/Helloworld/generate_protos.bat
index dcf60848f7..dcf60848f7 100644
--- a/examples/csharp/helloworld-from-cli/generate_protos.bat
+++ b/examples/csharp/Helloworld/generate_protos.bat
diff --git a/examples/csharp/helloworld/Greeter.sln b/examples/csharp/HelloworldLegacyCsproj/Greeter.sln
index 49e364d91c..49e364d91c 100644
--- a/examples/csharp/helloworld/Greeter.sln
+++ b/examples/csharp/HelloworldLegacyCsproj/Greeter.sln
diff --git a/examples/csharp/helloworld/Greeter/.gitignore b/examples/csharp/HelloworldLegacyCsproj/Greeter/.gitignore
index 1746e3269e..1746e3269e 100644
--- a/examples/csharp/helloworld/Greeter/.gitignore
+++ b/examples/csharp/HelloworldLegacyCsproj/Greeter/.gitignore
diff --git a/examples/csharp/helloworld/Greeter/Greeter.csproj b/examples/csharp/HelloworldLegacyCsproj/Greeter/Greeter.csproj
index d2597f13b5..ab584c86d3 100644
--- a/examples/csharp/helloworld/Greeter/Greeter.csproj
+++ b/examples/csharp/HelloworldLegacyCsproj/Greeter/Greeter.csproj
@@ -36,15 +36,15 @@
<HintPath>..\packages\Google.Protobuf.3.5.0\lib\net45\Google.Protobuf.dll</HintPath>
<Private>True</Private>
</Reference>
- <Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
- <HintPath>..\packages\Grpc.Core.1.8.0\lib\net45\Grpc.Core.dll</HintPath>
- <Private>True</Private>
- </Reference>
<Reference Include="System" />
<Reference Include="System.Interactive.Async, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
<HintPath>..\packages\System.Interactive.Async.3.1.1\lib\net45\System.Interactive.Async.dll</HintPath>
<Private>True</Private>
</Reference>
+ <Reference Include="Grpc.Core">
+ <HintPath>..\packages\Grpc.Core.1.13.1\lib\net45\Grpc.Core.dll</HintPath>
+ </Reference>
+ <Reference Include="Microsoft.CSharp" />
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
@@ -62,11 +62,5 @@
<None Include="packages.config" />
</ItemGroup>
<ItemGroup />
- <Import Project="..\packages\Grpc.Core.1.8.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.8.0\build\net45\Grpc.Core.targets')" />
- <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
- <PropertyGroup>
- <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
- </PropertyGroup>
- <Error Condition="!Exists('..\packages\Grpc.Core.1.8.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.8.0\build\net45\Grpc.Core.targets'))" />
- </Target>
+ <Import Project="..\packages\Grpc.Core.1.13.1\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.13.1\build\net45\Grpc.Core.targets')" />
</Project> \ No newline at end of file
diff --git a/examples/csharp/helloworld/Greeter/Helloworld.cs b/examples/csharp/HelloworldLegacyCsproj/Greeter/Helloworld.cs
index ecfc8e131c..ecfc8e131c 100644
--- a/examples/csharp/helloworld/Greeter/Helloworld.cs
+++ b/examples/csharp/HelloworldLegacyCsproj/Greeter/Helloworld.cs
diff --git a/examples/csharp/helloworld/Greeter/HelloworldGrpc.cs b/examples/csharp/HelloworldLegacyCsproj/Greeter/HelloworldGrpc.cs
index c808884e57..c808884e57 100644
--- a/examples/csharp/helloworld/Greeter/HelloworldGrpc.cs
+++ b/examples/csharp/HelloworldLegacyCsproj/Greeter/HelloworldGrpc.cs
diff --git a/examples/csharp/helloworld/Greeter/Properties/AssemblyInfo.cs b/examples/csharp/HelloworldLegacyCsproj/Greeter/Properties/AssemblyInfo.cs
index bdf394f8d4..bdf394f8d4 100644
--- a/examples/csharp/helloworld/Greeter/Properties/AssemblyInfo.cs
+++ b/examples/csharp/HelloworldLegacyCsproj/Greeter/Properties/AssemblyInfo.cs
diff --git a/examples/csharp/helloworld/Greeter/packages.config b/examples/csharp/HelloworldLegacyCsproj/Greeter/packages.config
index 38297f8d61..8e61429a8e 100644
--- a/examples/csharp/helloworld/Greeter/packages.config
+++ b/examples/csharp/HelloworldLegacyCsproj/Greeter/packages.config
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Google.Protobuf" version="3.5.0" targetFramework="net45" />
- <package id="Grpc" version="1.8.0" targetFramework="net45" />
- <package id="Grpc.Core" version="1.8.0" targetFramework="net45" />
- <package id="Grpc.Tools" version="1.8.0" targetFramework="net45" />
+ <package id="Grpc" version="1.13.1" targetFramework="net45" />
+ <package id="Grpc.Core" version="1.13.1" targetFramework="net45" />
+ <package id="Grpc.Tools" version="1.13.1" targetFramework="net45" />
<package id="System.Interactive.Async" version="3.1.1" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/examples/csharp/helloworld/GreeterClient/.gitignore b/examples/csharp/HelloworldLegacyCsproj/GreeterClient/.gitignore
index 1746e3269e..1746e3269e 100644
--- a/examples/csharp/helloworld/GreeterClient/.gitignore
+++ b/examples/csharp/HelloworldLegacyCsproj/GreeterClient/.gitignore
diff --git a/examples/csharp/helloworld/GreeterClient/GreeterClient.csproj b/examples/csharp/HelloworldLegacyCsproj/GreeterClient/GreeterClient.csproj
index 470749a2b2..2d2961d128 100644
--- a/examples/csharp/helloworld/GreeterClient/GreeterClient.csproj
+++ b/examples/csharp/HelloworldLegacyCsproj/GreeterClient/GreeterClient.csproj
@@ -36,15 +36,15 @@
<HintPath>..\packages\Google.Protobuf.3.5.0\lib\net45\Google.Protobuf.dll</HintPath>
<Private>True</Private>
</Reference>
- <Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
- <HintPath>..\packages\Grpc.Core.1.8.0\lib\net45\Grpc.Core.dll</HintPath>
- <Private>True</Private>
- </Reference>
<Reference Include="System" />
<Reference Include="System.Interactive.Async, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
<HintPath>..\packages\System.Interactive.Async.3.1.1\lib\net45\System.Interactive.Async.dll</HintPath>
<Private>True</Private>
</Reference>
+ <Reference Include="Grpc.Core">
+ <HintPath>..\packages\Grpc.Core.1.13.1\lib\net45\Grpc.Core.dll</HintPath>
+ </Reference>
+ <Reference Include="Microsoft.CSharp" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
@@ -60,11 +60,5 @@
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
- <Import Project="..\packages\Grpc.Core.1.8.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.8.0\build\net45\Grpc.Core.targets')" />
- <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
- <PropertyGroup>
- <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
- </PropertyGroup>
- <Error Condition="!Exists('..\packages\Grpc.Core.1.8.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.8.0\build\net45\Grpc.Core.targets'))" />
- </Target>
+ <Import Project="..\packages\Grpc.Core.1.13.1\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.13.1\build\net45\Grpc.Core.targets')" />
</Project> \ No newline at end of file
diff --git a/examples/csharp/helloworld/GreeterClient/Program.cs b/examples/csharp/HelloworldLegacyCsproj/GreeterClient/Program.cs
index 38e7625d14..38e7625d14 100644
--- a/examples/csharp/helloworld/GreeterClient/Program.cs
+++ b/examples/csharp/HelloworldLegacyCsproj/GreeterClient/Program.cs
diff --git a/examples/csharp/helloworld/GreeterClient/Properties/AssemblyInfo.cs b/examples/csharp/HelloworldLegacyCsproj/GreeterClient/Properties/AssemblyInfo.cs
index c88280b417..c88280b417 100644
--- a/examples/csharp/helloworld/GreeterClient/Properties/AssemblyInfo.cs
+++ b/examples/csharp/HelloworldLegacyCsproj/GreeterClient/Properties/AssemblyInfo.cs
diff --git a/examples/csharp/helloworld/GreeterClient/packages.config b/examples/csharp/HelloworldLegacyCsproj/GreeterClient/packages.config
index 4b3684edfd..da7dbcd8cb 100644
--- a/examples/csharp/helloworld/GreeterClient/packages.config
+++ b/examples/csharp/HelloworldLegacyCsproj/GreeterClient/packages.config
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Google.Protobuf" version="3.5.0" targetFramework="net45" />
- <package id="Grpc" version="1.8.0" targetFramework="net45" />
- <package id="Grpc.Core" version="1.8.0" targetFramework="net45" />
+ <package id="Grpc" version="1.13.1" targetFramework="net45" />
+ <package id="Grpc.Core" version="1.13.1" targetFramework="net45" />
<package id="System.Interactive.Async" version="3.1.1" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/examples/csharp/helloworld/GreeterServer/.gitignore b/examples/csharp/HelloworldLegacyCsproj/GreeterServer/.gitignore
index 1746e3269e..1746e3269e 100644
--- a/examples/csharp/helloworld/GreeterServer/.gitignore
+++ b/examples/csharp/HelloworldLegacyCsproj/GreeterServer/.gitignore
diff --git a/examples/csharp/helloworld/GreeterServer/GreeterServer.csproj b/examples/csharp/HelloworldLegacyCsproj/GreeterServer/GreeterServer.csproj
index 82e2961cad..1d47d70595 100644
--- a/examples/csharp/helloworld/GreeterServer/GreeterServer.csproj
+++ b/examples/csharp/HelloworldLegacyCsproj/GreeterServer/GreeterServer.csproj
@@ -36,15 +36,15 @@
<HintPath>..\packages\Google.Protobuf.3.5.0\lib\net45\Google.Protobuf.dll</HintPath>
<Private>True</Private>
</Reference>
- <Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
- <HintPath>..\packages\Grpc.Core.1.8.0\lib\net45\Grpc.Core.dll</HintPath>
- <Private>True</Private>
- </Reference>
<Reference Include="System" />
<Reference Include="System.Interactive.Async, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
<HintPath>..\packages\System.Interactive.Async.3.1.1\lib\net45\System.Interactive.Async.dll</HintPath>
<Private>True</Private>
</Reference>
+ <Reference Include="Grpc.Core">
+ <HintPath>..\packages\Grpc.Core.1.13.1\lib\net45\Grpc.Core.dll</HintPath>
+ </Reference>
+ <Reference Include="Microsoft.CSharp" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
@@ -60,11 +60,5 @@
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
- <Import Project="..\packages\Grpc.Core.1.8.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.8.0\build\net45\Grpc.Core.targets')" />
- <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
- <PropertyGroup>
- <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
- </PropertyGroup>
- <Error Condition="!Exists('..\packages\Grpc.Core.1.8.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.8.0\build\net45\Grpc.Core.targets'))" />
- </Target>
+ <Import Project="..\packages\Grpc.Core.1.13.1\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.13.1\build\net45\Grpc.Core.targets')" />
</Project> \ No newline at end of file
diff --git a/examples/csharp/helloworld/GreeterServer/Program.cs b/examples/csharp/HelloworldLegacyCsproj/GreeterServer/Program.cs
index 2b787ecf0f..2b787ecf0f 100644
--- a/examples/csharp/helloworld/GreeterServer/Program.cs
+++ b/examples/csharp/HelloworldLegacyCsproj/GreeterServer/Program.cs
diff --git a/examples/csharp/helloworld/GreeterServer/Properties/AssemblyInfo.cs b/examples/csharp/HelloworldLegacyCsproj/GreeterServer/Properties/AssemblyInfo.cs
index c0f2961cd3..c0f2961cd3 100644
--- a/examples/csharp/helloworld/GreeterServer/Properties/AssemblyInfo.cs
+++ b/examples/csharp/HelloworldLegacyCsproj/GreeterServer/Properties/AssemblyInfo.cs
diff --git a/examples/csharp/helloworld/GreeterServer/packages.config b/examples/csharp/HelloworldLegacyCsproj/GreeterServer/packages.config
index 4b3684edfd..da7dbcd8cb 100644
--- a/examples/csharp/helloworld/GreeterServer/packages.config
+++ b/examples/csharp/HelloworldLegacyCsproj/GreeterServer/packages.config
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Google.Protobuf" version="3.5.0" targetFramework="net45" />
- <package id="Grpc" version="1.8.0" targetFramework="net45" />
- <package id="Grpc.Core" version="1.8.0" targetFramework="net45" />
+ <package id="Grpc" version="1.13.1" targetFramework="net45" />
+ <package id="Grpc.Core" version="1.13.1" targetFramework="net45" />
<package id="System.Interactive.Async" version="3.1.1" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/examples/csharp/helloworld/README.md b/examples/csharp/HelloworldLegacyCsproj/README.md
index 55e3ab7030..6d42c5ef25 100644
--- a/examples/csharp/helloworld/README.md
+++ b/examples/csharp/HelloworldLegacyCsproj/README.md
@@ -3,6 +3,11 @@ gRPC in 3 minutes (C#)
BACKGROUND
-------------
+This is a different version of the helloworld example, using the old-style .csproj
+files supported by VS2013 and VS2015 (and older versions of mono).
+You can still use gRPC with the old-style .csproj files, but [using the new-style
+.csproj projects](../helloworld/README.md) (supported by VS2017 and dotnet SDK) is recommended.
+
For this sample, we've already generated the server and client stubs from [helloworld.proto][].
Example projects depend on the [Grpc](https://www.nuget.org/packages/Grpc/), [Grpc.Tools](https://www.nuget.org/packages/Grpc.Tools/)
@@ -28,7 +33,7 @@ BUILD
# Using Monodevelop or Xamarin Studio
The nuget add-in available for Xamarin Studio and Monodevelop IDEs is too old to
-download all of the nuget dependencies of gRPC. One alternative to is to use the dotnet command line tools instead (see [helloworld-from-cli]).
+download all of the nuget dependencies of gRPC.
Using these IDEs, a workaround is as follows:
* Obtain a nuget executable for your platform and update it with
@@ -62,6 +67,5 @@ Tutorial
You can find a more detailed tutorial in [gRPC Basics: C#][]
-[helloworld-from-cli]:../helloworld-from-cli/README.md
[helloworld.proto]:../../protos/helloworld.proto
[gRPC Basics: C#]:https://grpc.io/docs/tutorials/basic/csharp.html
diff --git a/examples/csharp/helloworld/generate_protos.bat b/examples/csharp/HelloworldLegacyCsproj/generate_protos.bat
index 45b097e837..45b097e837 100644
--- a/examples/csharp/helloworld/generate_protos.bat
+++ b/examples/csharp/HelloworldLegacyCsproj/generate_protos.bat
diff --git a/examples/csharp/HelloworldXamarin/.gitignore b/examples/csharp/HelloworldXamarin/.gitignore
new file mode 100644
index 0000000000..bf793edcc6
--- /dev/null
+++ b/examples/csharp/HelloworldXamarin/.gitignore
@@ -0,0 +1,41 @@
+# Autosave files
+*~
+
+# build
+[Oo]bj/
+[Bb]in/
+packages/
+TestResults/
+
+# globs
+Makefile.in
+*.DS_Store
+*.sln.cache
+*.suo
+*.cache
+*.pidb
+*.userprefs
+*.usertasks
+config.log
+config.make
+config.status
+aclocal.m4
+install-sh
+autom4te.cache/
+*.user
+*.tar.gz
+tarballs/
+test-results/
+Thumbs.db
+.vs/
+
+# Mac bundle stuff
+*.dmg
+*.app
+
+# resharper
+*_Resharper.*
+*.Resharper
+
+# dotCover
+*.dotCover
diff --git a/examples/csharp/HelloworldXamarin/Droid/Assets/AboutAssets.txt b/examples/csharp/HelloworldXamarin/Droid/Assets/AboutAssets.txt
new file mode 100644
index 0000000000..a9b0638eb1
--- /dev/null
+++ b/examples/csharp/HelloworldXamarin/Droid/Assets/AboutAssets.txt
@@ -0,0 +1,19 @@
+Any raw assets you want to be deployed with your application can be placed in
+this directory (and child directories) and given a Build Action of "AndroidAsset".
+
+These files will be deployed with your package and will be accessible using Android's
+AssetManager, like this:
+
+public class ReadAsset : Activity
+{
+ protected override void OnCreate (Bundle bundle)
+ {
+ base.OnCreate (bundle);
+
+ InputStream input = Assets.Open ("my_asset.txt");
+ }
+}
+
+Additionally, some Android functions will automatically load asset files:
+
+Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf");
diff --git a/examples/csharp/HelloworldXamarin/Droid/HelloworldXamarin.Droid.csproj b/examples/csharp/HelloworldXamarin/Droid/HelloworldXamarin.Droid.csproj
new file mode 100644
index 0000000000..b5ca8490a4
--- /dev/null
+++ b/examples/csharp/HelloworldXamarin/Droid/HelloworldXamarin.Droid.csproj
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{B9B0D41C-1C07-4590-A919-5865E741B2EA}</ProjectGuid>
+ <ProjectTypeGuids>{EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <OutputType>Library</OutputType>
+ <RootNamespace>HelloworldXamarin.Droid</RootNamespace>
+ <AssemblyName>HelloworldXamarin.Droid</AssemblyName>
+ <TargetFrameworkVersion>v8.1</TargetFrameworkVersion>
+ <AndroidApplication>True</AndroidApplication>
+ <AndroidResgenFile>Resources\Resource.designer.cs</AndroidResgenFile>
+ <AndroidResgenClass>Resource</AndroidResgenClass>
+ <AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest>
+ <MonoAndroidResourcePrefix>Resources</MonoAndroidResourcePrefix>
+ <MonoAndroidAssetsPrefix>Assets</MonoAndroidAssetsPrefix>
+ <AndroidUseLatestPlatformSdk>true</AndroidUseLatestPlatformSdk>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug</OutputPath>
+ <DefineConstants>DEBUG;</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <AndroidLinkMode>None</AndroidLinkMode>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release</OutputPath>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <AndroidManagedSymbols>true</AndroidManagedSymbols>
+ <AndroidUseSharedRuntime>false</AndroidUseSharedRuntime>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Xml" />
+ <Reference Include="System.Core" />
+ <Reference Include="Mono.Android" />
+ <Reference Include="System.IO.Compression" />
+ <Reference Include="System.Net.Http" />
+ <Reference Include="System.Runtime.Loader">
+ <HintPath>..\packages\System.Runtime.Loader.4.0.0\lib\netstandard1.5\System.Runtime.Loader.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Interactive.Async">
+ <HintPath>..\packages\System.Interactive.Async.3.1.1\lib\netstandard1.3\System.Interactive.Async.dll</HintPath>
+ </Reference>
+ <Reference Include="Grpc.Core">
+ <HintPath>..\packages\Grpc.Core.1.15.0-dev\lib\netstandard1.5\Grpc.Core.dll</HintPath>
+ </Reference>
+ <Reference Include="Google.Protobuf">
+ <HintPath>..\packages\Google.Protobuf.3.6.0\lib\netstandard1.0\Google.Protobuf.dll</HintPath>
+ </Reference>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="MainActivity.cs" />
+ <Compile Include="Resources\Resource.designer.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="Resources\AboutResources.txt" />
+ <None Include="Properties\AndroidManifest.xml" />
+ <None Include="Assets\AboutAssets.txt" />
+ <None Include="packages.config" />
+ </ItemGroup>
+ <ItemGroup>
+ <AndroidResource Include="Resources\layout\Main.axml" />
+ <AndroidResource Include="Resources\values\Strings.xml" />
+ <AndroidResource Include="Resources\mipmap-hdpi\Icon.png" />
+ <AndroidResource Include="Resources\mipmap-mdpi\Icon.png" />
+ <AndroidResource Include="Resources\mipmap-xhdpi\Icon.png" />
+ <AndroidResource Include="Resources\mipmap-xxhdpi\Icon.png" />
+ <AndroidResource Include="Resources\mipmap-xxxhdpi\Icon.png" />
+ </ItemGroup>
+ <Import Project="..\HelloworldXamarin\HelloworldXamarin.projitems" Label="Shared" Condition="Exists('..\HelloworldXamarin\HelloworldXamarin.projitems')" />
+ <Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
+ <Import Project="..\packages\Grpc.Core.1.15.0-dev\build\MonoAndroid\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.15.0-dev\build\MonoAndroid\Grpc.Core.targets')" />
+</Project> \ No newline at end of file
diff --git a/examples/csharp/HelloworldXamarin/Droid/MainActivity.cs b/examples/csharp/HelloworldXamarin/Droid/MainActivity.cs
new file mode 100644
index 0000000000..353943ced6
--- /dev/null
+++ b/examples/csharp/HelloworldXamarin/Droid/MainActivity.cs
@@ -0,0 +1,84 @@
+#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 Android.App;
+using Android.Widget;
+using Android.OS;
+using System.Threading.Tasks;
+using Grpc.Core;
+using Helloworld;
+
+namespace HelloworldXamarin.Droid
+{
+ [Activity(Label = "HelloworldXamarin", MainLauncher = true, Icon = "@mipmap/icon")]
+ public class MainActivity : Activity
+ {
+ const int Port = 50051;
+ int count = 1;
+
+ protected override void OnCreate(Bundle savedInstanceState)
+ {
+ base.OnCreate(savedInstanceState);
+
+ // Set our view from the "main" layout resource
+ SetContentView(Resource.Layout.Main);
+
+ // Get our button from the layout resource,
+ // and attach an event to it
+ Button button = FindViewById<Button>(Resource.Id.myButton);
+
+ button.Click += delegate { SayHello(button); };
+ }
+
+ private void SayHello(Button button)
+ {
+ Server server = new Server
+ {
+ Services = { Greeter.BindService(new GreeterImpl()) },
+ Ports = { new ServerPort("localhost", Port, ServerCredentials.Insecure) }
+ };
+ server.Start();
+
+ // use loopback on host machine: https://developer.android.com/studio/run/emulator-networking
+ //10.0.2.2:50051
+ Channel channel = new Channel("localhost:50051", ChannelCredentials.Insecure);
+
+ var client = new Greeter.GreeterClient(channel);
+ string user = "Xamarin " + count;
+
+ var reply = client.SayHello(new HelloRequest { Name = user });
+
+ button.Text = "Greeting: " + reply.Message;
+
+ channel.ShutdownAsync().Wait();
+ server.ShutdownAsync().Wait();
+
+ count++;
+ }
+
+ class GreeterImpl : Greeter.GreeterBase
+ {
+ // Server side handler of the SayHello RPC
+ public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
+ {
+ return Task.FromResult(new HelloReply { Message = "Hello " + request.Name });
+ }
+ }
+ }
+}
+
diff --git a/examples/csharp/HelloworldXamarin/Droid/Properties/AndroidManifest.xml b/examples/csharp/HelloworldXamarin/Droid/Properties/AndroidManifest.xml
new file mode 100644
index 0000000000..4f2167a1a0
--- /dev/null
+++ b/examples/csharp/HelloworldXamarin/Droid/Properties/AndroidManifest.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="io.grpc.examples.HelloworldXamarin">
+ <uses-sdk android:minSdkVersion="15" />
+ <application android:label="HelloworldXamarin">
+ </application>
+</manifest>
diff --git a/examples/csharp/HelloworldXamarin/Droid/Properties/AssemblyInfo.cs b/examples/csharp/HelloworldXamarin/Droid/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..5a479659da
--- /dev/null
+++ b/examples/csharp/HelloworldXamarin/Droid/Properties/AssemblyInfo.cs
@@ -0,0 +1,45 @@
+#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.Reflection;
+using System.Runtime.CompilerServices;
+using Android.App;
+
+// Information about this assembly is defined by the following attributes.
+// Change them to the values specific to your project.
+
+[assembly: AssemblyTitle("HelloworldXamarin.Droid")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("${AuthorCopyright}")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
+// The form "{Major}.{Minor}.*" will automatically update the build and revision,
+// and "{Major}.{Minor}.{Build}.*" will update just the revision.
+
+[assembly: AssemblyVersion("1.0.0")]
+
+// The following attributes are used to specify the signing key for the assembly,
+// if desired. See the Mono documentation for more information about signing.
+
+//[assembly: AssemblyDelaySign(false)]
+//[assembly: AssemblyKeyFile("")]
diff --git a/examples/csharp/HelloworldXamarin/Droid/Resources/AboutResources.txt b/examples/csharp/HelloworldXamarin/Droid/Resources/AboutResources.txt
new file mode 100644
index 0000000000..10f52d4602
--- /dev/null
+++ b/examples/csharp/HelloworldXamarin/Droid/Resources/AboutResources.txt
@@ -0,0 +1,44 @@
+Images, layout descriptions, binary blobs and string dictionaries can be included
+in your application as resource files. Various Android APIs are designed to
+operate on the resource IDs instead of dealing with images, strings or binary blobs
+directly.
+
+For example, a sample Android app that contains a user interface layout (main.axml),
+an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png)
+would keep its resources in the "Resources" directory of the application:
+
+Resources/
+ drawable/
+ icon.png
+
+ layout/
+ main.axml
+
+ values/
+ strings.xml
+
+In order to get the build system to recognize Android resources, set the build action to
+"AndroidResource". The native Android APIs do not operate directly with filenames, but
+instead operate on resource IDs. When you compile an Android application that uses resources,
+the build system will package the resources for distribution and generate a class called "R"
+(this is an Android convention) that contains the tokens for each one of the resources
+included. For example, for the above Resources layout, this is what the R class would expose:
+
+public class R {
+ public class drawable {
+ public const int icon = 0x123;
+ }
+
+ public class layout {
+ public const int main = 0x456;
+ }
+
+ public class strings {
+ public const int first_string = 0xabc;
+ public const int second_string = 0xbcd;
+ }
+}
+
+You would then use R.drawable.icon to reference the drawable/icon.png file, or R.layout.main
+to reference the layout/main.axml file, or R.strings.first_string to reference the first
+string in the dictionary file values/strings.xml.
diff --git a/examples/csharp/HelloworldXamarin/Droid/Resources/Resource.designer.cs b/examples/csharp/HelloworldXamarin/Droid/Resources/Resource.designer.cs
new file mode 100644
index 0000000000..0b8a27d3dd
--- /dev/null
+++ b/examples/csharp/HelloworldXamarin/Droid/Resources/Resource.designer.cs
@@ -0,0 +1,112 @@
+#pragma warning disable 1591
+//------------------------------------------------------------------------------
+// <auto-generated>
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+[assembly: global::Android.Runtime.ResourceDesignerAttribute("HelloworldXamarin.Droid.Resource", IsApplication=true)]
+
+namespace HelloworldXamarin.Droid
+{
+
+
+ [System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "1.0.0.0")]
+ public partial class Resource
+ {
+
+ static Resource()
+ {
+ global::Android.Runtime.ResourceIdManager.UpdateIdValues();
+ }
+
+ public static void UpdateIdValues()
+ {
+ }
+
+ public partial class Attribute
+ {
+
+ static Attribute()
+ {
+ global::Android.Runtime.ResourceIdManager.UpdateIdValues();
+ }
+
+ private Attribute()
+ {
+ }
+ }
+
+ public partial class Id
+ {
+
+ // aapt resource value: 0x7f050000
+ public const int myButton = 2131034112;
+
+ static Id()
+ {
+ global::Android.Runtime.ResourceIdManager.UpdateIdValues();
+ }
+
+ private Id()
+ {
+ }
+ }
+
+ public partial class Layout
+ {
+
+ // aapt resource value: 0x7f030000
+ public const int Main = 2130903040;
+
+ static Layout()
+ {
+ global::Android.Runtime.ResourceIdManager.UpdateIdValues();
+ }
+
+ private Layout()
+ {
+ }
+ }
+
+ public partial class Mipmap
+ {
+
+ // aapt resource value: 0x7f020000
+ public const int Icon = 2130837504;
+
+ static Mipmap()
+ {
+ global::Android.Runtime.ResourceIdManager.UpdateIdValues();
+ }
+
+ private Mipmap()
+ {
+ }
+ }
+
+ public partial class String
+ {
+
+ // aapt resource value: 0x7f040001
+ public const int app_name = 2130968577;
+
+ // aapt resource value: 0x7f040000
+ public const int hello = 2130968576;
+
+ static String()
+ {
+ global::Android.Runtime.ResourceIdManager.UpdateIdValues();
+ }
+
+ private String()
+ {
+ }
+ }
+ }
+}
+#pragma warning restore 1591
diff --git a/examples/csharp/HelloworldXamarin/Droid/Resources/layout/Main.axml b/examples/csharp/HelloworldXamarin/Droid/Resources/layout/Main.axml
new file mode 100644
index 0000000000..8cb72282b9
--- /dev/null
+++ b/examples/csharp/HelloworldXamarin/Droid/Resources/layout/Main.axml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent">
+ <Button android:id="@+id/myButton" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="@string/hello" />
+</LinearLayout>
diff --git a/examples/csharp/HelloworldXamarin/Droid/Resources/mipmap-hdpi/Icon.png b/examples/csharp/HelloworldXamarin/Droid/Resources/mipmap-hdpi/Icon.png
new file mode 100644
index 0000000000..f4c804644c
--- /dev/null
+++ b/examples/csharp/HelloworldXamarin/Droid/Resources/mipmap-hdpi/Icon.png
Binary files differ
diff --git a/examples/csharp/HelloworldXamarin/Droid/Resources/mipmap-mdpi/Icon.png b/examples/csharp/HelloworldXamarin/Droid/Resources/mipmap-mdpi/Icon.png
new file mode 100644
index 0000000000..ef1e1ee7dc
--- /dev/null
+++ b/examples/csharp/HelloworldXamarin/Droid/Resources/mipmap-mdpi/Icon.png
Binary files differ
diff --git a/examples/csharp/HelloworldXamarin/Droid/Resources/mipmap-xhdpi/Icon.png b/examples/csharp/HelloworldXamarin/Droid/Resources/mipmap-xhdpi/Icon.png
new file mode 100644
index 0000000000..b7e2e57aa9
--- /dev/null
+++ b/examples/csharp/HelloworldXamarin/Droid/Resources/mipmap-xhdpi/Icon.png
Binary files differ
diff --git a/examples/csharp/HelloworldXamarin/Droid/Resources/mipmap-xxhdpi/Icon.png b/examples/csharp/HelloworldXamarin/Droid/Resources/mipmap-xxhdpi/Icon.png
new file mode 100644
index 0000000000..8d20a38d17
--- /dev/null
+++ b/examples/csharp/HelloworldXamarin/Droid/Resources/mipmap-xxhdpi/Icon.png
Binary files differ
diff --git a/examples/csharp/HelloworldXamarin/Droid/Resources/mipmap-xxxhdpi/Icon.png b/examples/csharp/HelloworldXamarin/Droid/Resources/mipmap-xxxhdpi/Icon.png
new file mode 100644
index 0000000000..6d9919c41a
--- /dev/null
+++ b/examples/csharp/HelloworldXamarin/Droid/Resources/mipmap-xxxhdpi/Icon.png
Binary files differ
diff --git a/examples/csharp/HelloworldXamarin/Droid/Resources/values/Strings.xml b/examples/csharp/HelloworldXamarin/Droid/Resources/values/Strings.xml
new file mode 100644
index 0000000000..0a47c047e2
--- /dev/null
+++ b/examples/csharp/HelloworldXamarin/Droid/Resources/values/Strings.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <string name="hello">Hello World, Click Me!</string>
+ <string name="app_name">HelloworldXamarin.Droid</string>
+</resources>
diff --git a/examples/csharp/HelloworldXamarin/Droid/packages.config b/examples/csharp/HelloworldXamarin/Droid/packages.config
new file mode 100644
index 0000000000..3574b6782b
--- /dev/null
+++ b/examples/csharp/HelloworldXamarin/Droid/packages.config
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="Google.Protobuf" version="3.6.0" targetFramework="monoandroid81" />
+ <package id="Grpc.Core" version="1.15.0-dev" targetFramework="monoandroid81" />
+ <package id="Microsoft.NETCore.Platforms" version="1.1.0" targetFramework="monoandroid81" />
+ <package id="Microsoft.Win32.Primitives" version="4.3.0" targetFramework="monoandroid81" />
+ <package id="NETStandard.Library" version="1.6.1" targetFramework="monoandroid81" />
+ <package id="System.AppContext" version="4.3.0" targetFramework="monoandroid81" />
+ <package id="System.Collections" version="4.3.0" targetFramework="monoandroid81" />
+ <package id="System.Collections.Concurrent" version="4.3.0" targetFramework="monoandroid81" />
+ <package id="System.Console" version="4.3.0" targetFramework="monoandroid81" />
+ <package id="System.Diagnostics.Debug" version="4.3.0" targetFramework="monoandroid81" />
+ <package id="System.Diagnostics.Tools" version="4.3.0" targetFramework="monoandroid81" />
+ <package id="System.Diagnostics.Tracing" version="4.3.0" targetFramework="monoandroid81" />
+ <package id="System.Globalization" version="4.3.0" targetFramework="monoandroid81" />
+ <package id="System.Globalization.Calendars" version="4.3.0" targetFramework="monoandroid81" />
+ <package id="System.Interactive.Async" version="3.1.1" targetFramework="monoandroid81" />
+ <package id="System.IO" version="4.3.0" targetFramework="monoandroid81" />
+ <package id="System.IO.Compression" version="4.3.0" targetFramework="monoandroid81" />
+ <package id="System.IO.Compression.ZipFile" version="4.3.0" targetFramework="monoandroid81" />
+ <package id="System.IO.FileSystem" version="4.3.0" targetFramework="monoandroid81" />
+ <package id="System.IO.FileSystem.Primitives" version="4.3.0" targetFramework="monoandroid81" />
+ <package id="System.Linq" version="4.3.0" targetFramework="monoandroid81" />
+ <package id="System.Linq.Expressions" version="4.3.0" targetFramework="monoandroid81" />
+ <package id="System.Net.Http" version="4.3.0" targetFramework="monoandroid81" />
+ <package id="System.Net.Primitives" version="4.3.0" targetFramework="monoandroid81" />
+ <package id="System.Net.Sockets" version="4.3.0" targetFramework="monoandroid81" />
+ <package id="System.ObjectModel" version="4.3.0" targetFramework="monoandroid81" />
+ <package id="System.Reflection" version="4.3.0" targetFramework="monoandroid81" />
+ <package id="System.Reflection.Extensions" version="4.3.0" targetFramework="monoandroid81" />
+ <package id="System.Reflection.Primitives" version="4.3.0" targetFramework="monoandroid81" />
+ <package id="System.Resources.ResourceManager" version="4.3.0" targetFramework="monoandroid81" />
+ <package id="System.Runtime" version="4.3.0" targetFramework="monoandroid81" />
+ <package id="System.Runtime.Extensions" version="4.3.0" targetFramework="monoandroid81" />
+ <package id="System.Runtime.Handles" version="4.3.0" targetFramework="monoandroid81" />
+ <package id="System.Runtime.InteropServices" version="4.3.0" targetFramework="monoandroid81" />
+ <package id="System.Runtime.InteropServices.RuntimeInformation" version="4.3.0" targetFramework="monoandroid81" />
+ <package id="System.Runtime.Loader" version="4.0.0" targetFramework="monoandroid81" />
+ <package id="System.Runtime.Numerics" version="4.3.0" targetFramework="monoandroid81" />
+ <package id="System.Security.Cryptography.Algorithms" version="4.3.0" targetFramework="monoandroid81" />
+ <package id="System.Security.Cryptography.Encoding" version="4.3.0" targetFramework="monoandroid81" />
+ <package id="System.Security.Cryptography.Primitives" version="4.3.0" targetFramework="monoandroid81" />
+ <package id="System.Security.Cryptography.X509Certificates" version="4.3.0" targetFramework="monoandroid81" />
+ <package id="System.Text.Encoding" version="4.3.0" targetFramework="monoandroid81" />
+ <package id="System.Text.Encoding.Extensions" version="4.3.0" targetFramework="monoandroid81" />
+ <package id="System.Text.RegularExpressions" version="4.3.0" targetFramework="monoandroid81" />
+ <package id="System.Threading" version="4.3.0" targetFramework="monoandroid81" />
+ <package id="System.Threading.Tasks" version="4.3.0" targetFramework="monoandroid81" />
+ <package id="System.Threading.Thread" version="4.0.0" targetFramework="monoandroid81" />
+ <package id="System.Threading.ThreadPool" version="4.0.10" targetFramework="monoandroid81" />
+ <package id="System.Threading.Timer" version="4.3.0" targetFramework="monoandroid81" />
+ <package id="System.Xml.ReaderWriter" version="4.3.0" targetFramework="monoandroid81" />
+ <package id="System.Xml.XDocument" version="4.3.0" targetFramework="monoandroid81" />
+</packages> \ No newline at end of file
diff --git a/examples/csharp/HelloworldXamarin/HelloworldXamarin.sln b/examples/csharp/HelloworldXamarin/HelloworldXamarin.sln
new file mode 100644
index 0000000000..e2a738f157
--- /dev/null
+++ b/examples/csharp/HelloworldXamarin/HelloworldXamarin.sln
@@ -0,0 +1,45 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "HelloworldXamarin", "HelloworldXamarin\HelloworldXamarin.shproj", "{42FFF3D8-934F-4475-8E68-08DA340BF6E8}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HelloworldXamarin.Droid", "Droid\HelloworldXamarin.Droid.csproj", "{B9B0D41C-1C07-4590-A919-5865E741B2EA}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HelloworldXamarin.iOS", "iOS\HelloworldXamarin.iOS.csproj", "{62336DF0-60D8-478F-8140-B3CB089B417E}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ Debug|iPhoneSimulator = Debug|iPhoneSimulator
+ Release|iPhone = Release|iPhone
+ Release|iPhoneSimulator = Release|iPhoneSimulator
+ Debug|iPhone = Debug|iPhone
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {B9B0D41C-1C07-4590-A919-5865E741B2EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B9B0D41C-1C07-4590-A919-5865E741B2EA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B9B0D41C-1C07-4590-A919-5865E741B2EA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B9B0D41C-1C07-4590-A919-5865E741B2EA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B9B0D41C-1C07-4590-A919-5865E741B2EA}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+ {B9B0D41C-1C07-4590-A919-5865E741B2EA}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+ {B9B0D41C-1C07-4590-A919-5865E741B2EA}.Release|iPhone.ActiveCfg = Release|Any CPU
+ {B9B0D41C-1C07-4590-A919-5865E741B2EA}.Release|iPhone.Build.0 = Release|Any CPU
+ {B9B0D41C-1C07-4590-A919-5865E741B2EA}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+ {B9B0D41C-1C07-4590-A919-5865E741B2EA}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+ {B9B0D41C-1C07-4590-A919-5865E741B2EA}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+ {B9B0D41C-1C07-4590-A919-5865E741B2EA}.Debug|iPhone.Build.0 = Debug|Any CPU
+ {62336DF0-60D8-478F-8140-B3CB089B417E}.Debug|Any CPU.ActiveCfg = Debug|iPhoneSimulator
+ {62336DF0-60D8-478F-8140-B3CB089B417E}.Debug|Any CPU.Build.0 = Debug|iPhoneSimulator
+ {62336DF0-60D8-478F-8140-B3CB089B417E}.Release|Any CPU.ActiveCfg = Release|iPhone
+ {62336DF0-60D8-478F-8140-B3CB089B417E}.Release|Any CPU.Build.0 = Release|iPhone
+ {62336DF0-60D8-478F-8140-B3CB089B417E}.Debug|iPhoneSimulator.ActiveCfg = Debug|iPhoneSimulator
+ {62336DF0-60D8-478F-8140-B3CB089B417E}.Debug|iPhoneSimulator.Build.0 = Debug|iPhoneSimulator
+ {62336DF0-60D8-478F-8140-B3CB089B417E}.Release|iPhone.ActiveCfg = Release|iPhone
+ {62336DF0-60D8-478F-8140-B3CB089B417E}.Release|iPhone.Build.0 = Release|iPhone
+ {62336DF0-60D8-478F-8140-B3CB089B417E}.Release|iPhoneSimulator.ActiveCfg = Release|iPhoneSimulator
+ {62336DF0-60D8-478F-8140-B3CB089B417E}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
+ {62336DF0-60D8-478F-8140-B3CB089B417E}.Debug|iPhone.ActiveCfg = Debug|iPhone
+ {62336DF0-60D8-478F-8140-B3CB089B417E}.Debug|iPhone.Build.0 = Debug|iPhone
+ EndGlobalSection
+EndGlobal
diff --git a/examples/csharp/HelloworldXamarin/HelloworldXamarin/Helloworld.cs b/examples/csharp/HelloworldXamarin/HelloworldXamarin/Helloworld.cs
new file mode 100644
index 0000000000..ecfc8e131c
--- /dev/null
+++ b/examples/csharp/HelloworldXamarin/HelloworldXamarin/Helloworld.cs
@@ -0,0 +1,286 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: helloworld.proto
+#pragma warning disable 1591, 0612, 3021
+#region Designer generated code
+
+using pb = global::Google.Protobuf;
+using pbc = global::Google.Protobuf.Collections;
+using pbr = global::Google.Protobuf.Reflection;
+using scg = global::System.Collections.Generic;
+namespace Helloworld {
+
+ /// <summary>Holder for reflection information generated from helloworld.proto</summary>
+ public static partial class HelloworldReflection {
+
+ #region Descriptor
+ /// <summary>File descriptor for helloworld.proto</summary>
+ public static pbr::FileDescriptor Descriptor {
+ get { return descriptor; }
+ }
+ private static pbr::FileDescriptor descriptor;
+
+ static HelloworldReflection() {
+ byte[] descriptorData = global::System.Convert.FromBase64String(
+ string.Concat(
+ "ChBoZWxsb3dvcmxkLnByb3RvEgpoZWxsb3dvcmxkIhwKDEhlbGxvUmVxdWVz",
+ "dBIMCgRuYW1lGAEgASgJIh0KCkhlbGxvUmVwbHkSDwoHbWVzc2FnZRgBIAEo",
+ "CTJJCgdHcmVldGVyEj4KCFNheUhlbGxvEhguaGVsbG93b3JsZC5IZWxsb1Jl",
+ "cXVlc3QaFi5oZWxsb3dvcmxkLkhlbGxvUmVwbHkiAEI2Chtpby5ncnBjLmV4",
+ "YW1wbGVzLmhlbGxvd29ybGRCD0hlbGxvV29ybGRQcm90b1ABogIDSExXYgZw",
+ "cm90bzM="));
+ descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+ new pbr::FileDescriptor[] { },
+ new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
+ new pbr::GeneratedClrTypeInfo(typeof(global::Helloworld.HelloRequest), global::Helloworld.HelloRequest.Parser, new[]{ "Name" }, null, null, null),
+ new pbr::GeneratedClrTypeInfo(typeof(global::Helloworld.HelloReply), global::Helloworld.HelloReply.Parser, new[]{ "Message" }, null, null, null)
+ }));
+ }
+ #endregion
+
+ }
+ #region Messages
+ /// <summary>
+ /// The request message containing the user's name.
+ /// </summary>
+ public sealed partial class HelloRequest : pb::IMessage<HelloRequest> {
+ private static readonly pb::MessageParser<HelloRequest> _parser = new pb::MessageParser<HelloRequest>(() => new HelloRequest());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pb::MessageParser<HelloRequest> Parser { get { return _parser; } }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pbr::MessageDescriptor Descriptor {
+ get { return global::Helloworld.HelloworldReflection.Descriptor.MessageTypes[0]; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ pbr::MessageDescriptor pb::IMessage.Descriptor {
+ get { return Descriptor; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public HelloRequest() {
+ OnConstruction();
+ }
+
+ partial void OnConstruction();
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public HelloRequest(HelloRequest other) : this() {
+ name_ = other.name_;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public HelloRequest Clone() {
+ return new HelloRequest(this);
+ }
+
+ /// <summary>Field number for the "name" field.</summary>
+ public const int NameFieldNumber = 1;
+ private string name_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public string Name {
+ get { return name_; }
+ set {
+ name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override bool Equals(object other) {
+ return Equals(other as HelloRequest);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool Equals(HelloRequest other) {
+ if (ReferenceEquals(other, null)) {
+ return false;
+ }
+ if (ReferenceEquals(other, this)) {
+ return true;
+ }
+ if (Name != other.Name) return false;
+ return true;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override int GetHashCode() {
+ int hash = 1;
+ if (Name.Length != 0) hash ^= Name.GetHashCode();
+ return hash;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override string ToString() {
+ return pb::JsonFormatter.ToDiagnosticString(this);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void WriteTo(pb::CodedOutputStream output) {
+ if (Name.Length != 0) {
+ output.WriteRawTag(10);
+ output.WriteString(Name);
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int CalculateSize() {
+ int size = 0;
+ if (Name.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
+ }
+ return size;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(HelloRequest other) {
+ if (other == null) {
+ return;
+ }
+ if (other.Name.Length != 0) {
+ Name = other.Name;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(pb::CodedInputStream input) {
+ uint tag;
+ while ((tag = input.ReadTag()) != 0) {
+ switch(tag) {
+ default:
+ input.SkipLastField();
+ break;
+ case 10: {
+ Name = input.ReadString();
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+ /// <summary>
+ /// The response message containing the greetings
+ /// </summary>
+ public sealed partial class HelloReply : pb::IMessage<HelloReply> {
+ private static readonly pb::MessageParser<HelloReply> _parser = new pb::MessageParser<HelloReply>(() => new HelloReply());
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pb::MessageParser<HelloReply> Parser { get { return _parser; } }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public static pbr::MessageDescriptor Descriptor {
+ get { return global::Helloworld.HelloworldReflection.Descriptor.MessageTypes[1]; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ pbr::MessageDescriptor pb::IMessage.Descriptor {
+ get { return Descriptor; }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public HelloReply() {
+ OnConstruction();
+ }
+
+ partial void OnConstruction();
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public HelloReply(HelloReply other) : this() {
+ message_ = other.message_;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public HelloReply Clone() {
+ return new HelloReply(this);
+ }
+
+ /// <summary>Field number for the "message" field.</summary>
+ public const int MessageFieldNumber = 1;
+ private string message_ = "";
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public string Message {
+ get { return message_; }
+ set {
+ message_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override bool Equals(object other) {
+ return Equals(other as HelloReply);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public bool Equals(HelloReply other) {
+ if (ReferenceEquals(other, null)) {
+ return false;
+ }
+ if (ReferenceEquals(other, this)) {
+ return true;
+ }
+ if (Message != other.Message) return false;
+ return true;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override int GetHashCode() {
+ int hash = 1;
+ if (Message.Length != 0) hash ^= Message.GetHashCode();
+ return hash;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public override string ToString() {
+ return pb::JsonFormatter.ToDiagnosticString(this);
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void WriteTo(pb::CodedOutputStream output) {
+ if (Message.Length != 0) {
+ output.WriteRawTag(10);
+ output.WriteString(Message);
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public int CalculateSize() {
+ int size = 0;
+ if (Message.Length != 0) {
+ size += 1 + pb::CodedOutputStream.ComputeStringSize(Message);
+ }
+ return size;
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(HelloReply other) {
+ if (other == null) {
+ return;
+ }
+ if (other.Message.Length != 0) {
+ Message = other.Message;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+ public void MergeFrom(pb::CodedInputStream input) {
+ uint tag;
+ while ((tag = input.ReadTag()) != 0) {
+ switch(tag) {
+ default:
+ input.SkipLastField();
+ break;
+ case 10: {
+ Message = input.ReadString();
+ break;
+ }
+ }
+ }
+ }
+
+ }
+
+ #endregion
+
+}
+
+#endregion Designer generated code
diff --git a/examples/csharp/HelloworldXamarin/HelloworldXamarin/HelloworldGrpc.cs b/examples/csharp/HelloworldXamarin/HelloworldXamarin/HelloworldGrpc.cs
new file mode 100644
index 0000000000..c808884e57
--- /dev/null
+++ b/examples/csharp/HelloworldXamarin/HelloworldXamarin/HelloworldGrpc.cs
@@ -0,0 +1,150 @@
+// Generated by the protocol buffer compiler. DO NOT EDIT!
+// source: helloworld.proto
+// Original file comments:
+// 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.
+//
+#pragma warning disable 1591
+#region Designer generated code
+
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using grpc = global::Grpc.Core;
+
+namespace Helloworld {
+ /// <summary>
+ /// The greeting service definition.
+ /// </summary>
+ public static partial class Greeter
+ {
+ static readonly string __ServiceName = "helloworld.Greeter";
+
+ static readonly grpc::Marshaller<global::Helloworld.HelloRequest> __Marshaller_HelloRequest = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloRequest.Parser.ParseFrom);
+ static readonly grpc::Marshaller<global::Helloworld.HelloReply> __Marshaller_HelloReply = grpc::Marshallers.Create((arg) => global::Google.Protobuf.MessageExtensions.ToByteArray(arg), global::Helloworld.HelloReply.Parser.ParseFrom);
+
+ static readonly grpc::Method<global::Helloworld.HelloRequest, global::Helloworld.HelloReply> __Method_SayHello = new grpc::Method<global::Helloworld.HelloRequest, global::Helloworld.HelloReply>(
+ grpc::MethodType.Unary,
+ __ServiceName,
+ "SayHello",
+ __Marshaller_HelloRequest,
+ __Marshaller_HelloReply);
+
+ /// <summary>Service descriptor</summary>
+ public static global::Google.Protobuf.Reflection.ServiceDescriptor Descriptor
+ {
+ get { return global::Helloworld.HelloworldReflection.Descriptor.Services[0]; }
+ }
+
+ /// <summary>Base class for server-side implementations of Greeter</summary>
+ public abstract partial class GreeterBase
+ {
+ /// <summary>
+ /// Sends a greeting
+ /// </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::Helloworld.HelloReply> SayHello(global::Helloworld.HelloRequest request, grpc::ServerCallContext context)
+ {
+ throw new grpc::RpcException(new grpc::Status(grpc::StatusCode.Unimplemented, ""));
+ }
+
+ }
+
+ /// <summary>Client for Greeter</summary>
+ public partial class GreeterClient : grpc::ClientBase<GreeterClient>
+ {
+ /// <summary>Creates a new client for Greeter</summary>
+ /// <param name="channel">The channel to use to make remote calls.</param>
+ public GreeterClient(grpc::Channel channel) : base(channel)
+ {
+ }
+ /// <summary>Creates a new client for Greeter that uses a custom <c>CallInvoker</c>.</summary>
+ /// <param name="callInvoker">The callInvoker to use to make remote calls.</param>
+ public GreeterClient(grpc::CallInvoker callInvoker) : base(callInvoker)
+ {
+ }
+ /// <summary>Protected parameterless constructor to allow creation of test doubles.</summary>
+ protected GreeterClient() : base()
+ {
+ }
+ /// <summary>Protected constructor to allow creation of configured clients.</summary>
+ /// <param name="configuration">The client configuration.</param>
+ protected GreeterClient(ClientBaseConfiguration configuration) : base(configuration)
+ {
+ }
+
+ /// <summary>
+ /// Sends a greeting
+ /// </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::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ {
+ return SayHello(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+ }
+ /// <summary>
+ /// Sends a greeting
+ /// </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::Helloworld.HelloReply SayHello(global::Helloworld.HelloRequest request, grpc::CallOptions options)
+ {
+ return CallInvoker.BlockingUnaryCall(__Method_SayHello, null, options, request);
+ }
+ /// <summary>
+ /// Sends a greeting
+ /// </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::Helloworld.HelloReply> SayHelloAsync(global::Helloworld.HelloRequest request, grpc::Metadata headers = null, DateTime? deadline = null, CancellationToken cancellationToken = default(CancellationToken))
+ {
+ return SayHelloAsync(request, new grpc::CallOptions(headers, deadline, cancellationToken));
+ }
+ /// <summary>
+ /// Sends a greeting
+ /// </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::Helloworld.HelloReply> SayHelloAsync(global::Helloworld.HelloRequest request, grpc::CallOptions options)
+ {
+ return CallInvoker.AsyncUnaryCall(__Method_SayHello, null, options, request);
+ }
+ /// <summary>Creates a new instance of client from given <c>ClientBaseConfiguration</c>.</summary>
+ protected override GreeterClient NewInstance(ClientBaseConfiguration configuration)
+ {
+ return new GreeterClient(configuration);
+ }
+ }
+
+ /// <summary>Creates service definition that can be registered with a server</summary>
+ /// <param name="serviceImpl">An object implementing the server-side handling logic.</param>
+ public static grpc::ServerServiceDefinition BindService(GreeterBase serviceImpl)
+ {
+ return grpc::ServerServiceDefinition.CreateBuilder()
+ .AddMethod(__Method_SayHello, serviceImpl.SayHello).Build();
+ }
+
+ }
+}
+#endregion
diff --git a/examples/csharp/HelloworldXamarin/HelloworldXamarin/HelloworldXamarin.projitems b/examples/csharp/HelloworldXamarin/HelloworldXamarin/HelloworldXamarin.projitems
new file mode 100644
index 0000000000..25f5478c53
--- /dev/null
+++ b/examples/csharp/HelloworldXamarin/HelloworldXamarin/HelloworldXamarin.projitems
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
+ <HasSharedItems>true</HasSharedItems>
+ <SharedGUID>{42FFF3D8-934F-4475-8E68-08DA340BF6E8}</SharedGUID>
+ </PropertyGroup>
+ <PropertyGroup Label="Configuration">
+ <Import_RootNamespace>HelloworldXamarin</Import_RootNamespace>
+ </PropertyGroup>
+ <ItemGroup>
+ <Compile Include="$(MSBuildThisFileDirectory)Helloworld.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)HelloworldGrpc.cs" />
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/examples/csharp/HelloworldXamarin/HelloworldXamarin/HelloworldXamarin.shproj b/examples/csharp/HelloworldXamarin/HelloworldXamarin/HelloworldXamarin.shproj
new file mode 100644
index 0000000000..0eb2448b25
--- /dev/null
+++ b/examples/csharp/HelloworldXamarin/HelloworldXamarin/HelloworldXamarin.shproj
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <ProjectGuid>{42FFF3D8-934F-4475-8E68-08DA340BF6E8}</ProjectGuid>
+ </PropertyGroup>
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.Default.props" />
+ <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.props" />
+ <Import Project="HelloworldXamarin.projitems" Label="Shared" />
+ <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.CSharp.targets" />
+</Project> \ No newline at end of file
diff --git a/examples/csharp/HelloworldXamarin/README.md b/examples/csharp/HelloworldXamarin/README.md
new file mode 100644
index 0000000000..e47855de5e
--- /dev/null
+++ b/examples/csharp/HelloworldXamarin/README.md
@@ -0,0 +1,37 @@
+gRPC C# on Xamarin
+========================
+
+EXPERIMENTAL ONLY
+-------------
+Support of the Xamarin platform is currently experimental.
+The example depends on experimental Grpc.Core nuget package that hasn't
+been officially released and is only available via the [daily builds](https://packages.grpc.io/)
+source.
+
+HINT: To download the package, please manually download the latest `.nupkg` packages from "Daily Builds" in [packages.grpc.io](https://packages.grpc.io/) into a local directory. Then add a nuget source that points to that directory (That can be [done in Visual Studio](https://docs.microsoft.com/en-us/nuget/tools/package-manager-ui#package-sources) or Visual Studio for Mac via "Configure nuget sources"). After that, nuget will also explore that directory when looking for packages.
+
+BACKGROUND
+-------------
+The example project supports `Xamarin.Android` and `Xamarin.iOS`.
+
+For this sample, we've already generated the server and client stubs from [helloworld.proto][].
+
+PREREQUISITES
+-------------
+
+- The latest version Visual Studio 2017 or Visual Studio for Mac with Xamarin support installed.
+
+BUILD
+-------
+
+- Open the `HelloworldXamarin.sln` in Visual Studio (or Visual Studio for Mac)
+- Build the solution (Build -> Build All)
+
+Try it!
+-------
+
+You can deploy the example apps directly through Visual Studio IDE.
+Deployments can target both Android and iOS (both support physical device
+deployment as well as simulator).
+
+[helloworld.proto]:../../protos/helloworld.proto
diff --git a/examples/csharp/HelloworldXamarin/iOS/AppDelegate.cs b/examples/csharp/HelloworldXamarin/iOS/AppDelegate.cs
new file mode 100644
index 0000000000..e7620f91a2
--- /dev/null
+++ b/examples/csharp/HelloworldXamarin/iOS/AppDelegate.cs
@@ -0,0 +1,77 @@
+#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 Foundation;
+using UIKit;
+
+namespace HelloworldXamarin.iOS
+{
+ // The UIApplicationDelegate for the application. This class is responsible for launching the
+ // User Interface of the application, as well as listening (and optionally responding) to application events from iOS.
+ [Register("AppDelegate")]
+ public class AppDelegate : UIApplicationDelegate
+ {
+ // class-level declarations
+
+ public override UIWindow Window
+ {
+ get;
+ set;
+ }
+
+ public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
+ {
+ // Override point for customization after application launch.
+ // If not required for your application you can safely delete this method
+
+ return true;
+ }
+
+ public override void OnResignActivation(UIApplication application)
+ {
+ // Invoked when the application is about to move from active to inactive state.
+ // This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message)
+ // or when the user quits the application and it begins the transition to the background state.
+ // Games should use this method to pause the game.
+ }
+
+ public override void DidEnterBackground(UIApplication application)
+ {
+ // Use this method to release shared resources, save user data, invalidate timers and store the application state.
+ // If your application supports background exection this method is called instead of WillTerminate when the user quits.
+ }
+
+ public override void WillEnterForeground(UIApplication application)
+ {
+ // Called as part of the transiton from background to active state.
+ // Here you can undo many of the changes made on entering the background.
+ }
+
+ public override void OnActivated(UIApplication application)
+ {
+ // Restart any tasks that were paused (or not yet started) while the application was inactive.
+ // If the application was previously in the background, optionally refresh the user interface.
+ }
+
+ public override void WillTerminate(UIApplication application)
+ {
+ // Called when the application is about to terminate. Save data, if needed. See also DidEnterBackground.
+ }
+ }
+}
+
diff --git a/examples/csharp/HelloworldXamarin/iOS/Assets.xcassets/AppIcon.appiconset/Contents.json b/examples/csharp/HelloworldXamarin/iOS/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000000..64d0e3ddf8
--- /dev/null
+++ b/examples/csharp/HelloworldXamarin/iOS/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1,202 @@
+{
+ "images" : [
+ {
+ "idiom" : "iphone",
+ "size" : "20x20",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "20x20",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "60x60",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "iphone",
+ "size" : "60x60",
+ "scale" : "3x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "20x20",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "20x20",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "29x29",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "40x40",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "76x76",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "76x76",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ipad",
+ "size" : "83.5x83.5",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "ios-marketing",
+ "size" : "1024x1024",
+ "scale" : "1x"
+ },
+ {
+ "size" : "24x24",
+ "idiom" : "watch",
+ "scale" : "2x",
+ "role" : "notificationCenter",
+ "subtype" : "38mm"
+ },
+ {
+ "size" : "27.5x27.5",
+ "idiom" : "watch",
+ "scale" : "2x",
+ "role" : "notificationCenter",
+ "subtype" : "42mm"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "watch",
+ "role" : "companionSettings",
+ "scale" : "2x"
+ },
+ {
+ "size" : "29x29",
+ "idiom" : "watch",
+ "role" : "companionSettings",
+ "scale" : "3x"
+ },
+ {
+ "size" : "40x40",
+ "idiom" : "watch",
+ "scale" : "2x",
+ "role" : "appLauncher",
+ "subtype" : "38mm"
+ },
+ {
+ "size" : "44x44",
+ "idiom" : "watch",
+ "scale" : "2x",
+ "role" : "longLook",
+ "subtype" : "42mm"
+ },
+ {
+ "size" : "86x86",
+ "idiom" : "watch",
+ "scale" : "2x",
+ "role" : "quickLook",
+ "subtype" : "38mm"
+ },
+ {
+ "size" : "98x98",
+ "idiom" : "watch",
+ "scale" : "2x",
+ "role" : "quickLook",
+ "subtype" : "42mm"
+ },
+ {
+ "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"
+ }
+}
diff --git a/examples/csharp/HelloworldXamarin/iOS/Assets.xcassets/Contents.json b/examples/csharp/HelloworldXamarin/iOS/Assets.xcassets/Contents.json
new file mode 100644
index 0000000000..4caf392f92
--- /dev/null
+++ b/examples/csharp/HelloworldXamarin/iOS/Assets.xcassets/Contents.json
@@ -0,0 +1,6 @@
+{
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+} \ No newline at end of file
diff --git a/examples/csharp/HelloworldXamarin/iOS/Entitlements.plist b/examples/csharp/HelloworldXamarin/iOS/Entitlements.plist
new file mode 100644
index 0000000000..9ae599370b
--- /dev/null
+++ b/examples/csharp/HelloworldXamarin/iOS/Entitlements.plist
@@ -0,0 +1,6 @@
+<?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>
+</dict>
+</plist>
diff --git a/examples/csharp/HelloworldXamarin/iOS/HelloworldXamarin.iOS.csproj b/examples/csharp/HelloworldXamarin/iOS/HelloworldXamarin.iOS.csproj
new file mode 100644
index 0000000000..b5c0d1d119
--- /dev/null
+++ b/examples/csharp/HelloworldXamarin/iOS/HelloworldXamarin.iOS.csproj
@@ -0,0 +1,126 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">iPhoneSimulator</Platform>
+ <ProjectGuid>{62336DF0-60D8-478F-8140-B3CB089B417E}</ProjectGuid>
+ <ProjectTypeGuids>{FEACFBD2-3405-455C-9665-78FE426C6842};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+ <OutputType>Exe</OutputType>
+ <RootNamespace>HelloworldXamarin.iOS</RootNamespace>
+ <AssemblyName>HelloworldXamarin.iOS</AssemblyName>
+ <IPhoneResourcePrefix>Resources</IPhoneResourcePrefix>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhoneSimulator' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\iPhoneSimulator\Debug</OutputPath>
+ <DefineConstants>DEBUG;ENABLE_TEST_CLOUD;</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <CodesignKey>iPhone Developer</CodesignKey>
+ <MtouchDebug>true</MtouchDebug>
+ <MtouchNoSymbolStrip>true</MtouchNoSymbolStrip>
+ <MtouchFastDev>true</MtouchFastDev>
+ <IOSDebuggerPort>45216</IOSDebuggerPort>
+ <MtouchLink>None</MtouchLink>
+ <MtouchArch>x86_64</MtouchArch>
+ <MtouchHttpClientHandler>HttpClientHandler</MtouchHttpClientHandler>
+ <PlatformTarget>x86</PlatformTarget>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhone' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\iPhone\Release</OutputPath>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <CodesignKey>iPhone Developer</CodesignKey>
+ <MtouchFloat32>true</MtouchFloat32>
+ <CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
+ <MtouchLink>SdkOnly</MtouchLink>
+ <MtouchArch>ARM64</MtouchArch>
+ <MtouchHttpClientHandler>HttpClientHandler</MtouchHttpClientHandler>
+ <PlatformTarget>x86</PlatformTarget>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|iPhoneSimulator' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\iPhoneSimulator\Release</OutputPath>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <CodesignKey>iPhone Developer</CodesignKey>
+ <MtouchNoSymbolStrip>true</MtouchNoSymbolStrip>
+ <MtouchLink>None</MtouchLink>
+ <MtouchArch>x86_64</MtouchArch>
+ <MtouchHttpClientHandler>HttpClientHandler</MtouchHttpClientHandler>
+ <PlatformTarget>x86</PlatformTarget>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|iPhone' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\iPhone\Debug</OutputPath>
+ <DefineConstants>DEBUG;ENABLE_TEST_CLOUD;</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <CodesignKey>iPhone Developer</CodesignKey>
+ <DeviceSpecificBuild>true</DeviceSpecificBuild>
+ <MtouchDebug>true</MtouchDebug>
+ <MtouchNoSymbolStrip>true</MtouchNoSymbolStrip>
+ <MtouchFastDev>true</MtouchFastDev>
+ <MtouchFloat32>true</MtouchFloat32>
+ <CodesignEntitlements>Entitlements.plist</CodesignEntitlements>
+ <IOSDebuggerPort>35164</IOSDebuggerPort>
+ <MtouchLink>SdkOnly</MtouchLink>
+ <MtouchArch>ARM64</MtouchArch>
+ <MtouchHttpClientHandler>HttpClientHandler</MtouchHttpClientHandler>
+ <PlatformTarget>x86</PlatformTarget>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Xml" />
+ <Reference Include="System.Core" />
+ <Reference Include="Xamarin.iOS" />
+ <Reference Include="System.IO.Compression" />
+ <Reference Include="System.Net.Http" />
+ <Reference Include="System.Runtime.Loader">
+ <HintPath>..\packages\System.Runtime.Loader.4.0.0\lib\netstandard1.5\System.Runtime.Loader.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Interactive.Async">
+ <HintPath>..\packages\System.Interactive.Async.3.1.1\lib\netstandard1.3\System.Interactive.Async.dll</HintPath>
+ </Reference>
+ <Reference Include="Grpc.Core">
+ <HintPath>..\packages\Grpc.Core.1.15.0-dev\lib\netstandard1.5\Grpc.Core.dll</HintPath>
+ </Reference>
+ <Reference Include="Google.Protobuf">
+ <HintPath>..\packages\Google.Protobuf.3.6.0\lib\netstandard1.0\Google.Protobuf.dll</HintPath>
+ </Reference>
+ </ItemGroup>
+ <ItemGroup>
+ <ImageAsset Include="Assets.xcassets\AppIcon.appiconset\Contents.json" />
+ <ImageAsset Include="Assets.xcassets\Contents.json" />
+ </ItemGroup>
+ <ItemGroup>
+ <Folder Include="Resources\" />
+ </ItemGroup>
+ <ItemGroup>
+ <InterfaceDefinition Include="LaunchScreen.storyboard" />
+ <InterfaceDefinition Include="Main.storyboard" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="Info.plist" />
+ <None Include="Entitlements.plist" />
+ <None Include="packages.config" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Main.cs" />
+ <Compile Include="AppDelegate.cs" />
+ <Compile Include="ViewController.cs" />
+ <Compile Include="ViewController.designer.cs">
+ <DependentUpon>ViewController.cs</DependentUpon>
+ </Compile>
+ </ItemGroup>
+ <Import Project="..\HelloworldXamarin\HelloworldXamarin.projitems" Label="Shared" Condition="Exists('..\HelloworldXamarin\HelloworldXamarin.projitems')" />
+ <Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
+ <Import Project="..\packages\Grpc.Core.1.15.0-dev\build\Xamarin.iOS\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.15.0-dev\build\Xamarin.iOS\Grpc.Core.targets')" />
+</Project> \ No newline at end of file
diff --git a/examples/csharp/HelloworldXamarin/iOS/Info.plist b/examples/csharp/HelloworldXamarin/iOS/Info.plist
new file mode 100644
index 0000000000..1663f19452
--- /dev/null
+++ b/examples/csharp/HelloworldXamarin/iOS/Info.plist
@@ -0,0 +1,48 @@
+<?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>CFBundleName</key>
+ <string>HelloworldXamarin</string>
+ <key>CFBundleIdentifier</key>
+ <string>io.grpc.examples.HelloworldXamarin</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleVersion</key>
+ <string>1.0</string>
+ <key>LSRequiresIPhoneOS</key>
+ <true/>
+ <key>MinimumOSVersion</key>
+ <string>8.0</string>
+ <key>UIDeviceFamily</key>
+ <array>
+ <integer>1</integer>
+ <integer>2</integer>
+ </array>
+ <key>UILaunchStoryboardName</key>
+ <string>LaunchScreen</string>
+ <key>UIMainStoryboardFile</key>
+ <string>Main</string>
+ <key>UIMainStoryboardFile~ipad</key>
+ <string>Main</string>
+ <key>UIRequiredDeviceCapabilities</key>
+ <array>
+ <string>armv7</string>
+ </array>
+ <key>UISupportedInterfaceOrientations</key>
+ <array>
+ <string>UIInterfaceOrientationPortrait</string>
+ <string>UIInterfaceOrientationLandscapeLeft</string>
+ <string>UIInterfaceOrientationLandscapeRight</string>
+ </array>
+ <key>UISupportedInterfaceOrientations~ipad</key>
+ <array>
+ <string>UIInterfaceOrientationPortrait</string>
+ <string>UIInterfaceOrientationPortraitUpsideDown</string>
+ <string>UIInterfaceOrientationLandscapeLeft</string>
+ <string>UIInterfaceOrientationLandscapeRight</string>
+ </array>
+ <key>XSAppIconAssets</key>
+ <string>Assets.xcassets/AppIcon.appiconset</string>
+</dict>
+</plist>
diff --git a/examples/csharp/HelloworldXamarin/iOS/LaunchScreen.storyboard b/examples/csharp/HelloworldXamarin/iOS/LaunchScreen.storyboard
new file mode 100644
index 0000000000..5d2e905aa8
--- /dev/null
+++ b/examples/csharp/HelloworldXamarin/iOS/LaunchScreen.storyboard
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="9532" systemVersion="15D21" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" initialViewController="01J-lp-oVM">
+ <dependencies>
+ <deployment identifier="iOS" />
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9530" />
+ </dependencies>
+ <scenes>
+ <!--View Controller-->
+ <scene sceneID="EHf-IW-A2E">
+ <objects>
+ <viewController id="01J-lp-oVM" sceneMemberID="viewController">
+ <layoutGuides>
+ <viewControllerLayoutGuide type="top" id="Llm-lL-Icb" />
+ <viewControllerLayoutGuide type="bottom" id="xb3-aO-Qok" />
+ </layoutGuides>
+ <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
+ <rect key="frame" x="0.0" y="0.0" width="600" height="600" />
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" />
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite" />
+ </view>
+ </viewController>
+ <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder" />
+ </objects>
+ <point key="canvasLocation" x="53" y="375" />
+ </scene>
+ </scenes>
+</document>
diff --git a/examples/csharp/HelloworldXamarin/iOS/Main.cs b/examples/csharp/HelloworldXamarin/iOS/Main.cs
new file mode 100644
index 0000000000..a4ddf35c70
--- /dev/null
+++ b/examples/csharp/HelloworldXamarin/iOS/Main.cs
@@ -0,0 +1,38 @@
+#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.Linq;
+
+using Foundation;
+using UIKit;
+
+namespace HelloworldXamarin.iOS
+{
+ public class Application
+ {
+ // This is the main entry point of the application.
+ static void Main(string[] args)
+ {
+ // if you want to use a different Application Delegate class from "AppDelegate"
+ // you can specify it here.
+ UIApplication.Main(args, null, "AppDelegate");
+ }
+ }
+}
diff --git a/examples/csharp/HelloworldXamarin/iOS/Main.storyboard b/examples/csharp/HelloworldXamarin/iOS/Main.storyboard
new file mode 100644
index 0000000000..92a28ce08d
--- /dev/null
+++ b/examples/csharp/HelloworldXamarin/iOS/Main.storyboard
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="6750" systemVersion="14C109" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
+ <dependencies>
+ <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6735" />
+ </dependencies>
+ <scenes>
+ <!--View Controller-->
+ <scene sceneID="tne-QT-ifu">
+ <objects>
+ <viewController id="BYZ-38-t0r" customClass="ViewController" sceneMemberID="viewController">
+ <layoutGuides>
+ <viewControllerLayoutGuide type="top" id="y3c-jy-aDJ" />
+ <viewControllerLayoutGuide type="bottom" id="wfy-db-euE" />
+ </layoutGuides>
+ <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
+ <rect key="frame" x="0.0" y="0.0" width="600" height="600" />
+ <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES" />
+ <subviews>
+ <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="oBE-Ac-vcx">
+ <rect key="frame" x="224" y="285" width="152" height="30" />
+ <state key="normal" title="Hello World, Click Me!">
+ <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite" />
+ </state>
+ </button>
+ </subviews>
+ <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite" />
+ <constraints>
+ <constraint firstItem="oBE-Ac-vcx" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="HiD-uS-i16" />
+ <constraint firstItem="oBE-Ac-vcx" firstAttribute="centerY" secondItem="8bC-Xf-vdC" secondAttribute="centerY" id="YgX-7e-bMc" />
+ </constraints>
+ </view>
+ <connections>
+ <outlet property="Button" destination="oBE-Ac-vcx" id="OkX-0Z-gth" />
+ </connections>
+ </viewController>
+ <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder" />
+ </objects>
+ </scene>
+ </scenes>
+</document>
diff --git a/examples/csharp/HelloworldXamarin/iOS/ViewController.cs b/examples/csharp/HelloworldXamarin/iOS/ViewController.cs
new file mode 100644
index 0000000000..c553c1eb48
--- /dev/null
+++ b/examples/csharp/HelloworldXamarin/iOS/ViewController.cs
@@ -0,0 +1,91 @@
+#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.Threading.Tasks;
+
+using Grpc.Core;
+using Helloworld;
+
+using UIKit;
+
+namespace HelloworldXamarin.iOS
+{
+ public partial class ViewController : UIViewController
+ {
+ const int Port = 50051;
+ int count = 1;
+
+ public ViewController(IntPtr handle) : base(handle)
+ {
+ }
+
+ public override void ViewDidLoad()
+ {
+ base.ViewDidLoad();
+
+ // Perform any additional setup after loading the view, typically from a nib.
+ Button.AccessibilityIdentifier = "myButton";
+ Button.TouchUpInside += delegate
+ {
+ var title = SayHello();
+ Button.SetTitle(title, UIControlState.Normal);
+ };
+ }
+
+ public override void DidReceiveMemoryWarning()
+ {
+ base.DidReceiveMemoryWarning();
+ // Release any cached data, images, etc that aren't in use.
+ }
+
+ private string SayHello()
+ {
+ Server server = new Server
+ {
+ Services = { Greeter.BindService(new GreeterImpl()) },
+ Ports = { new ServerPort("localhost", Port, ServerCredentials.Insecure) }
+ };
+ server.Start();
+
+ Channel channel = new Channel("localhost:50051", ChannelCredentials.Insecure);
+
+ var client = new Greeter.GreeterClient(channel);
+ string user = "Xamarin " + count;
+
+ var reply = client.SayHello(new HelloRequest { Name = user });
+
+ channel.ShutdownAsync().Wait();
+ server.ShutdownAsync().Wait();
+
+ count++;
+
+ return "Greeting: " + reply.Message;
+ }
+
+
+ class GreeterImpl : Greeter.GreeterBase
+ {
+ // Server side handler of the SayHello RPC
+ public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
+ {
+ return Task.FromResult(new HelloReply { Message = "Hello " + request.Name });
+ }
+ }
+ }
+}
diff --git a/examples/csharp/HelloworldXamarin/iOS/ViewController.designer.cs b/examples/csharp/HelloworldXamarin/iOS/ViewController.designer.cs
new file mode 100644
index 0000000000..2677a068dc
--- /dev/null
+++ b/examples/csharp/HelloworldXamarin/iOS/ViewController.designer.cs
@@ -0,0 +1,25 @@
+//
+// This file has been generated automatically by MonoDevelop to store outlets and
+// actions made in the Xcode designer. If it is removed, they will be lost.
+// Manual changes to this file may not be handled correctly.
+//
+using Foundation;
+
+namespace HelloworldXamarin.iOS
+{
+ [Register("ViewController")]
+ partial class ViewController
+ {
+ [Outlet]
+ UIKit.UIButton Button { get; set; }
+
+ void ReleaseDesignerOutlets()
+ {
+ if (Button != null)
+ {
+ Button.Dispose();
+ Button = null;
+ }
+ }
+ }
+}
diff --git a/examples/csharp/HelloworldXamarin/iOS/packages.config b/examples/csharp/HelloworldXamarin/iOS/packages.config
new file mode 100644
index 0000000000..ce4bceb62a
--- /dev/null
+++ b/examples/csharp/HelloworldXamarin/iOS/packages.config
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="Google.Protobuf" version="3.6.0" targetFramework="xamarinios10" />
+ <package id="Grpc.Core" version="1.15.0-dev" targetFramework="xamarinios10" />
+ <package id="Microsoft.NETCore.Platforms" version="1.1.0" targetFramework="xamarinios10" />
+ <package id="Microsoft.Win32.Primitives" version="4.3.0" targetFramework="xamarinios10" />
+ <package id="NETStandard.Library" version="1.6.1" targetFramework="xamarinios10" />
+ <package id="System.AppContext" version="4.3.0" targetFramework="xamarinios10" />
+ <package id="System.Collections" version="4.3.0" targetFramework="xamarinios10" />
+ <package id="System.Collections.Concurrent" version="4.3.0" targetFramework="xamarinios10" />
+ <package id="System.Console" version="4.3.0" targetFramework="xamarinios10" />
+ <package id="System.Diagnostics.Debug" version="4.3.0" targetFramework="xamarinios10" />
+ <package id="System.Diagnostics.Tools" version="4.3.0" targetFramework="xamarinios10" />
+ <package id="System.Diagnostics.Tracing" version="4.3.0" targetFramework="xamarinios10" />
+ <package id="System.Globalization" version="4.3.0" targetFramework="xamarinios10" />
+ <package id="System.Globalization.Calendars" version="4.3.0" targetFramework="xamarinios10" />
+ <package id="System.Interactive.Async" version="3.1.1" targetFramework="xamarinios10" />
+ <package id="System.IO" version="4.3.0" targetFramework="xamarinios10" />
+ <package id="System.IO.Compression" version="4.3.0" targetFramework="xamarinios10" />
+ <package id="System.IO.Compression.ZipFile" version="4.3.0" targetFramework="xamarinios10" />
+ <package id="System.IO.FileSystem" version="4.3.0" targetFramework="xamarinios10" />
+ <package id="System.IO.FileSystem.Primitives" version="4.3.0" targetFramework="xamarinios10" />
+ <package id="System.Linq" version="4.3.0" targetFramework="xamarinios10" />
+ <package id="System.Linq.Expressions" version="4.3.0" targetFramework="xamarinios10" />
+ <package id="System.Net.Http" version="4.3.0" targetFramework="xamarinios10" />
+ <package id="System.Net.Primitives" version="4.3.0" targetFramework="xamarinios10" />
+ <package id="System.Net.Sockets" version="4.3.0" targetFramework="xamarinios10" />
+ <package id="System.ObjectModel" version="4.3.0" targetFramework="xamarinios10" />
+ <package id="System.Reflection" version="4.3.0" targetFramework="xamarinios10" />
+ <package id="System.Reflection.Extensions" version="4.3.0" targetFramework="xamarinios10" />
+ <package id="System.Reflection.Primitives" version="4.3.0" targetFramework="xamarinios10" />
+ <package id="System.Resources.ResourceManager" version="4.3.0" targetFramework="xamarinios10" />
+ <package id="System.Runtime" version="4.3.0" targetFramework="xamarinios10" />
+ <package id="System.Runtime.Extensions" version="4.3.0" targetFramework="xamarinios10" />
+ <package id="System.Runtime.Handles" version="4.3.0" targetFramework="xamarinios10" />
+ <package id="System.Runtime.InteropServices" version="4.3.0" targetFramework="xamarinios10" />
+ <package id="System.Runtime.InteropServices.RuntimeInformation" version="4.3.0" targetFramework="xamarinios10" />
+ <package id="System.Runtime.Loader" version="4.0.0" targetFramework="xamarinios10" />
+ <package id="System.Runtime.Numerics" version="4.3.0" targetFramework="xamarinios10" />
+ <package id="System.Security.Cryptography.Algorithms" version="4.3.0" targetFramework="xamarinios10" />
+ <package id="System.Security.Cryptography.Encoding" version="4.3.0" targetFramework="xamarinios10" />
+ <package id="System.Security.Cryptography.Primitives" version="4.3.0" targetFramework="xamarinios10" />
+ <package id="System.Security.Cryptography.X509Certificates" version="4.3.0" targetFramework="xamarinios10" />
+ <package id="System.Text.Encoding" version="4.3.0" targetFramework="xamarinios10" />
+ <package id="System.Text.Encoding.Extensions" version="4.3.0" targetFramework="xamarinios10" />
+ <package id="System.Text.RegularExpressions" version="4.3.0" targetFramework="xamarinios10" />
+ <package id="System.Threading" version="4.3.0" targetFramework="xamarinios10" />
+ <package id="System.Threading.Tasks" version="4.3.0" targetFramework="xamarinios10" />
+ <package id="System.Threading.Thread" version="4.0.0" targetFramework="xamarinios10" />
+ <package id="System.Threading.ThreadPool" version="4.0.10" targetFramework="xamarinios10" />
+ <package id="System.Threading.Timer" version="4.3.0" targetFramework="xamarinios10" />
+ <package id="System.Xml.ReaderWriter" version="4.3.0" targetFramework="xamarinios10" />
+ <package id="System.Xml.XDocument" version="4.3.0" targetFramework="xamarinios10" />
+</packages> \ No newline at end of file
diff --git a/examples/csharp/route_guide/.gitignore b/examples/csharp/RouteGuide/.gitignore
index 585000ea2d..585000ea2d 100644
--- a/examples/csharp/route_guide/.gitignore
+++ b/examples/csharp/RouteGuide/.gitignore
diff --git a/examples/csharp/route_guide/README.md b/examples/csharp/RouteGuide/README.md
index 3cfb14ae9a..3cfb14ae9a 100644
--- a/examples/csharp/route_guide/README.md
+++ b/examples/csharp/RouteGuide/README.md
diff --git a/examples/csharp/route_guide/RouteGuide.sln b/examples/csharp/RouteGuide/RouteGuide.sln
index 00065b0ba9..73e6e306b1 100644
--- a/examples/csharp/route_guide/RouteGuide.sln
+++ b/examples/csharp/RouteGuide/RouteGuide.sln
@@ -1,13 +1,13 @@

Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 2013
-VisualStudioVersion = 12.0.31101.0
+# Visual Studio 15
+VisualStudioVersion = 15.0.26228.4
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RouteGuide", "RouteGuide\RouteGuide.csproj", "{49954D9C-5F17-4662-96B2-73BE833DD81A}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RouteGuide", "RouteGuide\RouteGuide.csproj", "{49954D9C-5F17-4662-96B2-73BE833DD81A}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RouteGuideClient", "RouteGuideClient\RouteGuideClient.csproj", "{D47BE663-4DE3-4206-B7A8-EA3FA066DADC}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RouteGuideClient", "RouteGuideClient\RouteGuideClient.csproj", "{D47BE663-4DE3-4206-B7A8-EA3FA066DADC}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RouteGuideServer", "RouteGuideServer\RouteGuideServer.csproj", "{4B7C7794-BE24-4477-ACE7-18259EB73D27}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RouteGuideServer", "RouteGuideServer\RouteGuideServer.csproj", "{4B7C7794-BE24-4477-ACE7-18259EB73D27}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
diff --git a/examples/csharp/route_guide/RouteGuide/RouteGuide.cs b/examples/csharp/RouteGuide/RouteGuide/RouteGuide.cs
index 603809ee76..603809ee76 100644
--- a/examples/csharp/route_guide/RouteGuide/RouteGuide.cs
+++ b/examples/csharp/RouteGuide/RouteGuide/RouteGuide.cs
diff --git a/examples/csharp/RouteGuide/RouteGuide/RouteGuide.csproj b/examples/csharp/RouteGuide/RouteGuide/RouteGuide.csproj
new file mode 100644
index 0000000000..7419f1a277
--- /dev/null
+++ b/examples/csharp/RouteGuide/RouteGuide/RouteGuide.csproj
@@ -0,0 +1,25 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <AssemblyTitle>RouteGuide</AssemblyTitle>
+ <TargetFrameworks>netcoreapp1.0</TargetFrameworks>
+ <DebugType>portable</DebugType>
+ <AssemblyName>RouteGuide</AssemblyName>
+ <PackageId>RouteGuide</PackageId>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Include="Google.Protobuf" Version="3.5.0" />
+ <PackageReference Include="Google.Protobuf.Tools" Version="3.5.0" />
+ <PackageReference Include="Grpc" Version="1.13.1" />
+ <PackageReference Include="Grpc.Tools" Version="1.13.1" />
+ <PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <None Include="route_guide_db.json">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </None>
+ </ItemGroup>
+
+</Project>
diff --git a/examples/csharp/route_guide/RouteGuide/RouteGuideGrpc.cs b/examples/csharp/RouteGuide/RouteGuide/RouteGuideGrpc.cs
index 765d5d520b..765d5d520b 100644
--- a/examples/csharp/route_guide/RouteGuide/RouteGuideGrpc.cs
+++ b/examples/csharp/RouteGuide/RouteGuide/RouteGuideGrpc.cs
diff --git a/examples/csharp/route_guide/RouteGuide/RouteGuideUtil.cs b/examples/csharp/RouteGuide/RouteGuide/RouteGuideUtil.cs
index f9af190888..f9af190888 100644
--- a/examples/csharp/route_guide/RouteGuide/RouteGuideUtil.cs
+++ b/examples/csharp/RouteGuide/RouteGuide/RouteGuideUtil.cs
diff --git a/examples/csharp/route_guide/RouteGuide/route_guide_db.json b/examples/csharp/RouteGuide/RouteGuide/route_guide_db.json
index 209f016259..9342beb579 100644
--- a/examples/csharp/route_guide/RouteGuide/route_guide_db.json
+++ b/examples/csharp/RouteGuide/RouteGuide/route_guide_db.json
@@ -1,4 +1,4 @@
-[{
+[{
"location": {
"latitude": 407838351,
"longitude": -746143763
diff --git a/examples/csharp/route_guide/RouteGuideClient/Program.cs b/examples/csharp/RouteGuide/RouteGuideClient/Program.cs
index 9ce0cbcad3..9ce0cbcad3 100644
--- a/examples/csharp/route_guide/RouteGuideClient/Program.cs
+++ b/examples/csharp/RouteGuide/RouteGuideClient/Program.cs
diff --git a/examples/csharp/RouteGuide/RouteGuideClient/RouteGuideClient.csproj b/examples/csharp/RouteGuide/RouteGuideClient/RouteGuideClient.csproj
new file mode 100644
index 0000000000..96cc204ba3
--- /dev/null
+++ b/examples/csharp/RouteGuide/RouteGuideClient/RouteGuideClient.csproj
@@ -0,0 +1,16 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <AssemblyTitle>RouteGuideClient</AssemblyTitle>
+ <TargetFrameworks>netcoreapp1.0</TargetFrameworks>
+ <DebugType>portable</DebugType>
+ <AssemblyName>RouteGuideClient</AssemblyName>
+ <OutputType>Exe</OutputType>
+ <PackageId>RouteGuideClient</PackageId>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\RouteGuide\RouteGuide.csproj" />
+ </ItemGroup>
+
+</Project>
diff --git a/examples/csharp/route_guide/RouteGuideServer/Program.cs b/examples/csharp/RouteGuide/RouteGuideServer/Program.cs
index 4548ddf8e7..4548ddf8e7 100644
--- a/examples/csharp/route_guide/RouteGuideServer/Program.cs
+++ b/examples/csharp/RouteGuide/RouteGuideServer/Program.cs
diff --git a/examples/csharp/route_guide/RouteGuideServer/RouteGuideImpl.cs b/examples/csharp/RouteGuide/RouteGuideServer/RouteGuideImpl.cs
index f157ca08ab..f157ca08ab 100644
--- a/examples/csharp/route_guide/RouteGuideServer/RouteGuideImpl.cs
+++ b/examples/csharp/RouteGuide/RouteGuideServer/RouteGuideImpl.cs
diff --git a/examples/csharp/RouteGuide/RouteGuideServer/RouteGuideServer.csproj b/examples/csharp/RouteGuide/RouteGuideServer/RouteGuideServer.csproj
new file mode 100644
index 0000000000..aa6315bf81
--- /dev/null
+++ b/examples/csharp/RouteGuide/RouteGuideServer/RouteGuideServer.csproj
@@ -0,0 +1,16 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <AssemblyTitle>RouteGuideServer</AssemblyTitle>
+ <TargetFrameworks>netcoreapp1.0</TargetFrameworks>
+ <DebugType>portable</DebugType>
+ <AssemblyName>RouteGuideServer</AssemblyName>
+ <OutputType>Exe</OutputType>
+ <PackageId>RouteGuideServer</PackageId>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\RouteGuide\RouteGuide.csproj" />
+ </ItemGroup>
+
+</Project>
diff --git a/examples/csharp/route_guide/generate_protos.bat b/examples/csharp/RouteGuide/generate_protos.bat
index a8c9cb505a..a8c9cb505a 100644
--- a/examples/csharp/route_guide/generate_protos.bat
+++ b/examples/csharp/RouteGuide/generate_protos.bat
diff --git a/examples/csharp/route_guide/RouteGuide/Properties/AssemblyInfo.cs b/examples/csharp/route_guide/RouteGuide/Properties/AssemblyInfo.cs
deleted file mode 100644
index dfee25c14c..0000000000
--- a/examples/csharp/route_guide/RouteGuide/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,54 +0,0 @@
-#region Copyright notice and license
-
-// 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.
-
-#endregion
-
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("RouteGuide")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("RouteGuide")]
-[assembly: AssemblyCopyright("Copyright © 2015")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("ef6b85bc-ac27-46de-8714-a658236cc6fb")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/examples/csharp/route_guide/RouteGuide/RouteGuide.csproj b/examples/csharp/route_guide/RouteGuide/RouteGuide.csproj
deleted file mode 100644
index e66e986f71..0000000000
--- a/examples/csharp/route_guide/RouteGuide/RouteGuide.csproj
+++ /dev/null
@@ -1,92 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProjectGuid>{49954D9C-5F17-4662-96B2-73BE833DD81A}</ProjectGuid>
- <OutputType>Library</OutputType>
- <AppDesignerFolder>Properties</AppDesignerFolder>
- <RootNamespace>RouteGuide</RootNamespace>
- <AssemblyName>RouteGuide</AssemblyName>
- <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
- <FileAlignment>512</FileAlignment>
- <NuGetPackageImportStamp>
- </NuGetPackageImportStamp>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>bin\Debug\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <DebugType>pdbonly</DebugType>
- <Optimize>true</Optimize>
- <OutputPath>bin\Release\</OutputPath>
- <DefineConstants>TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="Google.Protobuf, Version=3.5.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
- <HintPath>..\packages\Google.Protobuf.3.5.0\lib\net45\Google.Protobuf.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
- <HintPath>..\packages\Grpc.Core.1.8.0\lib\net45\Grpc.Core.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
- </Reference>
- <Reference Include="System" />
- <Reference Include="System.Core" />
- <Reference Include="System.Interactive.Async, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
- <HintPath>..\packages\System.Interactive.Async.3.1.1\lib\net45\System.Interactive.Async.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="System.Xml.Linq" />
- <Reference Include="System.Data.DataSetExtensions" />
- <Reference Include="Microsoft.CSharp" />
- <Reference Include="System.Data" />
- <Reference Include="System.Xml" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="Properties\AssemblyInfo.cs" />
- <Compile Include="RouteGuide.cs" />
- <Compile Include="RouteGuideGrpc.cs" />
- <Compile Include="RouteGuideUtil.cs" />
- </ItemGroup>
- <ItemGroup>
- <None Include="..\..\..\protos\route_guide.proto">
- <Link>protos\route_guide.proto</Link>
- </None>
- <None Include="..\generate_protos.bat">
- <Link>generate_protos.bat</Link>
- </None>
- <None Include="packages.config" />
- <None Include="route_guide_db.json">
- <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
- </None>
- </ItemGroup>
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
- <Import Project="..\packages\Grpc.Core.1.8.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.8.0\build\net45\Grpc.Core.targets')" />
- <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
- <PropertyGroup>
- <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
- </PropertyGroup>
- <Error Condition="!Exists('..\packages\Grpc.Core.1.8.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.8.0\build\net45\Grpc.Core.targets'))" />
- </Target>
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
-</Project> \ No newline at end of file
diff --git a/examples/csharp/route_guide/RouteGuide/packages.config b/examples/csharp/route_guide/RouteGuide/packages.config
deleted file mode 100644
index fe2c995f26..0000000000
--- a/examples/csharp/route_guide/RouteGuide/packages.config
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
- <package id="Google.Protobuf" version="3.5.0" targetFramework="net45" />
- <package id="Grpc" version="1.8.0" targetFramework="net45" />
- <package id="Grpc.Core" version="1.8.0" targetFramework="net45" />
- <package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
- <package id="System.Interactive.Async" version="3.1.1" targetFramework="net45" />
-</packages> \ No newline at end of file
diff --git a/examples/csharp/route_guide/RouteGuideClient/Properties/AssemblyInfo.cs b/examples/csharp/route_guide/RouteGuideClient/Properties/AssemblyInfo.cs
deleted file mode 100644
index 4ccdf701d3..0000000000
--- a/examples/csharp/route_guide/RouteGuideClient/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,54 +0,0 @@
-#region Copyright notice and license
-
-// 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.
-
-#endregion
-
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("RouteGuideClient")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("RouteGuideClient")]
-[assembly: AssemblyCopyright("Copyright © 2015")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("914644eb-47cd-4a37-9fba-5e62dd432333")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/examples/csharp/route_guide/RouteGuideClient/RouteGuideClient.csproj b/examples/csharp/route_guide/RouteGuideClient/RouteGuideClient.csproj
deleted file mode 100644
index 612f60cba5..0000000000
--- a/examples/csharp/route_guide/RouteGuideClient/RouteGuideClient.csproj
+++ /dev/null
@@ -1,89 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProjectGuid>{D47BE663-4DE3-4206-B7A8-EA3FA066DADC}</ProjectGuid>
- <OutputType>Exe</OutputType>
- <AppDesignerFolder>Properties</AppDesignerFolder>
- <RootNamespace>RouteGuideClient</RootNamespace>
- <AssemblyName>RouteGuideClient</AssemblyName>
- <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
- <FileAlignment>512</FileAlignment>
- <NuGetPackageImportStamp>
- </NuGetPackageImportStamp>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <PlatformTarget>AnyCPU</PlatformTarget>
- <DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>bin\Debug\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <PlatformTarget>AnyCPU</PlatformTarget>
- <DebugType>pdbonly</DebugType>
- <Optimize>true</Optimize>
- <OutputPath>bin\Release\</OutputPath>
- <DefineConstants>TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="Google.Protobuf, Version=3.5.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
- <HintPath>..\packages\Google.Protobuf.3.5.0\lib\net45\Google.Protobuf.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
- <HintPath>..\packages\Grpc.Core.1.8.0\lib\net45\Grpc.Core.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
- </Reference>
- <Reference Include="System" />
- <Reference Include="System.Core" />
- <Reference Include="System.Interactive.Async, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
- <HintPath>..\packages\System.Interactive.Async.3.1.1\lib\net45\System.Interactive.Async.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="System.Xml.Linq" />
- <Reference Include="System.Data.DataSetExtensions" />
- <Reference Include="Microsoft.CSharp" />
- <Reference Include="System.Data" />
- <Reference Include="System.Xml" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="Program.cs" />
- <Compile Include="Properties\AssemblyInfo.cs" />
- </ItemGroup>
- <ItemGroup>
- <None Include="packages.config" />
- </ItemGroup>
- <ItemGroup>
- <ProjectReference Include="..\RouteGuide\RouteGuide.csproj">
- <Project>{49954d9c-5f17-4662-96b2-73be833dd81a}</Project>
- <Name>RouteGuide</Name>
- </ProjectReference>
- </ItemGroup>
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
- <Import Project="..\packages\Grpc.Core.1.8.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.8.0\build\net45\Grpc.Core.targets')" />
- <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
- <PropertyGroup>
- <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
- </PropertyGroup>
- <Error Condition="!Exists('..\packages\Grpc.Core.1.8.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.8.0\build\net45\Grpc.Core.targets'))" />
- </Target>
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
-</Project> \ No newline at end of file
diff --git a/examples/csharp/route_guide/RouteGuideClient/packages.config b/examples/csharp/route_guide/RouteGuideClient/packages.config
deleted file mode 100644
index fe2c995f26..0000000000
--- a/examples/csharp/route_guide/RouteGuideClient/packages.config
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
- <package id="Google.Protobuf" version="3.5.0" targetFramework="net45" />
- <package id="Grpc" version="1.8.0" targetFramework="net45" />
- <package id="Grpc.Core" version="1.8.0" targetFramework="net45" />
- <package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
- <package id="System.Interactive.Async" version="3.1.1" targetFramework="net45" />
-</packages> \ No newline at end of file
diff --git a/examples/csharp/route_guide/RouteGuideServer/Properties/AssemblyInfo.cs b/examples/csharp/route_guide/RouteGuideServer/Properties/AssemblyInfo.cs
deleted file mode 100644
index 679bc4c913..0000000000
--- a/examples/csharp/route_guide/RouteGuideServer/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,54 +0,0 @@
-#region Copyright notice and license
-
-// 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.
-
-#endregion
-
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("RouteGuideServer")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("RouteGuideServer")]
-[assembly: AssemblyCopyright("Copyright © 2015")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("908bdeef-05cc-42bf-9498-c4c573df8925")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/examples/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj b/examples/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj
deleted file mode 100644
index 4d9d9d74f2..0000000000
--- a/examples/csharp/route_guide/RouteGuideServer/RouteGuideServer.csproj
+++ /dev/null
@@ -1,90 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
- <PropertyGroup>
- <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
- <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
- <ProjectGuid>{4B7C7794-BE24-4477-ACE7-18259EB73D27}</ProjectGuid>
- <OutputType>Exe</OutputType>
- <AppDesignerFolder>Properties</AppDesignerFolder>
- <RootNamespace>RouteGuideServer</RootNamespace>
- <AssemblyName>RouteGuideServer</AssemblyName>
- <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
- <FileAlignment>512</FileAlignment>
- <NuGetPackageImportStamp>
- </NuGetPackageImportStamp>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
- <PlatformTarget>AnyCPU</PlatformTarget>
- <DebugSymbols>true</DebugSymbols>
- <DebugType>full</DebugType>
- <Optimize>false</Optimize>
- <OutputPath>bin\Debug\</OutputPath>
- <DefineConstants>DEBUG;TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <PlatformTarget>AnyCPU</PlatformTarget>
- <DebugType>pdbonly</DebugType>
- <Optimize>true</Optimize>
- <OutputPath>bin\Release\</OutputPath>
- <DefineConstants>TRACE</DefineConstants>
- <ErrorReport>prompt</ErrorReport>
- <WarningLevel>4</WarningLevel>
- </PropertyGroup>
- <ItemGroup>
- <Reference Include="Google.Protobuf, Version=3.5.0.0, Culture=neutral, PublicKeyToken=a7d26565bac4d604, processorArchitecture=MSIL">
- <HintPath>..\packages\Google.Protobuf.3.5.0\lib\net45\Google.Protobuf.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="Grpc.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=d754f35622e28bad, processorArchitecture=MSIL">
- <HintPath>..\packages\Grpc.Core.1.8.0\lib\net45\Grpc.Core.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="Newtonsoft.Json, Version=7.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
- </Reference>
- <Reference Include="System" />
- <Reference Include="System.Core" />
- <Reference Include="System.Interactive.Async, Version=3.0.1000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
- <HintPath>..\packages\System.Interactive.Async.3.1.1\lib\net45\System.Interactive.Async.dll</HintPath>
- <Private>True</Private>
- </Reference>
- <Reference Include="System.Xml.Linq" />
- <Reference Include="System.Data.DataSetExtensions" />
- <Reference Include="Microsoft.CSharp" />
- <Reference Include="System.Data" />
- <Reference Include="System.Xml" />
- </ItemGroup>
- <ItemGroup>
- <Compile Include="Program.cs" />
- <Compile Include="Properties\AssemblyInfo.cs" />
- <Compile Include="RouteGuideImpl.cs" />
- </ItemGroup>
- <ItemGroup>
- <None Include="packages.config" />
- </ItemGroup>
- <ItemGroup>
- <ProjectReference Include="..\RouteGuide\RouteGuide.csproj">
- <Project>{49954d9c-5f17-4662-96b2-73be833dd81a}</Project>
- <Name>RouteGuide</Name>
- </ProjectReference>
- </ItemGroup>
- <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
- <Import Project="..\packages\Grpc.Core.1.8.0\build\net45\Grpc.Core.targets" Condition="Exists('..\packages\Grpc.Core.1.8.0\build\net45\Grpc.Core.targets')" />
- <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
- <PropertyGroup>
- <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
- </PropertyGroup>
- <Error Condition="!Exists('..\packages\Grpc.Core.1.8.0\build\net45\Grpc.Core.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Grpc.Core.1.8.0\build\net45\Grpc.Core.targets'))" />
- </Target>
- <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
- Other similar extension points exist, see Microsoft.Common.targets.
- <Target Name="BeforeBuild">
- </Target>
- <Target Name="AfterBuild">
- </Target>
- -->
-</Project> \ No newline at end of file
diff --git a/examples/csharp/route_guide/RouteGuideServer/packages.config b/examples/csharp/route_guide/RouteGuideServer/packages.config
deleted file mode 100644
index 2bb1f0d0bf..0000000000
--- a/examples/csharp/route_guide/RouteGuideServer/packages.config
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
- <package id="Google.Protobuf" version="3.5.0" targetFramework="net45" />
- <package id="Grpc" version="1.8.0" targetFramework="net45" />
- <package id="Grpc.Core" version="1.8.0" targetFramework="net45" />
- <package id="Grpc.Tools" version="1.8.0" targetFramework="net45" />
- <package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
- <package id="System.Interactive.Async" version="3.1.1" targetFramework="net45" />
-</packages> \ No newline at end of file
diff --git a/examples/node/dynamic_codegen/greeter_client.js b/examples/node/dynamic_codegen/greeter_client.js
index 9fd1f88f4f..c289f501ee 100644
--- a/examples/node/dynamic_codegen/greeter_client.js
+++ b/examples/node/dynamic_codegen/greeter_client.js
@@ -19,7 +19,16 @@
var PROTO_PATH = __dirname + '/../../protos/helloworld.proto';
var grpc = require('grpc');
-var hello_proto = grpc.load(PROTO_PATH).helloworld;
+var protoLoader = require('@grpc/proto-loader');
+var packageDefinition = protoLoader.loadSync(
+ PROTO_PATH,
+ {keepCase: true,
+ longs: String,
+ enums: String,
+ defaults: true,
+ oneofs: true
+ });
+var hello_proto = grpc.loadPackageDefinition(packageDefinition).helloworld;
function main() {
var client = new hello_proto.Greeter('localhost:50051',
diff --git a/examples/node/dynamic_codegen/greeter_server.js b/examples/node/dynamic_codegen/greeter_server.js
index 180f96c28b..023257ecf0 100644
--- a/examples/node/dynamic_codegen/greeter_server.js
+++ b/examples/node/dynamic_codegen/greeter_server.js
@@ -19,7 +19,16 @@
var PROTO_PATH = __dirname + '/../../protos/helloworld.proto';
var grpc = require('grpc');
-var hello_proto = grpc.load(PROTO_PATH).helloworld;
+var protoLoader = require('@grpc/proto-loader');
+var packageDefinition = protoLoader.loadSync(
+ PROTO_PATH,
+ {keepCase: true,
+ longs: String,
+ enums: String,
+ defaults: true,
+ oneofs: true
+ });
+var hello_proto = grpc.loadPackageDefinition(packageDefinition).helloworld;
/**
* Implements the SayHello RPC method.
diff --git a/examples/node/dynamic_codegen/route_guide/route_guide_client.js b/examples/node/dynamic_codegen/route_guide/route_guide_client.js
index 703cfd2902..34a44bd6a9 100644
--- a/examples/node/dynamic_codegen/route_guide/route_guide_client.js
+++ b/examples/node/dynamic_codegen/route_guide/route_guide_client.js
@@ -24,7 +24,16 @@ var parseArgs = require('minimist');
var path = require('path');
var _ = require('lodash');
var grpc = require('grpc');
-var routeguide = grpc.load(PROTO_PATH).routeguide;
+var protoLoader = require('@grpc/proto-loader');
+var packageDefinition = protoLoader.loadSync(
+ PROTO_PATH,
+ {keepCase: true,
+ longs: String,
+ enums: String,
+ defaults: true,
+ oneofs: true
+ });
+var routeguide = grpc.loadPackageDefinition(packageDefinition).routeguide;
var client = new routeguide.RouteGuide('localhost:50051',
grpc.credentials.createInsecure());
diff --git a/examples/node/dynamic_codegen/route_guide/route_guide_server.js b/examples/node/dynamic_codegen/route_guide/route_guide_server.js
index 3819c092eb..106491c1a1 100644
--- a/examples/node/dynamic_codegen/route_guide/route_guide_server.js
+++ b/examples/node/dynamic_codegen/route_guide/route_guide_server.js
@@ -23,7 +23,16 @@ var parseArgs = require('minimist');
var path = require('path');
var _ = require('lodash');
var grpc = require('grpc');
-var routeguide = grpc.load(PROTO_PATH).routeguide;
+var protoLoader = require('@grpc/proto-loader');
+var packageDefinition = protoLoader.loadSync(
+ PROTO_PATH,
+ {keepCase: true,
+ longs: String,
+ enums: String,
+ defaults: true,
+ oneofs: true
+ });
+var routeguide = grpc.loadPackageDefinition(packageDefinition).routeguide;
var COORD_FACTOR = 1e7;
diff --git a/examples/node/package.json b/examples/node/package.json
index 6317838295..3af6a113fd 100644
--- a/examples/node/package.json
+++ b/examples/node/package.json
@@ -2,9 +2,10 @@
"name": "grpc-examples",
"version": "0.1.0",
"dependencies": {
+ "@grpc/proto-loader": "^0.1.0",
"async": "^1.5.2",
"google-protobuf": "^3.0.0",
- "grpc": "^1.0.0",
+ "grpc": "^1.11.0",
"lodash": "^4.6.1",
"minimist": "^1.2.0"
}
diff --git a/examples/python/multiplex/helloworld_pb2.py b/examples/python/multiplex/helloworld_pb2.py
index 6665b1f687..e18ab9acc7 100644
--- a/examples/python/multiplex/helloworld_pb2.py
+++ b/examples/python/multiplex/helloworld_pb2.py
@@ -21,7 +21,6 @@ DESCRIPTOR = _descriptor.FileDescriptor(
syntax='proto3',
serialized_pb=_b('\n\x10helloworld.proto\x12\nhelloworld\"\x1c\n\x0cHelloRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"\x1d\n\nHelloReply\x12\x0f\n\x07message\x18\x01 \x01(\t2I\n\x07Greeter\x12>\n\x08SayHello\x12\x18.helloworld.HelloRequest\x1a\x16.helloworld.HelloReply\"\x00\x42\x36\n\x1bio.grpc.examples.helloworldB\x0fHelloWorldProtoP\x01\xa2\x02\x03HLWb\x06proto3')
)
-_sym_db.RegisterFileDescriptor(DESCRIPTOR)
@@ -89,6 +88,7 @@ _HELLOREPLY = _descriptor.Descriptor(
DESCRIPTOR.message_types_by_name['HelloRequest'] = _HELLOREQUEST
DESCRIPTOR.message_types_by_name['HelloReply'] = _HELLOREPLY
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
HelloRequest = _reflection.GeneratedProtocolMessageType('HelloRequest', (_message.Message,), dict(
DESCRIPTOR = _HELLOREQUEST,
@@ -107,123 +107,28 @@ _sym_db.RegisterMessage(HelloReply)
DESCRIPTOR.has_options = True
DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\033io.grpc.examples.helloworldB\017HelloWorldProtoP\001\242\002\003HLW'))
-try:
- # THESE ELEMENTS WILL BE DEPRECATED.
- # Please use the generated *_pb2_grpc.py files instead.
- import grpc
- from grpc.framework.common import cardinality
- from grpc.framework.interfaces.face import utilities as face_utilities
- from grpc.beta import implementations as beta_implementations
- from grpc.beta import interfaces as beta_interfaces
-
-
- class GreeterStub(object):
- """The greeting service definition.
- """
-
- def __init__(self, channel):
- """Constructor.
-
- Args:
- channel: A grpc.Channel.
- """
- self.SayHello = channel.unary_unary(
- '/helloworld.Greeter/SayHello',
- request_serializer=HelloRequest.SerializeToString,
- response_deserializer=HelloReply.FromString,
- )
-
-
- class GreeterServicer(object):
- """The greeting service definition.
- """
-
- def SayHello(self, request, context):
- """Sends a greeting
- """
- context.set_code(grpc.StatusCode.UNIMPLEMENTED)
- context.set_details('Method not implemented!')
- raise NotImplementedError('Method not implemented!')
-
-
- def add_GreeterServicer_to_server(servicer, server):
- rpc_method_handlers = {
- 'SayHello': grpc.unary_unary_rpc_method_handler(
- servicer.SayHello,
- request_deserializer=HelloRequest.FromString,
- response_serializer=HelloReply.SerializeToString,
- ),
- }
- generic_handler = grpc.method_handlers_generic_handler(
- 'helloworld.Greeter', rpc_method_handlers)
- server.add_generic_rpc_handlers((generic_handler,))
-
-
- class BetaGreeterServicer(object):
- """The Beta API is deprecated for 0.15.0 and later.
-
- It is recommended to use the GA API (classes and functions in this
- file not marked beta) for all further purposes. This class was generated
- only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0."""
- """The greeting service definition.
- """
- def SayHello(self, request, context):
- """Sends a greeting
- """
- context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
-
-
- class BetaGreeterStub(object):
- """The Beta API is deprecated for 0.15.0 and later.
-
- It is recommended to use the GA API (classes and functions in this
- file not marked beta) for all further purposes. This class was generated
- only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0."""
- """The greeting service definition.
- """
- def SayHello(self, request, timeout, metadata=None, with_call=False, protocol_options=None):
- """Sends a greeting
- """
- raise NotImplementedError()
- SayHello.future = None
-
-
- def beta_create_Greeter_server(servicer, pool=None, pool_size=None, default_timeout=None, maximum_timeout=None):
- """The Beta API is deprecated for 0.15.0 and later.
-
- It is recommended to use the GA API (classes and functions in this
- file not marked beta) for all further purposes. This function was
- generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0"""
- request_deserializers = {
- ('helloworld.Greeter', 'SayHello'): HelloRequest.FromString,
- }
- response_serializers = {
- ('helloworld.Greeter', 'SayHello'): HelloReply.SerializeToString,
- }
- method_implementations = {
- ('helloworld.Greeter', 'SayHello'): face_utilities.unary_unary_inline(servicer.SayHello),
- }
- server_options = beta_implementations.server_options(request_deserializers=request_deserializers, response_serializers=response_serializers, thread_pool=pool, thread_pool_size=pool_size, default_timeout=default_timeout, maximum_timeout=maximum_timeout)
- return beta_implementations.server(method_implementations, options=server_options)
-
-
- def beta_create_Greeter_stub(channel, host=None, metadata_transformer=None, pool=None, pool_size=None):
- """The Beta API is deprecated for 0.15.0 and later.
-
- It is recommended to use the GA API (classes and functions in this
- file not marked beta) for all further purposes. This function was
- generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0"""
- request_serializers = {
- ('helloworld.Greeter', 'SayHello'): HelloRequest.SerializeToString,
- }
- response_deserializers = {
- ('helloworld.Greeter', 'SayHello'): HelloReply.FromString,
- }
- cardinalities = {
- 'SayHello': cardinality.Cardinality.UNARY_UNARY,
- }
- stub_options = beta_implementations.stub_options(host=host, metadata_transformer=metadata_transformer, request_serializers=request_serializers, response_deserializers=response_deserializers, thread_pool=pool, thread_pool_size=pool_size)
- return beta_implementations.dynamic_stub(channel, 'helloworld.Greeter', cardinalities, options=stub_options)
-except ImportError:
- pass
+
+_GREETER = _descriptor.ServiceDescriptor(
+ name='Greeter',
+ full_name='helloworld.Greeter',
+ file=DESCRIPTOR,
+ index=0,
+ options=None,
+ serialized_start=93,
+ serialized_end=166,
+ methods=[
+ _descriptor.MethodDescriptor(
+ name='SayHello',
+ full_name='helloworld.Greeter.SayHello',
+ index=0,
+ containing_service=None,
+ input_type=_HELLOREQUEST,
+ output_type=_HELLOREPLY,
+ options=None,
+ ),
+])
+_sym_db.RegisterServiceDescriptor(_GREETER)
+
+DESCRIPTOR.services_by_name['Greeter'] = _GREETER
+
# @@protoc_insertion_point(module_scope)
diff --git a/examples/python/multiplex/helloworld_pb2_grpc.py b/examples/python/multiplex/helloworld_pb2_grpc.py
index 682dc36cd8..18e07d1679 100644
--- a/examples/python/multiplex/helloworld_pb2_grpc.py
+++ b/examples/python/multiplex/helloworld_pb2_grpc.py
@@ -1,6 +1,5 @@
+# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
import grpc
-from grpc.framework.common import cardinality
-from grpc.framework.interfaces.face import utilities as face_utilities
import helloworld_pb2 as helloworld__pb2
diff --git a/examples/python/multiplex/route_guide_pb2.py b/examples/python/multiplex/route_guide_pb2.py
index e6775eb814..fbbc194a58 100644
--- a/examples/python/multiplex/route_guide_pb2.py
+++ b/examples/python/multiplex/route_guide_pb2.py
@@ -21,7 +21,6 @@ DESCRIPTOR = _descriptor.FileDescriptor(
syntax='proto3',
serialized_pb=_b('\n\x11route_guide.proto\x12\nrouteguide\",\n\x05Point\x12\x10\n\x08latitude\x18\x01 \x01(\x05\x12\x11\n\tlongitude\x18\x02 \x01(\x05\"I\n\tRectangle\x12\x1d\n\x02lo\x18\x01 \x01(\x0b\x32\x11.routeguide.Point\x12\x1d\n\x02hi\x18\x02 \x01(\x0b\x32\x11.routeguide.Point\"<\n\x07\x46\x65\x61ture\x12\x0c\n\x04name\x18\x01 \x01(\t\x12#\n\x08location\x18\x02 \x01(\x0b\x32\x11.routeguide.Point\"A\n\tRouteNote\x12#\n\x08location\x18\x01 \x01(\x0b\x32\x11.routeguide.Point\x12\x0f\n\x07message\x18\x02 \x01(\t\"b\n\x0cRouteSummary\x12\x13\n\x0bpoint_count\x18\x01 \x01(\x05\x12\x15\n\rfeature_count\x18\x02 \x01(\x05\x12\x10\n\x08\x64istance\x18\x03 \x01(\x05\x12\x14\n\x0c\x65lapsed_time\x18\x04 \x01(\x05\x32\x85\x02\n\nRouteGuide\x12\x36\n\nGetFeature\x12\x11.routeguide.Point\x1a\x13.routeguide.Feature\"\x00\x12>\n\x0cListFeatures\x12\x15.routeguide.Rectangle\x1a\x13.routeguide.Feature\"\x00\x30\x01\x12>\n\x0bRecordRoute\x12\x11.routeguide.Point\x1a\x18.routeguide.RouteSummary\"\x00(\x01\x12?\n\tRouteChat\x12\x15.routeguide.RouteNote\x1a\x15.routeguide.RouteNote\"\x00(\x01\x30\x01\x42\x36\n\x1bio.grpc.examples.routeguideB\x0fRouteGuideProtoP\x01\xa2\x02\x03RTGb\x06proto3')
)
-_sym_db.RegisterFileDescriptor(DESCRIPTOR)
@@ -238,6 +237,7 @@ DESCRIPTOR.message_types_by_name['Rectangle'] = _RECTANGLE
DESCRIPTOR.message_types_by_name['Feature'] = _FEATURE
DESCRIPTOR.message_types_by_name['RouteNote'] = _ROUTENOTE
DESCRIPTOR.message_types_by_name['RouteSummary'] = _ROUTESUMMARY
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
Point = _reflection.GeneratedProtocolMessageType('Point', (_message.Message,), dict(
DESCRIPTOR = _POINT,
@@ -277,265 +277,55 @@ _sym_db.RegisterMessage(RouteSummary)
DESCRIPTOR.has_options = True
DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\033io.grpc.examples.routeguideB\017RouteGuideProtoP\001\242\002\003RTG'))
-try:
- # THESE ELEMENTS WILL BE DEPRECATED.
- # Please use the generated *_pb2_grpc.py files instead.
- import grpc
- from grpc.framework.common import cardinality
- from grpc.framework.interfaces.face import utilities as face_utilities
- from grpc.beta import implementations as beta_implementations
- from grpc.beta import interfaces as beta_interfaces
-
-
- class RouteGuideStub(object):
- """Interface exported by the server.
- """
-
- def __init__(self, channel):
- """Constructor.
-
- Args:
- channel: A grpc.Channel.
- """
- self.GetFeature = channel.unary_unary(
- '/routeguide.RouteGuide/GetFeature',
- request_serializer=Point.SerializeToString,
- response_deserializer=Feature.FromString,
- )
- self.ListFeatures = channel.unary_stream(
- '/routeguide.RouteGuide/ListFeatures',
- request_serializer=Rectangle.SerializeToString,
- response_deserializer=Feature.FromString,
- )
- self.RecordRoute = channel.stream_unary(
- '/routeguide.RouteGuide/RecordRoute',
- request_serializer=Point.SerializeToString,
- response_deserializer=RouteSummary.FromString,
- )
- self.RouteChat = channel.stream_stream(
- '/routeguide.RouteGuide/RouteChat',
- request_serializer=RouteNote.SerializeToString,
- response_deserializer=RouteNote.FromString,
- )
-
-
- class RouteGuideServicer(object):
- """Interface exported by the server.
- """
-
- def GetFeature(self, request, context):
- """A simple RPC.
-
- Obtains the feature at a given position.
-
- A feature with an empty name is returned if there's no feature at the given
- position.
- """
- context.set_code(grpc.StatusCode.UNIMPLEMENTED)
- context.set_details('Method not implemented!')
- raise NotImplementedError('Method not implemented!')
-
- def ListFeatures(self, request, context):
- """A server-to-client streaming RPC.
-
- Obtains the Features available within the given Rectangle. Results are
- streamed rather than returned at once (e.g. in a response message with a
- repeated field), as the rectangle may cover a large area and contain a
- huge number of features.
- """
- context.set_code(grpc.StatusCode.UNIMPLEMENTED)
- context.set_details('Method not implemented!')
- raise NotImplementedError('Method not implemented!')
-
- def RecordRoute(self, request_iterator, context):
- """A client-to-server streaming RPC.
-
- Accepts a stream of Points on a route being traversed, returning a
- RouteSummary when traversal is completed.
- """
- context.set_code(grpc.StatusCode.UNIMPLEMENTED)
- context.set_details('Method not implemented!')
- raise NotImplementedError('Method not implemented!')
-
- def RouteChat(self, request_iterator, context):
- """A Bidirectional streaming RPC.
-
- Accepts a stream of RouteNotes sent while a route is being traversed,
- while receiving other RouteNotes (e.g. from other users).
- """
- context.set_code(grpc.StatusCode.UNIMPLEMENTED)
- context.set_details('Method not implemented!')
- raise NotImplementedError('Method not implemented!')
-
-
- def add_RouteGuideServicer_to_server(servicer, server):
- rpc_method_handlers = {
- 'GetFeature': grpc.unary_unary_rpc_method_handler(
- servicer.GetFeature,
- request_deserializer=Point.FromString,
- response_serializer=Feature.SerializeToString,
- ),
- 'ListFeatures': grpc.unary_stream_rpc_method_handler(
- servicer.ListFeatures,
- request_deserializer=Rectangle.FromString,
- response_serializer=Feature.SerializeToString,
- ),
- 'RecordRoute': grpc.stream_unary_rpc_method_handler(
- servicer.RecordRoute,
- request_deserializer=Point.FromString,
- response_serializer=RouteSummary.SerializeToString,
- ),
- 'RouteChat': grpc.stream_stream_rpc_method_handler(
- servicer.RouteChat,
- request_deserializer=RouteNote.FromString,
- response_serializer=RouteNote.SerializeToString,
- ),
- }
- generic_handler = grpc.method_handlers_generic_handler(
- 'routeguide.RouteGuide', rpc_method_handlers)
- server.add_generic_rpc_handlers((generic_handler,))
-
-
- class BetaRouteGuideServicer(object):
- """The Beta API is deprecated for 0.15.0 and later.
- It is recommended to use the GA API (classes and functions in this
- file not marked beta) for all further purposes. This class was generated
- only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0."""
- """Interface exported by the server.
- """
- def GetFeature(self, request, context):
- """A simple RPC.
-
- Obtains the feature at a given position.
-
- A feature with an empty name is returned if there's no feature at the given
- position.
- """
- context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
- def ListFeatures(self, request, context):
- """A server-to-client streaming RPC.
-
- Obtains the Features available within the given Rectangle. Results are
- streamed rather than returned at once (e.g. in a response message with a
- repeated field), as the rectangle may cover a large area and contain a
- huge number of features.
- """
- context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
- def RecordRoute(self, request_iterator, context):
- """A client-to-server streaming RPC.
-
- Accepts a stream of Points on a route being traversed, returning a
- RouteSummary when traversal is completed.
- """
- context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
- def RouteChat(self, request_iterator, context):
- """A Bidirectional streaming RPC.
-
- Accepts a stream of RouteNotes sent while a route is being traversed,
- while receiving other RouteNotes (e.g. from other users).
- """
- context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
-
-
- class BetaRouteGuideStub(object):
- """The Beta API is deprecated for 0.15.0 and later.
-
- It is recommended to use the GA API (classes and functions in this
- file not marked beta) for all further purposes. This class was generated
- only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0."""
- """Interface exported by the server.
- """
- def GetFeature(self, request, timeout, metadata=None, with_call=False, protocol_options=None):
- """A simple RPC.
-
- Obtains the feature at a given position.
-
- A feature with an empty name is returned if there's no feature at the given
- position.
- """
- raise NotImplementedError()
- GetFeature.future = None
- def ListFeatures(self, request, timeout, metadata=None, with_call=False, protocol_options=None):
- """A server-to-client streaming RPC.
-
- Obtains the Features available within the given Rectangle. Results are
- streamed rather than returned at once (e.g. in a response message with a
- repeated field), as the rectangle may cover a large area and contain a
- huge number of features.
- """
- raise NotImplementedError()
- def RecordRoute(self, request_iterator, timeout, metadata=None, with_call=False, protocol_options=None):
- """A client-to-server streaming RPC.
-
- Accepts a stream of Points on a route being traversed, returning a
- RouteSummary when traversal is completed.
- """
- raise NotImplementedError()
- RecordRoute.future = None
- def RouteChat(self, request_iterator, timeout, metadata=None, with_call=False, protocol_options=None):
- """A Bidirectional streaming RPC.
-
- Accepts a stream of RouteNotes sent while a route is being traversed,
- while receiving other RouteNotes (e.g. from other users).
- """
- raise NotImplementedError()
-
-
- def beta_create_RouteGuide_server(servicer, pool=None, pool_size=None, default_timeout=None, maximum_timeout=None):
- """The Beta API is deprecated for 0.15.0 and later.
-
- It is recommended to use the GA API (classes and functions in this
- file not marked beta) for all further purposes. This function was
- generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0"""
- request_deserializers = {
- ('routeguide.RouteGuide', 'GetFeature'): Point.FromString,
- ('routeguide.RouteGuide', 'ListFeatures'): Rectangle.FromString,
- ('routeguide.RouteGuide', 'RecordRoute'): Point.FromString,
- ('routeguide.RouteGuide', 'RouteChat'): RouteNote.FromString,
- }
- response_serializers = {
- ('routeguide.RouteGuide', 'GetFeature'): Feature.SerializeToString,
- ('routeguide.RouteGuide', 'ListFeatures'): Feature.SerializeToString,
- ('routeguide.RouteGuide', 'RecordRoute'): RouteSummary.SerializeToString,
- ('routeguide.RouteGuide', 'RouteChat'): RouteNote.SerializeToString,
- }
- method_implementations = {
- ('routeguide.RouteGuide', 'GetFeature'): face_utilities.unary_unary_inline(servicer.GetFeature),
- ('routeguide.RouteGuide', 'ListFeatures'): face_utilities.unary_stream_inline(servicer.ListFeatures),
- ('routeguide.RouteGuide', 'RecordRoute'): face_utilities.stream_unary_inline(servicer.RecordRoute),
- ('routeguide.RouteGuide', 'RouteChat'): face_utilities.stream_stream_inline(servicer.RouteChat),
- }
- server_options = beta_implementations.server_options(request_deserializers=request_deserializers, response_serializers=response_serializers, thread_pool=pool, thread_pool_size=pool_size, default_timeout=default_timeout, maximum_timeout=maximum_timeout)
- return beta_implementations.server(method_implementations, options=server_options)
-
-
- def beta_create_RouteGuide_stub(channel, host=None, metadata_transformer=None, pool=None, pool_size=None):
- """The Beta API is deprecated for 0.15.0 and later.
+_ROUTEGUIDE = _descriptor.ServiceDescriptor(
+ name='RouteGuide',
+ full_name='routeguide.RouteGuide',
+ file=DESCRIPTOR,
+ index=0,
+ options=None,
+ serialized_start=384,
+ serialized_end=645,
+ methods=[
+ _descriptor.MethodDescriptor(
+ name='GetFeature',
+ full_name='routeguide.RouteGuide.GetFeature',
+ index=0,
+ containing_service=None,
+ input_type=_POINT,
+ output_type=_FEATURE,
+ options=None,
+ ),
+ _descriptor.MethodDescriptor(
+ name='ListFeatures',
+ full_name='routeguide.RouteGuide.ListFeatures',
+ index=1,
+ containing_service=None,
+ input_type=_RECTANGLE,
+ output_type=_FEATURE,
+ options=None,
+ ),
+ _descriptor.MethodDescriptor(
+ name='RecordRoute',
+ full_name='routeguide.RouteGuide.RecordRoute',
+ index=2,
+ containing_service=None,
+ input_type=_POINT,
+ output_type=_ROUTESUMMARY,
+ options=None,
+ ),
+ _descriptor.MethodDescriptor(
+ name='RouteChat',
+ full_name='routeguide.RouteGuide.RouteChat',
+ index=3,
+ containing_service=None,
+ input_type=_ROUTENOTE,
+ output_type=_ROUTENOTE,
+ options=None,
+ ),
+])
+_sym_db.RegisterServiceDescriptor(_ROUTEGUIDE)
+
+DESCRIPTOR.services_by_name['RouteGuide'] = _ROUTEGUIDE
- It is recommended to use the GA API (classes and functions in this
- file not marked beta) for all further purposes. This function was
- generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0"""
- request_serializers = {
- ('routeguide.RouteGuide', 'GetFeature'): Point.SerializeToString,
- ('routeguide.RouteGuide', 'ListFeatures'): Rectangle.SerializeToString,
- ('routeguide.RouteGuide', 'RecordRoute'): Point.SerializeToString,
- ('routeguide.RouteGuide', 'RouteChat'): RouteNote.SerializeToString,
- }
- response_deserializers = {
- ('routeguide.RouteGuide', 'GetFeature'): Feature.FromString,
- ('routeguide.RouteGuide', 'ListFeatures'): Feature.FromString,
- ('routeguide.RouteGuide', 'RecordRoute'): RouteSummary.FromString,
- ('routeguide.RouteGuide', 'RouteChat'): RouteNote.FromString,
- }
- cardinalities = {
- 'GetFeature': cardinality.Cardinality.UNARY_UNARY,
- 'ListFeatures': cardinality.Cardinality.UNARY_STREAM,
- 'RecordRoute': cardinality.Cardinality.STREAM_UNARY,
- 'RouteChat': cardinality.Cardinality.STREAM_STREAM,
- }
- stub_options = beta_implementations.stub_options(host=host, metadata_transformer=metadata_transformer, request_serializers=request_serializers, response_deserializers=response_deserializers, thread_pool=pool, thread_pool_size=pool_size)
- return beta_implementations.dynamic_stub(channel, 'routeguide.RouteGuide', cardinalities, options=stub_options)
-except ImportError:
- pass
# @@protoc_insertion_point(module_scope)
diff --git a/examples/python/multiplex/route_guide_pb2_grpc.py b/examples/python/multiplex/route_guide_pb2_grpc.py
index 27b24c747d..05c1b79312 100644
--- a/examples/python/multiplex/route_guide_pb2_grpc.py
+++ b/examples/python/multiplex/route_guide_pb2_grpc.py
@@ -1,6 +1,5 @@
+# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
import grpc
-from grpc.framework.common import cardinality
-from grpc.framework.interfaces.face import utilities as face_utilities
import route_guide_pb2 as route__guide__pb2
diff --git a/examples/ruby/grpc-demo.gemspec b/examples/ruby/grpc-demo.gemspec
index 4423fd34d4..90f75fbb2b 100644
--- a/examples/ruby/grpc-demo.gemspec
+++ b/examples/ruby/grpc-demo.gemspec
@@ -18,6 +18,6 @@ Gem::Specification.new do |s|
s.platform = Gem::Platform::RUBY
s.add_dependency 'grpc', '~> 1.0'
-
+ s.add_dependency 'multi_json', '~> 1.13.1'
s.add_development_dependency 'bundler', '~> 1.7'
end
diff --git a/gRPC-C++.podspec b/gRPC-C++.podspec
index cbf765abb8..1d9237bf62 100644
--- a/gRPC-C++.podspec
+++ b/gRPC-C++.podspec
@@ -23,7 +23,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-C++'
# TODO (mxyan): use version that match gRPC version when pod is stabilized
- # version = '1.14.0'
+ # version = '1.15.0-dev'
version = '0.0.3'
s.version = version
s.summary = 'gRPC C++ library'
@@ -31,7 +31,7 @@ Pod::Spec.new do |s|
s.license = 'Apache License, Version 2.0'
s.authors = { 'The gRPC contributors' => 'grpc-packages@google.com' }
- grpc_version = '1.14.0'
+ grpc_version = '1.15.0-dev'
s.source = {
:git => 'https://github.com/grpc/grpc.git',
diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec
index 85071fb211..5c3649afbd 100644
--- a/gRPC-Core.podspec
+++ b/gRPC-Core.podspec
@@ -22,7 +22,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-Core'
- version = '1.14.0'
+ version = '1.15.0-dev'
s.version = version
s.summary = 'Core cross-platform gRPC library, written in C'
s.homepage = 'https://grpc.io'
@@ -802,8 +802,11 @@ Pod::Spec.new do |s|
'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc',
+ 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc',
+ 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc',
+ 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc',
'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc',
'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc',
'src/cpp/ext/filters/census/grpc_context.cc',
diff --git a/gRPC-ProtoRPC.podspec b/gRPC-ProtoRPC.podspec
index 3c4c6e1310..79ec679e3a 100644
--- a/gRPC-ProtoRPC.podspec
+++ b/gRPC-ProtoRPC.podspec
@@ -21,7 +21,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-ProtoRPC'
- version = '1.14.0'
+ version = '1.15.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 c37efca0ad..7a461e270f 100644
--- a/gRPC-RxLibrary.podspec
+++ b/gRPC-RxLibrary.podspec
@@ -21,7 +21,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC-RxLibrary'
- version = '1.14.0'
+ version = '1.15.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 9b155cbf44..bf3f56bd54 100644
--- a/gRPC.podspec
+++ b/gRPC.podspec
@@ -20,7 +20,7 @@
Pod::Spec.new do |s|
s.name = 'gRPC'
- version = '1.14.0'
+ version = '1.15.0-dev'
s.version = version
s.summary = 'gRPC client library for iOS/OSX'
s.homepage = 'https://grpc.io'
diff --git a/grpc.def b/grpc.def
index 06db74cad5..5b98792662 100644
--- a/grpc.def
+++ b/grpc.def
@@ -69,6 +69,8 @@ EXPORTS
grpc_resource_quota_unref
grpc_resource_quota_resize
grpc_resource_quota_arg_vtable
+ grpc_channelz_get_top_channels
+ grpc_channelz_get_channel
grpc_insecure_channel_create_from_fd
grpc_server_add_insecure_channel_from_fd
grpc_use_signal
diff --git a/grpc.gemspec b/grpc.gemspec
index b69d5a7c6f..c250316b99 100644
--- a/grpc.gemspec
+++ b/grpc.gemspec
@@ -742,8 +742,11 @@ Gem::Specification.new do |s|
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc )
+ s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc )
+ s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc )
+ s.files += %w( src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc )
s.files += %w( src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc )
s.files += %w( src/cpp/ext/filters/census/grpc_context.cc )
diff --git a/grpc.gyp b/grpc.gyp
index 0db6afe468..25082fe540 100644
--- a/grpc.gyp
+++ b/grpc.gyp
@@ -572,8 +572,11 @@
'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc',
+ 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc',
+ 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc',
+ 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc',
'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc',
'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc',
'src/cpp/ext/filters/census/grpc_context.cc',
@@ -1287,8 +1290,11 @@
'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc',
+ 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc',
+ 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc',
+ 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc',
'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc',
'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc',
'src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc',
@@ -1586,6 +1592,19 @@
],
},
{
+ 'target_name': 'grpcpp_channelz',
+ 'type': 'static_library',
+ 'dependencies': [
+ 'grpc++',
+ 'grpc',
+ ],
+ 'sources': [
+ 'src/cpp/server/channelz/channelz_service.cc',
+ 'src/cpp/server/channelz/channelz_service_plugin.cc',
+ 'src/proto/grpc/channelz/channelz.proto',
+ ],
+ },
+ {
'target_name': 'http2_client_main',
'type': 'static_library',
'dependencies': [
@@ -1705,6 +1724,7 @@
'test/cpp/qps/client_sync.cc',
'test/cpp/qps/driver.cc',
'test/cpp/qps/parse_json.cc',
+ 'test/cpp/qps/qps_server_builder.cc',
'test/cpp/qps/qps_worker.cc',
'test/cpp/qps/report.cc',
'test/cpp/qps/server_async.cc',
diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h
index c129a66949..3245aa5580 100644
--- a/include/grpc/grpc.h
+++ b/include/grpc/grpc.h
@@ -60,6 +60,8 @@ GRPCAPI void grpc_register_plugin(void (*init)(void), void (*destroy)(void));
/** Initialize the grpc library.
+ After it's called, a matching invocation to grpc_shutdown() is expected.
+
It is not safe to call any other grpc functions before calling this.
(To avoid overhead, little checking is done, and some things may work. We
do not warrant that they will continue to do so in future revisions of this
@@ -68,6 +70,9 @@ GRPCAPI void grpc_init(void);
/** Shut down the grpc library.
+ Before it's called, there should haven been a matching invocation to
+ grpc_init().
+
No memory is used by grpc after this call returns, nor are any instructions
executing within the grpc library.
Prior to calling, all application owned grpc objects must have been
@@ -454,6 +459,29 @@ GRPCAPI void grpc_resource_quota_resize(grpc_resource_quota* resource_quota,
*/
GRPCAPI const grpc_arg_pointer_vtable* grpc_resource_quota_arg_vtable(void);
+/************* CHANNELZ API *************/
+/** Channelz is under active development. The following APIs will see some
+ churn as the feature is implemented. This comment will be removed once
+ channelz is officially supported, and these APIs become stable. For now
+ you may track the progress by following this github issue:
+ https://github.com/grpc/grpc/issues/15340
+
+ the following APIs return allocated JSON strings that match the response
+ objects from the channelz proto, found here:
+ https://github.com/grpc/grpc/blob/master/src/proto/grpc/channelz/channelz.proto.
+
+ For easy conversion to protobuf, The JSON is formatted according to:
+ https://developers.google.com/protocol-buffers/docs/proto3#json. */
+
+/* Gets all root channels (i.e. channels the application has directly
+ created). This does not include subchannels nor non-top level channels.
+ The returned string is allocated and must be freed by the application. */
+GRPCAPI char* grpc_channelz_get_top_channels(intptr_t start_channel_id);
+
+/* Returns a single Channel, or else a NOT_FOUND code. The returned string
+ is allocated and must be freed by the application. */
+GRPCAPI char* grpc_channelz_get_channel(intptr_t channel_id);
+
#ifdef __cplusplus
}
#endif
diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h
index 102d20fcf9..02d87a493a 100644
--- a/include/grpc/grpc_security.h
+++ b/include/grpc/grpc_security.h
@@ -588,12 +588,6 @@ GRPCAPI grpc_server_credentials* grpc_alts_server_credentials_create(
/** --- Local channel/server credentials --- **/
/**
- * Type of local connection for which local channel/server credentials will be
- * applied. It only supports UDS for now.
- */
-typedef enum { UDS = 0 } grpc_local_connect_type;
-
-/**
* This method creates a local channel credential object. It is used for
* experimental purpose for now and subject to change.
*
diff --git a/include/grpc/grpc_security_constants.h b/include/grpc/grpc_security_constants.h
index 92580ea35e..944a1e927f 100644
--- a/include/grpc/grpc_security_constants.h
+++ b/include/grpc/grpc_security_constants.h
@@ -100,6 +100,12 @@ typedef enum {
GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY
} grpc_ssl_client_certificate_request_type;
+/**
+ * Type of local connection for which local channel/server credentials will be
+ * applied. It only supports UDS for now.
+ */
+typedef enum { UDS = 0 } grpc_local_connect_type;
+
#ifdef __cplusplus
}
#endif
diff --git a/include/grpc/impl/codegen/port_platform.h b/include/grpc/impl/codegen/port_platform.h
index 01ce5f03e9..2b61a8816d 100644
--- a/include/grpc/impl/codegen/port_platform.h
+++ b/include/grpc/impl/codegen/port_platform.h
@@ -420,12 +420,8 @@ typedef unsigned __int64 uint64_t;
#define GPR_MAX_ALIGNMENT 16
#ifndef GRPC_ARES
-#ifdef GPR_WINDOWS
-#define GRPC_ARES 0
-#else
#define GRPC_ARES 1
#endif
-#endif
#ifndef GRPC_MUST_USE_RESULT
#if defined(__GNUC__) && !defined(__MINGW32__)
diff --git a/include/grpcpp/ext/channelz_service_plugin.h b/include/grpcpp/ext/channelz_service_plugin.h
new file mode 100644
index 0000000000..af3192d451
--- /dev/null
+++ b/include/grpcpp/ext/channelz_service_plugin.h
@@ -0,0 +1,41 @@
+/*
+ *
+ * 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 GRPCPP_EXT_CHANNELZ_SERVICE_PLUGIN_H
+#define GRPCPP_EXT_CHANNELZ_SERVICE_PLUGIN_H
+
+#include <grpc/support/port_platform.h>
+
+#include <grpcpp/impl/server_builder_plugin.h>
+#include <grpcpp/impl/server_initializer.h>
+#include <grpcpp/support/config.h>
+
+namespace grpc {
+namespace channelz {
+namespace experimental {
+
+/// Add channelz server plugin to \a ServerBuilder. This function should
+/// be called at static initialization time. This service is experimental
+/// for now. Track progress in https://github.com/grpc/grpc/issues/15988.
+void InitChannelzService();
+
+} // namespace experimental
+} // namespace channelz
+} // namespace grpc
+
+#endif // GRPCPP_EXT_CHANNELZ_SERVICE_PLUGIN_H
diff --git a/include/grpcpp/impl/codegen/completion_queue.h b/include/grpcpp/impl/codegen/completion_queue.h
index 9713333cf5..5819e068ba 100644
--- a/include/grpcpp/impl/codegen/completion_queue.h
+++ b/include/grpcpp/impl/codegen/completion_queue.h
@@ -367,7 +367,7 @@ class ServerCompletionQueue : public CompletionQueue {
protected:
/// Default constructor
- ServerCompletionQueue() {}
+ ServerCompletionQueue() : polling_type_(GRPC_CQ_DEFAULT_POLLING) {}
private:
/// \param is_frequently_polled Informs the GRPC library about whether the
diff --git a/include/grpcpp/security/credentials.h b/include/grpcpp/security/credentials.h
index 36d95d1b42..bfadc15df5 100644
--- a/include/grpcpp/security/credentials.h
+++ b/include/grpcpp/security/credentials.h
@@ -23,6 +23,7 @@
#include <memory>
#include <vector>
+#include <grpc/grpc_security_constants.h>
#include <grpcpp/impl/codegen/grpc_library.h>
#include <grpcpp/security/auth_context.h>
#include <grpcpp/support/status.h>
@@ -234,6 +235,10 @@ struct AltsCredentialsOptions {
std::shared_ptr<ChannelCredentials> AltsCredentials(
const AltsCredentialsOptions& options);
+/// Builds Local Credentials.
+std::shared_ptr<ChannelCredentials> LocalCredentials(
+ grpc_local_connect_type type);
+
} // namespace experimental
} // namespace grpc
diff --git a/include/grpcpp/security/server_credentials.h b/include/grpcpp/security/server_credentials.h
index cf57e275f5..bd00a0a173 100644
--- a/include/grpcpp/security/server_credentials.h
+++ b/include/grpcpp/security/server_credentials.h
@@ -97,6 +97,10 @@ struct AltsServerCredentialsOptions {
std::shared_ptr<ServerCredentials> AltsServerCredentials(
const AltsServerCredentialsOptions& options);
+/// Builds Local ServerCredentials.
+std::shared_ptr<ServerCredentials> LocalServerCredentials(
+ grpc_local_connect_type type);
+
} // namespace experimental
} // namespace grpc
diff --git a/package.xml b/package.xml
index 2a30cffb4d..acdc6ffdb3 100644
--- a/package.xml
+++ b/package.xml
@@ -13,12 +13,12 @@
<date>2018-01-19</date>
<time>16:06:07</time>
<version>
- <release>1.14.0</release>
- <api>1.14.0</api>
+ <release>1.15.0dev</release>
+ <api>1.15.0dev</api>
</version>
<stability>
- <release>stable</release>
- <api>stable</api>
+ <release>beta</release>
+ <api>beta</api>
</stability>
<license>Apache 2.0</license>
<notes>
@@ -747,8 +747,11 @@
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc" role="src" />
+ <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc" role="src" />
+ <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc" role="src" />
+ <file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc" role="src" />
<file baseinstalldir="/" name="src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc" role="src" />
<file baseinstalldir="/" name="src/cpp/ext/filters/census/grpc_context.cc" role="src" />
diff --git a/requirements.bazel.txt b/requirements.bazel.txt
new file mode 100644
index 0000000000..16f31f9e94
--- /dev/null
+++ b/requirements.bazel.txt
@@ -0,0 +1,10 @@
+# GRPC Python setup requirements
+coverage>=4.0
+cython==0.28.3
+enum34>=1.0.4
+protobuf>=3.5.0.post1
+six>=1.10
+wheel>=0.29
+futures>=2.2.0
+google-auth>=1.0.0
+oauth2client==4.1.0
diff --git a/setup.py b/setup.py
index 388e629ec2..b87843f335 100644
--- a/setup.py
+++ b/setup.py
@@ -276,11 +276,11 @@ PACKAGE_DIRECTORIES = {
}
INSTALL_REQUIRES = (
- 'six>=1.5.2',
+ "six>=1.5.2",
+ "futures>=2.2.0 ; python_version<'3.2'",
+ "enum34>=1.0.4 ; python_version<'3.4'"
)
-if not PY3:
- INSTALL_REQUIRES += ('futures>=2.2.0', 'enum34>=1.0.4')
SETUP_REQUIRES = INSTALL_REQUIRES + (
'sphinx>=1.3',
diff --git a/src/android/test/interop/app/src/main/cpp/grpc-interop.cc b/src/android/test/interop/app/src/main/cpp/grpc-interop.cc
index bbdc84abdd..07834250d2 100644
--- a/src/android/test/interop/app/src/main/cpp/grpc-interop.cc
+++ b/src/android/test/interop/app/src/main/cpp/grpc-interop.cc
@@ -45,9 +45,10 @@ std::shared_ptr<grpc::testing::InteropClient> GetClient(const char* host,
credentials = grpc::InsecureChannelCredentials();
}
+ grpc::testing::ChannelCreationFunc channel_creation_func =
+ std::bind(grpc::CreateChannel, host_port, credentials);
return std::shared_ptr<grpc::testing::InteropClient>(
- new grpc::testing::InteropClient(
- grpc::CreateChannel(host_port, credentials), true, false));
+ new grpc::testing::InteropClient(channel_creation_func, true, false));
}
extern "C" JNIEXPORT jboolean JNICALL
diff --git a/src/core/ext/filters/client_channel/client_channel.cc b/src/core/ext/filters/client_channel/client_channel.cc
index 024c9d737e..fead8feb17 100644
--- a/src/core/ext/filters/client_channel/client_channel.cc
+++ b/src/core/ext/filters/client_channel/client_channel.cc
@@ -571,15 +571,32 @@ static void start_transport_op_locked(void* arg, grpc_error* error_ignored) {
if (op->send_ping.on_initiate != nullptr || op->send_ping.on_ack != nullptr) {
if (chand->lb_policy == nullptr) {
- GRPC_CLOSURE_SCHED(
- op->send_ping.on_initiate,
- GRPC_ERROR_CREATE_FROM_STATIC_STRING("Ping with no load balancing"));
- GRPC_CLOSURE_SCHED(
- op->send_ping.on_ack,
- GRPC_ERROR_CREATE_FROM_STATIC_STRING("Ping with no load balancing"));
+ grpc_error* error =
+ GRPC_ERROR_CREATE_FROM_STATIC_STRING("Ping with no load balancing");
+ GRPC_CLOSURE_SCHED(op->send_ping.on_initiate, GRPC_ERROR_REF(error));
+ GRPC_CLOSURE_SCHED(op->send_ping.on_ack, error);
} else {
- chand->lb_policy->PingOneLocked(op->send_ping.on_initiate,
- op->send_ping.on_ack);
+ grpc_error* error = GRPC_ERROR_NONE;
+ grpc_core::LoadBalancingPolicy::PickState pick_state;
+ pick_state.initial_metadata = nullptr;
+ pick_state.initial_metadata_flags = 0;
+ pick_state.on_complete = nullptr;
+ memset(&pick_state.subchannel_call_context, 0,
+ sizeof(pick_state.subchannel_call_context));
+ pick_state.user_data = nullptr;
+ // Pick must return synchronously, because pick_state.on_complete is null.
+ GPR_ASSERT(chand->lb_policy->PickLocked(&pick_state, &error));
+ if (pick_state.connected_subchannel != nullptr) {
+ pick_state.connected_subchannel->Ping(op->send_ping.on_initiate,
+ op->send_ping.on_ack);
+ } else {
+ if (error == GRPC_ERROR_NONE) {
+ error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+ "LB policy dropped call on ping");
+ }
+ GRPC_CLOSURE_SCHED(op->send_ping.on_initiate, GRPC_ERROR_REF(error));
+ GRPC_CLOSURE_SCHED(op->send_ping.on_ack, error);
+ }
op->bind_pollset = nullptr;
}
op->send_ping.on_initiate = nullptr;
@@ -2684,14 +2701,15 @@ class LbPicker {
grpc_combiner_scheduler(chand->combiner));
calld->pick.on_complete = &calld->pick_closure;
GRPC_CALL_STACK_REF(calld->owning_call, "pick_callback");
- const bool pick_done = chand->lb_policy->PickLocked(&calld->pick);
+ grpc_error* error = GRPC_ERROR_NONE;
+ const bool pick_done = chand->lb_policy->PickLocked(&calld->pick, &error);
if (GPR_LIKELY(pick_done)) {
// Pick completed synchronously.
if (grpc_client_channel_trace.enabled()) {
gpr_log(GPR_INFO, "chand=%p calld=%p: pick completed synchronously",
chand, calld);
}
- pick_done_locked(elem, GRPC_ERROR_NONE);
+ pick_done_locked(elem, error);
GRPC_CALL_STACK_UNREF(calld->owning_call, "pick_callback");
} else {
// Pick will be returned asynchronously.
diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.cc b/src/core/ext/filters/client_channel/client_channel_channelz.cc
index 235b8f3207..86c765df52 100644
--- a/src/core/ext/filters/client_channel/client_channel_channelz.cc
+++ b/src/core/ext/filters/client_channel/client_channel_channelz.cc
@@ -41,8 +41,9 @@ static const grpc_arg_pointer_vtable client_channel_channelz_vtable = {
client_channel_channelz_cmp};
ClientChannelNode::ClientChannelNode(grpc_channel* channel,
- size_t channel_tracer_max_nodes)
- : ChannelNode(channel, channel_tracer_max_nodes) {
+ size_t channel_tracer_max_nodes,
+ bool is_top_level_channel)
+ : ChannelNode(channel, channel_tracer_max_nodes, is_top_level_channel) {
client_channel_ =
grpc_channel_stack_last_element(grpc_channel_get_channel_stack(channel));
GPR_ASSERT(client_channel_->filter == &grpc_client_channel_filter);
@@ -69,7 +70,7 @@ void ClientChannelNode::PopulateChildRefs(grpc_json* json) {
grpc_json* json_iterator = nullptr;
grpc_client_channel_populate_child_refs(client_channel_, &child_subchannels,
&child_channels);
- if (child_subchannels.size() > 0) {
+ if (!child_subchannels.empty()) {
grpc_json* array_parent = grpc_json_create_child(
nullptr, json, "subchannelRef", nullptr, GRPC_JSON_ARRAY, false);
for (size_t i = 0; i < child_subchannels.size(); ++i) {
@@ -80,16 +81,16 @@ void ClientChannelNode::PopulateChildRefs(grpc_json* json) {
child_subchannels[i]);
}
}
- if (child_channels.size() > 0) {
+ if (!child_channels.empty()) {
grpc_json* array_parent = grpc_json_create_child(
nullptr, json, "channelRef", nullptr, GRPC_JSON_ARRAY, false);
json_iterator = nullptr;
- for (size_t i = 0; i < child_subchannels.size(); ++i) {
+ for (size_t i = 0; i < child_channels.size(); ++i) {
json_iterator =
grpc_json_create_child(json_iterator, array_parent, nullptr, nullptr,
GRPC_JSON_OBJECT, false);
grpc_json_add_number_string_child(json_iterator, nullptr, "channelId",
- child_subchannels[i]);
+ child_channels[i]);
}
}
}
@@ -102,9 +103,10 @@ grpc_arg ClientChannelNode::CreateChannelArg() {
}
RefCountedPtr<ChannelNode> ClientChannelNode::MakeClientChannelNode(
- grpc_channel* channel, size_t channel_tracer_max_nodes) {
- return MakePolymorphicRefCounted<ChannelNode, ClientChannelNode>(
- channel, channel_tracer_max_nodes);
+ grpc_channel* channel, size_t channel_tracer_max_nodes,
+ bool is_top_level_channel) {
+ return MakeRefCounted<ClientChannelNode>(channel, channel_tracer_max_nodes,
+ is_top_level_channel);
}
} // namespace channelz
diff --git a/src/core/ext/filters/client_channel/client_channel_channelz.h b/src/core/ext/filters/client_channel/client_channel_channelz.h
index 0547109d36..6f27b5c8b7 100644
--- a/src/core/ext/filters/client_channel/client_channel_channelz.h
+++ b/src/core/ext/filters/client_channel/client_channel_channelz.h
@@ -40,7 +40,8 @@ namespace channelz {
class ClientChannelNode : public ChannelNode {
public:
static RefCountedPtr<ChannelNode> MakeClientChannelNode(
- grpc_channel* channel, size_t channel_tracer_max_nodes);
+ grpc_channel* channel, size_t channel_tracer_max_nodes,
+ bool is_top_level_channel);
// Override this functionality since client_channels have a notion of
// channel connectivity.
@@ -56,7 +57,8 @@ class ClientChannelNode : public ChannelNode {
protected:
GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW
- ClientChannelNode(grpc_channel* channel, size_t channel_tracer_max_nodes);
+ ClientChannelNode(grpc_channel* channel, size_t channel_tracer_max_nodes,
+ bool is_top_level_channel);
virtual ~ClientChannelNode() {}
private:
diff --git a/src/core/ext/filters/client_channel/lb_policy.h b/src/core/ext/filters/client_channel/lb_policy.h
index 3150df8847..31c08246ae 100644
--- a/src/core/ext/filters/client_channel/lb_policy.h
+++ b/src/core/ext/filters/client_channel/lb_policy.h
@@ -71,6 +71,7 @@ class LoadBalancingPolicy
/// Storage for LB token in \a initial_metadata, or nullptr if not used.
grpc_linked_mdelem lb_token_mdelem_storage;
/// Closure to run when pick is complete, if not completed synchronously.
+ /// If null, pick will fail if a result is not available synchronously.
grpc_closure* on_complete;
/// Will be set to the selected subchannel, or nullptr on failure or when
/// the LB policy decides to drop the call.
@@ -99,10 +100,15 @@ class LoadBalancingPolicy
/// Finds an appropriate subchannel for a call, based on data in \a pick.
/// \a pick must remain alive until the pick is complete.
///
- /// If the pick succeeds and a result is known immediately, returns true.
- /// Otherwise, \a pick->on_complete will be invoked once the pick is
- /// complete with its error argument set to indicate success or failure.
- virtual bool PickLocked(PickState* pick) GRPC_ABSTRACT;
+ /// If a result is known immediately, returns true, setting \a *error
+ /// upon failure. Otherwise, \a pick->on_complete will be invoked once
+ /// the pick is complete with its error argument set to indicate success
+ /// or failure.
+ ///
+ /// If \a pick->on_complete is null and no result is known immediately,
+ /// a synchronous failure will be returned (i.e., \a *error will be
+ /// set and true will be returned).
+ virtual bool PickLocked(PickState* pick, grpc_error** error) GRPC_ABSTRACT;
/// Cancels \a pick.
/// The \a on_complete callback of the pending pick will be invoked with
@@ -133,12 +139,6 @@ class LoadBalancingPolicy
virtual void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy)
GRPC_ABSTRACT;
- /// Performs a connected subchannel ping via \a ConnectedSubchannel::Ping()
- /// against one of the connected subchannels managed by the policy.
- /// Note: This is intended only for use in tests.
- virtual void PingOneLocked(grpc_closure* on_initiate,
- grpc_closure* on_ack) GRPC_ABSTRACT;
-
/// Tries to enter a READY connectivity state.
/// TODO(roth): As part of restructuring how we handle IDLE state,
/// consider whether this method is still needed.
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 f757d6057c..2d1f777474 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,7 @@ class GrpcLb : public LoadBalancingPolicy {
GrpcLb(const grpc_lb_addresses* addresses, const Args& args);
void UpdateLocked(const grpc_channel_args& args) override;
- bool PickLocked(PickState* pick) 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,
uint32_t initial_metadata_flags_eq,
@@ -133,11 +133,9 @@ class GrpcLb : public LoadBalancingPolicy {
grpc_connectivity_state CheckConnectivityLocked(
grpc_error** connectivity_error) override;
void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) override;
- void PingOneLocked(grpc_closure* on_initiate, grpc_closure* on_ack) override;
void ExitIdleLocked() override;
- // TODO(ncteisen): implement this in a follow up PR
void FillChildRefsForChannelz(ChildRefsList* child_subchannels,
- ChildRefsList* child_channels) override {}
+ ChildRefsList* child_channels) override;
private:
/// Linked list of pending pick requests. It stores all information needed to
@@ -168,13 +166,6 @@ class GrpcLb : public LoadBalancingPolicy {
PendingPick* next = nullptr;
};
- /// A linked list of pending pings waiting for the RR policy to be created.
- struct PendingPing {
- grpc_closure* on_initiate;
- grpc_closure* on_ack;
- PendingPing* next = nullptr;
- };
-
/// Contains a call to the LB server and all the data related to the call.
class BalancerCallState
: public InternallyRefCountedWithTracing<BalancerCallState> {
@@ -273,14 +264,12 @@ class GrpcLb : public LoadBalancingPolicy {
void AddPendingPick(PendingPick* pp);
static void OnPendingPickComplete(void* arg, grpc_error* error);
- // Pending ping methods.
- void AddPendingPing(grpc_closure* on_initiate, grpc_closure* on_ack);
-
// 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);
+ bool PickFromRoundRobinPolicyLocked(bool force_async, PendingPick* pp,
+ grpc_error** error);
void UpdateConnectivityStateFromRoundRobinPolicyLocked(
grpc_error* rr_state_error);
static void OnRoundRobinConnectivityChangedLocked(void* arg,
@@ -301,6 +290,9 @@ class GrpcLb : public LoadBalancingPolicy {
// The channel for communicating with the LB server.
grpc_channel* lb_channel_ = nullptr;
+ // Mutex to protect the channel to the LB server. This is used when
+ // processing a channelz request.
+ gpr_mu lb_channel_mu_;
grpc_connectivity_state lb_channel_connectivity_;
grpc_closure lb_channel_on_connectivity_changed_;
// Are we already watching the LB channel's connectivity?
@@ -340,9 +332,8 @@ class GrpcLb : public LoadBalancingPolicy {
grpc_timer lb_fallback_timer_;
grpc_closure lb_on_fallback_;
- // Pending picks and pings that are waiting on the RR policy's connectivity.
+ // Pending picks that are waiting on the RR policy's connectivity.
PendingPick* pending_picks_ = nullptr;
- PendingPing* pending_pings_ = nullptr;
// The RR policy to use for the backends.
OrphanablePtr<LoadBalancingPolicy> rr_policy_;
@@ -1007,6 +998,10 @@ grpc_channel_args* BuildBalancerChannelArgs(
// A channel arg indicating the target is a grpclb load balancer.
grpc_channel_arg_integer_create(
const_cast<char*>(GRPC_ARG_ADDRESS_IS_GRPCLB_LOAD_BALANCER), 1),
+ // A channel arg indicating this is an internal channels, aka it is
+ // owned by components in Core, not by the user application.
+ grpc_channel_arg_integer_create(
+ const_cast<char*>(GRPC_ARG_CHANNELZ_CHANNEL_IS_INTERNAL_CHANNEL), 1),
};
// Construct channel args.
grpc_channel_args* new_args = grpc_channel_args_copy_and_add_and_remove(
@@ -1036,6 +1031,7 @@ GrpcLb::GrpcLb(const grpc_lb_addresses* addresses,
.set_max_backoff(GRPC_GRPCLB_RECONNECT_MAX_BACKOFF_SECONDS *
1000)) {
// Initialization.
+ gpr_mu_init(&lb_channel_mu_);
grpc_subchannel_index_ref();
GRPC_CLOSURE_INIT(&lb_channel_on_connectivity_changed_,
&GrpcLb::OnBalancerChannelConnectivityChangedLocked, this,
@@ -1073,7 +1069,7 @@ GrpcLb::GrpcLb(const grpc_lb_addresses* addresses,
GrpcLb::~GrpcLb() {
GPR_ASSERT(pending_picks_ == nullptr);
- GPR_ASSERT(pending_pings_ == nullptr);
+ gpr_mu_destroy(&lb_channel_mu_);
gpr_free((void*)server_name_);
grpc_channel_args_destroy(args_);
grpc_connectivity_state_destroy(&state_tracker_);
@@ -1103,8 +1099,10 @@ void GrpcLb::ShutdownLocked() {
// OnBalancerChannelConnectivityChangedLocked(), and we need to be
// alive when that callback is invoked.
if (lb_channel_ != nullptr) {
+ gpr_mu_lock(&lb_channel_mu_);
grpc_channel_destroy(lb_channel_);
lb_channel_ = nullptr;
+ gpr_mu_unlock(&lb_channel_mu_);
}
grpc_connectivity_state_set(&state_tracker_, GRPC_CHANNEL_SHUTDOWN,
GRPC_ERROR_REF(error), "grpclb_shutdown");
@@ -1116,14 +1114,6 @@ void GrpcLb::ShutdownLocked() {
// Note: pp is deleted in this callback.
GRPC_CLOSURE_SCHED(&pp->on_complete, GRPC_ERROR_REF(error));
}
- // Clear pending pings.
- PendingPing* pping;
- while ((pping = pending_pings_) != nullptr) {
- pending_pings_ = pping->next;
- GRPC_CLOSURE_SCHED(pping->on_initiate, GRPC_ERROR_REF(error));
- GRPC_CLOSURE_SCHED(pping->on_ack, GRPC_ERROR_REF(error));
- Delete(pping);
- }
GRPC_ERROR_UNREF(error);
}
@@ -1137,9 +1127,10 @@ void GrpcLb::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) {
pending_picks_ = pp->next;
pp->pick->on_complete = pp->original_on_complete;
pp->pick->user_data = nullptr;
- if (new_policy->PickLocked(pp->pick)) {
+ grpc_error* error = GRPC_ERROR_NONE;
+ if (new_policy->PickLocked(pp->pick, &error)) {
// Synchronous return; schedule closure.
- GRPC_CLOSURE_SCHED(pp->pick->on_complete, GRPC_ERROR_NONE);
+ GRPC_CLOSURE_SCHED(pp->pick->on_complete, error);
}
Delete(pp);
}
@@ -1223,54 +1214,47 @@ void GrpcLb::ExitIdleLocked() {
}
}
-bool GrpcLb::PickLocked(PickState* pick) {
+bool GrpcLb::PickLocked(PickState* pick, grpc_error** error) {
PendingPick* pp = PendingPickCreate(pick);
bool pick_done = false;
if (rr_policy_ != nullptr) {
- const grpc_connectivity_state rr_connectivity_state =
- rr_policy_->CheckConnectivityLocked(nullptr);
- // The RR policy may have transitioned to SHUTDOWN but the callback
- // registered to capture this event (on_rr_connectivity_changed_) may not
- // have been invoked yet. We need to make sure we aren't trying to pick
- // from an RR policy instance that's in shutdown.
- if (rr_connectivity_state == GRPC_CHANNEL_SHUTDOWN) {
+ if (grpc_lb_glb_trace.enabled()) {
+ gpr_log(GPR_INFO, "[grpclb %p] about to PICK from RR %p", this,
+ rr_policy_.get());
+ }
+ pick_done =
+ PickFromRoundRobinPolicyLocked(false /* force_async */, pp, error);
+ } else { // rr_policy_ == NULL
+ if (pick->on_complete == nullptr) {
+ *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+ "No pick result available but synchronous result required.");
+ pick_done = true;
+ } else {
if (grpc_lb_glb_trace.enabled()) {
gpr_log(GPR_INFO,
- "[grpclb %p] NOT picking from from RR %p: RR conn state=%s",
- this, rr_policy_.get(),
- grpc_connectivity_state_name(rr_connectivity_state));
+ "[grpclb %p] No RR policy. Adding to grpclb's pending picks",
+ this);
}
AddPendingPick(pp);
- pick_done = false;
- } else { // RR not in shutdown
- if (grpc_lb_glb_trace.enabled()) {
- gpr_log(GPR_INFO, "[grpclb %p] about to PICK from RR %p", this,
- rr_policy_.get());
+ if (!started_picking_) {
+ StartPickingLocked();
}
- pick_done = PickFromRoundRobinPolicyLocked(false /* force_async */, pp);
- }
- } else { // rr_policy_ == NULL
- if (grpc_lb_glb_trace.enabled()) {
- gpr_log(GPR_INFO,
- "[grpclb %p] No RR policy. Adding to grpclb's pending picks",
- this);
- }
- AddPendingPick(pp);
- if (!started_picking_) {
- StartPickingLocked();
+ pick_done = false;
}
- pick_done = false;
}
return pick_done;
}
-void GrpcLb::PingOneLocked(grpc_closure* on_initiate, grpc_closure* on_ack) {
- if (rr_policy_ != nullptr) {
- rr_policy_->PingOneLocked(on_initiate, on_ack);
- } else {
- AddPendingPing(on_initiate, on_ack);
- if (!started_picking_) {
- StartPickingLocked();
+void GrpcLb::FillChildRefsForChannelz(ChildRefsList* child_subchannels,
+ ChildRefsList* child_channels) {
+ // delegate to the RoundRobin to fill the children subchannels.
+ rr_policy_->FillChildRefsForChannelz(child_subchannels, child_channels);
+ mu_guard guard(&lb_channel_mu_);
+ if (lb_channel_ != nullptr) {
+ grpc_core::channelz::ChannelNode* channel_node =
+ grpc_channel_get_channelz_node(lb_channel_);
+ if (channel_node != nullptr) {
+ child_channels->push_back(channel_node->channel_uuid());
}
}
}
@@ -1318,9 +1302,11 @@ void GrpcLb::ProcessChannelArgsLocked(const grpc_channel_args& args) {
if (lb_channel_ == nullptr) {
char* uri_str;
gpr_asprintf(&uri_str, "fake:///%s", server_name_);
+ gpr_mu_lock(&lb_channel_mu_);
lb_channel_ = grpc_client_channel_factory_create_channel(
client_channel_factory(), uri_str,
GRPC_CLIENT_CHANNEL_TYPE_LOAD_BALANCING, lb_channel_args);
+ gpr_mu_unlock(&lb_channel_mu_);
GPR_ASSERT(lb_channel_ != nullptr);
gpr_free(uri_str);
}
@@ -1573,18 +1559,6 @@ void GrpcLb::AddPendingPick(PendingPick* pp) {
}
//
-// PendingPing
-//
-
-void GrpcLb::AddPendingPing(grpc_closure* on_initiate, grpc_closure* on_ack) {
- PendingPing* pping = New<PendingPing>();
- pping->on_initiate = on_initiate;
- pping->on_ack = on_ack;
- pping->next = pending_pings_;
- pending_pings_ = pping;
-}
-
-//
// code for interacting with the RR policy
//
@@ -1593,7 +1567,8 @@ void GrpcLb::AddPendingPing(grpc_closure* on_initiate, grpc_closure* on_ack) {
// 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 GrpcLb::PickFromRoundRobinPolicyLocked(bool force_async, 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) {
// Look at the index into the serverlist to see if we should drop this call.
@@ -1627,11 +1602,12 @@ bool GrpcLb::PickFromRoundRobinPolicyLocked(bool force_async, PendingPick* pp) {
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);
+ bool pick_done = rr_policy_->PickLocked(pp->pick, error);
if (pick_done) {
PendingPickSetMetadataAndContext(pp);
if (force_async) {
- GRPC_CLOSURE_SCHED(pp->original_on_complete, GRPC_ERROR_NONE);
+ GRPC_CLOSURE_SCHED(pp->original_on_complete, *error);
+ *error = GRPC_ERROR_NONE;
pick_done = false;
}
Delete(pp);
@@ -1683,18 +1659,8 @@ void GrpcLb::CreateRoundRobinPolicyLocked(const Args& args) {
"[grpclb %p] Pending pick about to (async) PICK from RR %p", this,
rr_policy_.get());
}
- PickFromRoundRobinPolicyLocked(true /* force_async */, pp);
- }
- // Send pending pings to RR policy.
- PendingPing* pping;
- while ((pping = pending_pings_)) {
- pending_pings_ = pping->next;
- if (grpc_lb_glb_trace.enabled()) {
- gpr_log(GPR_INFO, "[grpclb %p] Pending ping about to PING from RR %p",
- this, rr_policy_.get());
- }
- rr_policy_->PingOneLocked(pping->on_initiate, pping->on_ack);
- Delete(pping);
+ grpc_error* error = GRPC_ERROR_NONE;
+ PickFromRoundRobinPolicyLocked(true /* force_async */, pp, &error);
}
}
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 c50deb9679..46acbf628b 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,7 @@ class PickFirst : public LoadBalancingPolicy {
explicit PickFirst(const Args& args);
void UpdateLocked(const grpc_channel_args& args) override;
- bool PickLocked(PickState* pick) 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,
uint32_t initial_metadata_flags_eq,
@@ -56,10 +56,9 @@ class PickFirst : public LoadBalancingPolicy {
grpc_connectivity_state CheckConnectivityLocked(
grpc_error** connectivity_error) override;
void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) override;
- void PingOneLocked(grpc_closure* on_initiate, grpc_closure* on_ack) override;
void ExitIdleLocked() override;
void FillChildRefsForChannelz(ChildRefsList* child_subchannels,
- ChildRefsList* child_channels) override;
+ ChildRefsList* ignored) override;
private:
~PickFirst();
@@ -173,15 +172,16 @@ void PickFirst::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) {
PickState* pick;
while ((pick = pending_picks_) != nullptr) {
pending_picks_ = pick->next;
- if (new_policy->PickLocked(pick)) {
+ grpc_error* error = GRPC_ERROR_NONE;
+ if (new_policy->PickLocked(pick, &error)) {
// Synchronous return, schedule closure.
- GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_NONE);
+ GRPC_CLOSURE_SCHED(pick->on_complete, error);
}
}
}
void PickFirst::ShutdownLocked() {
- AutoChildRefsUpdater(this);
+ AutoChildRefsUpdater guard(this);
grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel shutdown");
if (grpc_lb_pick_first_trace.enabled()) {
gpr_log(GPR_INFO, "Pick First %p Shutting down", this);
@@ -259,13 +259,18 @@ void PickFirst::ExitIdleLocked() {
}
}
-bool PickFirst::PickLocked(PickState* pick) {
+bool PickFirst::PickLocked(PickState* pick, grpc_error** error) {
// If we have a selected subchannel already, return synchronously.
if (selected_ != nullptr) {
pick->connected_subchannel = selected_->connected_subchannel()->Ref();
return true;
}
// No subchannel selected yet, so handle asynchronously.
+ if (pick->on_complete == nullptr) {
+ *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+ "No pick result available but synchronous result required.");
+ return true;
+ }
if (!started_picking_) {
StartPickingLocked();
}
@@ -293,17 +298,6 @@ void PickFirst::NotifyOnStateChangeLocked(grpc_connectivity_state* current,
notify);
}
-void PickFirst::PingOneLocked(grpc_closure* on_initiate, grpc_closure* on_ack) {
- if (selected_ != nullptr) {
- selected_->connected_subchannel()->Ping(on_initiate, on_ack);
- } else {
- GRPC_CLOSURE_SCHED(on_initiate,
- GRPC_ERROR_CREATE_FROM_STATIC_STRING("Not connected"));
- GRPC_CLOSURE_SCHED(on_ack,
- GRPC_ERROR_CREATE_FROM_STATIC_STRING("Not connected"));
- }
-}
-
void PickFirst::FillChildRefsForChannelz(
ChildRefsList* child_subchannels_to_fill, ChildRefsList* ignored) {
mu_guard guard(&child_refs_mu_);
@@ -327,30 +321,10 @@ void PickFirst::FillChildRefsForChannelz(
void PickFirst::UpdateChildRefsLocked() {
ChildRefsList cs;
if (subchannel_list_ != nullptr) {
- for (size_t i = 0; i < subchannel_list_->num_subchannels(); ++i) {
- if (subchannel_list_->subchannel(i)->subchannel() != nullptr) {
- grpc_core::channelz::SubchannelNode* subchannel_node =
- grpc_subchannel_get_channelz_node(
- subchannel_list_->subchannel(i)->subchannel());
- if (subchannel_node != nullptr) {
- cs.push_back(subchannel_node->subchannel_uuid());
- }
- }
- }
+ subchannel_list_->PopulateChildRefsList(&cs);
}
if (latest_pending_subchannel_list_ != nullptr) {
- for (size_t i = 0; i < latest_pending_subchannel_list_->num_subchannels();
- ++i) {
- if (latest_pending_subchannel_list_->subchannel(i)->subchannel() !=
- nullptr) {
- grpc_core::channelz::SubchannelNode* subchannel_node =
- grpc_subchannel_get_channelz_node(
- latest_pending_subchannel_list_->subchannel(i)->subchannel());
- if (subchannel_node != nullptr) {
- cs.push_back(subchannel_node->subchannel_uuid());
- }
- }
- }
+ latest_pending_subchannel_list_->PopulateChildRefsList(&cs);
}
// atomically update the data that channelz will actually be looking at.
mu_guard guard(&child_refs_mu_);
@@ -471,6 +445,7 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked(
// latest pending subchannel lists.
GPR_ASSERT(subchannel_list() == p->subchannel_list_.get() ||
subchannel_list() == p->latest_pending_subchannel_list_.get());
+ GPR_ASSERT(connectivity_state != GRPC_CHANNEL_SHUTDOWN);
// Handle updates for the currently selected subchannel.
if (p->selected_ == this) {
if (grpc_lb_pick_first_trace.enabled()) {
@@ -500,14 +475,12 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked(
"update"),
"selected_not_ready+switch_to_update");
} else {
- // TODO(juanlishen): we re-resolve when the selected subchannel goes to
- // TRANSIENT_FAILURE because we used to shut down in this case before
- // re-resolution is introduced. But we need to investigate whether we
- // really want to take any action instead of waiting for the selected
- // subchannel reconnecting.
- GPR_ASSERT(connectivity_state != GRPC_CHANNEL_SHUTDOWN);
if (connectivity_state == GRPC_CHANNEL_TRANSIENT_FAILURE) {
- // If the selected channel goes bad, request a re-resolution.
+ // If the selected subchannel goes bad, request a re-resolution. We also
+ // set the channel state to IDLE and reset started_picking_. The reason
+ // is that if the new state is TRANSIENT_FAILURE due to a GOAWAY
+ // reception we don't want to connect to the re-resolved backends until
+ // we leave the IDLE state.
grpc_connectivity_state_set(&p->state_tracker_, GRPC_CHANNEL_IDLE,
GRPC_ERROR_NONE,
"selected_changed+reresolve");
@@ -588,9 +561,10 @@ void PickFirst::PickFirstSubchannelData::ProcessConnectivityChangeLocked(
// Case 1: Only set state to TRANSIENT_FAILURE if we've tried
// all subchannels.
if (sd->Index() == 0 && subchannel_list() == p->subchannel_list_.get()) {
+ p->TryReresolutionLocked(&grpc_lb_pick_first_trace, GRPC_ERROR_NONE);
grpc_connectivity_state_set(
&p->state_tracker_, GRPC_CHANNEL_TRANSIENT_FAILURE,
- GRPC_ERROR_REF(error), "connecting_transient_failure");
+ GRPC_ERROR_REF(error), "exhausted_subchannels");
}
sd->StartConnectivityWatchLocked();
break;
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 09634a2ad4..9c3a15c67b 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,7 @@ class RoundRobin : public LoadBalancingPolicy {
explicit RoundRobin(const Args& args);
void UpdateLocked(const grpc_channel_args& args) override;
- bool PickLocked(PickState* pick) 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,
uint32_t initial_metadata_flags_eq,
@@ -67,11 +67,9 @@ class RoundRobin : public LoadBalancingPolicy {
grpc_connectivity_state CheckConnectivityLocked(
grpc_error** connectivity_error) override;
void HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) override;
- void PingOneLocked(grpc_closure* on_initiate, grpc_closure* on_ack) override;
void ExitIdleLocked() override;
- // TODO(ncteisen): implement this in a follow up PR
void FillChildRefsForChannelz(ChildRefsList* child_subchannels,
- ChildRefsList* child_channels) override {}
+ ChildRefsList* ignored) override;
private:
~RoundRobin();
@@ -183,11 +181,24 @@ class RoundRobin : public LoadBalancingPolicy {
size_t last_ready_index_ = -1; // Index into list of last pick.
};
+ // Helper class to ensure that any function that modifies the child refs
+ // data structures will update the channelz snapshot data structures before
+ // returning.
+ class AutoChildRefsUpdater {
+ public:
+ explicit AutoChildRefsUpdater(RoundRobin* rr) : rr_(rr) {}
+ ~AutoChildRefsUpdater() { rr_->UpdateChildRefsLocked(); }
+
+ private:
+ RoundRobin* rr_;
+ };
+
void ShutdownLocked() override;
void StartPickingLocked();
bool DoPickLocked(PickState* pick);
void DrainPendingPicksLocked();
+ void UpdateChildRefsLocked();
/** list of subchannels */
OrphanablePtr<RoundRobinSubchannelList> subchannel_list_;
@@ -205,10 +216,16 @@ class RoundRobin : public LoadBalancingPolicy {
PickState* pending_picks_ = nullptr;
/** our connectivity state tracker */
grpc_connectivity_state_tracker state_tracker_;
+ /// Lock and data used to capture snapshots of this channel's child
+ /// channels and subchannels. This data is consumed by channelz.
+ gpr_mu child_refs_mu_;
+ ChildRefsList child_subchannels_;
+ ChildRefsList child_channels_;
};
RoundRobin::RoundRobin(const Args& args) : LoadBalancingPolicy(args) {
GPR_ASSERT(args.client_channel_factory != nullptr);
+ gpr_mu_init(&child_refs_mu_);
grpc_connectivity_state_init(&state_tracker_, GRPC_CHANNEL_IDLE,
"round_robin");
UpdateLocked(*args.args);
@@ -223,6 +240,7 @@ RoundRobin::~RoundRobin() {
if (grpc_lb_round_robin_trace.enabled()) {
gpr_log(GPR_INFO, "[RR %p] Destroying Round Robin policy", this);
}
+ gpr_mu_destroy(&child_refs_mu_);
GPR_ASSERT(subchannel_list_ == nullptr);
GPR_ASSERT(latest_pending_subchannel_list_ == nullptr);
GPR_ASSERT(pending_picks_ == nullptr);
@@ -234,14 +252,16 @@ void RoundRobin::HandOffPendingPicksLocked(LoadBalancingPolicy* new_policy) {
PickState* pick;
while ((pick = pending_picks_) != nullptr) {
pending_picks_ = pick->next;
- if (new_policy->PickLocked(pick)) {
+ grpc_error* error = GRPC_ERROR_NONE;
+ if (new_policy->PickLocked(pick, &error)) {
// Synchronous return, schedule closure.
- GRPC_CLOSURE_SCHED(pick->on_complete, GRPC_ERROR_NONE);
+ GRPC_CLOSURE_SCHED(pick->on_complete, error);
}
}
}
void RoundRobin::ShutdownLocked() {
+ AutoChildRefsUpdater guard(this);
grpc_error* error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Channel shutdown");
if (grpc_lb_round_robin_trace.enabled()) {
gpr_log(GPR_INFO, "[RR %p] Shutting down", this);
@@ -348,7 +368,7 @@ void RoundRobin::DrainPendingPicksLocked() {
}
}
-bool RoundRobin::PickLocked(PickState* pick) {
+bool RoundRobin::PickLocked(PickState* pick, grpc_error** error) {
if (grpc_lb_round_robin_trace.enabled()) {
gpr_log(GPR_INFO, "[RR %p] Trying to pick (shutdown: %d)", this, shutdown_);
}
@@ -356,6 +376,11 @@ bool RoundRobin::PickLocked(PickState* pick) {
if (subchannel_list_ != nullptr) {
if (DoPickLocked(pick)) return true;
}
+ if (pick->on_complete == nullptr) {
+ *error = GRPC_ERROR_CREATE_FROM_STATIC_STRING(
+ "No pick result available but synchronous result required.");
+ return true;
+ }
/* no pick currently available. Save for later in list of pending picks */
pick->next = pending_picks_;
pending_picks_ = pick;
@@ -365,6 +390,39 @@ bool RoundRobin::PickLocked(PickState* pick) {
return false;
}
+void RoundRobin::FillChildRefsForChannelz(
+ ChildRefsList* child_subchannels_to_fill, ChildRefsList* ignored) {
+ mu_guard guard(&child_refs_mu_);
+ for (size_t i = 0; i < child_subchannels_.size(); ++i) {
+ // TODO(ncteisen): implement a de dup loop that is not O(n^2). Might
+ // have to implement lightweight set. For now, we don't care about
+ // performance when channelz requests are made.
+ bool found = false;
+ for (size_t j = 0; j < child_subchannels_to_fill->size(); ++j) {
+ if ((*child_subchannels_to_fill)[j] == child_subchannels_[i]) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ child_subchannels_to_fill->push_back(child_subchannels_[i]);
+ }
+ }
+}
+
+void RoundRobin::UpdateChildRefsLocked() {
+ ChildRefsList cs;
+ if (subchannel_list_ != nullptr) {
+ subchannel_list_->PopulateChildRefsList(&cs);
+ }
+ if (latest_pending_subchannel_list_ != nullptr) {
+ latest_pending_subchannel_list_->PopulateChildRefsList(&cs);
+ }
+ // atomically update the data that channelz will actually be looking at.
+ mu_guard guard(&child_refs_mu_);
+ child_subchannels_ = std::move(cs);
+}
+
void RoundRobin::RoundRobinSubchannelList::StartWatchingLocked() {
if (num_subchannels() == 0) return;
// Check current state of each subchannel synchronously, since any
@@ -455,6 +513,7 @@ void RoundRobin::RoundRobinSubchannelList::
void RoundRobin::RoundRobinSubchannelList::
UpdateRoundRobinStateFromSubchannelStateCountsLocked() {
RoundRobin* p = static_cast<RoundRobin*>(policy());
+ AutoChildRefsUpdater guard(p);
if (num_ready_ > 0) {
if (p->subchannel_list_.get() != this) {
// Promote this list to p->subchannel_list_.
@@ -593,24 +652,9 @@ void RoundRobin::NotifyOnStateChangeLocked(grpc_connectivity_state* current,
notify);
}
-void RoundRobin::PingOneLocked(grpc_closure* on_initiate,
- grpc_closure* on_ack) {
- const size_t next_ready_index =
- subchannel_list_->GetNextReadySubchannelIndexLocked();
- if (next_ready_index < subchannel_list_->num_subchannels()) {
- RoundRobinSubchannelData* selected =
- subchannel_list_->subchannel(next_ready_index);
- selected->connected_subchannel()->Ping(on_initiate, on_ack);
- } else {
- GRPC_CLOSURE_SCHED(on_initiate, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
- "Round Robin not connected"));
- GRPC_CLOSURE_SCHED(on_ack, GRPC_ERROR_CREATE_FROM_STATIC_STRING(
- "Round Robin not connected"));
- }
-}
-
void RoundRobin::UpdateLocked(const grpc_channel_args& args) {
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)) {
gpr_log(GPR_ERROR, "[RR %p] update provided no addresses; ignoring", this);
// If we don't have a current subchannel list, go into TRANSIENT_FAILURE.
diff --git a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h
index 7e2046bcdc..018ac3bb86 100644
--- a/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h
+++ b/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h
@@ -189,6 +189,19 @@ class SubchannelList
// Returns true if the subchannel list is shutting down.
bool shutting_down() const { return shutting_down_; }
+ // Populates refs_list with the uuids of this SubchannelLists's subchannels.
+ void PopulateChildRefsList(ChildRefsList* refs_list) {
+ for (size_t i = 0; i < subchannels_.size(); ++i) {
+ if (subchannels_[i].subchannel() != nullptr) {
+ grpc_core::channelz::SubchannelNode* subchannel_node =
+ grpc_subchannel_get_channelz_node(subchannels_[i].subchannel());
+ if (subchannel_node != nullptr) {
+ refs_list->push_back(subchannel_node->subchannel_uuid());
+ }
+ }
+ }
+ }
+
// Accessors.
LoadBalancingPolicy* policy() const { return policy_; }
TraceFlag* tracer() const { return tracer_; }
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 f4f6444c5f..7050e82121 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
@@ -23,7 +23,6 @@
#include <limits.h>
#include <stdio.h>
#include <string.h>
-#include <unistd.h>
#include <grpc/support/alloc.h>
#include <grpc/support/string_util.h>
@@ -142,8 +141,8 @@ AresDnsResolver::AresDnsResolver(const ResolverArgs& args)
channel_args_ = grpc_channel_args_copy(args.args);
const grpc_arg* arg = grpc_channel_args_find(
channel_args_, GRPC_ARG_SERVICE_CONFIG_DISABLE_RESOLUTION);
- request_service_config_ = !grpc_channel_arg_get_integer(
- arg, (grpc_integer_options){false, false, true});
+ grpc_integer_options integer_options = {false, false, true};
+ request_service_config_ = !grpc_channel_arg_get_integer(arg, integer_options);
arg = grpc_channel_args_find(channel_args_,
GRPC_ARG_DNS_MIN_TIME_BETWEEN_RESOLUTIONS_MS);
min_time_between_resolutions_ =
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc
index c886795608..0068d0d5f4 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc
@@ -18,11 +18,10 @@
#include <grpc/support/port_platform.h>
#include "src/core/lib/iomgr/port.h"
-#if GRPC_ARES == 1 && defined(GRPC_POSIX_SOCKET_ARES_EV_DRIVER)
+#if GRPC_ARES == 1 && !defined(GRPC_UV)
#include <ares.h>
#include <string.h>
-#include <sys/ioctl.h>
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h"
@@ -32,7 +31,6 @@
#include <grpc/support/time.h>
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
#include "src/core/lib/gpr/string.h"
-#include "src/core/lib/iomgr/ev_posix.h"
#include "src/core/lib/iomgr/iomgr_internal.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
@@ -314,4 +312,4 @@ void grpc_ares_ev_driver_start_locked(grpc_ares_ev_driver* ev_driver) {
}
}
-#endif /* GRPC_ARES == 1 && defined(GRPC_POSIX_SOCKET_ARES_EV_DRIVER) */
+#endif /* GRPC_ARES == 1 && !defined(GRPC_UV) */
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc
new file mode 100644
index 0000000000..5d65ae3ab3
--- /dev/null
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc
@@ -0,0 +1,59 @@
+/*
+ *
+ * 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.
+ *
+ */
+#include <grpc/support/port_platform.h>
+
+#include "src/core/lib/iomgr/port.h"
+#if GRPC_ARES == 1 && defined(GPR_WINDOWS)
+
+#include <ares.h>
+#include <string.h>
+#include "src/core/lib/gprpp/memory.h"
+
+#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h"
+
+namespace grpc_core {
+
+/* TODO: fill in the body of GrpcPolledFdWindows to enable c-ares on Windows.
+ This dummy implementation only allows grpc to compile on windows with
+ GRPC_ARES=1. */
+class GrpcPolledFdWindows : public GrpcPolledFd {
+ public:
+ GrpcPolledFdWindows() { abort(); }
+ ~GrpcPolledFdWindows() { abort(); }
+ void RegisterForOnReadableLocked(grpc_closure* read_closure) override {
+ abort();
+ }
+ void RegisterForOnWriteableLocked(grpc_closure* write_closure) override {
+ abort();
+ }
+ bool IsFdStillReadableLocked() override { abort(); }
+ void ShutdownLocked(grpc_error* error) override { abort(); }
+ ares_socket_t GetWrappedAresSocketLocked() override { abort(); }
+ const char* GetName() override { abort(); }
+};
+
+GrpcPolledFd* NewGrpcPolledFdLocked(ares_socket_t as,
+ grpc_pollset_set* driver_pollset_set) {
+ return nullptr;
+}
+
+void ConfigureAresChannelLocked(ares_channel* channel) { abort(); }
+
+} // namespace grpc_core
+
+#endif /* GRPC_ARES == 1 && defined(GPR_WINDOWS) */
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
index 497ad998af..b3d6437e9a 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc
@@ -22,7 +22,6 @@
#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
#include "src/core/lib/iomgr/sockaddr.h"
-#include "src/core/lib/iomgr/socket_utils_posix.h"
#include <string.h>
#include <sys/types.h>
@@ -215,7 +214,7 @@ static void on_hostbyname_done_locked(void* arg, int status, int timeouts,
memset(&addr, 0, addr_len);
memcpy(&addr.sin6_addr, hostent->h_addr_list[i - prev_naddr],
sizeof(struct in6_addr));
- addr.sin6_family = static_cast<sa_family_t>(hostent->h_addrtype);
+ addr.sin6_family = static_cast<unsigned char>(hostent->h_addrtype);
addr.sin6_port = hr->port;
grpc_lb_addresses_set_address(
*lb_addresses, i, &addr, addr_len,
@@ -236,7 +235,7 @@ static void on_hostbyname_done_locked(void* arg, int status, int timeouts,
memset(&addr, 0, addr_len);
memcpy(&addr.sin_addr, hostent->h_addr_list[i - prev_naddr],
sizeof(struct in_addr));
- addr.sin_family = static_cast<sa_family_t>(hostent->h_addrtype);
+ addr.sin_family = static_cast<unsigned char>(hostent->h_addrtype);
addr.sin_port = hr->port;
grpc_lb_addresses_set_address(
*lb_addresses, i, &addr, addr_len,
@@ -281,7 +280,7 @@ static void on_srv_query_done_locked(void* arg, int status, int timeouts,
grpc_ares_ev_driver_get_channel_locked(r->ev_driver);
for (struct ares_srv_reply* srv_it = reply; srv_it != nullptr;
srv_it = srv_it->next) {
- if (grpc_ipv6_loopback_available()) {
+ if (grpc_ares_query_ipv6()) {
grpc_ares_hostbyname_request* hr = create_hostbyname_request_locked(
r, srv_it->host, htons(srv_it->port), true /* is_balancer */);
ares_gethostbyname(*channel, hr->host, AF_INET6,
@@ -452,7 +451,7 @@ static grpc_ares_request* grpc_dns_lookup_ares_locked_impl(
}
}
r->pending_queries = 1;
- if (grpc_ipv6_loopback_available()) {
+ if (grpc_ares_query_ipv6()) {
hr = create_hostbyname_request_locked(r, host, strhtons(port),
false /* is_balancer */);
ares_gethostbyname(*channel, hr->host, AF_INET6, on_hostbyname_done_locked,
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h
index ce26f5d524..17eaa7ccf0 100644
--- a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h
@@ -70,6 +70,10 @@ void grpc_ares_cleanup(void);
* and destroys the grpc_ares_request */
void grpc_ares_complete_request_locked(grpc_ares_request* request);
+/* Indicates whether or not AAAA queries should be attempted. */
+/* E.g., return false if ipv6 is known to not be available. */
+bool grpc_ares_query_ipv6();
+
/* Exposed only for testing */
void grpc_cares_wrapper_test_only_address_sorting_sort(
grpc_lb_addresses* lb_addrs);
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc
new file mode 100644
index 0000000000..23c0fec74f
--- /dev/null
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc
@@ -0,0 +1,29 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#include <grpc/support/port_platform.h>
+
+#include "src/core/lib/iomgr/port.h"
+#if GRPC_ARES == 1 && defined(GRPC_POSIX_SOCKET_ARES_EV_DRIVER)
+
+#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
+#include "src/core/lib/iomgr/socket_utils_posix.h"
+
+bool grpc_ares_query_ipv6() { return grpc_ipv6_loopback_available(); }
+
+#endif /* GRPC_ARES == 1 && defined(GRPC_POSIX_SOCKET_ARES_EV_DRIVER) */
diff --git a/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc
new file mode 100644
index 0000000000..ee827e284e
--- /dev/null
+++ b/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc
@@ -0,0 +1,29 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#include <grpc/support/port_platform.h>
+
+#include "src/core/lib/iomgr/port.h"
+#if GRPC_ARES == 1 && defined(GPR_WINDOWS)
+
+#include "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h"
+#include "src/core/lib/iomgr/socket_windows.h"
+
+bool grpc_ares_query_ipv6() { return grpc_ipv6_loopback_available(); }
+
+#endif /* GRPC_ARES == 1 && defined(GPR_WINDOWS) */
diff --git a/src/core/ext/filters/client_channel/subchannel.cc b/src/core/ext/filters/client_channel/subchannel.cc
index 9d608c3c55..71ef8c518b 100644
--- a/src/core/ext/filters/client_channel/subchannel.cc
+++ b/src/core/ext/filters/client_channel/subchannel.cc
@@ -390,8 +390,8 @@ grpc_subchannel* grpc_subchannel_create(grpc_connector* connector,
}
grpc_core::channelz::SubchannelNode* grpc_subchannel_get_channelz_node(
- grpc_subchannel* s) {
- return s->channelz_subchannel.get();
+ grpc_subchannel* subchannel) {
+ return subchannel->channelz_subchannel.get();
}
static void continue_connect_locked(grpc_subchannel* c) {
@@ -402,8 +402,6 @@ static void continue_connect_locked(grpc_subchannel* c) {
c->next_attempt_deadline = c->backoff->NextAttemptTime();
args.deadline = std::max(c->next_attempt_deadline, min_deadline);
args.channel_args = c->args;
- grpc_connectivity_state_set(&c->state_tracker, GRPC_CHANNEL_CONNECTING,
- GRPC_ERROR_NONE, "state_change");
grpc_connector_connect(c->connector, &args, &c->connecting_result,
&c->on_connected);
}
@@ -459,27 +457,24 @@ static void maybe_start_connecting_locked(grpc_subchannel* c) {
/* Don't try to connect if we're already disconnected */
return;
}
-
if (c->connecting) {
/* Already connecting: don't restart */
return;
}
-
if (c->connected_subchannel != nullptr) {
/* Already connected: don't restart */
return;
}
-
if (!grpc_connectivity_state_has_watchers(&c->state_tracker)) {
/* Nobody is interested in connecting: so don't just yet */
return;
}
-
c->connecting = true;
GRPC_SUBCHANNEL_WEAK_REF(c, "connecting");
-
if (!c->backoff_begun) {
c->backoff_begun = true;
+ grpc_connectivity_state_set(&c->state_tracker, GRPC_CHANNEL_CONNECTING,
+ GRPC_ERROR_NONE, "connecting");
continue_connect_locked(c);
} else {
GPR_ASSERT(!c->have_alarm);
@@ -494,6 +489,11 @@ static void maybe_start_connecting_locked(grpc_subchannel* c) {
}
GRPC_CLOSURE_INIT(&c->on_alarm, on_alarm, c, grpc_schedule_on_exec_ctx);
grpc_timer_init(&c->alarm, c->next_attempt_deadline, &c->on_alarm);
+ // During backoff, we prefer the connectivity state of CONNECTING instead of
+ // TRANSIENT_FAILURE in order to prevent triggering re-resolution
+ // continuously in pick_first.
+ grpc_connectivity_state_set(&c->state_tracker, GRPC_CHANNEL_CONNECTING,
+ GRPC_ERROR_NONE, "backoff");
}
}
diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc
index bd6fec6fbe..9ad271753c 100644
--- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc
+++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc
@@ -1208,7 +1208,7 @@ void grpc_chttp2_complete_closure_step(grpc_chttp2_transport* t,
grpc_error_add_child(closure->error_data.error, error);
}
if (closure->next_data.scratch < CLOSURE_BARRIER_FIRST_REF_BIT) {
- if (s->seen_error || (t->write_state == GRPC_CHTTP2_WRITE_STATE_IDLE) ||
+ if ((t->write_state == GRPC_CHTTP2_WRITE_STATE_IDLE) ||
!(closure->next_data.scratch & CLOSURE_BARRIER_MAY_COVER_WRITE)) {
GRPC_CLOSURE_RUN(closure, closure->error_data.error);
} else {
diff --git a/src/core/lib/channel/channel_stack.h b/src/core/lib/channel/channel_stack.h
index 7581f937b6..35c3fb01ea 100644
--- a/src/core/lib/channel/channel_stack.h
+++ b/src/core/lib/channel/channel_stack.h
@@ -82,7 +82,7 @@ typedef struct {
typedef struct {
grpc_call_stats stats;
grpc_status_code final_status;
- const char** error_string;
+ const char* error_string;
} grpc_call_final_info;
/* Channel filters specify:
diff --git a/src/core/lib/channel/channel_trace.cc b/src/core/lib/channel/channel_trace.cc
index c17885a713..b3443310ac 100644
--- a/src/core/lib/channel/channel_trace.cc
+++ b/src/core/lib/channel/channel_trace.cc
@@ -174,7 +174,7 @@ void ChannelTrace::TraceEvent::RenderTraceEvent(grpc_json* json) const {
}
}
-grpc_json* ChannelTrace::RenderJSON() const {
+grpc_json* ChannelTrace::RenderJson() const {
if (!max_list_size_)
return nullptr; // tracing is disabled if max_events == 0
grpc_json* json = grpc_json_create(GRPC_JSON_OBJECT);
diff --git a/src/core/lib/channel/channel_trace.h b/src/core/lib/channel/channel_trace.h
index 0dd162a777..596af7402f 100644
--- a/src/core/lib/channel/channel_trace.h
+++ b/src/core/lib/channel/channel_trace.h
@@ -71,7 +71,7 @@ class ChannelTrace {
// Creates and returns the raw grpc_json object, so a parent channelz
// object may incorporate the json before rendering.
- grpc_json* RenderJSON() const;
+ grpc_json* RenderJson() const;
private:
// Types of objects that can be references by trace events.
diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc
index 79a9220503..9d6002ed8a 100644
--- a/src/core/lib/channel/channelz.cc
+++ b/src/core/lib/channel/channelz.cc
@@ -41,18 +41,22 @@
namespace grpc_core {
namespace channelz {
-ChannelNode::ChannelNode(grpc_channel* channel, size_t channel_tracer_max_nodes)
- : channel_(channel), target_(nullptr), channel_uuid_(-1) {
+ChannelNode::ChannelNode(grpc_channel* channel, size_t channel_tracer_max_nodes,
+ bool is_top_level_channel)
+ : channel_(channel),
+ target_(nullptr),
+ channel_uuid_(-1),
+ is_top_level_channel_(is_top_level_channel) {
trace_.Init(channel_tracer_max_nodes);
target_ = UniquePtr<char>(grpc_channel_get_target(channel_));
- channel_uuid_ = ChannelzRegistry::Register(this);
+ channel_uuid_ = ChannelzRegistry::RegisterChannelNode(this);
gpr_atm_no_barrier_store(&last_call_started_millis_,
(gpr_atm)ExecCtx::Get()->Now());
}
ChannelNode::~ChannelNode() {
trace_.Destroy();
- ChannelzRegistry::Unregister(channel_uuid_);
+ ChannelzRegistry::UnregisterChannelNode(channel_uuid_);
}
void ChannelNode::RecordCallStarted() {
@@ -65,7 +69,7 @@ void ChannelNode::PopulateConnectivityState(grpc_json* json) {}
void ChannelNode::PopulateChildRefs(grpc_json* json) {}
-char* ChannelNode::RenderJSON() {
+grpc_json* ChannelNode::RenderJson() {
// We need to track these three json objects to build our object
grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT);
grpc_json* json = top_level_json;
@@ -86,30 +90,32 @@ char* ChannelNode::RenderJSON() {
json = data;
json_iterator = nullptr;
PopulateConnectivityState(json);
+ GPR_ASSERT(target_.get() != nullptr);
json_iterator = grpc_json_create_child(
json_iterator, json, "target", target_.get(), GRPC_JSON_STRING, false);
// fill in the channel trace if applicable
- grpc_json* trace = trace_->RenderJSON();
+ grpc_json* trace = trace_->RenderJson();
if (trace != nullptr) {
- // we manuall link up and fill the child since it was created for us in
- // ChannelTrace::RenderJSON
+ // we manually link up and fill the child since it was created for us in
+ // ChannelTrace::RenderJson
+ trace->key = "trace"; // this object is named trace in channelz.proto
json_iterator = grpc_json_link_child(json, trace, json_iterator);
- trace->parent = json;
- trace->value = nullptr;
- trace->key = "trace";
- trace->owns_value = false;
}
// reset the parent to be the data object.
json = data;
json_iterator = nullptr;
- // We use -1 as sentinel values since proto default value for integers is
- // zero, and the confuses the parser into thinking the value weren't present
- json_iterator = grpc_json_add_number_string_child(
- json, json_iterator, "callsStarted", calls_started_);
- json_iterator = grpc_json_add_number_string_child(
- json, json_iterator, "callsSucceeded", calls_succeeded_);
- json_iterator = grpc_json_add_number_string_child(
- json, json_iterator, "callsFailed", calls_failed_);
+ if (calls_started_ != 0) {
+ json_iterator = grpc_json_add_number_string_child(
+ json, json_iterator, "callsStarted", calls_started_);
+ }
+ if (calls_succeeded_ != 0) {
+ json_iterator = grpc_json_add_number_string_child(
+ json, json_iterator, "callsSucceeded", calls_succeeded_);
+ }
+ if (calls_failed_) {
+ json_iterator = grpc_json_add_number_string_child(
+ json, json_iterator, "callsFailed", calls_failed_);
+ }
gpr_timespec ts =
grpc_millis_to_timespec(last_call_started_millis_, GPR_CLOCK_REALTIME);
json_iterator =
@@ -118,25 +124,29 @@ char* ChannelNode::RenderJSON() {
json = top_level_json;
json_iterator = nullptr;
PopulateChildRefs(json);
+ return top_level_json;
+}
- // render and return the over json object
- char* json_str = grpc_json_dump_to_string(top_level_json, 0);
- grpc_json_destroy(top_level_json);
+char* ChannelNode::RenderJsonString() {
+ grpc_json* json = RenderJson();
+ char* json_str = grpc_json_dump_to_string(json, 0);
+ grpc_json_destroy(json);
return json_str;
}
RefCountedPtr<ChannelNode> ChannelNode::MakeChannelNode(
- grpc_channel* channel, size_t channel_tracer_max_nodes) {
+ grpc_channel* channel, size_t channel_tracer_max_nodes,
+ bool is_top_level_channel) {
return MakeRefCounted<grpc_core::channelz::ChannelNode>(
- channel, channel_tracer_max_nodes);
+ channel, channel_tracer_max_nodes, is_top_level_channel);
}
SubchannelNode::SubchannelNode() {
- subchannel_uuid_ = ChannelzRegistry::Register(this);
+ subchannel_uuid_ = ChannelzRegistry::RegisterSubchannelNode(this);
}
SubchannelNode::~SubchannelNode() {
- ChannelzRegistry::Unregister(subchannel_uuid_);
+ ChannelzRegistry::UnregisterSubchannelNode(subchannel_uuid_);
}
} // namespace channelz
diff --git a/src/core/lib/channel/channelz.h b/src/core/lib/channel/channelz.h
index 7184af93ec..07eb73d626 100644
--- a/src/core/lib/channel/channelz.h
+++ b/src/core/lib/channel/channelz.h
@@ -35,6 +35,10 @@
#define GRPC_ARG_CHANNELZ_CHANNEL_NODE_CREATION_FUNC \
"grpc.channelz_channel_node_creation_func"
+// Channel arg key to signal that the channel is an internal channel.
+#define GRPC_ARG_CHANNELZ_CHANNEL_IS_INTERNAL_CHANNEL \
+ "grpc.channelz_channel_is_internal_channel"
+
namespace grpc_core {
namespace channelz {
@@ -45,7 +49,8 @@ class ChannelNodePeer;
class ChannelNode : public RefCounted<ChannelNode> {
public:
static RefCountedPtr<ChannelNode> MakeChannelNode(
- grpc_channel* channel, size_t channel_tracer_max_nodes);
+ grpc_channel* channel, size_t channel_tracer_max_nodes,
+ bool is_top_level_channel);
void RecordCallStarted();
void RecordCallFailed() {
@@ -55,7 +60,8 @@ class ChannelNode : public RefCounted<ChannelNode> {
gpr_atm_no_barrier_fetch_add(&calls_succeeded_, (gpr_atm(1)));
}
- char* RenderJSON();
+ grpc_json* RenderJson();
+ char* RenderJsonString();
// helper for getting and populating connectivity state. It is virtual
// because it allows the client_channel specific code to live in ext/
@@ -74,11 +80,13 @@ class ChannelNode : public RefCounted<ChannelNode> {
bool ChannelIsDestroyed() { return channel_ == nullptr; }
intptr_t channel_uuid() { return channel_uuid_; }
+ bool is_top_level_channel() { return is_top_level_channel_; }
protected:
GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW
- ChannelNode(grpc_channel* channel, size_t channel_tracer_max_nodes);
+ ChannelNode(grpc_channel* channel, size_t channel_tracer_max_nodes,
+ bool is_top_level_channel);
virtual ~ChannelNode();
private:
@@ -92,6 +100,7 @@ class ChannelNode : public RefCounted<ChannelNode> {
gpr_atm calls_failed_ = 0;
gpr_atm last_call_started_millis_ = 0;
intptr_t channel_uuid_;
+ bool is_top_level_channel_ = true;
ManualConstructor<ChannelTrace> trace_;
};
@@ -116,7 +125,7 @@ class SubchannelNode : public RefCounted<SubchannelNode> {
// Creation functions
typedef RefCountedPtr<ChannelNode> (*ChannelNodeCreationFunc)(grpc_channel*,
- size_t);
+ size_t, bool);
} // namespace channelz
} // namespace grpc_core
diff --git a/src/core/lib/channel/channelz_registry.cc b/src/core/lib/channel/channelz_registry.cc
index 023ede552a..38496b3d78 100644
--- a/src/core/lib/channel/channelz_registry.cc
+++ b/src/core/lib/channel/channelz_registry.cc
@@ -19,16 +19,19 @@
#include <grpc/impl/codegen/port_platform.h>
#include "src/core/lib/channel/channel_trace.h"
+#include "src/core/lib/channel/channelz.h"
#include "src/core/lib/channel/channelz_registry.h"
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/gprpp/memory.h"
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
+#include <grpc/support/sync.h>
#include <cstring>
namespace grpc_core {
+namespace channelz {
namespace {
// singleton instance of the registry.
@@ -49,12 +52,93 @@ ChannelzRegistry::ChannelzRegistry() { gpr_mu_init(&mu_); }
ChannelzRegistry::~ChannelzRegistry() { gpr_mu_destroy(&mu_); }
-void ChannelzRegistry::InternalUnregister(intptr_t uuid) {
+intptr_t ChannelzRegistry::InternalRegisterEntry(const RegistryEntry& entry) {
+ mu_guard guard(&mu_);
+ entities_.push_back(entry);
+ intptr_t uuid = entities_.size();
+ return uuid;
+}
+
+void ChannelzRegistry::InternalUnregisterEntry(intptr_t uuid, EntityType type) {
GPR_ASSERT(uuid >= 1);
- gpr_mu_lock(&mu_);
+ mu_guard guard(&mu_);
GPR_ASSERT(static_cast<size_t>(uuid) <= entities_.size());
- entities_[uuid - 1] = nullptr;
- gpr_mu_unlock(&mu_);
+ GPR_ASSERT(entities_[uuid - 1].type == type);
+ entities_[uuid - 1].object = nullptr;
+ entities_[uuid - 1].type = EntityType::kUnset;
+}
+
+void* ChannelzRegistry::InternalGetEntry(intptr_t uuid, EntityType type) {
+ mu_guard guard(&mu_);
+ if (uuid < 1 || uuid > static_cast<intptr_t>(entities_.size())) {
+ return nullptr;
+ }
+ if (entities_[uuid - 1].type == type) {
+ return entities_[uuid - 1].object;
+ } else {
+ return nullptr;
+ }
+}
+
+char* ChannelzRegistry::InternalGetTopChannels(intptr_t start_channel_id) {
+ grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT);
+ grpc_json* json = top_level_json;
+ grpc_json* json_iterator = nullptr;
+ InlinedVector<ChannelNode*, 10> top_level_channels;
+ // uuids index into entities one-off (idx 0 is really uuid 1, since 0 is
+ // reserved). However, we want to support requests coming in with
+ // start_channel_id=0, which signifies "give me everything." Hence this
+ // funky looking line below.
+ size_t start_idx = start_channel_id == 0 ? 0 : start_channel_id - 1;
+ for (size_t i = start_idx; i < entities_.size(); ++i) {
+ if (entities_[i].type == EntityType::kChannelNode) {
+ ChannelNode* channel_node =
+ static_cast<ChannelNode*>(entities_[i].object);
+ if (channel_node->is_top_level_channel()) {
+ top_level_channels.push_back(channel_node);
+ }
+ }
+ }
+ if (top_level_channels.size() > 0) {
+ // create list of channels
+ grpc_json* array_parent = grpc_json_create_child(
+ nullptr, json, "channel", nullptr, GRPC_JSON_ARRAY, false);
+ for (size_t i = 0; i < top_level_channels.size(); ++i) {
+ grpc_json* channel_json = top_level_channels[i]->RenderJson();
+ json_iterator =
+ grpc_json_link_child(array_parent, channel_json, json_iterator);
+ }
+ }
+ // For now we do not have any pagination rules. In the future we could
+ // pick a constant for max_channels_sent for a GetTopChannels request.
+ // Tracking: https://github.com/grpc/grpc/issues/16019.
+ json_iterator = grpc_json_create_child(nullptr, json, "end", nullptr,
+ GRPC_JSON_TRUE, false);
+ char* json_str = grpc_json_dump_to_string(top_level_json, 0);
+ grpc_json_destroy(top_level_json);
+ return json_str;
}
+} // namespace channelz
} // namespace grpc_core
+
+char* grpc_channelz_get_top_channels(intptr_t start_channel_id) {
+ return grpc_core::channelz::ChannelzRegistry::GetTopChannels(
+ start_channel_id);
+}
+
+char* grpc_channelz_get_channel(intptr_t channel_id) {
+ grpc_core::channelz::ChannelNode* channel_node =
+ grpc_core::channelz::ChannelzRegistry::GetChannelNode(channel_id);
+ if (channel_node == nullptr) {
+ return nullptr;
+ }
+ grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT);
+ grpc_json* json = top_level_json;
+ grpc_json* channel_json = channel_node->RenderJson();
+ channel_json->key = "channel";
+ grpc_json_link_child(json, channel_json, nullptr);
+ char* json_str = grpc_json_dump_to_string(top_level_json, 0);
+ grpc_json_destroy(top_level_json);
+ return json_str;
+}
diff --git a/src/core/lib/channel/channelz_registry.h b/src/core/lib/channel/channelz_registry.h
index a5a187a054..5d7c936726 100644
--- a/src/core/lib/channel/channelz_registry.h
+++ b/src/core/lib/channel/channelz_registry.h
@@ -22,11 +22,13 @@
#include <grpc/impl/codegen/port_platform.h>
#include "src/core/lib/channel/channel_trace.h"
+#include "src/core/lib/channel/channelz.h"
#include "src/core/lib/gprpp/inlined_vector.h"
#include <stdint.h>
namespace grpc_core {
+namespace channelz {
// singleton registry object to track all objects that are needed to support
// channelz bookkeeping. All objects share globally distributed uuids.
@@ -35,26 +37,56 @@ class ChannelzRegistry {
// To be called in grpc_init()
static void Init();
- // To be callen in grpc_shutdown();
+ // To be called in grpc_shutdown();
static void Shutdown();
- // globally registers a channelz Object. Returns its unique uuid
- template <typename Object>
- static intptr_t Register(Object* object) {
- return Default()->InternalRegister(object);
+ // Register/Unregister/Get for ChannelNode
+ static intptr_t RegisterChannelNode(ChannelNode* channel_node) {
+ RegistryEntry entry(channel_node, EntityType::kChannelNode);
+ return Default()->InternalRegisterEntry(entry);
+ }
+ static void UnregisterChannelNode(intptr_t uuid) {
+ Default()->InternalUnregisterEntry(uuid, EntityType::kChannelNode);
+ }
+ static ChannelNode* GetChannelNode(intptr_t uuid) {
+ void* gotten = Default()->InternalGetEntry(uuid, EntityType::kChannelNode);
+ return gotten == nullptr ? nullptr : static_cast<ChannelNode*>(gotten);
}
- // globally unregisters the object that is associated to uuid.
- static void Unregister(intptr_t uuid) { Default()->InternalUnregister(uuid); }
+ // Register/Unregister/Get for SubchannelNode
+ static intptr_t RegisterSubchannelNode(SubchannelNode* channel_node) {
+ RegistryEntry entry(channel_node, EntityType::kSubchannelNode);
+ return Default()->InternalRegisterEntry(entry);
+ }
+ static void UnregisterSubchannelNode(intptr_t uuid) {
+ Default()->InternalUnregisterEntry(uuid, EntityType::kSubchannelNode);
+ }
+ static SubchannelNode* GetSubchannelNode(intptr_t uuid) {
+ void* gotten =
+ Default()->InternalGetEntry(uuid, EntityType::kSubchannelNode);
+ return gotten == nullptr ? nullptr : static_cast<SubchannelNode*>(gotten);
+ }
- // if object with uuid has previously been registered, returns the
- // Object associated with that uuid. Else returns nullptr.
- template <typename Object>
- static Object* Get(intptr_t uuid) {
- return Default()->InternalGet<Object>(uuid);
+ // Returns the allocated JSON string that represents the proto
+ // GetTopChannelsResponse as per channelz.proto.
+ static char* GetTopChannels(intptr_t start_channel_id) {
+ return Default()->InternalGetTopChannels(start_channel_id);
}
private:
+ enum class EntityType {
+ kChannelNode,
+ kSubchannelNode,
+ kUnset,
+ };
+
+ struct RegistryEntry {
+ RegistryEntry(void* object_in, EntityType type_in)
+ : object(object_in), type(type_in) {}
+ void* object;
+ EntityType type;
+ };
+
GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW
GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
@@ -64,40 +96,25 @@ class ChannelzRegistry {
// Returned the singleton instance of ChannelzRegistry;
static ChannelzRegistry* Default();
- // globally registers a channelz Object. Returns its unique uuid
- template <typename Object>
- intptr_t InternalRegister(Object* object) {
- gpr_mu_lock(&mu_);
- entities_.push_back(static_cast<void*>(object));
- intptr_t uuid = entities_.size();
- gpr_mu_unlock(&mu_);
- return uuid;
- }
+ // globally registers an Entry. Returns its unique uuid
+ intptr_t InternalRegisterEntry(const RegistryEntry& entry);
- // globally unregisters the object that is associated to uuid.
- void InternalUnregister(intptr_t uuid);
-
- // if object with uuid has previously been registered, returns the
- // Object associated with that uuid. Else returns nullptr.
- template <typename Object>
- Object* InternalGet(intptr_t uuid) {
- gpr_mu_lock(&mu_);
- if (uuid < 1 || uuid > static_cast<intptr_t>(entities_.size())) {
- gpr_mu_unlock(&mu_);
- return nullptr;
- }
- Object* ret = static_cast<Object*>(entities_[uuid - 1]);
- gpr_mu_unlock(&mu_);
- return ret;
- }
+ // globally unregisters the object that is associated to uuid. Also does
+ // sanity check that an object doesn't try to unregister the wrong type.
+ void InternalUnregisterEntry(intptr_t uuid, EntityType type);
+
+ // if object with uuid has previously been registered as the correct type,
+ // returns the void* associated with that uuid. Else returns nullptr.
+ void* InternalGetEntry(intptr_t uuid, EntityType type);
- // private members
+ char* InternalGetTopChannels(intptr_t start_channel_id);
// protects entities_ and uuid_
gpr_mu mu_;
- InlinedVector<void*, 20> entities_;
+ InlinedVector<RegistryEntry, 20> entities_;
};
+} // namespace channelz
} // namespace grpc_core
#endif /* GRPC_CORE_LIB_CHANNEL_CHANNELZ_REGISTRY_H */
diff --git a/src/core/lib/gpr/arena.cc b/src/core/lib/gpr/arena.cc
index 141de69426..e30b297aea 100644
--- a/src/core/lib/gpr/arena.cc
+++ b/src/core/lib/gpr/arena.cc
@@ -25,6 +25,7 @@
#include <grpc/support/alloc.h>
#include <grpc/support/atm.h>
#include <grpc/support/log.h>
+#include <grpc/support/sync.h>
#include "src/core/lib/gpr/alloc.h"
@@ -36,8 +37,6 @@
#ifdef SIMPLE_ARENA_FOR_DEBUGGING
-#include <grpc/support/sync.h>
-
struct gpr_arena {
gpr_mu mu;
void** ptrs;
@@ -78,14 +77,17 @@ void* gpr_arena_alloc(gpr_arena* arena, size_t size) {
// would allow us to use the alignment actually needed by the caller.
typedef struct zone {
- size_t size_begin;
- size_t size_end;
- gpr_atm next_atm;
+ size_t size_begin; // All the space we have set aside for allocations up
+ // until this zone.
+ size_t size_end; // size_end = size_begin plus all the space we set aside for
+ // allocations in zone z itself.
+ zone* next;
} zone;
struct gpr_arena {
gpr_atm size_so_far;
zone initial_zone;
+ gpr_mu arena_growth_mutex;
};
static void* zalloc_aligned(size_t size) {
@@ -99,15 +101,17 @@ gpr_arena* gpr_arena_create(size_t initial_size) {
gpr_arena* a = static_cast<gpr_arena*>(zalloc_aligned(
GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(gpr_arena)) + initial_size));
a->initial_zone.size_end = initial_size;
+ gpr_mu_init(&a->arena_growth_mutex);
return a;
}
size_t gpr_arena_destroy(gpr_arena* arena) {
+ gpr_mu_destroy(&arena->arena_growth_mutex);
gpr_atm size = gpr_atm_no_barrier_load(&arena->size_so_far);
- zone* z = (zone*)gpr_atm_no_barrier_load(&arena->initial_zone.next_atm);
+ zone* z = arena->initial_zone.next;
gpr_free_aligned(arena);
while (z) {
- zone* next_z = (zone*)gpr_atm_no_barrier_load(&z->next_atm);
+ zone* next_z = z->next;
gpr_free_aligned(z);
z = next_z;
}
@@ -116,37 +120,55 @@ size_t gpr_arena_destroy(gpr_arena* arena) {
void* gpr_arena_alloc(gpr_arena* arena, size_t size) {
size = GPR_ROUND_UP_TO_ALIGNMENT_SIZE(size);
- size_t start = static_cast<size_t>(
+ size_t previous_size_of_arena_allocations = static_cast<size_t>(
gpr_atm_no_barrier_fetch_add(&arena->size_so_far, size));
+ size_t updated_size_of_arena_allocations =
+ previous_size_of_arena_allocations + size;
zone* z = &arena->initial_zone;
- while (start > z->size_end) {
- zone* next_z = (zone*)gpr_atm_acq_load(&z->next_atm);
- if (next_z == nullptr) {
- size_t next_z_size =
- static_cast<size_t>(gpr_atm_no_barrier_load(&arena->size_so_far));
- next_z = static_cast<zone*>(zalloc_aligned(
- GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(zone)) + next_z_size));
- next_z->size_begin = z->size_end;
- next_z->size_end = z->size_end + next_z_size;
- if (!gpr_atm_rel_cas(&z->next_atm, static_cast<gpr_atm>(NULL),
- (gpr_atm)next_z)) {
- gpr_free_aligned(next_z);
- next_z = (zone*)gpr_atm_acq_load(&z->next_atm);
+ // Check to see if the allocation isn't able to end in the initial zone.
+ // This statement is true only in the uncommon case because of our arena
+ // sizing historesis (that is, most calls should have a large enough initial
+ // zone and will not need to grow the arena).
+ if (updated_size_of_arena_allocations > z->size_end) {
+ // Find a zone to fit this allocation
+ gpr_mu_lock(&arena->arena_growth_mutex);
+ while (updated_size_of_arena_allocations > z->size_end) {
+ if (z->next == nullptr) {
+ // Note that we do an extra increment of size_so_far to prevent multiple
+ // simultaneous callers from stepping on each other. However, this extra
+ // increment means some space in the arena is wasted.
+ // So whenever we need to allocate x bytes and there are x - n (where
+ // n > 0) remaining in the current zone, we will waste x bytes (x - n
+ // in the current zone and n in the new zone).
+ previous_size_of_arena_allocations = static_cast<size_t>(
+ gpr_atm_no_barrier_fetch_add(&arena->size_so_far, size));
+ updated_size_of_arena_allocations =
+ previous_size_of_arena_allocations + size;
+ size_t next_z_size = updated_size_of_arena_allocations;
+ z->next = static_cast<zone*>(zalloc_aligned(
+ GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(zone)) + next_z_size));
+ z->next->size_begin = z->size_end;
+ z->next->size_end = z->size_end + next_z_size;
}
+ z = z->next;
}
- z = next_z;
- }
- if (start + size > z->size_end) {
- return gpr_arena_alloc(arena, size);
+ gpr_mu_unlock(&arena->arena_growth_mutex);
}
- GPR_ASSERT(start >= z->size_begin);
- GPR_ASSERT(start + size <= z->size_end);
- char* ptr = (z == &arena->initial_zone)
- ? reinterpret_cast<char*>(arena) +
- GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(gpr_arena))
- : reinterpret_cast<char*>(z) +
- GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(zone));
- return ptr + start - z->size_begin;
+ GPR_ASSERT(previous_size_of_arena_allocations >= z->size_begin);
+ GPR_ASSERT(updated_size_of_arena_allocations <= z->size_end);
+ // Skip the first part of the zone, which just contains tracking information.
+ // For the initial zone, this is the gpr_arena struct and for any other zone,
+ // it's the zone struct.
+ char* start_of_allocation_space =
+ (z == &arena->initial_zone)
+ ? reinterpret_cast<char*>(arena) +
+ GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(gpr_arena))
+ : reinterpret_cast<char*>(z) +
+ GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(zone));
+ // previous_size_of_arena_allocations - size_begin is how many bytes have been
+ // allocated into the current zone
+ return start_of_allocation_space + previous_size_of_arena_allocations -
+ z->size_begin;
}
#endif // SIMPLE_ARENA_FOR_DEBUGGING
diff --git a/src/core/lib/gprpp/orphanable.h b/src/core/lib/gprpp/orphanable.h
index d0ec9b6461..3123e3f5a3 100644
--- a/src/core/lib/gprpp/orphanable.h
+++ b/src/core/lib/gprpp/orphanable.h
@@ -86,7 +86,8 @@ class InternallyRefCounted : public Orphanable {
GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
// Allow RefCountedPtr<> to access Unref() and IncrementRefCount().
- friend class RefCountedPtr<Child>;
+ template <typename T>
+ friend class RefCountedPtr;
InternallyRefCounted() { gpr_ref_init(&refs_, 1); }
virtual ~InternallyRefCounted() {}
@@ -129,7 +130,8 @@ class InternallyRefCountedWithTracing : public Orphanable {
GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
// Allow RefCountedPtr<> to access Unref() and IncrementRefCount().
- friend class RefCountedPtr<Child>;
+ template <typename T>
+ friend class RefCountedPtr;
InternallyRefCountedWithTracing()
: InternallyRefCountedWithTracing(static_cast<TraceFlag*>(nullptr)) {}
diff --git a/src/core/lib/gprpp/ref_counted.h b/src/core/lib/gprpp/ref_counted.h
index ddac5bd475..03c293f6ed 100644
--- a/src/core/lib/gprpp/ref_counted.h
+++ b/src/core/lib/gprpp/ref_counted.h
@@ -73,7 +73,8 @@ class RefCounted {
private:
// Allow RefCountedPtr<> to access IncrementRefCount().
- friend class RefCountedPtr<Child>;
+ template <typename T>
+ friend class RefCountedPtr;
void IncrementRefCount() { gpr_ref(&refs_); }
@@ -152,7 +153,8 @@ class RefCountedWithTracing {
private:
// Allow RefCountedPtr<> to access IncrementRefCount().
- friend class RefCountedPtr<Child>;
+ template <typename T>
+ friend class RefCountedPtr;
void IncrementRefCount() { gpr_ref(&refs_); }
diff --git a/src/core/lib/gprpp/ref_counted_ptr.h b/src/core/lib/gprpp/ref_counted_ptr.h
index 534d3d03cb..c2dfbdd90f 100644
--- a/src/core/lib/gprpp/ref_counted_ptr.h
+++ b/src/core/lib/gprpp/ref_counted_ptr.h
@@ -36,25 +36,49 @@ class RefCountedPtr {
RefCountedPtr(std::nullptr_t) {}
// If value is non-null, we take ownership of a ref to it.
- explicit RefCountedPtr(T* value) { value_ = value; }
+ template <typename Y>
+ explicit RefCountedPtr(Y* value) {
+ value_ = value;
+ }
- // Move support.
+ // Move ctors.
RefCountedPtr(RefCountedPtr&& other) {
value_ = other.value_;
other.value_ = nullptr;
}
+ template <typename Y>
+ RefCountedPtr(RefCountedPtr<Y>&& other) {
+ value_ = other.value_;
+ other.value_ = nullptr;
+ }
+
+ // Move assignment.
RefCountedPtr& operator=(RefCountedPtr&& other) {
if (value_ != nullptr) value_->Unref();
value_ = other.value_;
other.value_ = nullptr;
return *this;
}
+ template <typename Y>
+ RefCountedPtr& operator=(RefCountedPtr<Y>&& other) {
+ if (value_ != nullptr) value_->Unref();
+ value_ = other.value_;
+ other.value_ = nullptr;
+ return *this;
+ }
- // Copy support.
+ // Copy ctors.
RefCountedPtr(const RefCountedPtr& other) {
if (other.value_ != nullptr) other.value_->IncrementRefCount();
value_ = other.value_;
}
+ template <typename Y>
+ RefCountedPtr(const RefCountedPtr<Y>& other) {
+ if (other.value_ != nullptr) other.value_->IncrementRefCount();
+ value_ = other.value_;
+ }
+
+ // Copy assignment.
RefCountedPtr& operator=(const RefCountedPtr& other) {
// Note: Order of reffing and unreffing is important here in case value_
// and other.value_ are the same object.
@@ -63,17 +87,32 @@ class RefCountedPtr {
value_ = other.value_;
return *this;
}
+ template <typename Y>
+ RefCountedPtr& operator=(const RefCountedPtr<Y>& other) {
+ // 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();
+ if (value_ != nullptr) value_->Unref();
+ value_ = other.value_;
+ return *this;
+ }
~RefCountedPtr() {
if (value_ != nullptr) value_->Unref();
}
// If value is non-null, we take ownership of a ref to it.
- void reset(T* value = nullptr) {
+ template <typename Y>
+ void reset(Y* value) {
if (value_ != nullptr) value_->Unref();
value_ = value;
}
+ void reset() {
+ if (value_ != nullptr) value_->Unref();
+ value_ = nullptr;
+ }
+
// TODO(roth): This method exists solely as a transition mechanism to allow
// us to pass a ref to idiomatic C code that does not use RefCountedPtr<>.
// Once all of our code has been converted to idiomatic C++, this
@@ -89,16 +128,34 @@ class RefCountedPtr {
T& operator*() const { return *value_; }
T* operator->() const { return value_; }
- bool operator==(const RefCountedPtr& other) const {
+ template <typename Y>
+ bool operator==(const RefCountedPtr<Y>& other) const {
return value_ == other.value_;
}
- bool operator==(const T* other) const { return value_ == other; }
- bool operator!=(const RefCountedPtr& other) const {
+
+ template <typename Y>
+ bool operator==(const Y* other) const {
+ return value_ == other;
+ }
+
+ bool operator==(std::nullptr_t) const { return value_ == nullptr; }
+
+ template <typename Y>
+ bool operator!=(const RefCountedPtr<Y>& other) const {
return value_ != other.value_;
}
- bool operator!=(const T* other) const { return value_ != other; }
+
+ template <typename Y>
+ bool operator!=(const Y* other) const {
+ return value_ != other;
+ }
+
+ bool operator!=(std::nullptr_t) const { return value_ != nullptr; }
private:
+ template <typename Y>
+ friend class RefCountedPtr;
+
T* value_ = nullptr;
};
@@ -107,11 +164,6 @@ inline RefCountedPtr<T> MakeRefCounted(Args&&... args) {
return RefCountedPtr<T>(New<T>(std::forward<Args>(args)...));
}
-template <typename Parent, typename Child, typename... Args>
-inline RefCountedPtr<Parent> MakePolymorphicRefCounted(Args&&... args) {
- return RefCountedPtr<Parent>(New<Child>(std::forward<Args>(args)...));
-}
-
} // namespace grpc_core
#endif /* GRPC_CORE_LIB_GPRPP_REF_COUNTED_PTR_H */
diff --git a/src/core/lib/iomgr/ev_epoll1_linux.cc b/src/core/lib/iomgr/ev_epoll1_linux.cc
index 86a0243d2e..66e0f1fd6d 100644
--- a/src/core/lib/iomgr/ev_epoll1_linux.cc
+++ b/src/core/lib/iomgr/ev_epoll1_linux.cc
@@ -140,10 +140,6 @@ struct grpc_fd {
struct grpc_fd* freelist_next;
- /* The pollset that last noticed that the fd is readable. The actual type
- * stored in this is (grpc_pollset *) */
- gpr_atm read_notifier_pollset;
-
grpc_iomgr_object iomgr_object;
};
@@ -293,7 +289,6 @@ static grpc_fd* fd_create(int fd, const char* name, bool track_err) {
new_fd->read_closure->InitEvent();
new_fd->write_closure->InitEvent();
new_fd->error_closure->InitEvent();
- gpr_atm_no_barrier_store(&new_fd->read_notifier_pollset, (gpr_atm)NULL);
new_fd->freelist_next = nullptr;
@@ -376,11 +371,6 @@ static void fd_orphan(grpc_fd* fd, grpc_closure* on_done, int* release_fd,
gpr_mu_unlock(&fd_freelist_mu);
}
-static grpc_pollset* fd_get_read_notifier_pollset(grpc_fd* fd) {
- gpr_atm notifier = gpr_atm_acq_load(&fd->read_notifier_pollset);
- return (grpc_pollset*)notifier;
-}
-
static bool fd_is_shutdown(grpc_fd* fd) {
return fd->read_closure->IsShutdown();
}
@@ -397,11 +387,7 @@ static void fd_notify_on_error(grpc_fd* fd, grpc_closure* closure) {
fd->error_closure->NotifyOn(closure);
}
-static void fd_become_readable(grpc_fd* fd, grpc_pollset* notifier) {
- fd->read_closure->SetReady();
- /* Use release store to match with acquire load in fd_get_read_notifier */
- gpr_atm_rel_store(&fd->read_notifier_pollset, (gpr_atm)notifier);
-}
+static void fd_become_readable(grpc_fd* fd) { fd->read_closure->SetReady(); }
static void fd_become_writable(grpc_fd* fd) { fd->write_closure->SetReady(); }
@@ -642,7 +628,7 @@ static grpc_error* process_epoll_events(grpc_pollset* pollset) {
}
if (read_ev || cancel || err_fallback) {
- fd_become_readable(fd, pollset);
+ fd_become_readable(fd);
}
if (write_ev || cancel || err_fallback) {
@@ -1217,8 +1203,10 @@ static const grpc_event_engine_vtable vtable = {
fd_notify_on_read,
fd_notify_on_write,
fd_notify_on_error,
+ fd_become_readable,
+ fd_become_writable,
+ fd_has_errors,
fd_is_shutdown,
- fd_get_read_notifier_pollset,
pollset_init,
pollset_shutdown,
diff --git a/src/core/lib/iomgr/ev_epollex_linux.cc b/src/core/lib/iomgr/ev_epollex_linux.cc
index 7b368410cf..96eae30345 100644
--- a/src/core/lib/iomgr/ev_epollex_linux.cc
+++ b/src/core/lib/iomgr/ev_epollex_linux.cc
@@ -135,7 +135,7 @@ struct pollable {
// underlying epoll set (i.e whenever fd_orphan() is called).
//
// Implementing (2) above (i.e removing fds from cache on fd_orphan) adds a
- // lot of complexity since an fd can be present in multiple pollalbles. So our
+ // lot of complexity since an fd can be present in multiple pollables. So our
// implementation ONLY DOES (1) and NOT (2).
//
// The cache_fd.salt variable helps here to maintain correctness (it serves as
@@ -220,10 +220,6 @@ struct grpc_fd {
struct grpc_fd* freelist_next;
grpc_closure* on_done_closure;
- // The pollset that last noticed that the fd is readable. The actual type
- // stored in this is (grpc_pollset *)
- gpr_atm read_notifier_pollset;
-
grpc_iomgr_object iomgr_object;
// Do we need to track EPOLLERR events separately?
@@ -353,7 +349,6 @@ static void invalidate_fd(grpc_fd* fd) {
memset(&fd->pollable_mu, -1, sizeof(fd->pollable_mu));
fd->pollable_obj = nullptr;
fd->on_done_closure = nullptr;
- gpr_atm_no_barrier_store(&fd->read_notifier_pollset, 0);
memset(&fd->iomgr_object, -1, sizeof(fd->iomgr_object));
fd->track_err = false;
}
@@ -445,7 +440,6 @@ static grpc_fd* fd_create(int fd, const char* name, bool track_err) {
new_fd->error_closure->InitEvent();
new_fd->freelist_next = nullptr;
new_fd->on_done_closure = nullptr;
- gpr_atm_no_barrier_store(&new_fd->read_notifier_pollset, (gpr_atm)NULL);
char* fd_name;
gpr_asprintf(&fd_name, "%s fd=%d", name, fd);
@@ -514,11 +508,6 @@ static void fd_orphan(grpc_fd* fd, grpc_closure* on_done, int* release_fd,
UNREF_BY(fd, 2, reason); /* Drop the reference */
}
-static grpc_pollset* fd_get_read_notifier_pollset(grpc_fd* fd) {
- gpr_atm notifier = gpr_atm_acq_load(&fd->read_notifier_pollset);
- return (grpc_pollset*)notifier;
-}
-
static bool fd_is_shutdown(grpc_fd* fd) {
return fd->read_closure->IsShutdown();
}
@@ -875,17 +864,7 @@ static int poll_deadline_to_millis_timeout(grpc_millis millis) {
return static_cast<int>(delta);
}
-static void fd_become_readable(grpc_fd* fd, grpc_pollset* notifier) {
- fd->read_closure->SetReady();
-
- /* Note, it is possible that fd_become_readable might be called twice with
- different 'notifier's when an fd becomes readable and it is in two epoll
- sets (This can happen briefly during polling island merges). In such cases
- it does not really matter which notifer is set as the read_notifier_pollset
- (They would both point to the same polling island anyway) */
- /* Use release store to match with acquire load in fd_get_read_notifier */
- gpr_atm_rel_store(&fd->read_notifier_pollset, (gpr_atm)notifier);
-}
+static void fd_become_readable(grpc_fd* fd) { fd->read_closure->SetReady(); }
static void fd_become_writable(grpc_fd* fd) { fd->write_closure->SetReady(); }
@@ -983,7 +962,7 @@ static grpc_error* pollable_process_events(grpc_pollset* pollset,
fd_has_errors(fd);
}
if (read_ev || cancel || err_fallback) {
- fd_become_readable(fd, pollset);
+ fd_become_readable(fd);
}
if (write_ev || cancel || err_fallback) {
fd_become_writable(fd);
@@ -1636,8 +1615,10 @@ static const grpc_event_engine_vtable vtable = {
fd_notify_on_read,
fd_notify_on_write,
fd_notify_on_error,
+ fd_become_readable,
+ fd_become_writable,
+ fd_has_errors,
fd_is_shutdown,
- fd_get_read_notifier_pollset,
pollset_init,
pollset_shutdown,
diff --git a/src/core/lib/iomgr/ev_epollsig_linux.cc b/src/core/lib/iomgr/ev_epollsig_linux.cc
index 2189801c18..5695ac795d 100644
--- a/src/core/lib/iomgr/ev_epollsig_linux.cc
+++ b/src/core/lib/iomgr/ev_epollsig_linux.cc
@@ -137,10 +137,6 @@ struct grpc_fd {
struct grpc_fd* freelist_next;
grpc_closure* on_done_closure;
- /* The pollset that last noticed that the fd is readable. The actual type
- * stored in this is (grpc_pollset *) */
- gpr_atm read_notifier_pollset;
-
grpc_iomgr_object iomgr_object;
/* Do we need to track EPOLLERR events separately? */
@@ -845,7 +841,6 @@ static grpc_fd* fd_create(int fd, const char* name, bool track_err) {
new_fd->write_closure->InitEvent();
new_fd->error_closure->InitEvent();
new_fd->track_err = track_err;
- gpr_atm_no_barrier_store(&new_fd->read_notifier_pollset, (gpr_atm)NULL);
new_fd->freelist_next = nullptr;
new_fd->on_done_closure = nullptr;
@@ -927,11 +922,6 @@ static void fd_orphan(grpc_fd* fd, grpc_closure* on_done, int* release_fd,
GRPC_ERROR_UNREF(error);
}
-static grpc_pollset* fd_get_read_notifier_pollset(grpc_fd* fd) {
- gpr_atm notifier = gpr_atm_acq_load(&fd->read_notifier_pollset);
- return (grpc_pollset*)notifier;
-}
-
static bool fd_is_shutdown(grpc_fd* fd) {
return fd->read_closure->IsShutdown();
}
@@ -958,6 +948,12 @@ static void fd_notify_on_error(grpc_fd* fd, grpc_closure* closure) {
fd->error_closure->NotifyOn(closure);
}
+static void fd_become_readable(grpc_fd* fd) { fd->read_closure->SetReady(); }
+
+static void fd_become_writable(grpc_fd* fd) { fd->write_closure->SetReady(); }
+
+static void fd_has_errors(grpc_fd* fd) { fd->error_closure->SetReady(); }
+
/*******************************************************************************
* Pollset Definitions
*/
@@ -1115,22 +1111,6 @@ static int poll_deadline_to_millis_timeout(grpc_millis millis) {
return static_cast<int>(delta);
}
-static void fd_become_readable(grpc_fd* fd, grpc_pollset* notifier) {
- fd->read_closure->SetReady();
-
- /* Note, it is possible that fd_become_readable might be called twice with
- different 'notifier's when an fd becomes readable and it is in two epoll
- sets (This can happen briefly during polling island merges). In such cases
- it does not really matter which notifer is set as the read_notifier_pollset
- (They would both point to the same polling island anyway) */
- /* Use release store to match with acquire load in fd_get_read_notifier */
- gpr_atm_rel_store(&fd->read_notifier_pollset, (gpr_atm)notifier);
-}
-
-static void fd_become_writable(grpc_fd* fd) { fd->write_closure->SetReady(); }
-
-static void fd_has_errors(grpc_fd* fd) { fd->error_closure->SetReady(); }
-
static void pollset_release_polling_island(grpc_pollset* ps,
const char* reason) {
if (ps->po.pi != nullptr) {
@@ -1283,7 +1263,7 @@ static void pollset_work_and_unlock(grpc_pollset* pollset,
fd_has_errors(fd);
}
if (read_ev || cancel || err_fallback) {
- fd_become_readable(fd, pollset);
+ fd_become_readable(fd);
}
if (write_ev || cancel || err_fallback) {
fd_become_writable(fd);
@@ -1667,8 +1647,10 @@ static const grpc_event_engine_vtable vtable = {
fd_notify_on_read,
fd_notify_on_write,
fd_notify_on_error,
+ fd_become_readable,
+ fd_become_writable,
+ fd_has_errors,
fd_is_shutdown,
- fd_get_read_notifier_pollset,
pollset_init,
pollset_shutdown,
diff --git a/src/core/lib/iomgr/ev_poll_posix.cc b/src/core/lib/iomgr/ev_poll_posix.cc
index c9c09881a2..fb4c71ef71 100644
--- a/src/core/lib/iomgr/ev_poll_posix.cc
+++ b/src/core/lib/iomgr/ev_poll_posix.cc
@@ -108,9 +108,6 @@ struct grpc_fd {
grpc_closure* on_done_closure;
grpc_iomgr_object iomgr_object;
-
- /* The pollset that last noticed and notified that the fd is readable */
- grpc_pollset* read_notifier_pollset;
};
/* Begin polling on an fd.
@@ -131,8 +128,7 @@ static uint32_t fd_begin_poll(grpc_fd* fd, grpc_pollset* pollset,
MUST NOT be called with a pollset lock taken
if got_read or got_write are 1, also does the become_{readable,writable} as
appropriate. */
-static void fd_end_poll(grpc_fd_watcher* rec, int got_read, int got_write,
- grpc_pollset* read_notifier_pollset);
+static void fd_end_poll(grpc_fd_watcher* rec, int got_read, int got_write);
/* Return 1 if this fd is orphaned, 0 otherwise */
static bool fd_is_orphaned(grpc_fd* fd);
@@ -346,7 +342,6 @@ static grpc_fd* fd_create(int fd, const char* name, bool track_err) {
r->closed = 0;
r->released = 0;
gpr_atm_no_barrier_store(&r->pollhup, 0);
- r->read_notifier_pollset = nullptr;
char* name2;
gpr_asprintf(&name2, "%s fd=%d", name, fd);
@@ -359,17 +354,6 @@ static bool fd_is_orphaned(grpc_fd* fd) {
return (gpr_atm_acq_load(&fd->refst) & 1) == 0;
}
-/* Return the read-notifier pollset */
-static grpc_pollset* fd_get_read_notifier_pollset(grpc_fd* fd) {
- grpc_pollset* notifier = nullptr;
-
- gpr_mu_lock(&fd->mu);
- notifier = fd->read_notifier_pollset;
- gpr_mu_unlock(&fd->mu);
-
- return notifier;
-}
-
static grpc_error* pollset_kick_locked(grpc_fd_watcher* watcher) {
gpr_mu_lock(&watcher->pollset->mu);
GPR_ASSERT(watcher->worker);
@@ -512,11 +496,6 @@ static int set_ready_locked(grpc_fd* fd, grpc_closure** st) {
}
}
-static void set_read_notifier_pollset_locked(
- grpc_fd* fd, grpc_pollset* read_notifier_pollset) {
- fd->read_notifier_pollset = read_notifier_pollset;
-}
-
static void fd_shutdown(grpc_fd* fd, grpc_error* why) {
gpr_mu_lock(&fd->mu);
/* only shutdown once */
@@ -553,8 +532,28 @@ static void fd_notify_on_write(grpc_fd* fd, grpc_closure* closure) {
}
static void fd_notify_on_error(grpc_fd* fd, grpc_closure* closure) {
- gpr_log(GPR_ERROR, "Polling engine does not support tracking errors.");
- abort();
+ if (grpc_polling_trace.enabled()) {
+ gpr_log(GPR_ERROR, "Polling engine does not support tracking errors.");
+ }
+ GRPC_CLOSURE_SCHED(closure, GRPC_ERROR_CANCELLED);
+}
+
+static void fd_set_readable(grpc_fd* fd) {
+ gpr_mu_lock(&fd->mu);
+ set_ready_locked(fd, &fd->read_closure);
+ gpr_mu_unlock(&fd->mu);
+}
+
+static void fd_set_writable(grpc_fd* fd) {
+ gpr_mu_lock(&fd->mu);
+ set_ready_locked(fd, &fd->write_closure);
+ gpr_mu_unlock(&fd->mu);
+}
+
+static void fd_set_error(grpc_fd* fd) {
+ if (grpc_polling_trace.enabled()) {
+ gpr_log(GPR_ERROR, "Polling engine does not support tracking errors.");
+ }
}
static uint32_t fd_begin_poll(grpc_fd* fd, grpc_pollset* pollset,
@@ -608,8 +607,7 @@ static uint32_t fd_begin_poll(grpc_fd* fd, grpc_pollset* pollset,
return mask;
}
-static void fd_end_poll(grpc_fd_watcher* watcher, int got_read, int got_write,
- grpc_pollset* read_notifier_pollset) {
+static void fd_end_poll(grpc_fd_watcher* watcher, int got_read, int got_write) {
int was_polling = 0;
int kick = 0;
grpc_fd* fd = watcher->fd;
@@ -645,9 +643,6 @@ static void fd_end_poll(grpc_fd_watcher* watcher, int got_read, int got_write,
if (set_ready_locked(fd, &fd->read_closure)) {
kick = 1;
}
- if (read_notifier_pollset != nullptr) {
- set_read_notifier_pollset_locked(fd, read_notifier_pollset);
- }
}
if (got_write) {
if (set_ready_locked(fd, &fd->write_closure)) {
@@ -997,16 +992,16 @@ static grpc_error* pollset_work(grpc_pollset* pollset,
for (i = 1; i < pfd_count; i++) {
if (watchers[i].fd == nullptr) {
- fd_end_poll(&watchers[i], 0, 0, nullptr);
+ fd_end_poll(&watchers[i], 0, 0);
} else {
// Wake up all the file descriptors, if we have an invalid one
// we can identify it on the next pollset_work()
- fd_end_poll(&watchers[i], 1, 1, pollset);
+ fd_end_poll(&watchers[i], 1, 1);
}
}
} else if (r == 0) {
for (i = 1; i < pfd_count; i++) {
- fd_end_poll(&watchers[i], 0, 0, nullptr);
+ fd_end_poll(&watchers[i], 0, 0);
}
} else {
if (pfds[0].revents & POLLIN_CHECK) {
@@ -1018,7 +1013,7 @@ static grpc_error* pollset_work(grpc_pollset* pollset,
}
for (i = 1; i < pfd_count; i++) {
if (watchers[i].fd == nullptr) {
- fd_end_poll(&watchers[i], 0, 0, nullptr);
+ fd_end_poll(&watchers[i], 0, 0);
} else {
if (grpc_polling_trace.enabled()) {
gpr_log(GPR_INFO, "%p got_event: %d r:%d w:%d [%d]", pollset,
@@ -1032,7 +1027,7 @@ static grpc_error* pollset_work(grpc_pollset* pollset,
gpr_atm_no_barrier_store(&watchers[i].fd->pollhup, 1);
}
fd_end_poll(&watchers[i], pfds[i].revents & POLLIN_CHECK,
- pfds[i].revents & POLLOUT_CHECK, pollset);
+ pfds[i].revents & POLLOUT_CHECK);
}
}
}
@@ -1723,8 +1718,10 @@ static const grpc_event_engine_vtable vtable = {
fd_notify_on_read,
fd_notify_on_write,
fd_notify_on_error,
+ fd_set_readable,
+ fd_set_writable,
+ fd_set_error,
fd_is_shutdown,
- fd_get_read_notifier_pollset,
pollset_init,
pollset_shutdown,
diff --git a/src/core/lib/iomgr/ev_posix.cc b/src/core/lib/iomgr/ev_posix.cc
index 1139b3273a..0e45fc42ca 100644
--- a/src/core/lib/iomgr/ev_posix.cc
+++ b/src/core/lib/iomgr/ev_posix.cc
@@ -239,6 +239,12 @@ void grpc_fd_notify_on_error(grpc_fd* fd, grpc_closure* closure) {
g_event_engine->fd_notify_on_error(fd, closure);
}
+void grpc_fd_set_readable(grpc_fd* fd) { g_event_engine->fd_set_readable(fd); }
+
+void grpc_fd_set_writable(grpc_fd* fd) { g_event_engine->fd_set_writable(fd); }
+
+void grpc_fd_set_error(grpc_fd* fd) { g_event_engine->fd_set_error(fd); }
+
static size_t pollset_size(void) { return g_event_engine->pollset_size; }
static void pollset_init(grpc_pollset* pollset, gpr_mu** mu) {
diff --git a/src/core/lib/iomgr/ev_posix.h b/src/core/lib/iomgr/ev_posix.h
index b4c17fc80d..8d0bcc0710 100644
--- a/src/core/lib/iomgr/ev_posix.h
+++ b/src/core/lib/iomgr/ev_posix.h
@@ -51,8 +51,10 @@ typedef struct grpc_event_engine_vtable {
void (*fd_notify_on_read)(grpc_fd* fd, grpc_closure* closure);
void (*fd_notify_on_write)(grpc_fd* fd, grpc_closure* closure);
void (*fd_notify_on_error)(grpc_fd* fd, grpc_closure* closure);
+ void (*fd_set_readable)(grpc_fd* fd);
+ void (*fd_set_writable)(grpc_fd* fd);
+ void (*fd_set_error)(grpc_fd* fd);
bool (*fd_is_shutdown)(grpc_fd* fd);
- grpc_pollset* (*fd_get_read_notifier_pollset)(grpc_fd* fd);
void (*pollset_init)(grpc_pollset* pollset, gpr_mu** mu);
void (*pollset_shutdown)(grpc_pollset* pollset, grpc_closure* closure);
@@ -142,8 +144,20 @@ void grpc_fd_notify_on_write(grpc_fd* fd, grpc_closure* closure);
* needs to have been set on grpc_fd_create */
void grpc_fd_notify_on_error(grpc_fd* fd, grpc_closure* closure);
-/* Return the read notifier pollset from the fd */
-grpc_pollset* grpc_fd_get_read_notifier_pollset(grpc_fd* fd);
+/* Forcibly set the fd to be readable, resulting in the closure registered with
+ * grpc_fd_notify_on_read being invoked.
+ */
+void grpc_fd_set_readable(grpc_fd* fd);
+
+/* Forcibly set the fd to be writable, resulting in the closure registered with
+ * grpc_fd_notify_on_write being invoked.
+ */
+void grpc_fd_set_writable(grpc_fd* fd);
+
+/* Forcibly set the fd to have errored, resulting in the closure registered with
+ * grpc_fd_notify_on_error being invoked.
+ */
+void grpc_fd_set_error(grpc_fd* fd);
/* pollset_posix functions */
diff --git a/src/core/lib/iomgr/executor.cc b/src/core/lib/iomgr/executor.cc
index 1ad13b831d..45d96b80eb 100644
--- a/src/core/lib/iomgr/executor.cc
+++ b/src/core/lib/iomgr/executor.cc
@@ -40,19 +40,25 @@
gpr_log(GPR_INFO, "EXECUTOR " format, __VA_ARGS__); \
}
+#define EXECUTOR_TRACE0(str) \
+ if (executor_trace.enabled()) { \
+ gpr_log(GPR_INFO, "EXECUTOR " str); \
+ }
+
grpc_core::TraceFlag executor_trace(false, "executor");
GPR_TLS_DECL(g_this_thread_state);
-GrpcExecutor::GrpcExecutor(const char* executor_name) : name_(executor_name) {
+GrpcExecutor::GrpcExecutor(const char* name) : name_(name) {
adding_thread_lock_ = GPR_SPINLOCK_STATIC_INITIALIZER;
- gpr_atm_no_barrier_store(&num_threads_, 0);
+ gpr_atm_rel_store(&num_threads_, 0);
max_threads_ = GPR_MAX(1, 2 * gpr_cpu_num_cores());
}
void GrpcExecutor::Init() { SetThreading(true); }
-size_t GrpcExecutor::RunClosures(grpc_closure_list list) {
+size_t GrpcExecutor::RunClosures(const char* executor_name,
+ grpc_closure_list list) {
size_t n = 0;
grpc_closure* c = list.head;
@@ -60,11 +66,11 @@ size_t GrpcExecutor::RunClosures(grpc_closure_list list) {
grpc_closure* next = c->next_data.next;
grpc_error* error = c->error_data.error;
#ifndef NDEBUG
- EXECUTOR_TRACE("run %p [created by %s:%d]", c, c->file_created,
- c->line_created);
+ EXECUTOR_TRACE("(%s) run %p [created by %s:%d]", executor_name, c,
+ c->file_created, c->line_created);
c->scheduled = false;
#else
- EXECUTOR_TRACE("run %p", c);
+ EXECUTOR_TRACE("(%s) run %p", executor_name, c);
#endif
c->cb(c->cb_arg, error);
GRPC_ERROR_UNREF(error);
@@ -77,17 +83,21 @@ size_t GrpcExecutor::RunClosures(grpc_closure_list list) {
}
bool GrpcExecutor::IsThreaded() const {
- return gpr_atm_no_barrier_load(&num_threads_) > 0;
+ return gpr_atm_acq_load(&num_threads_) > 0;
}
void GrpcExecutor::SetThreading(bool threading) {
- gpr_atm curr_num_threads = gpr_atm_no_barrier_load(&num_threads_);
+ gpr_atm curr_num_threads = gpr_atm_acq_load(&num_threads_);
+ EXECUTOR_TRACE("(%s) SetThreading(%d) begin", name_, threading);
if (threading) {
- if (curr_num_threads > 0) return;
+ if (curr_num_threads > 0) {
+ EXECUTOR_TRACE("(%s) SetThreading(true). curr_num_threads == 0", name_);
+ return;
+ }
GPR_ASSERT(num_threads_ == 0);
- gpr_atm_no_barrier_store(&num_threads_, 1);
+ gpr_atm_rel_store(&num_threads_, 1);
gpr_tls_init(&g_this_thread_state);
thd_state_ = static_cast<ThreadState*>(
gpr_zalloc(sizeof(ThreadState) * max_threads_));
@@ -96,6 +106,7 @@ void GrpcExecutor::SetThreading(bool threading) {
gpr_mu_init(&thd_state_[i].mu);
gpr_cv_init(&thd_state_[i].cv);
thd_state_[i].id = i;
+ thd_state_[i].name = name_;
thd_state_[i].thd = grpc_core::Thread();
thd_state_[i].elems = GRPC_CLOSURE_LIST_INIT;
}
@@ -104,7 +115,10 @@ void GrpcExecutor::SetThreading(bool threading) {
grpc_core::Thread(name_, &GrpcExecutor::ThreadMain, &thd_state_[0]);
thd_state_[0].thd.Start();
} else { // !threading
- if (curr_num_threads == 0) return;
+ if (curr_num_threads == 0) {
+ EXECUTOR_TRACE("(%s) SetThreading(false). curr_num_threads == 0", name_);
+ return;
+ }
for (size_t i = 0; i < max_threads_; i++) {
gpr_mu_lock(&thd_state_[i].mu);
@@ -121,20 +135,22 @@ void GrpcExecutor::SetThreading(bool threading) {
curr_num_threads = gpr_atm_no_barrier_load(&num_threads_);
for (gpr_atm i = 0; i < curr_num_threads; i++) {
thd_state_[i].thd.Join();
- EXECUTOR_TRACE(" Thread %" PRIdPTR " of %" PRIdPTR " joined", i,
- curr_num_threads);
+ EXECUTOR_TRACE("(%s) Thread %" PRIdPTR " of %" PRIdPTR " joined", name_,
+ i + 1, curr_num_threads);
}
- gpr_atm_no_barrier_store(&num_threads_, 0);
+ gpr_atm_rel_store(&num_threads_, 0);
for (size_t i = 0; i < max_threads_; i++) {
gpr_mu_destroy(&thd_state_[i].mu);
gpr_cv_destroy(&thd_state_[i].cv);
- RunClosures(thd_state_[i].elems);
+ RunClosures(thd_state_[i].name, thd_state_[i].elems);
}
gpr_free(thd_state_);
gpr_tls_destroy(&g_this_thread_state);
}
+
+ EXECUTOR_TRACE("(%s) SetThreading(%d) done", name_, threading);
}
void GrpcExecutor::Shutdown() { SetThreading(false); }
@@ -147,8 +163,8 @@ void GrpcExecutor::ThreadMain(void* arg) {
size_t subtract_depth = 0;
for (;;) {
- EXECUTOR_TRACE("[%" PRIdPTR "]: step (sub_depth=%" PRIdPTR ")", ts->id,
- subtract_depth);
+ EXECUTOR_TRACE("(%s) [%" PRIdPTR "]: step (sub_depth=%" PRIdPTR ")",
+ ts->name, ts->id, subtract_depth);
gpr_mu_lock(&ts->mu);
ts->depth -= subtract_depth;
@@ -159,7 +175,7 @@ void GrpcExecutor::ThreadMain(void* arg) {
}
if (ts->shutdown) {
- EXECUTOR_TRACE("[%" PRIdPTR "]: shutdown", ts->id);
+ EXECUTOR_TRACE("(%s) [%" PRIdPTR "]: shutdown", ts->name, ts->id);
gpr_mu_unlock(&ts->mu);
break;
}
@@ -169,10 +185,10 @@ void GrpcExecutor::ThreadMain(void* arg) {
ts->elems = GRPC_CLOSURE_LIST_INIT;
gpr_mu_unlock(&ts->mu);
- EXECUTOR_TRACE("[%" PRIdPTR "]: execute", ts->id);
+ EXECUTOR_TRACE("(%s) [%" PRIdPTR "]: execute", ts->name, ts->id);
grpc_core::ExecCtx::Get()->InvalidateNow();
- subtract_depth = RunClosures(closures);
+ subtract_depth = RunClosures(ts->name, closures);
}
}
@@ -188,16 +204,16 @@ void GrpcExecutor::Enqueue(grpc_closure* closure, grpc_error* error,
do {
retry_push = false;
size_t cur_thread_count =
- static_cast<size_t>(gpr_atm_no_barrier_load(&num_threads_));
+ static_cast<size_t>(gpr_atm_acq_load(&num_threads_));
// If the number of threads is zero(i.e either the executor is not threaded
// or already shutdown), then queue the closure on the exec context itself
if (cur_thread_count == 0) {
#ifndef NDEBUG
- EXECUTOR_TRACE("schedule %p (created %s:%d) inline", closure,
+ EXECUTOR_TRACE("(%s) schedule %p (created %s:%d) inline", name_, closure,
closure->file_created, closure->line_created);
#else
- EXECUTOR_TRACE("schedule %p inline", closure);
+ EXECUTOR_TRACE("(%s) schedule %p inline", name_, closure);
#endif
grpc_closure_list_append(grpc_core::ExecCtx::Get()->closure_list(),
closure, error);
@@ -213,18 +229,18 @@ void GrpcExecutor::Enqueue(grpc_closure* closure, grpc_error* error,
}
ThreadState* orig_ts = ts;
-
bool try_new_thread = false;
+
for (;;) {
#ifndef NDEBUG
EXECUTOR_TRACE(
- "try to schedule %p (%s) (created %s:%d) to thread "
+ "(%s) try to schedule %p (%s) (created %s:%d) to thread "
"%" PRIdPTR,
- closure, is_short ? "short" : "long", closure->file_created,
+ name_, closure, is_short ? "short" : "long", closure->file_created,
closure->line_created, ts->id);
#else
- EXECUTOR_TRACE("try to schedule %p (%s) to thread %" PRIdPTR, closure,
- is_short ? "short" : "long", ts->id);
+ EXECUTOR_TRACE("(%s) try to schedule %p (%s) to thread %" PRIdPTR, name_,
+ closure, is_short ? "short" : "long", ts->id);
#endif
gpr_mu_lock(&ts->mu);
@@ -236,18 +252,22 @@ void GrpcExecutor::Enqueue(grpc_closure* closure, grpc_error* error,
size_t idx = ts->id;
ts = &thd_state_[(idx + 1) % cur_thread_count];
if (ts == orig_ts) {
- // We cycled through all the threads. Retry enqueue again (by creating
- // a new thread)
+ // We cycled through all the threads. Retry enqueue again by creating
+ // a new thread
+ //
+ // TODO (sreek): There is a potential issue here. We are
+ // unconditionally setting try_new_thread to true here. What if the
+ // executor is shutdown OR if cur_thread_count is already equal to
+ // max_threads ?
+ // (Fortunately, this is not an issue yet (as of july 2018) because
+ // there is only one instance of long job in gRPC and hence we will
+ // not hit this code path)
retry_push = true;
- // TODO (sreek): What if the executor is shutdown OR if
- // cur_thread_count is already equal to max_threads ? (currently - as
- // of July 2018, we do not run in to this issue because there is only
- // one instance of long job in gRPC. This has to be fixed soon)
try_new_thread = true;
break;
}
- continue;
+ continue; // Try the next thread-state
}
// == Found the thread state (i.e thread) to enqueue this closure! ==
@@ -277,13 +297,11 @@ void GrpcExecutor::Enqueue(grpc_closure* closure, grpc_error* error,
}
if (try_new_thread && gpr_spinlock_trylock(&adding_thread_lock_)) {
- cur_thread_count =
- static_cast<size_t>(gpr_atm_no_barrier_load(&num_threads_));
+ cur_thread_count = static_cast<size_t>(gpr_atm_acq_load(&num_threads_));
if (cur_thread_count < max_threads_) {
- // Increment num_threads (Safe to do a no_barrier_store instead of a
- // cas because we always increment num_threads under the
- // 'adding_thread_lock')
- gpr_atm_no_barrier_store(&num_threads_, cur_thread_count + 1);
+ // Increment num_threads (safe to do a store instead of a cas because we
+ // always increment num_threads under the 'adding_thread_lock')
+ gpr_atm_rel_store(&num_threads_, cur_thread_count + 1);
thd_state_[cur_thread_count].thd = grpc_core::Thread(
name_, &GrpcExecutor::ThreadMain, &thd_state_[cur_thread_count]);
@@ -298,60 +316,118 @@ void GrpcExecutor::Enqueue(grpc_closure* closure, grpc_error* error,
} while (retry_push);
}
-static GrpcExecutor* global_executor;
+static GrpcExecutor* executors[GRPC_NUM_EXECUTORS];
-void enqueue_long(grpc_closure* closure, grpc_error* error) {
- global_executor->Enqueue(closure, error, false /* is_short */);
+void default_enqueue_short(grpc_closure* closure, grpc_error* error) {
+ executors[GRPC_DEFAULT_EXECUTOR]->Enqueue(closure, error,
+ true /* is_short */);
}
-void enqueue_short(grpc_closure* closure, grpc_error* error) {
- global_executor->Enqueue(closure, error, true /* is_short */);
+void default_enqueue_long(grpc_closure* closure, grpc_error* error) {
+ executors[GRPC_DEFAULT_EXECUTOR]->Enqueue(closure, error,
+ false /* is_short */);
}
-// Short-Job executor scheduler
-static const grpc_closure_scheduler_vtable global_executor_vtable_short = {
- enqueue_short, enqueue_short, "executor-short"};
-static grpc_closure_scheduler global_scheduler_short = {
- &global_executor_vtable_short};
+void resolver_enqueue_short(grpc_closure* closure, grpc_error* error) {
+ executors[GRPC_RESOLVER_EXECUTOR]->Enqueue(closure, error,
+ true /* is_short */);
+}
-// Long-job executor scheduler
-static const grpc_closure_scheduler_vtable global_executor_vtable_long = {
- enqueue_long, enqueue_long, "executor-long"};
-static grpc_closure_scheduler global_scheduler_long = {
- &global_executor_vtable_long};
+void resolver_enqueue_long(grpc_closure* closure, grpc_error* error) {
+ executors[GRPC_RESOLVER_EXECUTOR]->Enqueue(closure, error,
+ false /* is_short */);
+}
+
+static const grpc_closure_scheduler_vtable
+ vtables_[GRPC_NUM_EXECUTORS][GRPC_NUM_EXECUTOR_JOB_TYPES] = {
+ {{&default_enqueue_short, &default_enqueue_short, "def-ex-short"},
+ {&default_enqueue_long, &default_enqueue_long, "def-ex-long"}},
+ {{&resolver_enqueue_short, &resolver_enqueue_short, "res-ex-short"},
+ {&resolver_enqueue_long, &resolver_enqueue_long, "res-ex-long"}}};
+
+static grpc_closure_scheduler
+ schedulers_[GRPC_NUM_EXECUTORS][GRPC_NUM_EXECUTOR_JOB_TYPES] = {
+ {{&vtables_[GRPC_DEFAULT_EXECUTOR][GRPC_EXECUTOR_SHORT]},
+ {&vtables_[GRPC_DEFAULT_EXECUTOR][GRPC_EXECUTOR_LONG]}},
+ {{&vtables_[GRPC_RESOLVER_EXECUTOR][GRPC_EXECUTOR_SHORT]},
+ {&vtables_[GRPC_RESOLVER_EXECUTOR][GRPC_EXECUTOR_LONG]}}};
// grpc_executor_init() and grpc_executor_shutdown() functions are called in the
// the grpc_init() and grpc_shutdown() code paths which are protected by a
// global mutex. So it is okay to assume that these functions are thread-safe
void grpc_executor_init() {
- if (global_executor != nullptr) {
- // grpc_executor_init() already called once (and grpc_executor_shutdown()
- // wasn't called)
+ EXECUTOR_TRACE0("grpc_executor_init() enter");
+
+ // Return if grpc_executor_init() is already called earlier
+ if (executors[GRPC_DEFAULT_EXECUTOR] != nullptr) {
+ GPR_ASSERT(executors[GRPC_RESOLVER_EXECUTOR] != nullptr);
return;
}
- global_executor = grpc_core::New<GrpcExecutor>("global-executor");
- global_executor->Init();
+ executors[GRPC_DEFAULT_EXECUTOR] =
+ grpc_core::New<GrpcExecutor>("default-executor");
+ executors[GRPC_RESOLVER_EXECUTOR] =
+ grpc_core::New<GrpcExecutor>("resolver-executor");
+
+ executors[GRPC_DEFAULT_EXECUTOR]->Init();
+ executors[GRPC_RESOLVER_EXECUTOR]->Init();
+
+ EXECUTOR_TRACE0("grpc_executor_init() done");
+}
+
+grpc_closure_scheduler* grpc_executor_scheduler(GrpcExecutorType executor_type,
+ GrpcExecutorJobType job_type) {
+ return &schedulers_[executor_type][job_type];
+}
+
+grpc_closure_scheduler* grpc_executor_scheduler(GrpcExecutorJobType job_type) {
+ return grpc_executor_scheduler(GRPC_DEFAULT_EXECUTOR, job_type);
}
void grpc_executor_shutdown() {
- // Shutdown already called
- if (global_executor == nullptr) {
+ EXECUTOR_TRACE0("grpc_executor_shutdown() enter");
+
+ // Return if grpc_executor_shutdown() is already called earlier
+ if (executors[GRPC_DEFAULT_EXECUTOR] == nullptr) {
+ GPR_ASSERT(executors[GRPC_RESOLVER_EXECUTOR] == nullptr);
return;
}
- global_executor->Shutdown();
- grpc_core::Delete<GrpcExecutor>(global_executor);
- global_executor = nullptr;
+ executors[GRPC_DEFAULT_EXECUTOR]->Shutdown();
+ executors[GRPC_RESOLVER_EXECUTOR]->Shutdown();
+
+ // Delete the executor objects.
+ //
+ // NOTE: It is important to call Shutdown() on all executors first before
+ // calling Delete() because it is possible for one executor (that is not
+ // shutdown yet) to call Enqueue() on a different executor which is already
+ // shutdown. This is legal and in such cases, the Enqueue() operation
+ // effectively "fails" and enqueues that closure on the calling thread's
+ // exec_ctx.
+ //
+ // By ensuring that all executors are shutdown first, we are also ensuring
+ // that no thread is active across all executors.
+
+ grpc_core::Delete<GrpcExecutor>(executors[GRPC_DEFAULT_EXECUTOR]);
+ grpc_core::Delete<GrpcExecutor>(executors[GRPC_RESOLVER_EXECUTOR]);
+ executors[GRPC_DEFAULT_EXECUTOR] = nullptr;
+ executors[GRPC_RESOLVER_EXECUTOR] = nullptr;
+
+ EXECUTOR_TRACE0("grpc_executor_shutdown() done");
}
-bool grpc_executor_is_threaded() { return global_executor->IsThreaded(); }
+bool grpc_executor_is_threaded(GrpcExecutorType executor_type) {
+ GPR_ASSERT(executor_type < GRPC_NUM_EXECUTORS);
+ return executors[executor_type]->IsThreaded();
+}
-void grpc_executor_set_threading(bool enable) {
- global_executor->SetThreading(enable);
+bool grpc_executor_is_threaded() {
+ return grpc_executor_is_threaded(GRPC_DEFAULT_EXECUTOR);
}
-grpc_closure_scheduler* grpc_executor_scheduler(GrpcExecutorJobType job_type) {
- return job_type == GRPC_EXECUTOR_SHORT ? &global_scheduler_short
- : &global_scheduler_long;
+void grpc_executor_set_threading(bool enable) {
+ EXECUTOR_TRACE("grpc_executor_set_threading(%d) called", enable);
+ for (int i = 0; i < GRPC_NUM_EXECUTORS; i++) {
+ executors[i]->SetThreading(enable);
+ }
}
diff --git a/src/core/lib/iomgr/executor.h b/src/core/lib/iomgr/executor.h
index 395fc52863..8829138c5f 100644
--- a/src/core/lib/iomgr/executor.h
+++ b/src/core/lib/iomgr/executor.h
@@ -27,7 +27,8 @@
typedef struct {
gpr_mu mu;
- size_t id; // For debugging purposes
+ size_t id; // For debugging purposes
+ const char* name; // Thread state name
gpr_cv cv;
grpc_closure_list elems;
size_t depth; // Number of closures in the closure list
@@ -36,7 +37,11 @@ typedef struct {
grpc_core::Thread thd;
} ThreadState;
-typedef enum { GRPC_EXECUTOR_SHORT, GRPC_EXECUTOR_LONG } GrpcExecutorJobType;
+typedef enum {
+ GRPC_EXECUTOR_SHORT = 0,
+ GRPC_EXECUTOR_LONG,
+ GRPC_NUM_EXECUTOR_JOB_TYPES // Add new values above this
+} GrpcExecutorJobType;
class GrpcExecutor {
public:
@@ -58,7 +63,7 @@ class GrpcExecutor {
void Enqueue(grpc_closure* closure, grpc_error* error, bool is_short);
private:
- static size_t RunClosures(grpc_closure_list list);
+ static size_t RunClosures(const char* executor_name, grpc_closure_list list);
static void ThreadMain(void* arg);
const char* name_;
@@ -70,14 +75,42 @@ class GrpcExecutor {
// == Global executor functions ==
+typedef enum {
+ GRPC_DEFAULT_EXECUTOR = 0,
+ GRPC_RESOLVER_EXECUTOR,
+
+ GRPC_NUM_EXECUTORS // Add new values above this
+} GrpcExecutorType;
+
+// TODO(sreek): Currently we have two executors (available globally): The
+// default executor and the resolver executor.
+//
+// Some of the functions below operate on the DEFAULT executor only while some
+// operate of ALL the executors. This is a bit confusing and should be cleaned
+// up in future (where we make all the following functions take executor_type
+// and/or job_type)
+
+// Initialize ALL the executors
void grpc_executor_init();
+// Shutdown ALL the executors
+void grpc_executor_shutdown();
+
+// Set the threading mode for ALL the executors
+void grpc_executor_set_threading(bool enable);
+
+// Get the DEFAULT executor scheduler for the given job_type
grpc_closure_scheduler* grpc_executor_scheduler(GrpcExecutorJobType job_type);
-void grpc_executor_shutdown();
+// Get the executor scheduler for a given executor_type and a job_type
+grpc_closure_scheduler* grpc_executor_scheduler(GrpcExecutorType executor_type,
+ GrpcExecutorJobType job_type);
-bool grpc_executor_is_threaded();
+// Return if a given executor is running in threaded mode (i.e if
+// grpc_executor_set_threading(true) was called previously on that executor)
+bool grpc_executor_is_threaded(GrpcExecutorType executor_type);
-void grpc_executor_set_threading(bool enable);
+// Return if the DEFAULT executor is threaded
+bool grpc_executor_is_threaded();
#endif /* GRPC_CORE_LIB_IOMGR_EXECUTOR_H */
diff --git a/src/core/lib/iomgr/lockfree_event.cc b/src/core/lib/iomgr/lockfree_event.cc
index 5b6b79fa91..085fea40a4 100644
--- a/src/core/lib/iomgr/lockfree_event.cc
+++ b/src/core/lib/iomgr/lockfree_event.cc
@@ -89,7 +89,11 @@ void LockfreeEvent::DestroyEvent() {
void LockfreeEvent::NotifyOn(grpc_closure* closure) {
while (true) {
- gpr_atm curr = gpr_atm_no_barrier_load(&state_);
+ /* This load needs to be an acquire load because this can be a shutdown
+ * error that we might need to reference. Adding acquire semantics makes
+ * sure that the shutdown error has been initialized properly before us
+ * referencing it. */
+ gpr_atm curr = gpr_atm_acq_load(&state_);
if (grpc_polling_trace.enabled()) {
gpr_log(GPR_ERROR, "LockfreeEvent::NotifyOn: %p curr=%p closure=%p", this,
(void*)curr, closure);
diff --git a/src/core/lib/iomgr/resolve_address_posix.cc b/src/core/lib/iomgr/resolve_address_posix.cc
index 7a825643e1..c285d7eca6 100644
--- a/src/core/lib/iomgr/resolve_address_posix.cc
+++ b/src/core/lib/iomgr/resolve_address_posix.cc
@@ -166,8 +166,9 @@ static void posix_resolve_address(const char* name, const char* default_port,
grpc_closure* on_done,
grpc_resolved_addresses** addrs) {
request* r = static_cast<request*>(gpr_malloc(sizeof(request)));
- GRPC_CLOSURE_INIT(&r->request_closure, do_request_thread, r,
- grpc_executor_scheduler(GRPC_EXECUTOR_SHORT));
+ GRPC_CLOSURE_INIT(
+ &r->request_closure, do_request_thread, r,
+ grpc_executor_scheduler(GRPC_RESOLVER_EXECUTOR, GRPC_EXECUTOR_SHORT));
r->name = gpr_strdup(name);
r->default_port = gpr_strdup(default_port);
r->on_done = on_done;
diff --git a/src/core/lib/iomgr/resolve_address_windows.cc b/src/core/lib/iomgr/resolve_address_windows.cc
index 71c92615ad..3e977dca2d 100644
--- a/src/core/lib/iomgr/resolve_address_windows.cc
+++ b/src/core/lib/iomgr/resolve_address_windows.cc
@@ -151,8 +151,9 @@ static void windows_resolve_address(const char* name, const char* default_port,
grpc_closure* on_done,
grpc_resolved_addresses** addresses) {
request* r = (request*)gpr_malloc(sizeof(request));
- GRPC_CLOSURE_INIT(&r->request_closure, do_request_thread, r,
- grpc_executor_scheduler(GRPC_EXECUTOR_SHORT));
+ GRPC_CLOSURE_INIT(
+ &r->request_closure, do_request_thread, r,
+ grpc_executor_scheduler(GRPC_RESOLVER_EXECUTOR, GRPC_EXECUTOR_SHORT));
r->name = gpr_strdup(name);
r->default_port = gpr_strdup(default_port);
r->on_done = on_done;
diff --git a/src/core/lib/iomgr/socket_windows.cc b/src/core/lib/iomgr/socket_windows.cc
index 2e23409582..4ad31cb35d 100644
--- a/src/core/lib/iomgr/socket_windows.cc
+++ b/src/core/lib/iomgr/socket_windows.cc
@@ -36,6 +36,7 @@
#include "src/core/lib/iomgr/iomgr_internal.h"
#include "src/core/lib/iomgr/pollset.h"
#include "src/core/lib/iomgr/pollset_windows.h"
+#include "src/core/lib/iomgr/sockaddr_windows.h"
#include "src/core/lib/iomgr/socket_windows.h"
grpc_winsocket* grpc_winsocket_create(SOCKET socket, const char* name) {
@@ -148,4 +149,32 @@ void grpc_socket_become_ready(grpc_winsocket* socket,
if (should_destroy) destroy(socket);
}
+static gpr_once g_probe_ipv6_once = GPR_ONCE_INIT;
+static bool g_ipv6_loopback_available = false;
+
+static void probe_ipv6_once(void) {
+ SOCKET s = socket(AF_INET6, SOCK_STREAM, 0);
+ g_ipv6_loopback_available = 0;
+ if (s == INVALID_SOCKET) {
+ gpr_log(GPR_INFO, "Disabling AF_INET6 sockets because socket() failed.");
+ } else {
+ grpc_sockaddr_in6 addr;
+ memset(&addr, 0, sizeof(addr));
+ addr.sin6_family = AF_INET6;
+ addr.sin6_addr.s6_addr[15] = 1; /* [::1]:0 */
+ if (bind(s, reinterpret_cast<grpc_sockaddr*>(&addr), sizeof(addr)) == 0) {
+ g_ipv6_loopback_available = 1;
+ } else {
+ gpr_log(GPR_INFO,
+ "Disabling AF_INET6 sockets because ::1 is not available.");
+ }
+ closesocket(s);
+ }
+}
+
+int grpc_ipv6_loopback_available(void) {
+ gpr_once_init(&g_probe_ipv6_once, probe_ipv6_once);
+ return g_ipv6_loopback_available;
+}
+
#endif /* GRPC_WINSOCK_SOCKET */
diff --git a/src/core/lib/iomgr/socket_windows.h b/src/core/lib/iomgr/socket_windows.h
index 7bd01eded5..b09b9da562 100644
--- a/src/core/lib/iomgr/socket_windows.h
+++ b/src/core/lib/iomgr/socket_windows.h
@@ -108,6 +108,10 @@ void grpc_socket_notify_on_read(grpc_winsocket* winsocket,
void grpc_socket_become_ready(grpc_winsocket* winsocket,
grpc_winsocket_callback_info* ci);
+/* Returns true if this system can create AF_INET6 sockets bound to ::1.
+ The value is probed once, and cached for the life of the process. */
+int grpc_ipv6_loopback_available(void);
+
#endif
#endif /* GRPC_CORE_LIB_IOMGR_SOCKET_WINDOWS_H */
diff --git a/src/core/lib/json/json.cc b/src/core/lib/json/json.cc
index 6d359573f8..e78b73cefd 100644
--- a/src/core/lib/json/json.cc
+++ b/src/core/lib/json/json.cc
@@ -58,6 +58,8 @@ void grpc_json_destroy(grpc_json* json) {
grpc_json* grpc_json_link_child(grpc_json* parent, grpc_json* child,
grpc_json* sibling) {
+ // link child up to parent
+ child->parent = parent;
// first child case.
if (parent->child == nullptr) {
GPR_ASSERT(sibling == nullptr);
@@ -81,7 +83,6 @@ grpc_json* grpc_json_create_child(grpc_json* sibling, grpc_json* parent,
grpc_json* child = grpc_json_create(type);
grpc_json_link_child(parent, child, sibling);
child->owns_value = owns_value;
- child->parent = parent;
child->value = value;
child->key = key;
return child;
diff --git a/src/core/lib/security/credentials/alts/check_gcp_environment_linux.cc b/src/core/lib/security/credentials/alts/check_gcp_environment_linux.cc
index 7c4d7a71cd..8454fd7558 100644
--- a/src/core/lib/security/credentials/alts/check_gcp_environment_linux.cc
+++ b/src/core/lib/security/credentials/alts/check_gcp_environment_linux.cc
@@ -41,8 +41,9 @@ namespace internal {
bool check_bios_data(const char* bios_data_file) {
char* bios_data = read_bios_file(bios_data_file);
- bool result = (!strcmp(bios_data, GRPC_ALTS_EXPECT_NAME_GOOGLE)) ||
- (!strcmp(bios_data, GRPC_ALTS_EXPECT_NAME_GCE));
+ bool result =
+ bios_data && ((!strcmp(bios_data, GRPC_ALTS_EXPECT_NAME_GOOGLE)) ||
+ (!strcmp(bios_data, GRPC_ALTS_EXPECT_NAME_GCE)));
gpr_free(bios_data);
return result;
}
diff --git a/src/core/lib/security/security_connector/security_connector.cc b/src/core/lib/security/security_connector/security_connector.cc
index cc72bb6164..59cf3a0af1 100644
--- a/src/core/lib/security/security_connector/security_connector.cc
+++ b/src/core/lib/security/security_connector/security_connector.cc
@@ -57,6 +57,10 @@ static const char* installed_roots_path =
INSTALL_PREFIX "/share/grpc/roots.pem";
#endif
+#ifndef TSI_OPENSSL_ALPN_SUPPORT
+#define TSI_OPENSSL_ALPN_SUPPORT 1
+#endif
+
/* -- Overridden default roots. -- */
static grpc_ssl_roots_override_callback ssl_roots_override_cb = nullptr;
@@ -850,7 +854,8 @@ grpc_auth_context* grpc_ssl_peer_to_auth_context(const tsi_peer* peer) {
static grpc_error* ssl_check_peer(grpc_security_connector* sc,
const char* peer_name, const tsi_peer* peer,
grpc_auth_context** auth_context) {
- /* Check the ALPN. */
+#if TSI_OPENSSL_ALPN_SUPPORT
+ /* Check the ALPN if ALPN is supported. */
const tsi_peer_property* p =
tsi_peer_get_property_by_name(peer, TSI_SSL_ALPN_SELECTED_PROTOCOL);
if (p == nullptr) {
@@ -861,7 +866,7 @@ static grpc_error* ssl_check_peer(grpc_security_connector* sc,
return GRPC_ERROR_CREATE_FROM_STATIC_STRING(
"Cannot check peer: invalid ALPN value.");
}
-
+#endif /* TSI_OPENSSL_ALPN_SUPPORT */
/* Check the peer name if specified. */
if (peer_name != nullptr && !grpc_ssl_host_matches_name(peer, peer_name)) {
char* msg;
diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc
index 88e015ce22..dbad5ded4d 100644
--- a/src/core/lib/surface/call.cc
+++ b/src/core/lib/surface/call.cc
@@ -529,6 +529,7 @@ void grpc_call_internal_unref(grpc_call* c REF_ARG) {
static void release_call(void* call, grpc_error* error) {
grpc_call* c = static_cast<grpc_call*>(call);
grpc_channel* channel = c->channel;
+ gpr_free(static_cast<void*>(const_cast<char*>(c->final_info.error_string)));
grpc_call_combiner_destroy(&c->call_combiner);
grpc_channel_update_call_size_estimate(channel, gpr_arena_destroy(c->arena));
GRPC_CHANNEL_INTERNAL_UNREF(channel, "call");
@@ -561,7 +562,7 @@ static void destroy_call(void* call, grpc_error* error) {
}
get_final_status(c, set_status_value_directly, &c->final_info.final_status,
- nullptr, c->final_info.error_string);
+ nullptr, &(c->final_info.error_string));
c->final_info.stats.latency =
gpr_time_sub(gpr_now(GPR_CLOCK_MONOTONIC), c->start_time);
diff --git a/src/core/lib/surface/channel.cc b/src/core/lib/surface/channel.cc
index 8f3ad6c191..7cbd61adef 100644
--- a/src/core/lib/surface/channel.cc
+++ b/src/core/lib/surface/channel.cc
@@ -105,6 +105,7 @@ grpc_channel* grpc_channel_create_with_builder(
channel->is_client = grpc_channel_stack_type_is_client(channel_stack_type);
size_t channel_tracer_max_nodes = 0; // default to off
bool channelz_enabled = false;
+ bool internal_channel = false;
// this creates the default ChannelNode. Different types of channels may
// override this to ensure a correct ChannelNode is created.
grpc_core::channelz::ChannelNodeCreationFunc channel_node_create_func =
@@ -158,13 +159,17 @@ grpc_channel* grpc_channel_create_with_builder(
channel_node_create_func =
reinterpret_cast<grpc_core::channelz::ChannelNodeCreationFunc>(
args->args[i].value.pointer.p);
+ } else if (0 == strcmp(args->args[i].key,
+ GRPC_ARG_CHANNELZ_CHANNEL_IS_INTERNAL_CHANNEL)) {
+ internal_channel = grpc_channel_arg_get_bool(&args->args[i], false);
}
}
grpc_channel_args_destroy(args);
if (channelz_enabled) {
- channel->channelz_channel =
- channel_node_create_func(channel, channel_tracer_max_nodes);
+ bool is_top_level_channel = channel->is_client && !internal_channel;
+ channel->channelz_channel = channel_node_create_func(
+ channel, channel_tracer_max_nodes, is_top_level_channel);
channel->channelz_channel->trace()->AddTraceEvent(
grpc_core::channelz::ChannelTrace::Severity::Info,
grpc_slice_from_static_string("Channel created"));
diff --git a/src/core/lib/surface/init.cc b/src/core/lib/surface/init.cc
index 16be81e9c2..0ad82fed99 100644
--- a/src/core/lib/surface/init.cc
+++ b/src/core/lib/surface/init.cc
@@ -127,7 +127,7 @@ void grpc_init(void) {
grpc_slice_intern_init();
grpc_mdctx_global_init();
grpc_channel_init_init();
- grpc_core::ChannelzRegistry::Init();
+ grpc_core::channelz::ChannelzRegistry::Init();
grpc_security_pre_init();
grpc_core::ExecCtx::GlobalInit();
grpc_iomgr_init();
@@ -176,7 +176,7 @@ void grpc_shutdown(void) {
grpc_mdctx_global_shutdown();
grpc_handshaker_factory_registry_shutdown();
grpc_slice_intern_shutdown();
- grpc_core::ChannelzRegistry::Shutdown();
+ grpc_core::channelz::ChannelzRegistry::Shutdown();
grpc_stats_shutdown();
grpc_core::Fork::GlobalShutdown();
}
diff --git a/src/core/lib/surface/version.cc b/src/core/lib/surface/version.cc
index f4b1bb0cd8..e92fe2c5a1 100644
--- a/src/core/lib/surface/version.cc
+++ b/src/core/lib/surface/version.cc
@@ -23,6 +23,6 @@
#include <grpc/grpc.h>
-const char* grpc_version_string(void) { return "6.0.0"; }
+const char* grpc_version_string(void) { return "6.0.0-dev"; }
-const char* grpc_g_stands_for(void) { return "gladiolus"; }
+const char* grpc_g_stands_for(void) { return "glider"; }
diff --git a/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc b/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc
index 06b999899a..1df1021bb1 100644
--- a/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc
+++ b/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc
@@ -462,6 +462,14 @@ void alts_tsi_handshaker_handle_response(alts_tsi_handshaker* handshaker,
set_unused_bytes(result, &handshaker->recv_bytes, resp->bytes_consumed);
}
grpc_status_code code = static_cast<grpc_status_code>(resp->status.code);
+ if (code != GRPC_STATUS_OK) {
+ grpc_slice* details = static_cast<grpc_slice*>(resp->status.details.arg);
+ if (details != nullptr) {
+ char* error_details = grpc_slice_to_c_string(*details);
+ gpr_log(GPR_ERROR, "Error from handshaker service:%s", error_details);
+ gpr_free(error_details);
+ }
+ }
grpc_gcp_handshaker_resp_destroy(resp);
cb(alts_tsi_utils_convert_to_tsi_result(code), user_data, bytes_to_send,
bytes_to_send_size, result);
diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc
index bdb6359632..e48fbeb86d 100644
--- a/src/cpp/client/secure_credentials.cc
+++ b/src/cpp/client/secure_credentials.cc
@@ -107,6 +107,13 @@ std::shared_ptr<ChannelCredentials> AltsCredentials(
return WrapChannelCredentials(c_creds);
}
+// Builds Local Credentials
+std::shared_ptr<ChannelCredentials> LocalCredentials(
+ grpc_local_connect_type type) {
+ GrpcLibraryCodegen init; // To call grpc_init().
+ return WrapChannelCredentials(grpc_local_credentials_create(type));
+}
+
} // namespace experimental
// Builds credentials for use when running in GCE
diff --git a/src/cpp/common/version_cc.cc b/src/cpp/common/version_cc.cc
index de42c6fea3..b8fca9a6ee 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.14.0"; }
+grpc::string Version() { return "1.15.0-dev"; }
} // namespace grpc
diff --git a/src/cpp/server/channelz/channelz_service.cc b/src/cpp/server/channelz/channelz_service.cc
new file mode 100644
index 0000000000..77c175e5b8
--- /dev/null
+++ b/src/cpp/server/channelz/channelz_service.cc
@@ -0,0 +1,57 @@
+/*
+ *
+ * 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/cpp/server/channelz/channelz_service.h"
+
+#include <google/protobuf/text_format.h>
+#include <google/protobuf/util/json_util.h>
+
+#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
+
+namespace grpc {
+
+Status ChannelzService::GetTopChannels(
+ ServerContext* unused, const channelz::v1::GetTopChannelsRequest* request,
+ channelz::v1::GetTopChannelsResponse* response) {
+ char* json_str = grpc_channelz_get_top_channels(request->start_channel_id());
+ google::protobuf::util::Status s =
+ google::protobuf::util::JsonStringToMessage(json_str, response);
+ gpr_free(json_str);
+ if (s != google::protobuf::util::Status::OK) {
+ return Status(INTERNAL, s.ToString());
+ }
+ return Status::OK;
+}
+
+Status ChannelzService::GetChannel(
+ ServerContext* unused, const channelz::v1::GetChannelRequest* request,
+ channelz::v1::GetChannelResponse* response) {
+ char* json_str = grpc_channelz_get_channel(request->channel_id());
+ google::protobuf::util::Status s =
+ google::protobuf::util::JsonStringToMessage(json_str, response);
+ gpr_free(json_str);
+ if (s != google::protobuf::util::Status::OK) {
+ return Status(INTERNAL, s.ToString());
+ }
+ return Status::OK;
+}
+
+} // namespace grpc
diff --git a/src/cpp/server/channelz/channelz_service.h b/src/cpp/server/channelz/channelz_service.h
new file mode 100644
index 0000000000..f619ea49e0
--- /dev/null
+++ b/src/cpp/server/channelz/channelz_service.h
@@ -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.
+ *
+ */
+
+#ifndef GRPC_INTERNAL_CPP_SERVER_CHANNELZ_SERVICE_H
+#define GRPC_INTERNAL_CPP_SERVER_CHANNELZ_SERVICE_H
+
+#include <grpc/support/port_platform.h>
+
+#include <grpcpp/grpcpp.h>
+#include "src/proto/grpc/channelz/channelz.grpc.pb.h"
+
+namespace grpc {
+
+class ChannelzService final : public channelz::v1::Channelz::Service {
+ private:
+ // implementation of GetTopChannels rpc
+ Status GetTopChannels(
+ ServerContext* unused, const channelz::v1::GetTopChannelsRequest* request,
+ channelz::v1::GetTopChannelsResponse* response) override;
+ // implementation of GetChannel rpc
+ Status GetChannel(ServerContext* unused,
+ const channelz::v1::GetChannelRequest* request,
+ channelz::v1::GetChannelResponse* response) override;
+};
+
+} // namespace grpc
+
+#endif // GRPC_INTERNAL_CPP_SERVER_CHANNELZ_SERVICE_H
diff --git a/src/cpp/server/channelz/channelz_service_plugin.cc b/src/cpp/server/channelz/channelz_service_plugin.cc
new file mode 100644
index 0000000000..b93e5b551e
--- /dev/null
+++ b/src/cpp/server/channelz/channelz_service_plugin.cc
@@ -0,0 +1,79 @@
+/*
+ *
+ * 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 <grpcpp/ext/channelz_service_plugin.h>
+#include <grpcpp/impl/server_builder_plugin.h>
+#include <grpcpp/impl/server_initializer.h>
+#include <grpcpp/server.h>
+
+#include "src/cpp/server/channelz/channelz_service.h"
+
+namespace grpc {
+namespace channelz {
+namespace experimental {
+
+class ChannelzServicePlugin : public ::grpc::ServerBuilderPlugin {
+ public:
+ ChannelzServicePlugin() : channelz_service_(new grpc::ChannelzService()) {}
+
+ grpc::string name() override { return "channelz_service"; }
+
+ void InitServer(grpc::ServerInitializer* si) override {
+ si->RegisterService(channelz_service_);
+ }
+
+ void Finish(grpc::ServerInitializer* si) override {}
+
+ void ChangeArguments(const grpc::string& name, void* value) override {}
+
+ bool has_sync_methods() const override {
+ if (channelz_service_) {
+ return channelz_service_->has_synchronous_methods();
+ }
+ return false;
+ }
+
+ bool has_async_methods() const override {
+ if (channelz_service_) {
+ return channelz_service_->has_async_methods();
+ }
+ return false;
+ }
+
+ private:
+ std::shared_ptr<grpc::ChannelzService> channelz_service_;
+};
+
+static std::unique_ptr< ::grpc::ServerBuilderPlugin>
+CreateChannelzServicePlugin() {
+ return std::unique_ptr< ::grpc::ServerBuilderPlugin>(
+ new ChannelzServicePlugin());
+}
+
+void InitChannelzService() {
+ static bool already_here = false;
+ if (already_here) return;
+ already_here = true;
+ ::grpc::ServerBuilder::InternalAddPluginFactory(&CreateChannelzServicePlugin);
+}
+
+} // namespace experimental
+} // namespace channelz
+} // namespace grpc
diff --git a/src/cpp/server/secure_server_credentials.cc b/src/cpp/server/secure_server_credentials.cc
index a5af25751a..536bf022dd 100644
--- a/src/cpp/server/secure_server_credentials.cc
+++ b/src/cpp/server/secure_server_credentials.cc
@@ -139,5 +139,11 @@ std::shared_ptr<ServerCredentials> AltsServerCredentials(
new SecureServerCredentials(c_creds));
}
+std::shared_ptr<ServerCredentials> LocalServerCredentials(
+ grpc_local_connect_type type) {
+ return std::shared_ptr<ServerCredentials>(
+ new SecureServerCredentials(grpc_local_server_credentials_create(type)));
+}
+
} // namespace experimental
} // namespace grpc
diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj
index 6d44be7ddd..fc32271063 100755
--- a/src/csharp/Grpc.Core/Grpc.Core.csproj
+++ b/src/csharp/Grpc.Core/Grpc.Core.csproj
@@ -46,10 +46,38 @@
<PackagePath>runtimes/win/native/grpc_csharp_ext.x86.dll</PackagePath>
<Pack>true</Pack>
</Content>
- <Content Include="Grpc.Core.targets">
+ <Content Include="..\nativelibs\csharp_ext_linux_android_armeabi-v7a\libgrpc_csharp_ext.so">
+ <PackagePath>runtimes/monoandroid/armeabi-v7a/libgrpc_csharp_ext.so</PackagePath>
+ <Pack>true</Pack>
+ </Content>
+ <Content Include="..\nativelibs\csharp_ext_linux_android_arm64-v8a\libgrpc_csharp_ext.so">
+ <PackagePath>runtimes/monoandroid/arm64-v8a/libgrpc_csharp_ext.so</PackagePath>
+ <Pack>true</Pack>
+ </Content>
+ <Content Include="..\nativelibs\csharp_ext_linux_android_x86\libgrpc_csharp_ext.so">
+ <PackagePath>runtimes/monoandroid/x86/libgrpc_csharp_ext.so</PackagePath>
+ <Pack>true</Pack>
+ </Content>
+ <Content Include="..\nativelibs\csharp_ext_macos_ios\libgrpc_csharp_ext.a">
+ <PackagePath>runtimes/ios/native/libgrpc_csharp_ext.a</PackagePath>
+ <Pack>true</Pack>
+ </Content>
+ <Content Include="..\nativelibs\csharp_ext_macos_ios\libgrpc.a">
+ <PackagePath>runtimes/ios/native/libgrpc.a</PackagePath>
+ <Pack>true</Pack>
+ </Content>
+ <Content Include="build\net45\Grpc.Core.targets">
<PackagePath>build/net45/</PackagePath>
<Pack>true</Pack>
</Content>
+ <Content Include="build\MonoAndroid\Grpc.Core.targets">
+ <PackagePath>build/MonoAndroid/</PackagePath>
+ <Pack>true</Pack>
+ </Content>
+ <Content Include="build\Xamarin.iOS\Grpc.Core.targets">
+ <PackagePath>build/Xamarin.iOS/</PackagePath>
+ <Pack>true</Pack>
+ </Content>
</ItemGroup>
<ItemGroup>
diff --git a/src/csharp/Grpc.Core/Internal/NativeExtension.cs b/src/csharp/Grpc.Core/Internal/NativeExtension.cs
index d5ec998bbd..f526b913af 100644
--- a/src/csharp/Grpc.Core/Internal/NativeExtension.cs
+++ b/src/csharp/Grpc.Core/Internal/NativeExtension.cs
@@ -106,7 +106,15 @@ namespace Grpc.Core.Internal
/// </summary>
private static NativeMethods LoadNativeMethods()
{
- return PlatformApis.IsUnity ? LoadNativeMethodsUnity() : new NativeMethods(LoadUnmanagedLibrary());
+ if (PlatformApis.IsUnity)
+ {
+ return LoadNativeMethodsUnity();
+ }
+ if (PlatformApis.IsXamarin)
+ {
+ return LoadNativeMethodsXamarin();
+ }
+ return new NativeMethods(LoadUnmanagedLibrary());
}
/// <summary>
@@ -128,6 +136,20 @@ namespace Grpc.Core.Internal
}
}
+ /// <summary>
+ /// Return native method delegates when running on the Xamarin platform.
+ /// WARNING: Xamarin support is experimental and work-in-progress. Don't expect it to work.
+ /// </summary>
+ private static NativeMethods LoadNativeMethodsXamarin()
+ {
+ if (PlatformApis.IsXamarinAndroid)
+ {
+ return new NativeMethods(new NativeMethods.DllImportsFromSharedLib());
+ }
+ // not tested yet
+ return new NativeMethods(new NativeMethods.DllImportsFromStaticLib());
+ }
+
private static string GetAssemblyPath()
{
var assembly = typeof(NativeExtension).GetTypeInfo().Assembly;
diff --git a/src/csharp/Grpc.Core/Internal/NativeLogRedirector.cs b/src/csharp/Grpc.Core/Internal/NativeLogRedirector.cs
index bf6440123a..30264acb10 100644
--- a/src/csharp/Grpc.Core/Internal/NativeLogRedirector.cs
+++ b/src/csharp/Grpc.Core/Internal/NativeLogRedirector.cs
@@ -51,6 +51,7 @@ namespace Grpc.Core.Internal
}
}
+ [MonoPInvokeCallback(typeof(GprLogDelegate))]
private static void HandleWrite(IntPtr fileStringPtr, int line, ulong threadId, IntPtr severityStringPtr, IntPtr msgPtr)
{
try
@@ -86,4 +87,22 @@ namespace Grpc.Core.Internal
}
}
}
+
+ /// <summary>
+ /// Use this attribute to mark methods that will be called back from P/Invoke calls.
+ /// iOS (and probably other AOT platforms) needs to have delegates registered.
+ /// Instead of depending on Xamarin.iOS for this, we can just create our own,
+ /// the iOS runtime just checks for the type name.
+ /// See: https://docs.microsoft.com/en-gb/xamarin/ios/internals/limitations#reverse-callbacks
+ /// </summary>
+ [AttributeUsage(AttributeTargets.Method)]
+ internal sealed class MonoPInvokeCallbackAttribute : Attribute
+ {
+ public MonoPInvokeCallbackAttribute(Type type)
+ {
+ Type = type;
+ }
+
+ public Type Type { get; private set; }
+ }
}
diff --git a/src/csharp/Grpc.Core/Internal/PlatformApis.cs b/src/csharp/Grpc.Core/Internal/PlatformApis.cs
index b90fbccb2b..c501aa89fb 100644
--- a/src/csharp/Grpc.Core/Internal/PlatformApis.cs
+++ b/src/csharp/Grpc.Core/Internal/PlatformApis.cs
@@ -33,12 +33,18 @@ namespace Grpc.Core.Internal
internal static class PlatformApis
{
const string UnityEngineApplicationClassName = "UnityEngine.Application, UnityEngine";
+ const string XamarinAndroidObjectClassName = "Java.Lang.Object, Mono.Android";
+ const string XamarinIOSObjectClassName = "Foundation.NSObject, Xamarin.iOS";
+
static readonly bool isLinux;
static readonly bool isMacOSX;
static readonly bool isWindows;
static readonly bool isMono;
static readonly bool isNetCore;
static readonly bool isUnity;
+ static readonly bool isXamarin;
+ static readonly bool isXamarinIOS;
+ static readonly bool isXamarinAndroid;
static PlatformApis()
{
@@ -58,6 +64,9 @@ namespace Grpc.Core.Internal
#endif
isMono = Type.GetType("Mono.Runtime") != null;
isUnity = Type.GetType(UnityEngineApplicationClassName) != null;
+ isXamarinIOS = Type.GetType(XamarinIOSObjectClassName) != null;
+ isXamarinAndroid = Type.GetType(XamarinAndroidObjectClassName) != null;
+ isXamarin = isXamarinIOS || isXamarinAndroid;
}
public static bool IsLinux
@@ -89,6 +98,31 @@ namespace Grpc.Core.Internal
}
/// <summary>
+ /// true if running on a Xamarin platform (either Xamarin.Android or Xamarin.iOS),
+ /// false otherwise.
+ /// </summary>
+ public static bool IsXamarin
+ {
+ get { return isXamarin; }
+ }
+
+ /// <summary>
+ /// true if running on Xamarin.iOS, false otherwise.
+ /// </summary>
+ public static bool IsXamarinIOS
+ {
+ get { return isXamarinIOS; }
+ }
+
+ /// <summary>
+ /// true if running on Xamarin.Android, false otherwise.
+ /// </summary>
+ public static bool IsXamarinAndroid
+ {
+ get { return isXamarinAndroid; }
+ }
+
+ /// <summary>
/// true if running on .NET Core (CoreCLR), false otherwise.
/// </summary>
public static bool IsNetCore
diff --git a/src/csharp/Grpc.Core/Version.csproj.include b/src/csharp/Grpc.Core/Version.csproj.include
index 92bec0e067..1a746acdd4 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.14.0</GrpcCsharpVersion>
+ <GrpcCsharpVersion>1.15.0-dev</GrpcCsharpVersion>
<GoogleProtobufVersion>3.5.1</GoogleProtobufVersion>
</PropertyGroup>
</Project>
diff --git a/src/csharp/Grpc.Core/VersionInfo.cs b/src/csharp/Grpc.Core/VersionInfo.cs
index 35888b0300..295e0f2577 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.14.0.0";
+ public const string CurrentAssemblyFileVersion = "1.15.0.0";
/// <summary>
/// Current version of gRPC C#
/// </summary>
- public const string CurrentVersion = "1.14.0";
+ public const string CurrentVersion = "1.15.0-dev";
}
}
diff --git a/src/csharp/Grpc.Core/build/MonoAndroid/Grpc.Core.targets b/src/csharp/Grpc.Core/build/MonoAndroid/Grpc.Core.targets
new file mode 100644
index 0000000000..d75e5a2f2f
--- /dev/null
+++ b/src/csharp/Grpc.Core/build/MonoAndroid/Grpc.Core.targets
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <_GrpcCoreNugetNativePath Condition="'$(_GrpcCoreNugetNativePath)' == ''">$(MSBuildThisFileDirectory)..\..\</_GrpcCoreNugetNativePath>
+ </PropertyGroup>
+
+ <ItemGroup Condition="'$(TargetFrameworkIdentifier)' == 'MonoAndroid'">
+ <AndroidNativeLibrary Include="$(_GrpcCoreNugetNativePath)runtimes\monoandroid\arm64-v8a\libgrpc_csharp_ext.so">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ <Abi>arm64-v8a</Abi>
+ </AndroidNativeLibrary>
+ </ItemGroup>
+
+ <ItemGroup Condition="'$(TargetFrameworkIdentifier)' == 'MonoAndroid'">
+ <AndroidNativeLibrary Include="$(_GrpcCoreNugetNativePath)runtimes\monoandroid\armeabi-v7a\libgrpc_csharp_ext.so">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ <Abi>armeabi-v7a</Abi>
+ </AndroidNativeLibrary>
+ </ItemGroup>
+
+ <ItemGroup Condition="'$(TargetFrameworkIdentifier)' == 'MonoAndroid'">
+ <AndroidNativeLibrary Include="$(_GrpcCoreNugetNativePath)runtimes\monoandroid\x86\libgrpc_csharp_ext.so">
+ <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+ <Abi>x86</Abi>
+ </AndroidNativeLibrary>
+ </ItemGroup>
+
+</Project>
diff --git a/src/csharp/Grpc.Core/build/Xamarin.iOS/Grpc.Core.targets b/src/csharp/Grpc.Core/build/Xamarin.iOS/Grpc.Core.targets
new file mode 100644
index 0000000000..658158f6ea
--- /dev/null
+++ b/src/csharp/Grpc.Core/build/Xamarin.iOS/Grpc.Core.targets
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+
+ <ItemGroup>
+ <NativeReference Include="$(MSBuildThisFileDirectory)..\..\runtimes\ios\native\libgrpc_csharp_ext.a">
+ <Kind>Static</Kind>
+ <ForceLoad>True</ForceLoad>
+ </NativeReference>
+ <NativeReference Include="$(MSBuildThisFileDirectory)..\..\runtimes\ios\native\libgrpc.a">
+ <Kind>Static</Kind>
+ <ForceLoad>True</ForceLoad>
+ </NativeReference>
+ </ItemGroup>
+
+</Project>
diff --git a/src/csharp/Grpc.Core/Grpc.Core.targets b/src/csharp/Grpc.Core/build/net45/Grpc.Core.targets
index cce53db82b..cce53db82b 100644
--- a/src/csharp/Grpc.Core/Grpc.Core.targets
+++ b/src/csharp/Grpc.Core/build/net45/Grpc.Core.targets
diff --git a/src/csharp/README.md b/src/csharp/README.md
index 92be4bf1e5..d8aed94988 100644
--- a/src/csharp/README.md
+++ b/src/csharp/README.md
@@ -32,6 +32,14 @@ HOW TO USE
- To be able to generate code from Protocol Buffer (`.proto`) file definitions, add the [Grpc.Tools](https://www.nuget.org/packages/Grpc.Tools/) NuGet package that contains Protocol Buffers compiler (_protoc_) and the gRPC _protoc_ plugin.
+**Xamarin.Android and Xamarin.iOS (Experimental only)**
+
+See [Experimentally supported platforms](experimental) for instructions.
+
+**Unity (Experimental only)**
+
+See [Experimentally supported platforms](experimental) for instructions.
+
BUILD FROM SOURCE
-----------------
diff --git a/src/csharp/build_packages_dotnetcli.bat b/src/csharp/build_packages_dotnetcli.bat
index bb0ae71360..8f38f0aa20 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.14.0
+set VERSION=1.15.0-dev
@rem Adjust the location of nuget.exe
set NUGET=C:\nuget\nuget.exe
@@ -21,18 +21,12 @@ set DOTNET=dotnet
mkdir ..\..\artifacts
-@rem Collect the artifacts built by the previous build step if running on Jenkins
+@rem Collect the artifacts built by the previous build step
mkdir nativelibs
-@rem Jenkins flow (deprecated)
-powershell -Command "cp -r ..\..\platform=*\artifacts\csharp_ext_* nativelibs"
-@rem Kokoro flow
powershell -Command "cp -r ..\..\input_artifacts\csharp_ext_* nativelibs"
@rem Collect protoc artifacts built by the previous build step
mkdir protoc_plugins
-@rem Jenkins flow (deprecated)
-powershell -Command "cp -r ..\..\platform=*\artifacts\protoc_* protoc_plugins"
-@rem Kokoro flow
powershell -Command "cp -r ..\..\input_artifacts\protoc_* protoc_plugins"
%DOTNET% restore Grpc.sln || goto :error
diff --git a/src/csharp/build_packages_dotnetcli.sh b/src/csharp/build_packages_dotnetcli.sh
deleted file mode 100755
index e298ea62a9..0000000000
--- a/src/csharp/build_packages_dotnetcli.sh
+++ /dev/null
@@ -1,52 +0,0 @@
-#!/bin/bash
-# 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.
-
-set -ex
-
-cd $(dirname $0)
-
-mkdir -p ../../artifacts/
-
-# Collect the artifacts built by the previous build step
-mkdir -p nativelibs
-# Jenkins flow (deprecated)
-cp -r $EXTERNAL_GIT_ROOT/platform={windows,linux,macos}/artifacts/csharp_ext_* nativelibs || true
-# Kokoro flow
-cp -r $EXTERNAL_GIT_ROOT/input_artifacts/csharp_ext_* nativelibs || true
-
-# Collect protoc artifacts built by the previous build step
-mkdir -p protoc_plugins
-# Jenkins flow (deprecated)
-cp -r $EXTERNAL_GIT_ROOT/platform={windows,linux,macos}/artifacts/protoc_* protoc_plugins || true
-# Kokoro flow
-cp -r $EXTERNAL_GIT_ROOT/input_artifacts/protoc_* protoc_plugins || true
-
-dotnet restore Grpc.sln
-
-# To be able to build, we also need to put grpc_csharp_ext to its normal location
-mkdir -p ../../libs/opt
-cp nativelibs/csharp_ext_linux_x64/libgrpc_csharp_ext.so ../../libs/opt
-
-dotnet pack --configuration Release Grpc.Core --output ../../../artifacts
-dotnet pack --configuration Release Grpc.Core.Testing --output ../../../artifacts
-dotnet pack --configuration Release Grpc.Auth --output ../../../artifacts
-dotnet pack --configuration Release Grpc.HealthCheck --output ../../../artifacts
-dotnet pack --configuration Release Grpc.Reflection --output ../../../artifacts
-
-nuget pack Grpc.nuspec -Version "1.14.0" -OutputDirectory ../../artifacts
-nuget pack Grpc.Core.NativeDebug.nuspec -Version "1.14.0" -OutputDirectory ../../artifacts
-nuget pack Grpc.Tools.nuspec -Version "1.14.0" -OutputDirectory ../../artifacts
-
-(cd ../../artifacts && zip csharp_nugets_dotnetcli.zip *.nupkg)
diff --git a/src/csharp/build_unitypackage.bat b/src/csharp/build_unitypackage.bat
new file mode 100644
index 0000000000..0dcc38ee96
--- /dev/null
+++ b/src/csharp/build_unitypackage.bat
@@ -0,0 +1,78 @@
+@rem Copyright 2018 The gRPC Authors
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem http://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+
+@rem Current package versions
+set VERSION=1.15.0-dev
+
+@rem Adjust the location of nuget.exe
+set NUGET=C:\nuget\nuget.exe
+set DOTNET=dotnet
+
+mkdir ..\..\artifacts
+
+@rem Collect the artifacts built by the previous build step
+mkdir nativelibs
+powershell -Command "cp -r ..\..\input_artifacts\csharp_ext_* nativelibs"
+
+@rem Collect protoc artifacts built by the previous build step
+mkdir protoc_plugins
+powershell -Command "cp -r ..\..\input_artifacts\protoc_* protoc_plugins"
+
+%DOTNET% restore Grpc.sln || goto :error
+
+@rem To be able to build, we also need to put grpc_csharp_ext to its normal location
+xcopy /Y /I nativelibs\csharp_ext_windows_x64\grpc_csharp_ext.dll ..\..\cmake\build\x64\Release\
+
+%DOTNET% build --configuration Release Grpc.Core || goto :error
+@rem build HealthCheck to get hold of Google.Protobuf.dll assembly
+%DOTNET% build --configuration Release Grpc.HealthCheck || goto :error
+
+@rem copy Grpc assemblies to the unity package skeleton
+@rem TODO(jtattermusch): Add Grpc.Auth assembly and its dependencies
+copy /Y Grpc.Core\bin\Release\net45\Grpc.Core.dll unitypackage\unitypackage_skeleton\Plugins\Grpc.Core\lib\net45\Grpc.Core.dll || goto :error
+copy /Y Grpc.Core\bin\Release\net45\Grpc.Core.pdb unitypackage\unitypackage_skeleton\Plugins\Grpc.Core\lib\net45\Grpc.Core.pdb || goto :error
+copy /Y Grpc.Core\bin\Release\net45\Grpc.Core.xml unitypackage\unitypackage_skeleton\Plugins\Grpc.Core\lib\net45\Grpc.Core.xml || goto :error
+
+@rem copy desktop native libraries to the unity package skeleton
+copy /Y nativelibs\csharp_ext_linux_x86\libgrpc_csharp_ext.so unitypackage\unitypackage_skeleton\Plugins\Grpc.Core\runtimes\linux\x86\libgrpc_csharp_ext.so || goto :error
+copy /Y nativelibs\csharp_ext_linux_x64\libgrpc_csharp_ext.so unitypackage\unitypackage_skeleton\Plugins\Grpc.Core\runtimes\linux\x64\libgrpc_csharp_ext.so || goto :error
+copy /Y nativelibs\csharp_ext_macos_x86\libgrpc_csharp_ext.dylib unitypackage\unitypackage_skeleton\Plugins\Grpc.Core\runtimes\osx\x86\grpc_csharp_ext.bundle || goto :error
+copy /Y nativelibs\csharp_ext_macos_x64\libgrpc_csharp_ext.dylib unitypackage\unitypackage_skeleton\Plugins\Grpc.Core\runtimes\osx\x64\grpc_csharp_ext.bundle || goto :error
+copy /Y nativelibs\csharp_ext_windows_x86\grpc_csharp_ext.dll unitypackage\unitypackage_skeleton\Plugins\Grpc.Core\runtimes\win\x86\grpc_csharp_ext.dll || goto :error
+copy /Y nativelibs\csharp_ext_windows_x64\grpc_csharp_ext.dll unitypackage\unitypackage_skeleton\Plugins\Grpc.Core\runtimes\win\x64\grpc_csharp_ext.dll || goto :error
+
+@rem add Android and iOS native libraries
+copy /Y nativelibs\csharp_ext_linux_android_armeabi-v7a\libgrpc_csharp_ext.so unitypackage\unitypackage_skeleton\Plugins\Grpc.Core\runtimes\android\armeabi-v7a\libgrpc_csharp_ext.so || goto :error
+copy /Y nativelibs\csharp_ext_linux_android_arm64-v8a\libgrpc_csharp_ext.so unitypackage\unitypackage_skeleton\Plugins\Grpc.Core\runtimes\android\arm64-v8a\libgrpc_csharp_ext.so || goto :error
+copy /Y nativelibs\csharp_ext_linux_android_x86\libgrpc_csharp_ext.so unitypackage\unitypackage_skeleton\Plugins\Grpc.Core\runtimes\android\x86\libgrpc_csharp_ext.so || goto :error
+copy /Y nativelibs\csharp_ext_macos_ios\libgrpc_csharp_ext.a unitypackage\unitypackage_skeleton\Plugins\Grpc.Core\runtimes\ios\libgrpc_csharp_ext.a || goto :error
+copy /Y nativelibs\csharp_ext_macos_ios\libgrpc.a unitypackage\unitypackage_skeleton\Plugins\Grpc.Core\runtimes\ios\libgrpc.a || goto :error
+
+@rem add gRPC dependencies
+@rem TODO(jtattermusch): also include XMLdoc
+copy /Y Grpc.Core\bin\Release\net45\System.Interactive.Async.dll unitypackage\unitypackage_skeleton\Plugins\System.Interactive.Async\lib\net45\System.Interactive.Async.dll || goto :error
+
+@rem add Google.Protobuf
+@rem TODO(jtattermusch): also include XMLdoc
+copy /Y Grpc.HealthCheck\bin\Release\net45\Google.Protobuf.dll unitypackage\unitypackage_skeleton\Plugins\Google.Protobuf\lib\net45\Google.Protobuf.dll || goto :error
+
+@rem create a zipfile that will act as a Unity package
+powershell -Command "Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::CreateFromDirectory('unitypackage\unitypackage_skeleton', 'grpc_unity_package.zip');"
+copy /Y grpc_unity_package.zip ..\..\artifacts\grpc_unity_package.%VERSION%.zip || goto :error
+
+goto :EOF
+
+:error
+echo Failed!
+exit /b %errorlevel%
diff --git a/src/csharp/doc/docfx.json b/src/csharp/doc/docfx.json
index 7219d0e7a6..0ce5f7262a 100644
--- a/src/csharp/doc/docfx.json
+++ b/src/csharp/doc/docfx.json
@@ -24,7 +24,7 @@
"dest": "api"
},
{
- "files": [ "toc.yml"],
+ "files": [ "toc.yml"]
}
],
"globalMetadata": {
diff --git a/src/csharp/experimental/README.md b/src/csharp/experimental/README.md
index f892a2ee95..bd53cbcd35 100644
--- a/src/csharp/experimental/README.md
+++ b/src/csharp/experimental/README.md
@@ -1,16 +1,35 @@
This directory contains useful resources for getting gRPC C# to work on
-not-yet-supported platforms.
+platforms that are not yet fully supported.
-# Unity & Xamarin
-gRPC C# currently doesn't support Unity or Xamarin, but some proof-of-concept
-work has been done. Some of the resources are shared in this directory to
-ease community work on Unity & Xamarin support.
+# Xamarin
-## Crosscompiling `grpc_csharp_ext` for Android
+gRPC C# now has experimental support for Xamarin.
+See [HelloworldXamarin](/examples/csharp/HelloworldXamarin) for an example how to use it.
-* Install [Android NDK](https://developer.android.com/ndk/index.html)
-* Run `./build_native_ext_for_android.sh` to crosscompile using cmake.
+What's currently supported:
-## Crosscompiling `grpc_csharp_ext` for iOS
+Xamarin.Android
+- supported API level: Kitkat 4.4+ (= API level 19)
+- supported ABIs: `armeabi-v7a` (vast majority of Android devices out there),
+ `arm64-v8a` (some newer Android devices), `x86` (for emulator)
-TBD
+Xamarin.iOS
+- supported architectures: arm64 (iPhone 6+) and x86_64 (iPhone simulator)
+
+# Unity
+
+gRPC C# now has experimental support for Unity. Please try using gRPC with
+Unity and provide feedback!
+
+How to test gRPC in a Unity project
+1. Create a Unity project that targets .NET 4.x (Edit -> Project Settings -> Editor -> Scripting Runtime Version). gRPC uses APIs that are only available in .NET4.5+ so this is a requirement.
+2. Download the latest development build of `grpc_unity_package.VERSION.zip` from
+ [daily builds](https://packages.grpc.io/)
+3. Extract the `.zip` file in the `Assets` directory in your Unity project
+4. Unity IDE will pick up all the bundled files and add them to project automatically.
+ You should be able to use gRPC and Protobuf in your scripts from now on.
+
+What's currently bundled in the `grpc_unity_package`
+- Grpc.Core and its dependencies
+- Google.Protobuf
+- Precompiled native libraries for Linux, MacOS, Windows, Android and iOS.
diff --git a/src/csharp/experimental/build_native_ext_for_android.sh b/src/csharp/experimental/build_native_ext_for_android.sh
index 8197df7c53..6518e03c53 100755
--- a/src/csharp/experimental/build_native_ext_for_android.sh
+++ b/src/csharp/experimental/build_native_ext_for_android.sh
@@ -23,17 +23,30 @@ mkdir -p build
cd build
# set to the location where Android SDK is installed
-# e.g. ANDROID_NDK_PATH="$HOME/android-ndk-r16b"
+# e.g. ANDROID_SDK_PATH="$HOME/Android/Sdk"
-cmake ../.. \
- -DCMAKE_SYSTEM_NAME=Android \
- -DCMAKE_SYSTEM_VERSION=15 \
- -DCMAKE_ANDROID_ARCH_ABI=armeabi-v7a \
+# set to location where Android NDK is installed, usually a subfolder of Android SDK
+# to install the Android NKD, use the "sdkmanager" tool
+# e.g. ANDROID_NDK_PATH=${ANDROID_SDK_PATH}/ndk-bundle
+
+# set to location of the cmake executable from the Android SDK
+# to install cmake, use the "sdkmanager" tool
+# e.g. ANDROID_SDK_CMAKE=${ANDROID_SDK_PATH}/cmake/3.6.4111459/bin/cmake
+
+# ANDROID_ABI in ('arm64-v8a', 'armeabi-v7a')
+# e.g. ANDROID_ABI=armeabi-v7a
+
+# android-19 corresponds to Kitkat 4.4
+${ANDROID_SDK_CMAKE} ../.. \
+ -DCMAKE_TOOLCHAIN_FILE="${ANDROID_NDK_PATH}/build/cmake/android.toolchain.cmake" \
-DCMAKE_ANDROID_NDK="${ANDROID_NDK_PATH}" \
-DCMAKE_ANDROID_STL_TYPE=c++_static \
-DRUN_HAVE_POSIX_REGEX=0 \
-DRUN_HAVE_STD_REGEX=0 \
-DRUN_HAVE_STEADY_CLOCK=0 \
- -DCMAKE_BUILD_TYPE=Release
+ -DCMAKE_BUILD_TYPE=Release \
+ -DANDROID_PLATFORM=android-19 \
+ -DANDROID_ABI="${ANDROID_ABI}" \
+ -DANDROID_NDK="${ANDROID_NDK_PATH}"
make -j4 grpc_csharp_ext
diff --git a/src/csharp/experimental/build_native_ext_for_ios.sh b/src/csharp/experimental/build_native_ext_for_ios.sh
new file mode 100755
index 0000000000..69c9cdf021
--- /dev/null
+++ b/src/csharp/experimental/build_native_ext_for_ios.sh
@@ -0,0 +1,62 @@
+#!/bin/sh
+# 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.
+
+# Helper script to crosscompile grpc_csharp_ext native extension for Android.
+
+set -ex
+
+cd "$(dirname "$0")/../../.."
+
+# Usage: build <iphoneos|iphonesimulator> <arm64|x86_64|...>
+function build {
+ SDK="$1"
+ ARCH="$2"
+
+ PATH_AR="$(xcrun --sdk $SDK --find ar)"
+ PATH_CC="$(xcrun --sdk $SDK --find clang)"
+ PATH_CXX="$(xcrun --sdk $SDK --find clang++)"
+
+ # TODO(jtattermusch): add -mios-version-min=6.0 and -Wl,ios_version_min=6.0
+ CPPFLAGS="-O2 -Wframe-larger-than=16384 -arch $ARCH -isysroot $(xcrun --sdk $SDK --show-sdk-path) -DPB_NO_PACKED_STRUCTS=1"
+ LDFLAGS="-arch $ARCH -isysroot $(xcrun --sdk $SDK --show-sdk-path)"
+
+ # TODO(jtattermusch): revisit the build arguments
+ make -j4 static_csharp \
+ VALID_CONFIG_ios_$ARCH="1" \
+ CC_ios_$ARCH="$PATH_CC" \
+ CXX_ios_$ARCH="$PATH_CXX" \
+ LD_ios_$ARCH="$PATH_CC" \
+ LDXX_ios_$ARCH="$PATH_CXX" \
+ CPPFLAGS_ios_$ARCH="$CPPFLAGS" \
+ LDFLAGS_ios_$ARCH="$LDFLAGS" \
+ DEFINES_ios_$ARCH="NDEBUG" \
+ CONFIG="ios_$ARCH"
+}
+
+# Usage: fatten <grpc_csharp_ext|...>
+function fatten {
+ LIB_NAME="$1"
+
+ mkdir -p libs/ios
+ lipo -create -output libs/ios/lib$LIB_NAME.a \
+ libs/ios_arm64/lib$LIB_NAME.a \
+ libs/ios_x86_64/lib$LIB_NAME.a
+}
+
+build iphoneos arm64
+build iphonesimulator x86_64
+
+fatten grpc
+fatten grpc_csharp_ext
diff --git a/src/csharp/unitypackage/README.md b/src/csharp/unitypackage/README.md
new file mode 100644
index 0000000000..aa8ffb2eca
--- /dev/null
+++ b/src/csharp/unitypackage/README.md
@@ -0,0 +1,13 @@
+# Scripts for building gRPC C# package for Unity
+
+Scripts in this directory are of no interest for end users. They are part
+of internal tooling to automate building of the gRPC C# package for Unity.
+
+- `unitypackage_skeleton` - preconfigured `.meta` files for the unity package
+ layout. The actual assemblies and native libraries will be added into
+ this hierarchy while building the package.
+ Note: The `.meta` file were created by the Unity IDE by manually adding the assemblies/native libraries
+ to a Unity project and configuring their target plaform/architecture in the UI (these setting get recorded in
+ `.meta` files). The `.meta` format is not very well documented and there seems to be no easy way to generate them
+ automatically.
+ \ No newline at end of file
diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Google.Protobuf.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Google.Protobuf.meta
new file mode 100644
index 0000000000..c9d3ca96b7
--- /dev/null
+++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Google.Protobuf.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 4b6ebd913ac610041b63fc847ee96302
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Google.Protobuf/lib.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Google.Protobuf/lib.meta
new file mode 100644
index 0000000000..d415abf6dd
--- /dev/null
+++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Google.Protobuf/lib.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: e4ab5b3f8a676a84a9eb3ffcf1e8138d
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Google.Protobuf/lib/net45.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Google.Protobuf/lib/net45.meta
new file mode 100644
index 0000000000..b7670b6f72
--- /dev/null
+++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Google.Protobuf/lib/net45.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 4c50e24955a9a294b99ad097ae2e252a
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Google.Protobuf/lib/net45/Google.Protobuf.dll.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Google.Protobuf/lib/net45/Google.Protobuf.dll.meta
new file mode 100644
index 0000000000..d6a537838e
--- /dev/null
+++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Google.Protobuf/lib/net45/Google.Protobuf.dll.meta
@@ -0,0 +1,30 @@
+fileFormatVersion: 2
+guid: 286edf5aec6aae64697e5e8b7ab9b60e
+PluginImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ iconMap: {}
+ executionOrder: {}
+ isPreloaded: 0
+ isOverridable: 0
+ platformData:
+ - first:
+ Any:
+ second:
+ enabled: 1
+ settings: {}
+ - first:
+ Editor: Editor
+ second:
+ enabled: 0
+ settings:
+ DefaultValueInitialized: true
+ - first:
+ Windows Store Apps: WindowsStoreApps
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Google.Protobuf/lib/net45/Google.Protobuf.xml.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Google.Protobuf/lib/net45/Google.Protobuf.xml.meta
new file mode 100644
index 0000000000..2b706c1910
--- /dev/null
+++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Google.Protobuf/lib/net45/Google.Protobuf.xml.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 22de11620a7e57e41bc221729937524c
+TextScriptImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.meta
new file mode 100644
index 0000000000..47737027ee
--- /dev/null
+++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core.meta
@@ -0,0 +1,10 @@
+fileFormatVersion: 2
+guid: e28eaddc034fe664591e93e8816968aa
+folderAsset: yes
+timeCreated: 1531219385
+licenseType: Free
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/lib.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/lib.meta
new file mode 100644
index 0000000000..0e284f0be5
--- /dev/null
+++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/lib.meta
@@ -0,0 +1,10 @@
+fileFormatVersion: 2
+guid: 1f862d451f11a2442aeac99ad2827285
+folderAsset: yes
+timeCreated: 1531219385
+licenseType: Free
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/lib/net45.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/lib/net45.meta
new file mode 100644
index 0000000000..85acb0b286
--- /dev/null
+++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/lib/net45.meta
@@ -0,0 +1,10 @@
+fileFormatVersion: 2
+guid: 89bdbe2a1282d4e40ba11e96b1481d09
+folderAsset: yes
+timeCreated: 1531219385
+licenseType: Free
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/lib/net45/Grpc.Core.dll.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/lib/net45/Grpc.Core.dll.meta
new file mode 100644
index 0000000000..f22a7c4c3b
--- /dev/null
+++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/lib/net45/Grpc.Core.dll.meta
@@ -0,0 +1,32 @@
+fileFormatVersion: 2
+guid: 63fdcd70d29d1dc49b4e61e22a9e96e1
+timeCreated: 1531219386
+licenseType: Free
+PluginImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ iconMap: {}
+ executionOrder: {}
+ isPreloaded: 0
+ isOverridable: 0
+ platformData:
+ - first:
+ Any:
+ second:
+ enabled: 1
+ settings: {}
+ - first:
+ Editor: Editor
+ second:
+ enabled: 0
+ settings:
+ DefaultValueInitialized: true
+ - first:
+ Windows Store Apps: WindowsStoreApps
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/lib/net45/Grpc.Core.pdb.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/lib/net45/Grpc.Core.pdb.meta
new file mode 100644
index 0000000000..d3390e9673
--- /dev/null
+++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/lib/net45/Grpc.Core.pdb.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 49a6ef383d4d43640b6c7fd8168415ae
+timeCreated: 1531219385
+licenseType: Free
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/lib/net45/Grpc.Core.xml.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/lib/net45/Grpc.Core.xml.meta
new file mode 100644
index 0000000000..2c1a532920
--- /dev/null
+++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/lib/net45/Grpc.Core.xml.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: ec9cf7702008ac648af0687c05064f78
+timeCreated: 1531219386
+licenseType: Free
+TextScriptImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes.meta
new file mode 100644
index 0000000000..921669fdd3
--- /dev/null
+++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes.meta
@@ -0,0 +1,10 @@
+fileFormatVersion: 2
+guid: 643bdb9ca01174f4eb77e3e15f8324b3
+folderAsset: yes
+timeCreated: 1531219385
+licenseType: Free
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/android.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/android.meta
new file mode 100644
index 0000000000..489e8ddd46
--- /dev/null
+++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/android.meta
@@ -0,0 +1,10 @@
+fileFormatVersion: 2
+guid: f7f79be62cf24a940be0211dab5d2e5e
+folderAsset: yes
+timeCreated: 1531220113
+licenseType: Free
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/android/arm64-v8a.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/android/arm64-v8a.meta
new file mode 100644
index 0000000000..976b74b6e2
--- /dev/null
+++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/android/arm64-v8a.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 47ba39f5fad6b49c5aae011940e9eea2
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/android/arm64-v8a/libgrpc_csharp_ext.so.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/android/arm64-v8a/libgrpc_csharp_ext.so.meta
new file mode 100644
index 0000000000..ccaf0c20ec
--- /dev/null
+++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/android/arm64-v8a/libgrpc_csharp_ext.so.meta
@@ -0,0 +1,102 @@
+fileFormatVersion: 2
+guid: e5beceb1c8fb2403ab3dea319dcd9a2e
+PluginImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ iconMap: {}
+ executionOrder: {}
+ isPreloaded: 0
+ isOverridable: 0
+ platformData:
+ - first:
+ '': Any
+ second:
+ enabled: 0
+ settings:
+ Exclude Android: 0
+ Exclude Editor: 1
+ Exclude Linux: 1
+ Exclude Linux64: 1
+ Exclude LinuxUniversal: 1
+ Exclude OSXUniversal: 1
+ Exclude Win: 1
+ Exclude Win64: 1
+ Exclude iOS: 1
+ - first:
+ Android: Android
+ second:
+ enabled: 1
+ settings:
+ CPU: ARM64
+ - first:
+ Any:
+ second:
+ enabled: 0
+ settings: {}
+ - first:
+ Editor: Editor
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ DefaultValueInitialized: true
+ OS: AnyOS
+ - first:
+ Facebook: Win
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ - first:
+ Facebook: Win64
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ - first:
+ Standalone: Linux
+ second:
+ enabled: 0
+ settings:
+ CPU: x86
+ - first:
+ Standalone: Linux64
+ second:
+ enabled: 0
+ settings:
+ CPU: x86_64
+ - first:
+ Standalone: LinuxUniversal
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ - first:
+ Standalone: OSXUniversal
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ - first:
+ Standalone: Win
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ - first:
+ Standalone: Win64
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ - first:
+ iPhone: iOS
+ second:
+ enabled: 0
+ settings:
+ AddToEmbeddedBinaries: false
+ CompileFlags:
+ FrameworkDependencies:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/android/armeabi-v7a.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/android/armeabi-v7a.meta
new file mode 100644
index 0000000000..36a3b7e6ca
--- /dev/null
+++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/android/armeabi-v7a.meta
@@ -0,0 +1,10 @@
+fileFormatVersion: 2
+guid: de2aa4d10bc38f54fb8345aca9b21195
+folderAsset: yes
+timeCreated: 1531220167
+licenseType: Free
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/android/armeabi-v7a/libgrpc_csharp_ext.so.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/android/armeabi-v7a/libgrpc_csharp_ext.so.meta
new file mode 100644
index 0000000000..1560e207fb
--- /dev/null
+++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/android/armeabi-v7a/libgrpc_csharp_ext.so.meta
@@ -0,0 +1,102 @@
+fileFormatVersion: 2
+guid: e5beceb1c8fb2403ab3dea319dcd9a2e
+PluginImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ iconMap: {}
+ executionOrder: {}
+ isPreloaded: 0
+ isOverridable: 0
+ platformData:
+ - first:
+ '': Any
+ second:
+ enabled: 0
+ settings:
+ Exclude Android: 0
+ Exclude Editor: 1
+ Exclude Linux: 1
+ Exclude Linux64: 1
+ Exclude LinuxUniversal: 1
+ Exclude OSXUniversal: 1
+ Exclude Win: 1
+ Exclude Win64: 1
+ Exclude iOS: 1
+ - first:
+ Android: Android
+ second:
+ enabled: 1
+ settings:
+ CPU: ARMv7
+ - first:
+ Any:
+ second:
+ enabled: 0
+ settings: {}
+ - first:
+ Editor: Editor
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ DefaultValueInitialized: true
+ OS: AnyOS
+ - first:
+ Facebook: Win
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ - first:
+ Facebook: Win64
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ - first:
+ Standalone: Linux
+ second:
+ enabled: 0
+ settings:
+ CPU: x86
+ - first:
+ Standalone: Linux64
+ second:
+ enabled: 0
+ settings:
+ CPU: x86_64
+ - first:
+ Standalone: LinuxUniversal
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ - first:
+ Standalone: OSXUniversal
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ - first:
+ Standalone: Win
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ - first:
+ Standalone: Win64
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ - first:
+ iPhone: iOS
+ second:
+ enabled: 0
+ settings:
+ AddToEmbeddedBinaries: false
+ CompileFlags:
+ FrameworkDependencies:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/android/x86.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/android/x86.meta
new file mode 100644
index 0000000000..53032587eb
--- /dev/null
+++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/android/x86.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 800ab3aa15d1b49b19df1caf1315bd3e
+folderAsset: yes
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/android/x86/libgrpc_csharp_ext.so.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/android/x86/libgrpc_csharp_ext.so.meta
new file mode 100644
index 0000000000..4e216b8b42
--- /dev/null
+++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/android/x86/libgrpc_csharp_ext.so.meta
@@ -0,0 +1,102 @@
+fileFormatVersion: 2
+guid: e5beceb1c8fb2403ab3dea319dcd9a2e
+PluginImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ iconMap: {}
+ executionOrder: {}
+ isPreloaded: 0
+ isOverridable: 0
+ platformData:
+ - first:
+ '': Any
+ second:
+ enabled: 0
+ settings:
+ Exclude Android: 0
+ Exclude Editor: 1
+ Exclude Linux: 1
+ Exclude Linux64: 1
+ Exclude LinuxUniversal: 1
+ Exclude OSXUniversal: 1
+ Exclude Win: 1
+ Exclude Win64: 1
+ Exclude iOS: 1
+ - first:
+ Android: Android
+ second:
+ enabled: 1
+ settings:
+ CPU: x86
+ - first:
+ Any:
+ second:
+ enabled: 0
+ settings: {}
+ - first:
+ Editor: Editor
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ DefaultValueInitialized: true
+ OS: AnyOS
+ - first:
+ Facebook: Win
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ - first:
+ Facebook: Win64
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ - first:
+ Standalone: Linux
+ second:
+ enabled: 0
+ settings:
+ CPU: x86
+ - first:
+ Standalone: Linux64
+ second:
+ enabled: 0
+ settings:
+ CPU: x86_64
+ - first:
+ Standalone: LinuxUniversal
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ - first:
+ Standalone: OSXUniversal
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ - first:
+ Standalone: Win
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ - first:
+ Standalone: Win64
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ - first:
+ iPhone: iOS
+ second:
+ enabled: 0
+ settings:
+ AddToEmbeddedBinaries: false
+ CompileFlags:
+ FrameworkDependencies:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/ios.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/ios.meta
new file mode 100644
index 0000000000..5d3259e209
--- /dev/null
+++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/ios.meta
@@ -0,0 +1,10 @@
+fileFormatVersion: 2
+guid: a5f54f019e6510541ac61eeec96aa82d
+folderAsset: yes
+timeCreated: 1531456012
+licenseType: Pro
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/ios/libgrpc.a.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/ios/libgrpc.a.meta
new file mode 100644
index 0000000000..3647568a8b
--- /dev/null
+++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/ios/libgrpc.a.meta
@@ -0,0 +1,95 @@
+fileFormatVersion: 2
+guid: dde9f75258bae4033a4f778fd1149ccd
+PluginImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ iconMap: {}
+ executionOrder: {}
+ isPreloaded: 0
+ isOverridable: 0
+ platformData:
+ - first:
+ '': Any
+ second:
+ enabled: 0
+ settings:
+ Exclude Editor: 1
+ Exclude Linux: 1
+ Exclude Linux64: 1
+ Exclude LinuxUniversal: 1
+ Exclude OSXUniversal: 1
+ Exclude Win: 1
+ Exclude Win64: 1
+ Exclude iOS: 0
+ - first:
+ Any:
+ second:
+ enabled: 0
+ settings: {}
+ - first:
+ Editor: Editor
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ DefaultValueInitialized: true
+ OS: AnyOS
+ - first:
+ Facebook: Win
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ - first:
+ Facebook: Win64
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ - first:
+ Standalone: Linux
+ second:
+ enabled: 0
+ settings:
+ CPU: x86
+ - first:
+ Standalone: Linux64
+ second:
+ enabled: 0
+ settings:
+ CPU: x86_64
+ - first:
+ Standalone: LinuxUniversal
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ - first:
+ Standalone: OSXUniversal
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ - first:
+ Standalone: Win
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ - first:
+ Standalone: Win64
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ - first:
+ iPhone: iOS
+ second:
+ enabled: 1
+ settings:
+ AddToEmbeddedBinaries: false
+ CompileFlags:
+ FrameworkDependencies:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/ios/libgrpc_csharp_ext.a.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/ios/libgrpc_csharp_ext.a.meta
new file mode 100644
index 0000000000..af8485851f
--- /dev/null
+++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/ios/libgrpc_csharp_ext.a.meta
@@ -0,0 +1,117 @@
+fileFormatVersion: 2
+guid: 83f99c0e7db71754ba8927bbfb83c668
+timeCreated: 1531456013
+licenseType: Pro
+PluginImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ iconMap: {}
+ executionOrder: {}
+ isPreloaded: 0
+ isOverridable: 0
+ platformData:
+ - first:
+ '': Any
+ second:
+ enabled: 0
+ settings:
+ Exclude Android: 1
+ Exclude Editor: 1
+ Exclude Linux: 1
+ Exclude Linux64: 1
+ Exclude LinuxUniversal: 1
+ Exclude OSXIntel: 1
+ Exclude OSXIntel64: 1
+ Exclude OSXUniversal: 1
+ Exclude Win: 1
+ Exclude Win64: 1
+ Exclude iOS: 0
+ - first:
+ Android: Android
+ second:
+ enabled: 0
+ settings:
+ CPU: ARMv7
+ - first:
+ Any:
+ second:
+ enabled: 0
+ settings: {}
+ - first:
+ Editor: Editor
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ DefaultValueInitialized: true
+ OS: AnyOS
+ - first:
+ Facebook: Win
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ - first:
+ Facebook: Win64
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ - first:
+ Standalone: Linux
+ second:
+ enabled: 0
+ settings:
+ CPU: x86
+ - first:
+ Standalone: Linux64
+ second:
+ enabled: 0
+ settings:
+ CPU: x86_64
+ - first:
+ Standalone: LinuxUniversal
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ - first:
+ Standalone: OSXIntel
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ - first:
+ Standalone: OSXIntel64
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ - first:
+ Standalone: OSXUniversal
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ - first:
+ Standalone: Win
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ - first:
+ Standalone: Win64
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ - first:
+ iPhone: iOS
+ second:
+ enabled: 1
+ settings:
+ CompileFlags:
+ FrameworkDependencies:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/linux.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/linux.meta
new file mode 100644
index 0000000000..9fc0e64785
--- /dev/null
+++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/linux.meta
@@ -0,0 +1,10 @@
+fileFormatVersion: 2
+guid: 1ff40de7dc502c14e8893c7679e9f44a
+folderAsset: yes
+timeCreated: 1531219385
+licenseType: Free
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/linux/x64.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/linux/x64.meta
new file mode 100644
index 0000000000..28d3c0fd8d
--- /dev/null
+++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/linux/x64.meta
@@ -0,0 +1,10 @@
+fileFormatVersion: 2
+guid: 08ccfdbfbd8d2d6458eb44d41a7b0b0a
+folderAsset: yes
+timeCreated: 1531219385
+licenseType: Free
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/linux/x64/libgrpc_csharp_ext.so.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/linux/x64/libgrpc_csharp_ext.so.meta
new file mode 100644
index 0000000000..0d639762e8
--- /dev/null
+++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/linux/x64/libgrpc_csharp_ext.so.meta
@@ -0,0 +1,117 @@
+fileFormatVersion: 2
+guid: c176dc12f2803e14bb37bcd0ba4a0718
+timeCreated: 1531219386
+licenseType: Free
+PluginImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ iconMap: {}
+ executionOrder: {}
+ isPreloaded: 0
+ isOverridable: 0
+ platformData:
+ - first:
+ '': Any
+ second:
+ enabled: 0
+ settings:
+ Exclude Android: 1
+ Exclude Editor: 0
+ Exclude Linux: 1
+ Exclude Linux64: 0
+ Exclude LinuxUniversal: 0
+ Exclude OSXIntel: 1
+ Exclude OSXIntel64: 1
+ Exclude OSXUniversal: 1
+ Exclude Win: 0
+ Exclude Win64: 0
+ Exclude iOS: 1
+ - first:
+ Android: Android
+ second:
+ enabled: 0
+ settings:
+ CPU: ARMv7
+ - first:
+ Any:
+ second:
+ enabled: 0
+ settings: {}
+ - first:
+ Editor: Editor
+ second:
+ enabled: 1
+ settings:
+ CPU: x86_64
+ DefaultValueInitialized: true
+ OS: Linux
+ - first:
+ Facebook: Win
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ - first:
+ Facebook: Win64
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ - first:
+ Standalone: Linux
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ - first:
+ Standalone: Linux64
+ second:
+ enabled: 1
+ settings:
+ CPU: x86_64
+ - first:
+ Standalone: LinuxUniversal
+ second:
+ enabled: 1
+ settings:
+ CPU: x86_64
+ - first:
+ Standalone: OSXIntel
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ - first:
+ Standalone: OSXIntel64
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ - first:
+ Standalone: OSXUniversal
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ - first:
+ Standalone: Win
+ second:
+ enabled: 1
+ settings:
+ CPU: AnyCPU
+ - first:
+ Standalone: Win64
+ second:
+ enabled: 1
+ settings:
+ CPU: AnyCPU
+ - first:
+ iPhone: iOS
+ second:
+ enabled: 0
+ settings:
+ CompileFlags:
+ FrameworkDependencies:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/linux/x86.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/linux/x86.meta
new file mode 100644
index 0000000000..b050a3b23f
--- /dev/null
+++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/linux/x86.meta
@@ -0,0 +1,10 @@
+fileFormatVersion: 2
+guid: d62d998e3cdebd542a967743103c64b6
+folderAsset: yes
+timeCreated: 1531219385
+licenseType: Free
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/linux/x86/libgrpc_csharp_ext.so.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/linux/x86/libgrpc_csharp_ext.so.meta
new file mode 100644
index 0000000000..f597b1aa23
--- /dev/null
+++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/linux/x86/libgrpc_csharp_ext.so.meta
@@ -0,0 +1,117 @@
+fileFormatVersion: 2
+guid: 0165d78fa73d0cc4c8984f3d4f2a6c86
+timeCreated: 1531219386
+licenseType: Free
+PluginImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ iconMap: {}
+ executionOrder: {}
+ isPreloaded: 0
+ isOverridable: 0
+ platformData:
+ - first:
+ '': Any
+ second:
+ enabled: 0
+ settings:
+ Exclude Android: 1
+ Exclude Editor: 0
+ Exclude Linux: 0
+ Exclude Linux64: 1
+ Exclude LinuxUniversal: 0
+ Exclude OSXIntel: 1
+ Exclude OSXIntel64: 1
+ Exclude OSXUniversal: 1
+ Exclude Win: 0
+ Exclude Win64: 0
+ Exclude iOS: 1
+ - first:
+ Android: Android
+ second:
+ enabled: 0
+ settings:
+ CPU: ARMv7
+ - first:
+ Any:
+ second:
+ enabled: 0
+ settings: {}
+ - first:
+ Editor: Editor
+ second:
+ enabled: 1
+ settings:
+ CPU: x86
+ DefaultValueInitialized: true
+ OS: Linux
+ - first:
+ Facebook: Win
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ - first:
+ Facebook: Win64
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ - first:
+ Standalone: Linux
+ second:
+ enabled: 1
+ settings:
+ CPU: x86
+ - first:
+ Standalone: Linux64
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ - first:
+ Standalone: LinuxUniversal
+ second:
+ enabled: 1
+ settings:
+ CPU: x86
+ - first:
+ Standalone: OSXIntel
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ - first:
+ Standalone: OSXIntel64
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ - first:
+ Standalone: OSXUniversal
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ - first:
+ Standalone: Win
+ second:
+ enabled: 1
+ settings:
+ CPU: AnyCPU
+ - first:
+ Standalone: Win64
+ second:
+ enabled: 1
+ settings:
+ CPU: AnyCPU
+ - first:
+ iPhone: iOS
+ second:
+ enabled: 0
+ settings:
+ CompileFlags:
+ FrameworkDependencies:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/osx.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/osx.meta
new file mode 100644
index 0000000000..cc9c9b60ff
--- /dev/null
+++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/osx.meta
@@ -0,0 +1,10 @@
+fileFormatVersion: 2
+guid: 7b1ebe888da0a174c95a712766d2558c
+folderAsset: yes
+timeCreated: 1531219385
+licenseType: Free
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/osx/x64.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/osx/x64.meta
new file mode 100644
index 0000000000..d01c158c67
--- /dev/null
+++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/osx/x64.meta
@@ -0,0 +1,10 @@
+fileFormatVersion: 2
+guid: ccea531b15a71974a91329186dd65075
+folderAsset: yes
+timeCreated: 1531219385
+licenseType: Free
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/osx/x64/grpc_csharp_ext.bundle.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/osx/x64/grpc_csharp_ext.bundle.meta
new file mode 100644
index 0000000000..9d192f59e5
--- /dev/null
+++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/osx/x64/grpc_csharp_ext.bundle.meta
@@ -0,0 +1,117 @@
+fileFormatVersion: 2
+guid: da53c729add26524fbecb84a7b599289
+timeCreated: 1531219386
+licenseType: Free
+PluginImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ iconMap: {}
+ executionOrder: {}
+ isPreloaded: 0
+ isOverridable: 0
+ platformData:
+ - first:
+ '': Any
+ second:
+ enabled: 0
+ settings:
+ Exclude Android: 1
+ Exclude Editor: 0
+ Exclude Linux: 1
+ Exclude Linux64: 1
+ Exclude LinuxUniversal: 1
+ Exclude OSXIntel: 1
+ Exclude OSXIntel64: 0
+ Exclude OSXUniversal: 0
+ Exclude Win: 1
+ Exclude Win64: 1
+ Exclude iOS: 1
+ - first:
+ Android: Android
+ second:
+ enabled: 0
+ settings:
+ CPU: ARMv7
+ - first:
+ Any:
+ second:
+ enabled: 0
+ settings: {}
+ - first:
+ Editor: Editor
+ second:
+ enabled: 1
+ settings:
+ CPU: x86_64
+ DefaultValueInitialized: true
+ OS: OSX
+ - first:
+ Facebook: Win
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ - first:
+ Facebook: Win64
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ - first:
+ Standalone: Linux
+ second:
+ enabled: 0
+ settings:
+ CPU: x86
+ - first:
+ Standalone: Linux64
+ second:
+ enabled: 0
+ settings:
+ CPU: x86_64
+ - first:
+ Standalone: LinuxUniversal
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ - first:
+ Standalone: OSXIntel
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ - first:
+ Standalone: OSXIntel64
+ second:
+ enabled: 1
+ settings:
+ CPU: AnyCPU
+ - first:
+ Standalone: OSXUniversal
+ second:
+ enabled: 1
+ settings:
+ CPU: x86_64
+ - first:
+ Standalone: Win
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ - first:
+ Standalone: Win64
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ - first:
+ iPhone: iOS
+ second:
+ enabled: 0
+ settings:
+ CompileFlags:
+ FrameworkDependencies:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/osx/x86.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/osx/x86.meta
new file mode 100644
index 0000000000..17713f8c94
--- /dev/null
+++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/osx/x86.meta
@@ -0,0 +1,10 @@
+fileFormatVersion: 2
+guid: 2ee63d0ffcfa72a4fbd7ad04ba34cadb
+folderAsset: yes
+timeCreated: 1531219385
+licenseType: Free
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/osx/x86/grpc_csharp_ext.bundle.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/osx/x86/grpc_csharp_ext.bundle.meta
new file mode 100644
index 0000000000..53822bbe0c
--- /dev/null
+++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/osx/x86/grpc_csharp_ext.bundle.meta
@@ -0,0 +1,117 @@
+fileFormatVersion: 2
+guid: 34ec9b69f128d6d4fa3fb46bc70b547c
+timeCreated: 1531219386
+licenseType: Free
+PluginImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ iconMap: {}
+ executionOrder: {}
+ isPreloaded: 0
+ isOverridable: 0
+ platformData:
+ - first:
+ '': Any
+ second:
+ enabled: 0
+ settings:
+ Exclude Android: 1
+ Exclude Editor: 0
+ Exclude Linux: 1
+ Exclude Linux64: 1
+ Exclude LinuxUniversal: 1
+ Exclude OSXIntel: 0
+ Exclude OSXIntel64: 1
+ Exclude OSXUniversal: 0
+ Exclude Win: 1
+ Exclude Win64: 1
+ Exclude iOS: 1
+ - first:
+ Android: Android
+ second:
+ enabled: 0
+ settings:
+ CPU: ARMv7
+ - first:
+ Any:
+ second:
+ enabled: 0
+ settings: {}
+ - first:
+ Editor: Editor
+ second:
+ enabled: 1
+ settings:
+ CPU: x86
+ DefaultValueInitialized: true
+ OS: OSX
+ - first:
+ Facebook: Win
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ - first:
+ Facebook: Win64
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ - first:
+ Standalone: Linux
+ second:
+ enabled: 0
+ settings:
+ CPU: x86
+ - first:
+ Standalone: Linux64
+ second:
+ enabled: 0
+ settings:
+ CPU: x86_64
+ - first:
+ Standalone: LinuxUniversal
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ - first:
+ Standalone: OSXIntel
+ second:
+ enabled: 1
+ settings:
+ CPU: AnyCPU
+ - first:
+ Standalone: OSXIntel64
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ - first:
+ Standalone: OSXUniversal
+ second:
+ enabled: 1
+ settings:
+ CPU: x86
+ - first:
+ Standalone: Win
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ - first:
+ Standalone: Win64
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ - first:
+ iPhone: iOS
+ second:
+ enabled: 0
+ settings:
+ CompileFlags:
+ FrameworkDependencies:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/win.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/win.meta
new file mode 100644
index 0000000000..1491ee6f0d
--- /dev/null
+++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/win.meta
@@ -0,0 +1,10 @@
+fileFormatVersion: 2
+guid: 928a9392668000344b70b6fd126e522c
+folderAsset: yes
+timeCreated: 1531219385
+licenseType: Free
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/win/x64.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/win/x64.meta
new file mode 100644
index 0000000000..ac2a063f98
--- /dev/null
+++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/win/x64.meta
@@ -0,0 +1,10 @@
+fileFormatVersion: 2
+guid: 34969b8c99d7a934eaa5e84da9fcf326
+folderAsset: yes
+timeCreated: 1531219385
+licenseType: Free
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/win/x64/grpc_csharp_ext.dll.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/win/x64/grpc_csharp_ext.dll.meta
new file mode 100644
index 0000000000..a42f84fc8a
--- /dev/null
+++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/win/x64/grpc_csharp_ext.dll.meta
@@ -0,0 +1,117 @@
+fileFormatVersion: 2
+guid: cb634ddbaed75c344a6b79bc91ca996e
+timeCreated: 1531219386
+licenseType: Free
+PluginImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ iconMap: {}
+ executionOrder: {}
+ isPreloaded: 0
+ isOverridable: 0
+ platformData:
+ - first:
+ '': Any
+ second:
+ enabled: 0
+ settings:
+ Exclude Android: 1
+ Exclude Editor: 0
+ Exclude Linux: 0
+ Exclude Linux64: 0
+ Exclude LinuxUniversal: 0
+ Exclude OSXIntel: 0
+ Exclude OSXIntel64: 0
+ Exclude OSXUniversal: 0
+ Exclude Win: 1
+ Exclude Win64: 0
+ Exclude iOS: 1
+ - first:
+ Android: Android
+ second:
+ enabled: 0
+ settings:
+ CPU: ARMv7
+ - first:
+ Any:
+ second:
+ enabled: 0
+ settings: {}
+ - first:
+ Editor: Editor
+ second:
+ enabled: 1
+ settings:
+ CPU: x86_64
+ DefaultValueInitialized: true
+ OS: Windows
+ - first:
+ Facebook: Win
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ - first:
+ Facebook: Win64
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ - first:
+ Standalone: Linux
+ second:
+ enabled: 1
+ settings:
+ CPU: x86
+ - first:
+ Standalone: Linux64
+ second:
+ enabled: 1
+ settings:
+ CPU: x86_64
+ - first:
+ Standalone: LinuxUniversal
+ second:
+ enabled: 1
+ settings:
+ CPU: AnyCPU
+ - first:
+ Standalone: OSXIntel
+ second:
+ enabled: 1
+ settings:
+ CPU: AnyCPU
+ - first:
+ Standalone: OSXIntel64
+ second:
+ enabled: 1
+ settings:
+ CPU: AnyCPU
+ - first:
+ Standalone: OSXUniversal
+ second:
+ enabled: 1
+ settings:
+ CPU: AnyCPU
+ - first:
+ Standalone: Win
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ - first:
+ Standalone: Win64
+ second:
+ enabled: 1
+ settings:
+ CPU: AnyCPU
+ - first:
+ iPhone: iOS
+ second:
+ enabled: 0
+ settings:
+ CompileFlags:
+ FrameworkDependencies:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/win/x86.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/win/x86.meta
new file mode 100644
index 0000000000..f3eb146cc8
--- /dev/null
+++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/win/x86.meta
@@ -0,0 +1,10 @@
+fileFormatVersion: 2
+guid: ed5c6044f868f9a4f955b7db2d2df619
+folderAsset: yes
+timeCreated: 1531219385
+licenseType: Free
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/win/x86/grpc_csharp_ext.dll.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/win/x86/grpc_csharp_ext.dll.meta
new file mode 100644
index 0000000000..bd6291eafc
--- /dev/null
+++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/Grpc.Core/runtimes/win/x86/grpc_csharp_ext.dll.meta
@@ -0,0 +1,117 @@
+fileFormatVersion: 2
+guid: fe9aa1338bfc3864eb50df0f9d648316
+timeCreated: 1531219386
+licenseType: Free
+PluginImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ iconMap: {}
+ executionOrder: {}
+ isPreloaded: 0
+ isOverridable: 0
+ platformData:
+ - first:
+ '': Any
+ second:
+ enabled: 0
+ settings:
+ Exclude Android: 1
+ Exclude Editor: 0
+ Exclude Linux: 0
+ Exclude Linux64: 0
+ Exclude LinuxUniversal: 0
+ Exclude OSXIntel: 0
+ Exclude OSXIntel64: 0
+ Exclude OSXUniversal: 0
+ Exclude Win: 0
+ Exclude Win64: 1
+ Exclude iOS: 1
+ - first:
+ Android: Android
+ second:
+ enabled: 0
+ settings:
+ CPU: ARMv7
+ - first:
+ Any:
+ second:
+ enabled: 0
+ settings: {}
+ - first:
+ Editor: Editor
+ second:
+ enabled: 1
+ settings:
+ CPU: x86
+ DefaultValueInitialized: true
+ OS: Windows
+ - first:
+ Facebook: Win
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ - first:
+ Facebook: Win64
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ - first:
+ Standalone: Linux
+ second:
+ enabled: 1
+ settings:
+ CPU: x86
+ - first:
+ Standalone: Linux64
+ second:
+ enabled: 1
+ settings:
+ CPU: x86_64
+ - first:
+ Standalone: LinuxUniversal
+ second:
+ enabled: 1
+ settings:
+ CPU: AnyCPU
+ - first:
+ Standalone: OSXIntel
+ second:
+ enabled: 1
+ settings:
+ CPU: AnyCPU
+ - first:
+ Standalone: OSXIntel64
+ second:
+ enabled: 1
+ settings:
+ CPU: AnyCPU
+ - first:
+ Standalone: OSXUniversal
+ second:
+ enabled: 1
+ settings:
+ CPU: AnyCPU
+ - first:
+ Standalone: Win
+ second:
+ enabled: 1
+ settings:
+ CPU: AnyCPU
+ - first:
+ Standalone: Win64
+ second:
+ enabled: 0
+ settings:
+ CPU: None
+ - first:
+ iPhone: iOS
+ second:
+ enabled: 0
+ settings:
+ CompileFlags:
+ FrameworkDependencies:
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Interactive.Async.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Interactive.Async.meta
new file mode 100644
index 0000000000..6f1b910534
--- /dev/null
+++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Interactive.Async.meta
@@ -0,0 +1,10 @@
+fileFormatVersion: 2
+guid: b2ba2199282e9c641bc2e611f1e776a0
+folderAsset: yes
+timeCreated: 1531219385
+licenseType: Free
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Interactive.Async/lib.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Interactive.Async/lib.meta
new file mode 100644
index 0000000000..d7ae012a39
--- /dev/null
+++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Interactive.Async/lib.meta
@@ -0,0 +1,10 @@
+fileFormatVersion: 2
+guid: bd5ddd2522dc301488ffe002106fe0ab
+folderAsset: yes
+timeCreated: 1531219385
+licenseType: Free
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Interactive.Async/lib/net45.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Interactive.Async/lib/net45.meta
new file mode 100644
index 0000000000..9b1748d3e7
--- /dev/null
+++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Interactive.Async/lib/net45.meta
@@ -0,0 +1,10 @@
+fileFormatVersion: 2
+guid: a68443518bcd1d44ba88a871dcab0c83
+folderAsset: yes
+timeCreated: 1531219385
+licenseType: Free
+DefaultImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Interactive.Async/lib/net45/System.Interactive.Async.dll.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Interactive.Async/lib/net45/System.Interactive.Async.dll.meta
new file mode 100644
index 0000000000..bb910fe922
--- /dev/null
+++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Interactive.Async/lib/net45/System.Interactive.Async.dll.meta
@@ -0,0 +1,32 @@
+fileFormatVersion: 2
+guid: 4c05e46cbf00c68408f5ddc1eef9ae3b
+timeCreated: 1531219386
+licenseType: Free
+PluginImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ iconMap: {}
+ executionOrder: {}
+ isPreloaded: 0
+ isOverridable: 0
+ platformData:
+ - first:
+ Any:
+ second:
+ enabled: 1
+ settings: {}
+ - first:
+ Editor: Editor
+ second:
+ enabled: 0
+ settings:
+ DefaultValueInitialized: true
+ - first:
+ Windows Store Apps: WindowsStoreApps
+ second:
+ enabled: 0
+ settings:
+ CPU: AnyCPU
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Interactive.Async/lib/net45/System.Interactive.Async.xml.meta b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Interactive.Async/lib/net45/System.Interactive.Async.xml.meta
new file mode 100644
index 0000000000..53f91502bd
--- /dev/null
+++ b/src/csharp/unitypackage/unitypackage_skeleton/Plugins/System.Interactive.Async/lib/net45/System.Interactive.Async.xml.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 6fc38864f2d3dde46b3833c62c91a008
+timeCreated: 1531219386
+licenseType: Free
+TextScriptImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec b/src/objective-c/!ProtoCompiler-gRPCPlugin.podspec
index bf5b7ae351..6ad9166b32 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.14.0'
+ v = '1.15.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 59c172fc4b..52fe0dd050 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.14.0"
+#define GRPC_OBJC_VERSION_STRING @"1.15.0-dev"
diff --git a/src/objective-c/tests/build_one_example.sh b/src/objective-c/tests/build_one_example.sh
index 1eace541e6..084147f1d4 100755
--- a/src/objective-c/tests/build_one_example.sh
+++ b/src/objective-c/tests/build_one_example.sh
@@ -43,7 +43,7 @@ xcodebuild \
-workspace *.xcworkspace \
-scheme $SCHEME \
-destination generic/platform=iOS \
- -derivedDataPath Build \
+ -derivedDataPath Build/Build \
CODE_SIGN_IDENTITY="" \
CODE_SIGNING_REQUIRED=NO \
| egrep -v "$XCODEBUILD_FILTER" \
diff --git a/src/objective-c/tests/version.h b/src/objective-c/tests/version.h
index d0a4b496c7..d532eed245 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.14.0"
-#define GRPC_C_VERSION_STRING @"6.0.0"
+#define GRPC_OBJC_VERSION_STRING @"1.15.0-dev"
+#define GRPC_C_VERSION_STRING @"6.0.0-dev"
diff --git a/src/php/composer.json b/src/php/composer.json
index 94918417d9..91913d73d2 100644
--- a/src/php/composer.json
+++ b/src/php/composer.json
@@ -2,13 +2,13 @@
"name": "grpc/grpc-dev",
"description": "gRPC library for PHP - for Developement use only",
"license": "Apache-2.0",
- "version": "1.14.0",
+ "version": "1.15.0",
"require": {
"php": ">=5.5.0",
"google/protobuf": "^v3.3.0"
},
"require-dev": {
- "google/auth": "v0.9"
+ "google/auth": "^v1.3.0"
},
"autoload": {
"psr-4": {
diff --git a/src/php/ext/grpc/version.h b/src/php/ext/grpc/version.h
index 22631f126f..99dd9d68f0 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.14.0"
+#define PHP_GRPC_VERSION "1.15.0dev"
#endif /* VERSION_H */
diff --git a/src/php/lib/Grpc/BaseStub.php b/src/php/lib/Grpc/BaseStub.php
index ecb419ac8f..fe81e37761 100644
--- a/src/php/lib/Grpc/BaseStub.php
+++ b/src/php/lib/Grpc/BaseStub.php
@@ -83,10 +83,11 @@ class BaseStub
}
private static function updateOpts($opts) {
- $package_config = json_decode(
- file_get_contents(dirname(__FILE__).'/../../composer.json'),
- true
- );
+ if (!file_exists($composerFile = __DIR__.'/../../composer.json')) {
+ // for grpc/grpc-php subpackage
+ $composerFile = __DIR__.'/../composer.json';
+ }
+ $package_config = json_decode(file_get_contents($composerFile), true);
if (!empty($opts['grpc.primary_user_agent'])) {
$opts['grpc.primary_user_agent'] .= ' ';
} else {
diff --git a/src/proto/grpc/testing/echo_messages.proto b/src/proto/grpc/testing/echo_messages.proto
index 5396a2fd39..2f935304ab 100644
--- a/src/proto/grpc/testing/echo_messages.proto
+++ b/src/proto/grpc/testing/echo_messages.proto
@@ -46,6 +46,7 @@ message RequestParams {
string binary_error_details = 13;
ErrorStatus expected_error = 14;
int32 server_sleep_us = 15; // Amount to sleep when invoking server
+ int32 backend_channel_idx = 16; // which backend to send request to
}
message EchoRequest {
diff --git a/src/python/grpcio/grpc/BUILD.bazel b/src/python/grpcio/grpc/BUILD.bazel
new file mode 100644
index 0000000000..3f214bf3b0
--- /dev/null
+++ b/src/python/grpcio/grpc/BUILD.bazel
@@ -0,0 +1,82 @@
+load("@grpc_python_dependencies//:requirements.bzl", "requirement")
+
+package(default_visibility = ["//visibility:public"])
+
+py_binary(
+ name = "grpcio",
+ srcs = ["__init__.py"],
+ deps = [
+ ":utilities",
+ ":auth",
+ ":plugin_wrapping",
+ ":channel",
+ ":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'),
+ requirement('six'),
+ ],
+ data = [
+ "//:grpc",
+ ],
+ main = "__init__.py",
+ imports = ["../",],
+)
+
+py_library(
+ name = "auth",
+ srcs = ["_auth.py"],
+)
+
+py_library(
+ name = "channel",
+ srcs = ["_channel.py"],
+ deps = [
+ ":common",
+ ":grpcio_metadata",
+ ],
+)
+
+py_library(
+ name = "common",
+ srcs = ["_common.py"],
+)
+
+py_library(
+ name = "grpcio_metadata",
+ srcs = ["_grpcio_metadata.py"],
+)
+
+py_library(
+ name = "interceptor",
+ srcs = ["_interceptor.py"],
+)
+
+py_library(
+ name = "plugin_wrapping",
+ srcs = ["_plugin_wrapping.py"],
+ deps = [
+ ":common",
+ ]
+)
+
+py_library(
+ name = "server",
+ srcs = ["_server.py"],
+ deps = [
+ ":common",
+ ":interceptor",
+ ],
+)
+
+py_library(
+ name = "utilities",
+ srcs = ["_utilities.py"],
+ deps = [
+ ":common",
+ ],
+)
+
diff --git a/src/python/grpcio/grpc/_cython/BUILD.bazel b/src/python/grpcio/grpc/_cython/BUILD.bazel
new file mode 100644
index 0000000000..7124e83dee
--- /dev/null
+++ b/src/python/grpcio/grpc/_cython/BUILD.bazel
@@ -0,0 +1,46 @@
+package(default_visibility = ["//visibility:public"])
+
+load("//bazel:cython_library.bzl", "pyx_library")
+
+pyx_library(
+ name = "cygrpc",
+ srcs = [
+ "__init__.py",
+ "cygrpc.pxd",
+ "cygrpc.pyx",
+ "_cygrpc/grpc_string.pyx.pxi",
+ "_cygrpc/arguments.pyx.pxi",
+ "_cygrpc/call.pyx.pxi",
+ "_cygrpc/channel.pyx.pxi",
+ "_cygrpc/credentials.pyx.pxi",
+ "_cygrpc/completion_queue.pyx.pxi",
+ "_cygrpc/event.pyx.pxi",
+ "_cygrpc/metadata.pyx.pxi",
+ "_cygrpc/operation.pyx.pxi",
+ "_cygrpc/records.pyx.pxi",
+ "_cygrpc/security.pyx.pxi",
+ "_cygrpc/server.pyx.pxi",
+ "_cygrpc/tag.pyx.pxi",
+ "_cygrpc/time.pyx.pxi",
+ "_cygrpc/grpc_gevent.pyx.pxi",
+ "_cygrpc/grpc.pxi",
+ "_cygrpc/arguments.pxd.pxi",
+ "_cygrpc/call.pxd.pxi",
+ "_cygrpc/channel.pxd.pxi",
+ "_cygrpc/credentials.pxd.pxi",
+ "_cygrpc/completion_queue.pxd.pxi",
+ "_cygrpc/event.pxd.pxi",
+ "_cygrpc/metadata.pxd.pxi",
+ "_cygrpc/operation.pxd.pxi",
+ "_cygrpc/records.pxd.pxi",
+ "_cygrpc/security.pxd.pxi",
+ "_cygrpc/server.pxd.pxi",
+ "_cygrpc/tag.pxd.pxi",
+ "_cygrpc/time.pxd.pxi",
+ "_cygrpc/grpc_gevent.pxd.pxi",
+ ],
+ deps = [
+ "//:grpc",
+ ],
+)
+
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pxd.pxi
new file mode 100644
index 0000000000..3eb10f5275
--- /dev/null
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pxd.pxi
@@ -0,0 +1,16 @@
+# 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.
+
+
+cdef object _custom_op_on_c_call(int op, grpc_call *call)
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pyx.pxi
new file mode 100644
index 0000000000..38cf629dc2
--- /dev/null
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/_hooks.pyx.pxi
@@ -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.
+
+
+cdef object _custom_op_on_c_call(int op, grpc_call *call):
+ raise NotImplementedError("No custom hooks are implemented")
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pxd.pxi
index 853bf6f8e0..6cb1bc0c05 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pxd.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pxd.pxi
@@ -1,4 +1,4 @@
-# Copyright 2018 gRPC authors.
+# 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.
@@ -22,6 +22,12 @@ cdef void _destroy_pointer(void* pointer)
cdef int _compare_pointer(void* first_pointer, void* second_pointer)
+cdef tuple _wrap_grpc_arg(grpc_arg arg)
+
+
+cdef grpc_arg _unwrap_grpc_arg(tuple wrapped_arg)
+
+
cdef class _ArgumentProcessor:
cdef grpc_arg c_argument
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pyx.pxi
index aecd3d7b11..2239e26b32 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/arguments.pyx.pxi
@@ -34,6 +34,22 @@ cdef int _compare_pointer(void* first_pointer, void* second_pointer):
return 0
+cdef class _GrpcArgWrapper:
+
+ cdef grpc_arg arg
+
+
+cdef tuple _wrap_grpc_arg(grpc_arg arg):
+ wrapped = _GrpcArgWrapper()
+ wrapped.arg = arg
+ return ("grpc.python._cygrpc._GrpcArgWrapper", wrapped)
+
+
+cdef grpc_arg _unwrap_grpc_arg(tuple wrapped_arg):
+ cdef _GrpcArgWrapper wrapped = wrapped_arg[1]
+ return wrapped.arg
+
+
cdef class _ArgumentProcessor:
cdef void c(self, argument, grpc_arg_pointer_vtable *vtable, references):
@@ -51,6 +67,8 @@ cdef class _ArgumentProcessor:
if encoded_value is not value:
references.append(encoded_value)
self.c_argument.value.string = encoded_value
+ elif isinstance(value, _GrpcArgWrapper):
+ self.c_argument = (<_GrpcArgWrapper>value).arg
elif hasattr(value, '__int__'):
# Pointer objects must override __int__() to return
# the underlying C address (Python ints are word size). The
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi
index 2e02111ddd..a0de862d94 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/call.pyx.pxi
@@ -94,3 +94,5 @@ cdef class Call:
def is_valid(self):
return self.c_call != NULL
+ def _custom_op_on_c_call(self, int op):
+ return _custom_op_on_c_call(op, self.c_call)
diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi
index 8c37a3cf85..893df8eac6 100644
--- a/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi
+++ b/src/python/grpcio/grpc/_cython/_cygrpc/channel.pyx.pxi
@@ -300,7 +300,7 @@ cdef class SegregatedCall:
def next_event(self):
def on_success(tag):
_process_segregated_call_tag(
- self._channel_state, self._call_state, self._c_completion_queue, tag)
+ self._channel_state, self._call_state, self._c_completion_queue, tag)
return _next_call_event(
self._channel_state, self._c_completion_queue, on_success)
diff --git a/src/python/grpcio/grpc/_cython/cygrpc.pxd b/src/python/grpcio/grpc/_cython/cygrpc.pxd
index e33c01c28f..0cc26bc0d0 100644
--- a/src/python/grpcio/grpc/_cython/cygrpc.pxd
+++ b/src/python/grpcio/grpc/_cython/cygrpc.pxd
@@ -28,5 +28,6 @@ include "_cygrpc/security.pxd.pxi"
include "_cygrpc/server.pxd.pxi"
include "_cygrpc/tag.pxd.pxi"
include "_cygrpc/time.pxd.pxi"
+include "_cygrpc/_hooks.pxd.pxi"
include "_cygrpc/grpc_gevent.pxd.pxi"
diff --git a/src/python/grpcio/grpc/_cython/cygrpc.pyx b/src/python/grpcio/grpc/_cython/cygrpc.pyx
index fb16fb16bf..3cac406687 100644
--- a/src/python/grpcio/grpc/_cython/cygrpc.pyx
+++ b/src/python/grpcio/grpc/_cython/cygrpc.pyx
@@ -35,6 +35,7 @@ include "_cygrpc/security.pyx.pxi"
include "_cygrpc/server.pyx.pxi"
include "_cygrpc/tag.pyx.pxi"
include "_cygrpc/time.pyx.pxi"
+include "_cygrpc/_hooks.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 3d3e253155..c33911ebc1 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.14.0"""
+__version__ = """1.15.0.dev0"""
diff --git a/src/python/grpcio/grpc/beta/BUILD.bazel b/src/python/grpcio/grpc/beta/BUILD.bazel
new file mode 100644
index 0000000000..731be5cb25
--- /dev/null
+++ b/src/python/grpcio/grpc/beta/BUILD.bazel
@@ -0,0 +1,58 @@
+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/experimental/BUILD.bazel b/src/python/grpcio/grpc/experimental/BUILD.bazel
new file mode 100644
index 0000000000..6598d02747
--- /dev/null
+++ b/src/python/grpcio/grpc/experimental/BUILD.bazel
@@ -0,0 +1,27 @@
+load("@grpc_python_dependencies//:requirements.bzl", "requirement")
+package(default_visibility = ["//visibility:public"])
+
+py_library(
+ name = "experimental",
+ srcs = ["__init__.py",],
+ deps = [
+ ":gevent",
+ ":session_cache",
+ ],
+)
+
+py_library(
+ name = "gevent",
+ srcs = ["gevent.py"],
+ deps = [
+ "//src/python/grpcio/grpc/_cython:cygrpc",
+ ],
+)
+
+py_library(
+ name = "session_cache",
+ srcs = ["session_cache.py"],
+ deps = [
+ "//src/python/grpcio/grpc/_cython:cygrpc",
+ ],
+)
diff --git a/src/python/grpcio/grpc/framework/BUILD.bazel b/src/python/grpcio/grpc/framework/BUILD.bazel
new file mode 100644
index 0000000000..55b4f4d2df
--- /dev/null
+++ b/src/python/grpcio/grpc/framework/BUILD.bazel
@@ -0,0 +1,11 @@
+package(default_visibility = ["//visibility:public"])
+
+py_library(
+ name = "framework",
+ srcs = ["__init__.py",],
+ deps = [
+ "//src/python/grpcio/grpc/framework/common",
+ "//src/python/grpcio/grpc/framework/foundation",
+ "//src/python/grpcio/grpc/framework/interfaces",
+ ],
+)
diff --git a/src/python/grpcio/grpc/framework/common/BUILD.bazel b/src/python/grpcio/grpc/framework/common/BUILD.bazel
new file mode 100644
index 0000000000..9d9ef682c9
--- /dev/null
+++ b/src/python/grpcio/grpc/framework/common/BUILD.bazel
@@ -0,0 +1,27 @@
+load("@grpc_python_dependencies//:requirements.bzl", "requirement")
+package(default_visibility = ["//visibility:public"])
+
+py_library(
+ name = "common",
+ srcs = ["__init__.py",],
+ deps = [
+ ":cardinality",
+ ":style",
+ ],
+)
+
+py_library(
+ name = "cardinality",
+ srcs = ["cardinality.py"],
+ deps = [
+ requirement("enum34"),
+ ],
+)
+
+py_library(
+ name = "style",
+ srcs = ["style.py"],
+ deps = [
+ requirement("enum34"),
+ ],
+)
diff --git a/src/python/grpcio/grpc/framework/foundation/BUILD.bazel b/src/python/grpcio/grpc/framework/foundation/BUILD.bazel
new file mode 100644
index 0000000000..1287fdd44e
--- /dev/null
+++ b/src/python/grpcio/grpc/framework/foundation/BUILD.bazel
@@ -0,0 +1,61 @@
+load("@grpc_python_dependencies//:requirements.bzl", "requirement")
+package(default_visibility = ["//visibility:public"])
+
+py_library(
+ name = "foundation",
+ srcs = ["__init__.py",],
+ deps = [
+ ":abandonment",
+ ":callable_util",
+ ":future",
+ ":logging_pool",
+ ":stream_util",
+ ":stream",
+ ],
+)
+
+py_library(
+ name = "abandonment",
+ srcs = ["abandonment.py"],
+)
+
+py_library(
+ name = "callable_util",
+ srcs = ["callable_util.py"],
+ deps = [
+ requirement("enum34"),
+ requirement("six"),
+ ],
+)
+
+py_library(
+ name = "future",
+ srcs = ["future.py"],
+ deps = [
+ requirement("six"),
+ ],
+)
+
+py_library(
+ name = "logging_pool",
+ srcs = ["logging_pool.py"],
+ deps = [
+ requirement("futures"),
+ ],
+)
+
+py_library(
+ name = "stream_util",
+ srcs = ["stream_util.py"],
+ deps = [
+ ":stream",
+ ],
+)
+
+py_library(
+ name = "stream",
+ srcs = ["stream.py"],
+ deps = [
+ requirement("six"),
+ ],
+)
diff --git a/src/python/grpcio/grpc/framework/interfaces/BUILD.bazel b/src/python/grpcio/grpc/framework/interfaces/BUILD.bazel
new file mode 100644
index 0000000000..b81e196cc3
--- /dev/null
+++ b/src/python/grpcio/grpc/framework/interfaces/BUILD.bazel
@@ -0,0 +1,10 @@
+package(default_visibility = ["//visibility:public"])
+
+py_library(
+ name = "interfaces",
+ srcs = ["__init__.py",],
+ deps = [
+ "//src/python/grpcio/grpc/framework/interfaces/base",
+ "//src/python/grpcio/grpc/framework/interfaces/face",
+ ],
+)
diff --git a/src/python/grpcio/grpc/framework/interfaces/base/BUILD.bazel b/src/python/grpcio/grpc/framework/interfaces/base/BUILD.bazel
new file mode 100644
index 0000000000..408a66a631
--- /dev/null
+++ b/src/python/grpcio/grpc/framework/interfaces/base/BUILD.bazel
@@ -0,0 +1,29 @@
+load("@grpc_python_dependencies//:requirements.bzl", "requirement")
+package(default_visibility = ["//visibility:public"])
+
+py_library(
+ name = "base_lib",
+ srcs = ["__init__.py",],
+ deps = [
+ ":base",
+ ":utilities",
+ ],
+)
+
+py_library(
+ name = "base",
+ srcs = ["base.py"],
+ deps = [
+ "//src/python/grpcio/grpc/framework/foundation:abandonment",
+ requirement("enum34"),
+ requirement("six"),
+ ],
+)
+
+py_library(
+ name = "utilities",
+ srcs = ["utilities.py"],
+ deps = [
+ requirement("enum34"),
+ ],
+)
diff --git a/src/python/grpcio/grpc/framework/interfaces/face/BUILD.bazel b/src/python/grpcio/grpc/framework/interfaces/face/BUILD.bazel
new file mode 100644
index 0000000000..e683e7cc42
--- /dev/null
+++ b/src/python/grpcio/grpc/framework/interfaces/face/BUILD.bazel
@@ -0,0 +1,32 @@
+load("@grpc_python_dependencies//:requirements.bzl", "requirement")
+package(default_visibility = ["//visibility:public"])
+
+py_library(
+ name = "face",
+ srcs = ["__init__.py",],
+ deps = [
+ ":face_lib",
+ ":utilities",
+ ],
+)
+
+py_library(
+ name = "face_lib",
+ srcs = ["face.py"],
+ deps = [
+ "//src/python/grpcio/grpc/framework/foundation",
+ "//src/python/grpcio/grpc/framework/common",
+ requirement("enum34"),
+ requirement("six"),
+ ],
+)
+
+py_library(
+ name = "utilities",
+ srcs = ["utilities.py"],
+ deps = [
+ "//src/python/grpcio/grpc/framework/common",
+ "//src/python/grpcio/grpc/framework/foundation:stream",
+ ":face_lib",
+ ],
+)
diff --git a/src/python/grpcio/grpc_core_dependencies.py b/src/python/grpcio/grpc_core_dependencies.py
index 49185cc648..d6efb49750 100644
--- a/src/python/grpcio/grpc_core_dependencies.py
+++ b/src/python/grpcio/grpc_core_dependencies.py
@@ -354,8 +354,11 @@ CORE_SOURCE_FILES = [
'src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc',
+ 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc',
'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc',
+ 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc',
+ 'src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc',
'src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc',
'src/core/ext/filters/client_channel/resolver/sockaddr/sockaddr_resolver.cc',
'src/cpp/ext/filters/census/grpc_context.cc',
diff --git a/src/python/grpcio/grpc_version.py b/src/python/grpcio/grpc_version.py
index 248cd63275..9337800a33 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.14.0'
+VERSION = '1.15.0.dev0'
diff --git a/src/python/grpcio_health_checking/grpc_version.py b/src/python/grpcio_health_checking/grpc_version.py
index 1e48f81b79..3b84f7a4c5 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.14.0'
+VERSION = '1.15.0.dev0'
diff --git a/src/python/grpcio_reflection/grpc_version.py b/src/python/grpcio_reflection/grpc_version.py
index ec79577825..7b0e48ea23 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.14.0'
+VERSION = '1.15.0.dev0'
diff --git a/src/python/grpcio_testing/grpc_version.py b/src/python/grpcio_testing/grpc_version.py
index 50e2aa2219..df9953fa25 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.14.0'
+VERSION = '1.15.0.dev0'
diff --git a/src/python/grpcio_tests/grpc_version.py b/src/python/grpcio_tests/grpc_version.py
index 18d34cc1a2..b2cf129e4f 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.14.0'
+VERSION = '1.15.0.dev0'
diff --git a/src/python/grpcio_tests/tests/unit/beta/_utilities_test.py b/src/python/grpcio_tests/tests/unit/beta/_utilities_test.py
index aebee4da96..e042262796 100644
--- a/src/python/grpcio_tests/tests/unit/beta/_utilities_test.py
+++ b/src/python/grpcio_tests/tests/unit/beta/_utilities_test.py
@@ -41,6 +41,7 @@ class _Callback(object):
return self._value
+@unittest.skip('https://github.com/grpc/grpc/issues/16134')
class ChannelConnectivityTest(unittest.TestCase):
def test_lonely_channel_connectivity(self):
diff --git a/src/python/grpcio_tests/tests/unit/framework/foundation/BUILD.bazel b/src/python/grpcio_tests/tests/unit/framework/foundation/BUILD.bazel
new file mode 100644
index 0000000000..d69186e1fd
--- /dev/null
+++ b/src/python/grpcio_tests/tests/unit/framework/foundation/BUILD.bazel
@@ -0,0 +1,17 @@
+package(default_visibility = ["//visibility:public"])
+
+py_library(
+ name = "stream_testing",
+ srcs = ["stream_testing.py"],
+)
+
+py_test(
+ name = "logging_pool_test",
+ srcs = ["_logging_pool_test.py"],
+ main = "_logging_pool_test.py",
+ size = "small",
+ deps = [
+ "//src/python/grpcio/grpc:grpcio",
+ ],
+)
+
diff --git a/src/ruby/ext/grpc/extconf.rb b/src/ruby/ext/grpc/extconf.rb
index 4760f33e38..505357021e 100644
--- a/src/ruby/ext/grpc/extconf.rb
+++ b/src/ruby/ext/grpc/extconf.rb
@@ -15,31 +15,6 @@
require 'etc'
require 'mkmf'
-LIBDIR = RbConfig::CONFIG['libdir']
-INCLUDEDIR = RbConfig::CONFIG['includedir']
-
-HEADER_DIRS = [
- # Search /opt/local (Mac source install)
- '/opt/local/include',
-
- # Search /usr/local (Source install)
- '/usr/local/include',
-
- # Check the ruby install locations
- INCLUDEDIR
-]
-
-LIB_DIRS = [
- # Search /opt/local (Mac source install)
- '/opt/local/lib',
-
- # Search /usr/local (Source install)
- '/usr/local/lib',
-
- # Check the ruby install locations
- LIBDIR
-]
-
windows = RUBY_PLATFORM =~ /mingw|mswin/
bsd = RUBY_PLATFORM =~ /bsd/
@@ -110,7 +85,7 @@ if grpc_config == 'opt'
o.puts i
end
o.puts
- o.puts 'strip:'
+ o.puts 'strip: $(DLLIB)'
o.puts "\t$(ECHO) Stripping $(DLLIB)"
o.puts "\t$(Q) #{strip_tool} $(DLLIB)"
end
diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c
index 4e235121e2..2443532bb8 100644
--- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c
+++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c
@@ -92,6 +92,8 @@ grpc_resource_quota_ref_type grpc_resource_quota_ref_import;
grpc_resource_quota_unref_type grpc_resource_quota_unref_import;
grpc_resource_quota_resize_type grpc_resource_quota_resize_import;
grpc_resource_quota_arg_vtable_type grpc_resource_quota_arg_vtable_import;
+grpc_channelz_get_top_channels_type grpc_channelz_get_top_channels_import;
+grpc_channelz_get_channel_type grpc_channelz_get_channel_import;
grpc_insecure_channel_create_from_fd_type grpc_insecure_channel_create_from_fd_import;
grpc_server_add_insecure_channel_from_fd_type grpc_server_add_insecure_channel_from_fd_import;
grpc_use_signal_type grpc_use_signal_import;
@@ -340,6 +342,8 @@ void grpc_rb_load_imports(HMODULE library) {
grpc_resource_quota_unref_import = (grpc_resource_quota_unref_type) GetProcAddress(library, "grpc_resource_quota_unref");
grpc_resource_quota_resize_import = (grpc_resource_quota_resize_type) GetProcAddress(library, "grpc_resource_quota_resize");
grpc_resource_quota_arg_vtable_import = (grpc_resource_quota_arg_vtable_type) GetProcAddress(library, "grpc_resource_quota_arg_vtable");
+ grpc_channelz_get_top_channels_import = (grpc_channelz_get_top_channels_type) GetProcAddress(library, "grpc_channelz_get_top_channels");
+ grpc_channelz_get_channel_import = (grpc_channelz_get_channel_type) GetProcAddress(library, "grpc_channelz_get_channel");
grpc_insecure_channel_create_from_fd_import = (grpc_insecure_channel_create_from_fd_type) GetProcAddress(library, "grpc_insecure_channel_create_from_fd");
grpc_server_add_insecure_channel_from_fd_import = (grpc_server_add_insecure_channel_from_fd_type) GetProcAddress(library, "grpc_server_add_insecure_channel_from_fd");
grpc_use_signal_import = (grpc_use_signal_type) GetProcAddress(library, "grpc_use_signal");
diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h
index f01c9c8248..b08a1f94f7 100644
--- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h
+++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h
@@ -251,6 +251,12 @@ extern grpc_resource_quota_resize_type grpc_resource_quota_resize_import;
typedef const grpc_arg_pointer_vtable*(*grpc_resource_quota_arg_vtable_type)(void);
extern grpc_resource_quota_arg_vtable_type grpc_resource_quota_arg_vtable_import;
#define grpc_resource_quota_arg_vtable grpc_resource_quota_arg_vtable_import
+typedef char*(*grpc_channelz_get_top_channels_type)(intptr_t start_channel_id);
+extern grpc_channelz_get_top_channels_type grpc_channelz_get_top_channels_import;
+#define grpc_channelz_get_top_channels grpc_channelz_get_top_channels_import
+typedef char*(*grpc_channelz_get_channel_type)(intptr_t channel_id);
+extern grpc_channelz_get_channel_type grpc_channelz_get_channel_import;
+#define grpc_channelz_get_channel grpc_channelz_get_channel_import
typedef grpc_channel*(*grpc_insecure_channel_create_from_fd_type)(const char* target, int fd, const grpc_channel_args* args);
extern grpc_insecure_channel_create_from_fd_type grpc_insecure_channel_create_from_fd_import;
#define grpc_insecure_channel_create_from_fd grpc_insecure_channel_create_from_fd_import
diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb
index 55ae016bf0..5c21a5b168 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.14.0'
+ VERSION = '1.15.0.dev'
end
diff --git a/src/ruby/tools/version.rb b/src/ruby/tools/version.rb
index 3bd5529215..1b5e2c362b 100644
--- a/src/ruby/tools/version.rb
+++ b/src/ruby/tools/version.rb
@@ -14,6 +14,6 @@
module GRPC
module Tools
- VERSION = '1.14.0'
+ VERSION = '1.15.0.dev'
end
end
diff --git a/templates/Makefile.template b/templates/Makefile.template
index 628056ed4d..50b81e5f9f 100644
--- a/templates/Makefile.template
+++ b/templates/Makefile.template
@@ -921,6 +921,16 @@
% endfor
+ static_csharp: static_c \
+ % for lib in libs:
+ % if 'Makefile' in lib.get('build_system', ['Makefile']):
+ % if lib.build == 'all' and lib.language == 'csharp':
+ $(LIBDIR)/$(CONFIG)/lib${lib.name}.a\
+ % endif
+ % endif
+ % endfor
+
+
shared: shared_c shared_cxx
shared_c: pc_c pc_c_unsecure cache.mk\
diff --git a/templates/composer.json.template b/templates/composer.json.template
index aa6cbb8bcb..a9cc6cca86 100644
--- a/templates/composer.json.template
+++ b/templates/composer.json.template
@@ -11,7 +11,7 @@
"php": ">=5.5.0"
},
"require-dev": {
- "google/auth": "v0.9"
+ "google/auth": "^v1.3.0"
},
"suggest": {
"ext-protobuf": "For better performance, install the protobuf C extension.",
diff --git a/templates/src/csharp/build_packages_dotnetcli.bat.template b/templates/src/csharp/build_packages_dotnetcli.bat.template
index 45010fec74..2ae909f53a 100755
--- a/templates/src/csharp/build_packages_dotnetcli.bat.template
+++ b/templates/src/csharp/build_packages_dotnetcli.bat.template
@@ -23,18 +23,12 @@
mkdir ..\..\artifacts
- @rem Collect the artifacts built by the previous build step if running on Jenkins
+ @rem Collect the artifacts built by the previous build step
mkdir nativelibs
- @rem Jenkins flow (deprecated)
- powershell -Command "cp -r ..\..\platform=*\artifacts\csharp_ext_* nativelibs"
- @rem Kokoro flow
powershell -Command "cp -r ..\..\input_artifacts\csharp_ext_* nativelibs"
@rem Collect protoc artifacts built by the previous build step
mkdir protoc_plugins
- @rem Jenkins flow (deprecated)
- powershell -Command "cp -r ..\..\platform=*\artifacts\protoc_* protoc_plugins"
- @rem Kokoro flow
powershell -Command "cp -r ..\..\input_artifacts\protoc_* protoc_plugins"
%%DOTNET% restore Grpc.sln || goto :error
diff --git a/templates/src/csharp/build_packages_dotnetcli.sh.template b/templates/src/csharp/build_packages_dotnetcli.sh.template
deleted file mode 100755
index 1172582ebd..0000000000
--- a/templates/src/csharp/build_packages_dotnetcli.sh.template
+++ /dev/null
@@ -1,54 +0,0 @@
-%YAML 1.2
---- |
- #!/bin/bash
- # 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.
-
- set -ex
-
- cd $(dirname $0)
-
- mkdir -p ../../artifacts/
-
- # Collect the artifacts built by the previous build step
- mkdir -p nativelibs
- # Jenkins flow (deprecated)
- cp -r $EXTERNAL_GIT_ROOT/platform={windows,linux,macos}/artifacts/csharp_ext_* nativelibs || true
- # Kokoro flow
- cp -r $EXTERNAL_GIT_ROOT/input_artifacts/csharp_ext_* nativelibs || true
-
- # Collect protoc artifacts built by the previous build step
- mkdir -p protoc_plugins
- # Jenkins flow (deprecated)
- cp -r $EXTERNAL_GIT_ROOT/platform={windows,linux,macos}/artifacts/protoc_* protoc_plugins || true
- # Kokoro flow
- cp -r $EXTERNAL_GIT_ROOT/input_artifacts/protoc_* protoc_plugins || true
-
- dotnet restore Grpc.sln
-
- # To be able to build, we also need to put grpc_csharp_ext to its normal location
- mkdir -p ../../libs/opt
- cp nativelibs/csharp_ext_linux_x64/libgrpc_csharp_ext.so ../../libs/opt
-
- dotnet pack --configuration Release Grpc.Core --output ../../../artifacts
- dotnet pack --configuration Release Grpc.Core.Testing --output ../../../artifacts
- dotnet pack --configuration Release Grpc.Auth --output ../../../artifacts
- dotnet pack --configuration Release Grpc.HealthCheck --output ../../../artifacts
- dotnet pack --configuration Release Grpc.Reflection --output ../../../artifacts
-
- nuget pack Grpc.nuspec -Version "${settings.csharp_version}" -OutputDirectory ../../artifacts
- nuget pack Grpc.Core.NativeDebug.nuspec -Version "${settings.csharp_version}" -OutputDirectory ../../artifacts
- nuget pack Grpc.Tools.nuspec -Version "${settings.csharp_version}" -OutputDirectory ../../artifacts
-
- (cd ../../artifacts && zip csharp_nugets_dotnetcli.zip *.nupkg)
diff --git a/templates/src/csharp/build_unitypackage.bat.template b/templates/src/csharp/build_unitypackage.bat.template
new file mode 100755
index 0000000000..a53e385f9b
--- /dev/null
+++ b/templates/src/csharp/build_unitypackage.bat.template
@@ -0,0 +1,80 @@
+%YAML 1.2
+--- |
+ @rem Copyright 2018 The gRPC Authors
+ @rem
+ @rem Licensed under the Apache License, Version 2.0 (the "License");
+ @rem you may not use this file except in compliance with the License.
+ @rem You may obtain a copy of the License at
+ @rem
+ @rem http://www.apache.org/licenses/LICENSE-2.0
+ @rem
+ @rem Unless required by applicable law or agreed to in writing, software
+ @rem distributed under the License is distributed on an "AS IS" BASIS,
+ @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ @rem See the License for the specific language governing permissions and
+ @rem limitations under the License.
+
+ @rem Current package versions
+ set VERSION=${settings.csharp_version}
+
+ @rem Adjust the location of nuget.exe
+ set NUGET=C:\nuget\nuget.exe
+ set DOTNET=dotnet
+
+ mkdir ..\..\artifacts
+
+ @rem Collect the artifacts built by the previous build step
+ mkdir nativelibs
+ powershell -Command "cp -r ..\..\input_artifacts\csharp_ext_* nativelibs"
+
+ @rem Collect protoc artifacts built by the previous build step
+ mkdir protoc_plugins
+ powershell -Command "cp -r ..\..\input_artifacts\protoc_* protoc_plugins"
+
+ %%DOTNET% restore Grpc.sln || goto :error
+
+ @rem To be able to build, we also need to put grpc_csharp_ext to its normal location
+ xcopy /Y /I nativelibs\csharp_ext_windows_x64\grpc_csharp_ext.dll ..\..\cmake\build\x64\Release${"\\"}
+
+ %%DOTNET% build --configuration Release Grpc.Core || goto :error
+ @rem build HealthCheck to get hold of Google.Protobuf.dll assembly
+ %%DOTNET% build --configuration Release Grpc.HealthCheck || goto :error
+
+ @rem copy Grpc assemblies to the unity package skeleton
+ @rem TODO(jtattermusch): Add Grpc.Auth assembly and its dependencies
+ copy /Y Grpc.Core\bin\Release\net45\Grpc.Core.dll unitypackage\unitypackage_skeleton\Plugins\Grpc.Core\lib\net45\Grpc.Core.dll || goto :error
+ copy /Y Grpc.Core\bin\Release\net45\Grpc.Core.pdb unitypackage\unitypackage_skeleton\Plugins\Grpc.Core\lib\net45\Grpc.Core.pdb || goto :error
+ copy /Y Grpc.Core\bin\Release\net45\Grpc.Core.xml unitypackage\unitypackage_skeleton\Plugins\Grpc.Core\lib\net45\Grpc.Core.xml || goto :error
+
+ @rem copy desktop native libraries to the unity package skeleton
+ copy /Y nativelibs\csharp_ext_linux_x86\libgrpc_csharp_ext.so unitypackage\unitypackage_skeleton\Plugins\Grpc.Core\runtimes\linux\x86\libgrpc_csharp_ext.so || goto :error
+ copy /Y nativelibs\csharp_ext_linux_x64\libgrpc_csharp_ext.so unitypackage\unitypackage_skeleton\Plugins\Grpc.Core\runtimes\linux\x64\libgrpc_csharp_ext.so || goto :error
+ copy /Y nativelibs\csharp_ext_macos_x86\libgrpc_csharp_ext.dylib unitypackage\unitypackage_skeleton\Plugins\Grpc.Core\runtimes\osx\x86\grpc_csharp_ext.bundle || goto :error
+ copy /Y nativelibs\csharp_ext_macos_x64\libgrpc_csharp_ext.dylib unitypackage\unitypackage_skeleton\Plugins\Grpc.Core\runtimes\osx\x64\grpc_csharp_ext.bundle || goto :error
+ copy /Y nativelibs\csharp_ext_windows_x86\grpc_csharp_ext.dll unitypackage\unitypackage_skeleton\Plugins\Grpc.Core\runtimes\win\x86\grpc_csharp_ext.dll || goto :error
+ copy /Y nativelibs\csharp_ext_windows_x64\grpc_csharp_ext.dll unitypackage\unitypackage_skeleton\Plugins\Grpc.Core\runtimes\win\x64\grpc_csharp_ext.dll || goto :error
+
+ @rem add Android and iOS native libraries
+ copy /Y nativelibs\csharp_ext_linux_android_armeabi-v7a\libgrpc_csharp_ext.so unitypackage\unitypackage_skeleton\Plugins\Grpc.Core\runtimes\android\armeabi-v7a\libgrpc_csharp_ext.so || goto :error
+ copy /Y nativelibs\csharp_ext_linux_android_arm64-v8a\libgrpc_csharp_ext.so unitypackage\unitypackage_skeleton\Plugins\Grpc.Core\runtimes\android\arm64-v8a\libgrpc_csharp_ext.so || goto :error
+ copy /Y nativelibs\csharp_ext_linux_android_x86\libgrpc_csharp_ext.so unitypackage\unitypackage_skeleton\Plugins\Grpc.Core\runtimes\android\x86\libgrpc_csharp_ext.so || goto :error
+ copy /Y nativelibs\csharp_ext_macos_ios\libgrpc_csharp_ext.a unitypackage\unitypackage_skeleton\Plugins\Grpc.Core\runtimes\ios\libgrpc_csharp_ext.a || goto :error
+ copy /Y nativelibs\csharp_ext_macos_ios\libgrpc.a unitypackage\unitypackage_skeleton\Plugins\Grpc.Core\runtimes\ios\libgrpc.a || goto :error
+
+ @rem add gRPC dependencies
+ @rem TODO(jtattermusch): also include XMLdoc
+ copy /Y Grpc.Core\bin\Release\net45\System.Interactive.Async.dll unitypackage\unitypackage_skeleton\Plugins\System.Interactive.Async\lib\net45\System.Interactive.Async.dll || goto :error
+
+ @rem add Google.Protobuf
+ @rem TODO(jtattermusch): also include XMLdoc
+ copy /Y Grpc.HealthCheck\bin\Release\net45\Google.Protobuf.dll unitypackage\unitypackage_skeleton\Plugins\Google.Protobuf\lib\net45\Google.Protobuf.dll || goto :error
+
+ @rem create a zipfile that will act as a Unity package
+ powershell -Command "Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::CreateFromDirectory('unitypackage\unitypackage_skeleton', 'grpc_unity_package.zip');"
+ copy /Y grpc_unity_package.zip ..\..\artifacts\grpc_unity_package.%VERSION%.zip || goto :error
+
+ goto :EOF
+
+ :error
+ echo Failed!
+ exit /b %errorlevel%
diff --git a/templates/src/php/composer.json.template b/templates/src/php/composer.json.template
index d647997113..3793634a2f 100644
--- a/templates/src/php/composer.json.template
+++ b/templates/src/php/composer.json.template
@@ -10,7 +10,7 @@
"google/protobuf": "^v3.3.0"
},
"require-dev": {
- "google/auth": "v0.9"
+ "google/auth": "^v1.3.0"
},
"autoload": {
"psr-4": {
diff --git a/test/core/channel/channel_trace_test.cc b/test/core/channel/channel_trace_test.cc
index bbddee3f14..f224457a55 100644
--- a/test/core/channel/channel_trace_test.cc
+++ b/test/core/channel/channel_trace_test.cc
@@ -34,8 +34,6 @@
#include "test/core/util/test_config.h"
#include "test/cpp/util/channel_trace_proto_helper.h"
-// remove me
-#include <grpc/support/string_util.h>
#include <stdlib.h>
#include <string.h>
@@ -88,7 +86,7 @@ void AddSimpleTrace(ChannelTrace* tracer) {
void ValidateChannelTrace(ChannelTrace* tracer,
size_t expected_num_event_logged, size_t max_nodes) {
if (!max_nodes) return;
- grpc_json* json = tracer->RenderJSON();
+ grpc_json* json = tracer->RenderJson();
EXPECT_NE(json, nullptr);
char* json_str = grpc_json_dump_to_string(json, 0);
grpc_json_destroy(json);
@@ -157,7 +155,7 @@ TEST_P(ChannelTracerTest, ComplexTest) {
AddSimpleTrace(&tracer);
ChannelFixture channel1(GetParam());
RefCountedPtr<ChannelNode> sc1 =
- MakeRefCounted<ChannelNode>(channel1.channel(), GetParam());
+ MakeRefCounted<ChannelNode>(channel1.channel(), GetParam(), true);
tracer.AddTraceEventReferencingSubchannel(
ChannelTrace::Severity::Info,
grpc_slice_from_static_string("subchannel one created"), sc1);
@@ -175,7 +173,7 @@ TEST_P(ChannelTracerTest, ComplexTest) {
ValidateChannelTrace(&tracer, 5, GetParam());
ChannelFixture channel2(GetParam());
RefCountedPtr<ChannelNode> sc2 =
- MakeRefCounted<ChannelNode>(channel2.channel(), GetParam());
+ MakeRefCounted<ChannelNode>(channel2.channel(), GetParam(), true);
tracer.AddTraceEventReferencingChannel(
ChannelTrace::Severity::Info,
grpc_slice_from_static_string("LB channel two created"), sc2);
@@ -189,8 +187,8 @@ TEST_P(ChannelTracerTest, ComplexTest) {
AddSimpleTrace(&tracer);
AddSimpleTrace(&tracer);
AddSimpleTrace(&tracer);
- sc1.reset(nullptr);
- sc2.reset(nullptr);
+ sc1.reset();
+ sc2.reset();
}
// Test a case in which the parent channel has subchannels and the subchannels
@@ -204,7 +202,7 @@ TEST_P(ChannelTracerTest, TestNesting) {
ValidateChannelTrace(&tracer, 2, GetParam());
ChannelFixture channel1(GetParam());
RefCountedPtr<ChannelNode> sc1 =
- MakeRefCounted<ChannelNode>(channel1.channel(), GetParam());
+ MakeRefCounted<ChannelNode>(channel1.channel(), GetParam(), true);
tracer.AddTraceEventReferencingChannel(
ChannelTrace::Severity::Info,
grpc_slice_from_static_string("subchannel one created"), sc1);
@@ -212,7 +210,7 @@ TEST_P(ChannelTracerTest, TestNesting) {
AddSimpleTrace(sc1->trace());
ChannelFixture channel2(GetParam());
RefCountedPtr<ChannelNode> conn1 =
- MakeRefCounted<ChannelNode>(channel2.channel(), GetParam());
+ MakeRefCounted<ChannelNode>(channel2.channel(), GetParam(), true);
// nesting one level deeper.
sc1->trace()->AddTraceEventReferencingSubchannel(
ChannelTrace::Severity::Info,
@@ -225,7 +223,7 @@ TEST_P(ChannelTracerTest, TestNesting) {
ValidateChannelTrace(conn1->trace(), 1, GetParam());
ChannelFixture channel3(GetParam());
RefCountedPtr<ChannelNode> sc2 =
- MakeRefCounted<ChannelNode>(channel3.channel(), GetParam());
+ MakeRefCounted<ChannelNode>(channel3.channel(), GetParam(), true);
tracer.AddTraceEventReferencingSubchannel(
ChannelTrace::Severity::Info,
grpc_slice_from_static_string("subchannel two created"), sc2);
@@ -236,9 +234,9 @@ TEST_P(ChannelTracerTest, TestNesting) {
grpc_slice_from_static_string("subchannel one inactive"), sc1);
AddSimpleTrace(&tracer);
ValidateChannelTrace(&tracer, 8, GetParam());
- sc1.reset(nullptr);
- sc2.reset(nullptr);
- conn1.reset(nullptr);
+ sc1.reset();
+ sc2.reset();
+ conn1.reset();
}
INSTANTIATE_TEST_CASE_P(ChannelTracerTestSweep, ChannelTracerTest,
diff --git a/test/core/channel/channelz_registry_test.cc b/test/core/channel/channelz_registry_test.cc
index 24e50933d7..581e867584 100644
--- a/test/core/channel/channelz_registry_test.cc
+++ b/test/core/channel/channelz_registry_test.cc
@@ -19,17 +19,20 @@
#include <stdlib.h>
#include <string.h>
+#include <grpc/grpc.h>
#include <gtest/gtest.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include "src/core/lib/channel/channel_trace.h"
+#include "src/core/lib/channel/channelz.h"
#include "src/core/lib/channel/channelz_registry.h"
#include "src/core/lib/gpr/useful.h"
#include "src/core/lib/gprpp/memory.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/json/json.h"
+#include "src/core/lib/surface/channel.h"
#include "test/core/util/test_config.h"
@@ -37,27 +40,26 @@
#include <string.h>
namespace grpc_core {
+namespace channelz {
namespace testing {
-// Tests basic ChannelTrace functionality like construction, adding trace, and
-// lookups by uuid.
TEST(ChannelzRegistryTest, UuidStartsAboveZeroTest) {
- int object_to_register;
- intptr_t uuid = ChannelzRegistry::Register(&object_to_register);
+ ChannelNode* channelz_channel = nullptr;
+ intptr_t uuid = ChannelzRegistry::RegisterChannelNode(channelz_channel);
EXPECT_GT(uuid, 0) << "First uuid chose must be greater than zero. Zero if "
"reserved according to "
"https://github.com/grpc/proposal/blob/master/"
"A14-channelz.md";
- ChannelzRegistry::Unregister(uuid);
+ ChannelzRegistry::UnregisterChannelNode(uuid);
}
TEST(ChannelzRegistryTest, UuidsAreIncreasing) {
- int object_to_register;
+ ChannelNode* channelz_channel = nullptr;
std::vector<intptr_t> uuids;
uuids.reserve(10);
for (int i = 0; i < 10; ++i) {
// reregister the same object. It's ok since we are just testing uuids
- uuids.push_back(ChannelzRegistry::Register(&object_to_register));
+ uuids.push_back(ChannelzRegistry::RegisterChannelNode(channelz_channel));
}
for (size_t i = 1; i < uuids.size(); ++i) {
EXPECT_LT(uuids[i - 1], uuids[i]) << "Uuids must always be increasing";
@@ -65,60 +67,36 @@ TEST(ChannelzRegistryTest, UuidsAreIncreasing) {
}
TEST(ChannelzRegistryTest, RegisterGetTest) {
- int object_to_register = 42;
- intptr_t uuid = ChannelzRegistry::Register(&object_to_register);
- int* retrieved = ChannelzRegistry::Get<int>(uuid);
- EXPECT_EQ(&object_to_register, retrieved);
-}
-
-TEST(ChannelzRegistryTest, MultipleTypeTest) {
- int int_to_register = 42;
- intptr_t int_uuid = ChannelzRegistry::Register(&int_to_register);
- std::string str_to_register = "hello world";
- intptr_t str_uuid = ChannelzRegistry::Register(&str_to_register);
- int* retrieved_int = ChannelzRegistry::Get<int>(int_uuid);
- std::string* retrieved_str = ChannelzRegistry::Get<std::string>(str_uuid);
- EXPECT_EQ(&int_to_register, retrieved_int);
- EXPECT_EQ(&str_to_register, retrieved_str);
+ // we hackily jam an intptr_t into this pointer to check for equality later
+ ChannelNode* channelz_channel = (ChannelNode*)42;
+ intptr_t uuid = ChannelzRegistry::RegisterChannelNode(channelz_channel);
+ ChannelNode* retrieved = ChannelzRegistry::GetChannelNode(uuid);
+ EXPECT_EQ(channelz_channel, retrieved);
}
TEST(ChannelzRegistryTest, RegisterManyItems) {
- int object_to_register = 42;
+ // we hackily jam an intptr_t into this pointer to check for equality later
+ ChannelNode* channelz_channel = (ChannelNode*)42;
for (int i = 0; i < 100; i++) {
- intptr_t uuid = ChannelzRegistry::Register(&object_to_register);
- int* retrieved = ChannelzRegistry::Get<int>(uuid);
- EXPECT_EQ(&object_to_register, retrieved);
+ intptr_t uuid = ChannelzRegistry::RegisterChannelNode(channelz_channel);
+ ChannelNode* retrieved = ChannelzRegistry::GetChannelNode(uuid);
+ EXPECT_EQ(channelz_channel, retrieved);
}
}
-namespace {
-class Foo {
- public:
- int bar;
-};
-} // namespace
-
-TEST(ChannelzRegistryTest, CustomObjectTest) {
- Foo* foo = New<Foo>();
- foo->bar = 1024;
- intptr_t uuid = ChannelzRegistry::Register(foo);
- Foo* retrieved = ChannelzRegistry::Get<Foo>(uuid);
- EXPECT_EQ(foo, retrieved);
- Delete(foo);
-}
-
TEST(ChannelzRegistryTest, NullIfNotPresentTest) {
- int object_to_register = 42;
- intptr_t uuid = ChannelzRegistry::Register(&object_to_register);
+ // we hackily jam an intptr_t into this pointer to check for equality later
+ ChannelNode* channelz_channel = (ChannelNode*)42;
+ intptr_t uuid = ChannelzRegistry::RegisterChannelNode(channelz_channel);
// try to pull out a uuid that does not exist.
- int* nonexistant = ChannelzRegistry::Get<int>(uuid + 1);
+ ChannelNode* nonexistant = ChannelzRegistry::GetChannelNode(uuid + 1);
EXPECT_EQ(nonexistant, nullptr);
- int* retrieved = ChannelzRegistry::Get<int>(uuid);
- EXPECT_EQ(object_to_register, *retrieved);
- EXPECT_EQ(&object_to_register, retrieved);
+ ChannelNode* retrieved = ChannelzRegistry::GetChannelNode(uuid);
+ EXPECT_EQ(channelz_channel, retrieved);
}
} // namespace testing
+} // namespace channelz
} // namespace grpc_core
int main(int argc, char** argv) {
diff --git a/test/core/channel/channelz_test.cc b/test/core/channel/channelz_test.cc
index 058eea914c..ad5f86d934 100644
--- a/test/core/channel/channelz_test.cc
+++ b/test/core/channel/channelz_test.cc
@@ -67,17 +67,50 @@ grpc_json* GetJsonChild(grpc_json* parent, const char* key) {
return nullptr;
}
+void ValidateJsonArraySize(grpc_json* json, const char* key,
+ size_t expected_size) {
+ grpc_json* arr = GetJsonChild(json, key);
+ if (expected_size == 0) {
+ ASSERT_EQ(arr, nullptr);
+ return;
+ }
+ ASSERT_NE(arr, nullptr);
+ ASSERT_EQ(arr->type, GRPC_JSON_ARRAY);
+ size_t count = 0;
+ for (grpc_json* child = arr->child; child != nullptr; child = child->next) {
+ ++count;
+ }
+ EXPECT_EQ(count, expected_size);
+}
+
+void ValidateGetTopChannels(size_t expected_channels) {
+ char* json_str = ChannelzRegistry::GetTopChannels(0);
+ grpc::testing::ValidateGetTopChannelsResponseProtoJsonTranslation(json_str);
+ grpc_json* parsed_json = grpc_json_parse_string(json_str);
+ // This check will naturally have to change when we support pagination.
+ // tracked: https://github.com/grpc/grpc/issues/16019.
+ ValidateJsonArraySize(parsed_json, "channel", expected_channels);
+ grpc_json* end = GetJsonChild(parsed_json, "end");
+ ASSERT_NE(end, nullptr);
+ EXPECT_EQ(end->type, GRPC_JSON_TRUE);
+ grpc_json_destroy(parsed_json);
+ gpr_free(json_str);
+ // also check that the core API formats this correctly
+ char* core_api_json_str = grpc_channelz_get_top_channels(0);
+ grpc::testing::ValidateGetTopChannelsResponseProtoJsonTranslation(
+ core_api_json_str);
+ gpr_free(core_api_json_str);
+}
+
class ChannelFixture {
public:
- ChannelFixture(int max_trace_nodes) {
+ ChannelFixture(int max_trace_nodes = 0) {
grpc_arg client_a[2];
- client_a[0].type = GRPC_ARG_INTEGER;
- client_a[0].key =
- const_cast<char*>(GRPC_ARG_MAX_CHANNEL_TRACE_EVENTS_PER_NODE);
- client_a[0].value.integer = max_trace_nodes;
- client_a[1].type = GRPC_ARG_INTEGER;
- client_a[1].key = const_cast<char*>(GRPC_ARG_ENABLE_CHANNELZ);
- client_a[1].value.integer = true;
+ client_a[0] = grpc_channel_arg_integer_create(
+ const_cast<char*>(GRPC_ARG_MAX_CHANNEL_TRACE_EVENTS_PER_NODE),
+ max_trace_nodes);
+ client_a[1] = grpc_channel_arg_integer_create(
+ const_cast<char*>(GRPC_ARG_ENABLE_CHANNELZ), true);
grpc_channel_args client_args = {GPR_ARRAY_SIZE(client_a), client_a};
channel_ =
grpc_insecure_channel_create("fake_target", &client_args, nullptr);
@@ -99,6 +132,10 @@ struct validate_channel_data_args {
void ValidateChildInteger(grpc_json* json, int64_t expect, const char* key) {
grpc_json* gotten_json = GetJsonChild(json, key);
+ if (expect == 0) {
+ ASSERT_EQ(gotten_json, nullptr);
+ return;
+ }
ASSERT_NE(gotten_json, nullptr);
int64_t gotten_number = (int64_t)strtol(gotten_json->value, nullptr, 0);
EXPECT_EQ(gotten_number, expect);
@@ -115,10 +152,15 @@ void ValidateCounters(char* json_str, validate_channel_data_args args) {
}
void ValidateChannel(ChannelNode* channel, validate_channel_data_args args) {
- char* json_str = channel->RenderJSON();
+ char* json_str = channel->RenderJsonString();
grpc::testing::ValidateChannelProtoJsonTranslation(json_str);
ValidateCounters(json_str, args);
gpr_free(json_str);
+ // also check that the core API formats this the correct way
+ char* core_api_json_str = grpc_channelz_get_channel(channel->channel_uuid());
+ grpc::testing::ValidateGetChannelResponseProtoJsonTranslation(
+ core_api_json_str);
+ gpr_free(core_api_json_str);
}
grpc_millis GetLastCallStartedMillis(ChannelNode* channel) {
@@ -141,9 +183,7 @@ TEST_P(ChannelzChannelTest, BasicChannel) {
ChannelFixture channel(GetParam());
ChannelNode* channelz_channel =
grpc_channel_get_channelz_node(channel.channel());
- char* json_str = channelz_channel->RenderJSON();
- ValidateCounters(json_str, {0, 0, 0});
- gpr_free(json_str);
+ ValidateChannel(channelz_channel, {0, 0, 0});
}
TEST(ChannelzChannelTest, ChannelzDisabled) {
@@ -199,6 +239,42 @@ TEST_P(ChannelzChannelTest, LastCallStartedMillis) {
EXPECT_NE(millis1, millis4);
}
+TEST(ChannelzGetTopChannelsTest, BasicTest) {
+ grpc_core::ExecCtx exec_ctx;
+ ChannelFixture channel;
+ ValidateGetTopChannels(1);
+}
+
+TEST(ChannelzGetTopChannelsTest, NoChannelsTest) {
+ grpc_core::ExecCtx exec_ctx;
+ ValidateGetTopChannels(0);
+}
+
+TEST(ChannelzGetTopChannelsTest, ManyChannelsTest) {
+ grpc_core::ExecCtx exec_ctx;
+ ChannelFixture channels[10];
+ (void)channels; // suppress unused variable error
+ ValidateGetTopChannels(10);
+}
+
+TEST(ChannelzGetTopChannelsTest, InternalChannelTest) {
+ grpc_core::ExecCtx exec_ctx;
+ ChannelFixture channels[10];
+ (void)channels; // suppress unused variable error
+ // create an internal channel
+ grpc_arg client_a[2];
+ client_a[0] = grpc_channel_arg_integer_create(
+ const_cast<char*>(GRPC_ARG_CHANNELZ_CHANNEL_IS_INTERNAL_CHANNEL), true);
+ client_a[1] = grpc_channel_arg_integer_create(
+ const_cast<char*>(GRPC_ARG_ENABLE_CHANNELZ), true);
+ grpc_channel_args client_args = {GPR_ARRAY_SIZE(client_a), client_a};
+ grpc_channel* internal_channel =
+ grpc_insecure_channel_create("fake_target", &client_args, nullptr);
+ // The internal channel should not be returned from the request
+ ValidateGetTopChannels(10);
+ grpc_channel_destroy(internal_channel);
+}
+
INSTANTIATE_TEST_CASE_P(ChannelzChannelTestSweep, ChannelzChannelTest,
::testing::Values(0, 1, 2, 6, 10, 15));
diff --git a/test/core/end2end/tests/channelz.cc b/test/core/end2end/tests/channelz.cc
index eb052119ca..533703a2be 100644
--- a/test/core/end2end/tests/channelz.cc
+++ b/test/core/end2end/tests/channelz.cc
@@ -209,27 +209,27 @@ static void test_channelz(grpc_end2end_test_config config) {
grpc_channel_get_channelz_node(f.client);
GPR_ASSERT(channelz_channel != nullptr);
- char* json = channelz_channel->RenderJSON();
+ char* json = channelz_channel->RenderJsonString();
GPR_ASSERT(json != nullptr);
- GPR_ASSERT(nullptr != strstr(json, "\"callsStarted\":\"0\""));
- GPR_ASSERT(nullptr != strstr(json, "\"callsFailed\":\"0\""));
- GPR_ASSERT(nullptr != strstr(json, "\"callsSucceeded\":\"0\""));
+ // nothing is present yet
+ GPR_ASSERT(nullptr == strstr(json, "\"callsStarted\""));
+ GPR_ASSERT(nullptr == strstr(json, "\"callsFailed\""));
+ GPR_ASSERT(nullptr == strstr(json, "\"callsSucceeded\""));
gpr_free(json);
// one successful request
run_one_request(config, f, true);
- json = channelz_channel->RenderJSON();
+ json = channelz_channel->RenderJsonString();
GPR_ASSERT(json != nullptr);
GPR_ASSERT(nullptr != strstr(json, "\"callsStarted\":\"1\""));
- GPR_ASSERT(nullptr != strstr(json, "\"callsFailed\":\"0\""));
GPR_ASSERT(nullptr != strstr(json, "\"callsSucceeded\":\"1\""));
gpr_free(json);
// one failed request
run_one_request(config, f, false);
- json = channelz_channel->RenderJSON();
+ json = channelz_channel->RenderJsonString();
GPR_ASSERT(json != nullptr);
gpr_log(GPR_INFO, "%s", json);
GPR_ASSERT(nullptr != strstr(json, "\"callsStarted\":\"2\""));
@@ -264,7 +264,7 @@ static void test_channelz_with_channel_trace(grpc_end2end_test_config config) {
grpc_channel_get_channelz_node(f.client);
GPR_ASSERT(channelz_channel != nullptr);
- char* json = channelz_channel->RenderJSON();
+ char* json = channelz_channel->RenderJsonString();
GPR_ASSERT(json != nullptr);
gpr_log(GPR_INFO, "%s", json);
GPR_ASSERT(nullptr != strstr(json, "\"trace\""));
diff --git a/test/core/gprpp/ref_counted_ptr_test.cc b/test/core/gprpp/ref_counted_ptr_test.cc
index aa30b72282..463b5e8966 100644
--- a/test/core/gprpp/ref_counted_ptr_test.cc
+++ b/test/core/gprpp/ref_counted_ptr_test.cc
@@ -127,7 +127,7 @@ TEST(RefCountedPtr, ResetFromNonNullToNull) {
TEST(RefCountedPtr, ResetFromNullToNull) {
RefCountedPtr<Foo> foo;
EXPECT_EQ(nullptr, foo.get());
- foo.reset(nullptr);
+ foo.reset();
EXPECT_EQ(nullptr, foo.get());
}
@@ -175,6 +175,67 @@ TEST(RefCountedPtr, RefCountedWithTracing) {
foo->Unref(DEBUG_LOCATION, "foo");
}
+class BaseClass : public RefCounted<BaseClass> {
+ public:
+ BaseClass() {}
+};
+
+class Subclass : public BaseClass {
+ public:
+ Subclass() {}
+};
+
+TEST(RefCountedPtr, ConstructFromSubclass) {
+ RefCountedPtr<BaseClass> p(New<Subclass>());
+}
+
+TEST(RefCountedPtr, CopyAssignFromSubclass) {
+ RefCountedPtr<BaseClass> b;
+ EXPECT_EQ(nullptr, b.get());
+ RefCountedPtr<Subclass> s = MakeRefCounted<Subclass>();
+ b = s;
+ EXPECT_NE(nullptr, b.get());
+}
+
+TEST(RefCountedPtr, MoveAssignFromSubclass) {
+ RefCountedPtr<BaseClass> b;
+ EXPECT_EQ(nullptr, b.get());
+ RefCountedPtr<Subclass> s = MakeRefCounted<Subclass>();
+ b = std::move(s);
+ EXPECT_NE(nullptr, b.get());
+}
+
+TEST(RefCountedPtr, ResetFromSubclass) {
+ RefCountedPtr<BaseClass> b;
+ EXPECT_EQ(nullptr, b.get());
+ b.reset(New<Subclass>());
+ EXPECT_NE(nullptr, b.get());
+}
+
+TEST(RefCountedPtr, EqualityWithSubclass) {
+ Subclass* s = New<Subclass>();
+ RefCountedPtr<BaseClass> b(s);
+ EXPECT_EQ(b, s);
+}
+
+void FunctionTakingBaseClass(RefCountedPtr<BaseClass> p) {
+ p.reset(); // To appease clang-tidy.
+}
+
+TEST(RefCountedPtr, CanPassSubclassToFunctionExpectingBaseClass) {
+ RefCountedPtr<Subclass> p = MakeRefCounted<Subclass>();
+ FunctionTakingBaseClass(p);
+}
+
+void FunctionTakingSubclass(RefCountedPtr<Subclass> p) {
+ p.reset(); // To appease clang-tidy.
+}
+
+TEST(RefCountedPtr, CanPassSubclassToFunctionExpectingSubclass) {
+ RefCountedPtr<Subclass> p = MakeRefCounted<Subclass>();
+ FunctionTakingSubclass(p);
+}
+
} // namespace
} // namespace testing
} // namespace grpc_core
diff --git a/test/core/iomgr/BUILD b/test/core/iomgr/BUILD
index fb0490a95f..002671a5fa 100644
--- a/test/core/iomgr/BUILD
+++ b/test/core/iomgr/BUILD
@@ -125,6 +125,19 @@ grpc_cc_test(
)
grpc_cc_test(
+ name = "grpc_ipv6_loopback_available_test",
+ srcs = ["grpc_ipv6_loopback_available_test.cc"],
+ language = "C++",
+ deps = [
+ "//:gpr",
+ "//:grpc",
+ "//test/core/util:gpr_test_util",
+ "//test/core/util:grpc_test_util",
+ ],
+)
+
+
+grpc_cc_test(
name = "load_file_test",
srcs = ["load_file_test.cc"],
language = "C++",
diff --git a/test/core/iomgr/grpc_ipv6_loopback_available_test.cc b/test/core/iomgr/grpc_ipv6_loopback_available_test.cc
new file mode 100644
index 0000000000..329aa9a851
--- /dev/null
+++ b/test/core/iomgr/grpc_ipv6_loopback_available_test.cc
@@ -0,0 +1,48 @@
+/*
+ *
+ * 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 "src/core/lib/iomgr/port.h"
+
+// grpc_ipv6_loopback_available isn't currently available on UV.
+#ifndef GRPC_UV
+
+#include <grpc/grpc.h>
+#include <grpc/support/log.h>
+#include "test/core/util/test_config.h"
+
+#ifdef GPR_WINDOWS
+#include "src/core/lib/iomgr/socket_windows.h"
+#else
+#include "src/core/lib/iomgr/socket_utils_posix.h"
+#endif
+
+int main(int argc, char** argv) {
+ grpc_test_init(argc, argv);
+ grpc_init();
+ // This test assumes that the ipv6 loopback is available
+ // in all environments in which grpc tests run in.
+ GPR_ASSERT(grpc_ipv6_loopback_available());
+ grpc_shutdown();
+ return 0;
+}
+
+#else
+
+int main(int argc, char** argv) { return 0; }
+
+#endif /* GRPC_UV */
diff --git a/test/core/security/check_gcp_environment_linux_test.cc b/test/core/security/check_gcp_environment_linux_test.cc
index 3acd5b6ae4..b01471abd3 100644
--- a/test/core/security/check_gcp_environment_linux_test.cc
+++ b/test/core/security/check_gcp_environment_linux_test.cc
@@ -69,6 +69,7 @@ static void test_gcp_environment_check_failure() {
GPR_ASSERT(!check_bios_data_linux_test("Amazon"));
GPR_ASSERT(!check_bios_data_linux_test("Google-Chrome\t\t"));
GPR_ASSERT(!check_bios_data_linux_test("Amazon"));
+ GPR_ASSERT(!check_bios_data_linux_test("\n"));
}
int main(int argc, char** argv) {
diff --git a/test/core/surface/public_headers_must_be_c89.c b/test/core/surface/public_headers_must_be_c89.c
index 9a79b468dd..9f4ad2b4d7 100644
--- a/test/core/surface/public_headers_must_be_c89.c
+++ b/test/core/surface/public_headers_must_be_c89.c
@@ -131,6 +131,8 @@ int main(int argc, char **argv) {
printf("%lx", (unsigned long) grpc_resource_quota_unref);
printf("%lx", (unsigned long) grpc_resource_quota_resize);
printf("%lx", (unsigned long) grpc_resource_quota_arg_vtable);
+ printf("%lx", (unsigned long) grpc_channelz_get_top_channels);
+ printf("%lx", (unsigned long) grpc_channelz_get_channel);
printf("%lx", (unsigned long) grpc_auth_property_iterator_next);
printf("%lx", (unsigned long) grpc_auth_context_property_iterator);
printf("%lx", (unsigned long) grpc_auth_context_peer_identity);
diff --git a/test/cpp/end2end/BUILD b/test/cpp/end2end/BUILD
index 95bb7ed229..75dec56a60 100644
--- a/test/cpp/end2end/BUILD
+++ b/test/cpp/end2end/BUILD
@@ -120,6 +120,27 @@ grpc_cc_library(
)
grpc_cc_test(
+ name = "channelz_service_test",
+ srcs = ["channelz_service_test.cc"],
+ external_deps = [
+ "gtest",
+ ],
+ deps = [
+ ":test_service_impl",
+ "//:gpr",
+ "//:grpc",
+ "//:grpc++",
+ "//:grpcpp_channelz",
+ "//src/proto/grpc/channelz:channelz_proto",
+ "//src/proto/grpc/testing:echo_messages_proto",
+ "//src/proto/grpc/testing:echo_proto",
+ "//test/core/util:gpr_test_util",
+ "//test/core/util:grpc_test_util",
+ "//test/cpp/util:test_util",
+ ],
+)
+
+grpc_cc_test(
name = "server_early_return_test",
srcs = ["server_early_return_test.cc"],
external_deps = [
diff --git a/test/cpp/end2end/channelz_service_test.cc b/test/cpp/end2end/channelz_service_test.cc
new file mode 100644
index 0000000000..933e4a1ff6
--- /dev/null
+++ b/test/cpp/end2end/channelz_service_test.cc
@@ -0,0 +1,352 @@
+/*
+ *
+ * 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 <grpc/grpc.h>
+#include <grpcpp/channel.h>
+#include <grpcpp/client_context.h>
+#include <grpcpp/create_channel.h>
+#include <grpcpp/security/credentials.h>
+#include <grpcpp/security/server_credentials.h>
+#include <grpcpp/server.h>
+#include <grpcpp/server_builder.h>
+#include <grpcpp/server_context.h>
+
+#include <grpcpp/ext/channelz_service_plugin.h>
+#include "src/proto/grpc/channelz/channelz.grpc.pb.h"
+#include "src/proto/grpc/testing/echo.grpc.pb.h"
+#include "test/core/util/port.h"
+#include "test/core/util/test_config.h"
+#include "test/cpp/end2end/test_service_impl.h"
+
+#include <gtest/gtest.h>
+
+using grpc::channelz::v1::GetChannelRequest;
+using grpc::channelz::v1::GetChannelResponse;
+using grpc::channelz::v1::GetTopChannelsRequest;
+using grpc::channelz::v1::GetTopChannelsResponse;
+
+namespace grpc {
+namespace testing {
+namespace {
+
+// Proxy service supports N backends. Sends RPC to backend dictated by
+// request->backend_channel_idx().
+class Proxy : public ::grpc::testing::EchoTestService::Service {
+ public:
+ Proxy() {}
+
+ void AddChannelToBackend(const std::shared_ptr<Channel>& channel) {
+ stubs_.push_back(grpc::testing::EchoTestService::NewStub(channel));
+ }
+
+ Status Echo(ServerContext* server_context, const EchoRequest* request,
+ EchoResponse* response) override {
+ std::unique_ptr<ClientContext> client_context =
+ ClientContext::FromServerContext(*server_context);
+ size_t idx = request->param().backend_channel_idx();
+ GPR_ASSERT(idx < stubs_.size());
+ return stubs_[idx]->Echo(client_context.get(), *request, response);
+ }
+
+ private:
+ std::vector<std::unique_ptr<::grpc::testing::EchoTestService::Stub>> stubs_;
+};
+
+} // namespace
+
+class ChannelzServerTest : public ::testing::Test {
+ public:
+ ChannelzServerTest() {}
+
+ void SetUp() override {
+ // ensure channel server is brought up on all severs we build.
+ ::grpc::channelz::experimental::InitChannelzService();
+
+ // We set up a proxy server with channelz enabled.
+ proxy_port_ = grpc_pick_unused_port_or_die();
+ ServerBuilder proxy_builder;
+ grpc::string proxy_server_address = "localhost:" + to_string(proxy_port_);
+ proxy_builder.AddListeningPort(proxy_server_address,
+ InsecureServerCredentials());
+ // forces channelz and channel tracing to be enabled.
+ proxy_builder.AddChannelArgument(GRPC_ARG_ENABLE_CHANNELZ, 1);
+ proxy_builder.AddChannelArgument(GRPC_ARG_MAX_CHANNEL_TRACE_EVENTS_PER_NODE,
+ 10);
+ proxy_builder.RegisterService(&proxy_service_);
+ proxy_server_ = proxy_builder.BuildAndStart();
+ }
+
+ // Sets the proxy up to have an arbitrary number of backends.
+ void ConfigureProxy(size_t num_backends) {
+ backends_.resize(num_backends);
+ for (size_t i = 0; i < num_backends; ++i) {
+ // create a new backend.
+ backends_[i].port = grpc_pick_unused_port_or_die();
+ ServerBuilder backend_builder;
+ grpc::string backend_server_address =
+ "localhost:" + to_string(backends_[i].port);
+ backend_builder.AddListeningPort(backend_server_address,
+ InsecureServerCredentials());
+ backends_[i].service.reset(new TestServiceImpl);
+ // ensure that the backend itself has channelz disabled.
+ backend_builder.AddChannelArgument(GRPC_ARG_ENABLE_CHANNELZ, 0);
+ backend_builder.RegisterService(backends_[i].service.get());
+ backends_[i].server = backend_builder.BuildAndStart();
+ // set up a channel to the backend. We ensure that this channel has
+ // channelz enabled since these channels (proxy outbound to backends)
+ // are the ones that our test will actually be validating.
+ ChannelArguments args;
+ args.SetInt(GRPC_ARG_ENABLE_CHANNELZ, 1);
+ args.SetInt(GRPC_ARG_MAX_CHANNEL_TRACE_EVENTS_PER_NODE, 10);
+ std::shared_ptr<Channel> channel_to_backend = CreateCustomChannel(
+ backend_server_address, InsecureChannelCredentials(), args);
+ proxy_service_.AddChannelToBackend(channel_to_backend);
+ }
+ }
+
+ void ResetStubs() {
+ string target = "dns:localhost:" + to_string(proxy_port_);
+ ChannelArguments args;
+ // disable channelz. We only want to focus on proxy to backend outbound.
+ args.SetInt(GRPC_ARG_ENABLE_CHANNELZ, 0);
+ std::shared_ptr<Channel> channel =
+ CreateCustomChannel(target, InsecureChannelCredentials(), args);
+ channelz_stub_ = grpc::channelz::v1::Channelz::NewStub(channel);
+ echo_stub_ = grpc::testing::EchoTestService::NewStub(channel);
+ }
+
+ void SendSuccessfulEcho(int channel_idx) {
+ EchoRequest request;
+ EchoResponse response;
+ request.set_message("Hello channelz");
+ request.mutable_param()->set_backend_channel_idx(channel_idx);
+ ClientContext context;
+ Status s = echo_stub_->Echo(&context, request, &response);
+ EXPECT_EQ(response.message(), request.message());
+ EXPECT_TRUE(s.ok());
+ }
+
+ void SendFailedEcho(int channel_idx) {
+ EchoRequest request;
+ EchoResponse response;
+ request.set_message("Hello channelz");
+ request.mutable_param()->set_backend_channel_idx(channel_idx);
+ auto* error = request.mutable_param()->mutable_expected_error();
+ error->set_code(13); // INTERNAL
+ error->set_error_message("error");
+ ClientContext context;
+ Status s = echo_stub_->Echo(&context, request, &response);
+ EXPECT_FALSE(s.ok());
+ }
+
+ static string to_string(const int number) {
+ std::stringstream strs;
+ strs << number;
+ return strs.str();
+ }
+
+ protected:
+ // package of data needed for each backend server.
+ struct BackendData {
+ std::unique_ptr<Server> server;
+ int port;
+ std::unique_ptr<TestServiceImpl> service;
+ };
+
+ std::unique_ptr<grpc::channelz::v1::Channelz::Stub> channelz_stub_;
+ std::unique_ptr<grpc::testing::EchoTestService::Stub> echo_stub_;
+
+ // proxy server to ping with channelz requests.
+ std::unique_ptr<Server> proxy_server_;
+ int proxy_port_;
+ Proxy proxy_service_;
+
+ // backends. All implement the echo service.
+ std::vector<BackendData> backends_;
+};
+
+TEST_F(ChannelzServerTest, BasicTest) {
+ ResetStubs();
+ ConfigureProxy(1);
+ GetTopChannelsRequest request;
+ GetTopChannelsResponse response;
+ request.set_start_channel_id(0);
+ ClientContext context;
+ Status s = channelz_stub_->GetTopChannels(&context, request, &response);
+ EXPECT_TRUE(s.ok());
+ EXPECT_EQ(response.channel_size(), 1);
+}
+
+TEST_F(ChannelzServerTest, HighStartId) {
+ ResetStubs();
+ ConfigureProxy(1);
+ GetTopChannelsRequest request;
+ GetTopChannelsResponse response;
+ request.set_start_channel_id(10000);
+ ClientContext context;
+ Status s = channelz_stub_->GetTopChannels(&context, request, &response);
+ EXPECT_TRUE(s.ok());
+ EXPECT_EQ(response.channel_size(), 0);
+}
+
+TEST_F(ChannelzServerTest, SuccessfulRequestTest) {
+ ResetStubs();
+ ConfigureProxy(1);
+ SendSuccessfulEcho(0);
+ GetChannelRequest request;
+ GetChannelResponse response;
+ request.set_channel_id(1);
+ ClientContext context;
+ Status s = channelz_stub_->GetChannel(&context, request, &response);
+ EXPECT_TRUE(s.ok());
+ EXPECT_EQ(response.channel().data().calls_started(), 1);
+ EXPECT_EQ(response.channel().data().calls_succeeded(), 1);
+ EXPECT_EQ(response.channel().data().calls_failed(), 0);
+}
+
+TEST_F(ChannelzServerTest, FailedRequestTest) {
+ ResetStubs();
+ ConfigureProxy(1);
+ SendFailedEcho(0);
+ GetChannelRequest request;
+ GetChannelResponse response;
+ request.set_channel_id(1);
+ ClientContext context;
+ Status s = channelz_stub_->GetChannel(&context, request, &response);
+ EXPECT_TRUE(s.ok());
+ EXPECT_EQ(response.channel().data().calls_started(), 1);
+ EXPECT_EQ(response.channel().data().calls_succeeded(), 0);
+ EXPECT_EQ(response.channel().data().calls_failed(), 1);
+}
+
+TEST_F(ChannelzServerTest, ManyRequestsTest) {
+ ResetStubs();
+ ConfigureProxy(1);
+ // send some RPCs
+ const int kNumSuccess = 10;
+ const int kNumFailed = 11;
+ for (int i = 0; i < kNumSuccess; ++i) {
+ SendSuccessfulEcho(0);
+ }
+ for (int i = 0; i < kNumFailed; ++i) {
+ SendFailedEcho(0);
+ }
+ GetChannelRequest request;
+ GetChannelResponse response;
+ request.set_channel_id(1);
+ ClientContext context;
+ Status s = channelz_stub_->GetChannel(&context, request, &response);
+ EXPECT_TRUE(s.ok());
+ EXPECT_EQ(response.channel().data().calls_started(),
+ kNumSuccess + kNumFailed);
+ EXPECT_EQ(response.channel().data().calls_succeeded(), kNumSuccess);
+ EXPECT_EQ(response.channel().data().calls_failed(), kNumFailed);
+}
+
+TEST_F(ChannelzServerTest, ManyChannels) {
+ ResetStubs();
+ const int kNumChannels = 4;
+ ConfigureProxy(kNumChannels);
+ GetTopChannelsRequest request;
+ GetTopChannelsResponse response;
+ request.set_start_channel_id(0);
+ ClientContext context;
+ Status s = channelz_stub_->GetTopChannels(&context, request, &response);
+ EXPECT_TRUE(s.ok());
+ EXPECT_EQ(response.channel_size(), kNumChannels);
+}
+
+TEST_F(ChannelzServerTest, ManyRequestsManyChannels) {
+ ResetStubs();
+ const int kNumChannels = 4;
+ ConfigureProxy(kNumChannels);
+ const int kNumSuccess = 10;
+ const int kNumFailed = 11;
+ for (int i = 0; i < kNumSuccess; ++i) {
+ SendSuccessfulEcho(0);
+ SendSuccessfulEcho(2);
+ }
+ for (int i = 0; i < kNumFailed; ++i) {
+ SendFailedEcho(1);
+ SendFailedEcho(2);
+ }
+
+ // the first channel saw only successes
+ {
+ GetChannelRequest request;
+ GetChannelResponse response;
+ request.set_channel_id(1);
+ ClientContext context;
+ Status s = channelz_stub_->GetChannel(&context, request, &response);
+ EXPECT_TRUE(s.ok());
+ EXPECT_EQ(response.channel().data().calls_started(), kNumSuccess);
+ EXPECT_EQ(response.channel().data().calls_succeeded(), kNumSuccess);
+ EXPECT_EQ(response.channel().data().calls_failed(), 0);
+ }
+
+ // the second channel saw only failures
+ {
+ GetChannelRequest request;
+ GetChannelResponse response;
+ request.set_channel_id(2);
+ ClientContext context;
+ Status s = channelz_stub_->GetChannel(&context, request, &response);
+ EXPECT_TRUE(s.ok());
+ EXPECT_EQ(response.channel().data().calls_started(), kNumFailed);
+ EXPECT_EQ(response.channel().data().calls_succeeded(), 0);
+ EXPECT_EQ(response.channel().data().calls_failed(), kNumFailed);
+ }
+
+ // the third channel saw both
+ {
+ GetChannelRequest request;
+ GetChannelResponse response;
+ request.set_channel_id(3);
+ ClientContext context;
+ Status s = channelz_stub_->GetChannel(&context, request, &response);
+ EXPECT_TRUE(s.ok());
+ EXPECT_EQ(response.channel().data().calls_started(),
+ kNumSuccess + kNumFailed);
+ EXPECT_EQ(response.channel().data().calls_succeeded(), kNumSuccess);
+ EXPECT_EQ(response.channel().data().calls_failed(), kNumFailed);
+ }
+
+ // the fourth channel saw nothing
+ {
+ GetChannelRequest request;
+ GetChannelResponse response;
+ request.set_channel_id(4);
+ ClientContext context;
+ Status s = channelz_stub_->GetChannel(&context, request, &response);
+ EXPECT_TRUE(s.ok());
+ EXPECT_EQ(response.channel().data().calls_started(), 0);
+ EXPECT_EQ(response.channel().data().calls_succeeded(), 0);
+ EXPECT_EQ(response.channel().data().calls_failed(), 0);
+ }
+}
+
+} // namespace testing
+} // namespace grpc
+
+int main(int argc, char** argv) {
+ grpc_test_init(argc, argv);
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc
index 8896fc6cae..c5a73a2469 100644
--- a/test/cpp/end2end/client_lb_end2end_test.cc
+++ b/test/cpp/end2end/client_lb_end2end_test.cc
@@ -279,9 +279,14 @@ class ClientLbEnd2endTest : public ::testing::Test {
void WaitForServer(
const std::unique_ptr<grpc::testing::EchoTestService::Stub>& stub,
- size_t server_idx, const grpc_core::DebugLocation& location) {
+ size_t server_idx, const grpc_core::DebugLocation& location,
+ bool ignore_failure = false) {
do {
- CheckRpcSendOk(stub, location);
+ if (ignore_failure) {
+ SendRpc(stub);
+ } else {
+ CheckRpcSendOk(stub, location);
+ }
} while (servers_[server_idx]->service_.request_count() == 0);
ResetCounters();
}
@@ -507,6 +512,37 @@ TEST_F(ClientLbEnd2endTest, PickFirstManyUpdates) {
EXPECT_EQ("pick_first", channel->GetLoadBalancingPolicyName());
}
+TEST_F(ClientLbEnd2endTest, PickFirstReresolutionNoSelected) {
+ // Prepare the ports for up servers and down servers.
+ const int kNumServers = 3;
+ const int kNumAliveServers = 1;
+ StartServers(kNumAliveServers);
+ std::vector<int> alive_ports, dead_ports;
+ for (size_t i = 0; i < kNumServers; ++i) {
+ if (i < kNumAliveServers) {
+ alive_ports.emplace_back(servers_[i]->port_);
+ } else {
+ dead_ports.emplace_back(grpc_pick_unused_port_or_die());
+ }
+ }
+ auto channel = BuildChannel("pick_first");
+ auto stub = BuildStub(channel);
+ // The initial resolution only contains dead ports. There won't be any
+ // selected subchannel. Re-resolution will return the same result.
+ SetNextResolution(dead_ports);
+ gpr_log(GPR_INFO, "****** INITIAL RESOLUTION SET *******");
+ for (size_t i = 0; i < 10; ++i) CheckRpcSendFailure(stub);
+ // Set a re-resolution result that contains reachable ports, so that the
+ // pick_first LB policy can recover soon.
+ SetNextResolutionUponError(alive_ports);
+ gpr_log(GPR_INFO, "****** RE-RESOLUTION SET *******");
+ WaitForServer(stub, 0, DEBUG_LOCATION, true /* ignore_failure */);
+ CheckRpcSendOk(stub, DEBUG_LOCATION);
+ EXPECT_EQ(servers_[0]->service_.request_count(), 1);
+ // Check LB policy name for the channel.
+ EXPECT_EQ("pick_first", channel->GetLoadBalancingPolicyName());
+}
+
TEST_F(ClientLbEnd2endTest, RoundRobin) {
// Start servers and send one RPC per server.
const int kNumServers = 3;
diff --git a/test/cpp/interop/client.cc b/test/cpp/interop/client.cc
index 3eb155ef95..7bcf23c0eb 100644
--- a/test/cpp/interop/client.cc
+++ b/test/cpp/interop/client.cc
@@ -46,6 +46,7 @@ DEFINE_string(
"all : all test cases;\n"
"cancel_after_begin : cancel stream after starting it;\n"
"cancel_after_first_response: cancel on first response;\n"
+ "channel_soak: sends 'soak_iterations' rpcs, rebuilds channel each time;\n"
"client_compressed_streaming : compressed request streaming with "
"client_compressed_unary : single compressed request;\n"
"client_streaming : request streaming with single response;\n"
@@ -60,6 +61,7 @@ DEFINE_string(
"per_rpc_creds: raw oauth2 access token on a single rpc;\n"
"ping_pong : full-duplex streaming;\n"
"response streaming;\n"
+ "rpc_soak: 'sends soak_iterations' large_unary rpcs;\n"
"server_compressed_streaming : single request with compressed "
"server_compressed_unary : single compressed response;\n"
"server_streaming : single request with response streaming;\n"
@@ -83,6 +85,10 @@ DEFINE_bool(do_not_abort_on_transient_failures, false,
"test is retried in case of transient failures (and currently the "
"interop tests are not retried even if this flag is set to true)");
+DEFINE_int32(soak_iterations, 1000,
+ "number of iterations to use for the two soak tests; rpc_soak and "
+ "channel_soak");
+
using grpc::testing::CreateChannelForTestCase;
using grpc::testing::GetServiceAccountJsonKey;
using grpc::testing::UpdateActions;
@@ -91,8 +97,9 @@ int main(int argc, char** argv) {
grpc::testing::InitTest(&argc, &argv, true);
gpr_log(GPR_INFO, "Testing these cases: %s", FLAGS_test_case.c_str());
int ret = 0;
- grpc::testing::InteropClient client(CreateChannelForTestCase(FLAGS_test_case),
- true,
+ grpc::testing::ChannelCreationFunc channel_creation_func =
+ std::bind(&CreateChannelForTestCase, FLAGS_test_case);
+ grpc::testing::InteropClient client(channel_creation_func, true,
FLAGS_do_not_abort_on_transient_failures);
std::unordered_map<grpc::string, std::function<bool()>> actions;
@@ -151,6 +158,11 @@ int main(int argc, char** argv) {
std::bind(&grpc::testing::InteropClient::DoUnimplementedService, &client);
actions["cacheable_unary"] =
std::bind(&grpc::testing::InteropClient::DoCacheableUnary, &client);
+ actions["channel_soak"] =
+ std::bind(&grpc::testing::InteropClient::DoChannelSoakTest, &client,
+ FLAGS_soak_iterations);
+ actions["rpc_soak"] = std::bind(&grpc::testing::InteropClient::DoRpcSoakTest,
+ &client, FLAGS_soak_iterations);
UpdateActions(&actions);
diff --git a/test/cpp/interop/interop_client.cc b/test/cpp/interop/interop_client.cc
index fce99a1697..b7ce90803b 100644
--- a/test/cpp/interop/interop_client.cc
+++ b/test/cpp/interop/interop_client.cc
@@ -74,13 +74,15 @@ void UnaryCompressionChecks(const InteropClientContextInspector& inspector,
}
} // namespace
-InteropClient::ServiceStub::ServiceStub(const std::shared_ptr<Channel>& channel,
- bool new_stub_every_call)
- : channel_(channel), new_stub_every_call_(new_stub_every_call) {
+InteropClient::ServiceStub::ServiceStub(
+ ChannelCreationFunc channel_creation_func, bool new_stub_every_call)
+ : channel_creation_func_(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
// stub_. (see Get())
if (!new_stub_every_call) {
- stub_ = TestService::NewStub(channel);
+ stub_ = TestService::NewStub(channel_);
}
}
@@ -100,27 +102,17 @@ InteropClient::ServiceStub::GetUnimplementedServiceStub() {
return unimplemented_service_stub_.get();
}
-void InteropClient::ServiceStub::Reset(
- const std::shared_ptr<Channel>& channel) {
- channel_ = channel;
-
- // Update stub_ as well. Note: If new_stub_every_call_ is true, we can reset
- // the stub_ since the next call to Get() will create a new stub
- if (new_stub_every_call_) {
- stub_.reset();
- } else {
- stub_ = TestService::NewStub(channel);
+void InteropClient::ServiceStub::ResetChannel() {
+ channel_ = channel_creation_func_();
+ if (!new_stub_every_call_) {
+ stub_ = TestService::NewStub(channel_);
}
}
-void InteropClient::Reset(const std::shared_ptr<Channel>& channel) {
- serviceStub_.Reset(std::move(channel));
-}
-
-InteropClient::InteropClient(const std::shared_ptr<Channel>& channel,
+InteropClient::InteropClient(ChannelCreationFunc channel_creation_func,
bool new_stub_every_test_case,
bool do_not_abort_on_transient_failures)
- : serviceStub_(std::move(channel), new_stub_every_test_case),
+ : serviceStub_(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,
@@ -1028,6 +1020,38 @@ bool InteropClient::DoCustomMetadata() {
return true;
}
+bool InteropClient::DoRpcSoakTest(int32_t soak_iterations) {
+ gpr_log(GPR_DEBUG, "Sending %d RPCs...", soak_iterations);
+ GPR_ASSERT(soak_iterations > 0);
+ SimpleRequest request;
+ SimpleResponse response;
+ for (int i = 0; i < soak_iterations; ++i) {
+ if (!PerformLargeUnary(&request, &response)) {
+ gpr_log(GPR_ERROR, "rpc_soak test failed on iteration %d", i);
+ return false;
+ }
+ }
+ gpr_log(GPR_DEBUG, "rpc_soak test done.");
+ return true;
+}
+
+bool InteropClient::DoChannelSoakTest(int32_t soak_iterations) {
+ gpr_log(GPR_DEBUG, "Sending %d RPCs, tearing down the channel each time...",
+ soak_iterations);
+ GPR_ASSERT(soak_iterations > 0);
+ SimpleRequest request;
+ SimpleResponse response;
+ for (int i = 0; i < soak_iterations; ++i) {
+ serviceStub_.ResetChannel();
+ if (!PerformLargeUnary(&request, &response)) {
+ gpr_log(GPR_ERROR, "channel_soak test failed on iteration %d", i);
+ return false;
+ }
+ }
+ gpr_log(GPR_DEBUG, "channel_soak test done.");
+ return true;
+}
+
bool InteropClient::DoUnimplementedService() {
gpr_log(GPR_DEBUG, "Sending a request for an unimplemented service...");
diff --git a/test/cpp/interop/interop_client.h b/test/cpp/interop/interop_client.h
index 480eb3f4b6..e5be44d1d4 100644
--- a/test/cpp/interop/interop_client.h
+++ b/test/cpp/interop/interop_client.h
@@ -34,13 +34,15 @@ typedef std::function<void(const InteropClientContextInspector&,
const SimpleRequest*, const SimpleResponse*)>
CheckerFn;
+typedef std::function<std::shared_ptr<Channel>(void)> ChannelCreationFunc;
+
class InteropClient {
public:
/// If new_stub_every_test_case is true, a new TestService::Stub object is
/// created for every test case
/// If do_not_abort_on_transient_failures is true, abort() is not called in
/// case of transient failures (like connection failures)
- explicit InteropClient(const std::shared_ptr<Channel>& channel,
+ explicit InteropClient(ChannelCreationFunc channel_creation_func,
bool new_stub_every_test_case,
bool do_not_abort_on_transient_failures);
~InteropClient() {}
@@ -67,6 +69,14 @@ class InteropClient {
bool DoUnimplementedMethod();
bool DoUnimplementedService();
bool DoCacheableUnary();
+
+ // The following interop test are not yet part of the interop spec, and are
+ // not implemented cross-language. They are considered experimental for now,
+ // but at some point in the future, might be codified and implemented in all
+ // languages
+ bool DoChannelSoakTest(int32_t soak_iterations);
+ bool DoRpcSoakTest(int32_t soak_iterations);
+
// Auth tests.
// username is a string containing the user email
bool DoJwtTokenCreds(const grpc::string& username);
@@ -83,15 +93,17 @@ class InteropClient {
public:
// If new_stub_every_call = true, pointer to a new instance of
// TestServce::Stub is returned by Get() everytime it is called
- ServiceStub(const std::shared_ptr<Channel>& channel,
+ ServiceStub(ChannelCreationFunc channel_creation_func,
bool new_stub_every_call);
TestService::Stub* Get();
UnimplementedService::Stub* GetUnimplementedServiceStub();
- void Reset(const std::shared_ptr<Channel>& channel);
+ // forces channel to be recreated.
+ void ResetChannel();
private:
+ ChannelCreationFunc channel_creation_func_;
std::unique_ptr<TestService::Stub> stub_;
std::unique_ptr<UnimplementedService::Stub> unimplemented_service_stub_;
std::shared_ptr<Channel> channel_;
@@ -109,8 +121,8 @@ class InteropClient {
bool AssertStatusCode(const Status& s, StatusCode expected_code,
const grpc::string& optional_debug_string);
bool TransientFailureOrAbort();
- ServiceStub serviceStub_;
+ ServiceStub serviceStub_;
/// If true, abort() is not called for transient failures
bool do_not_abort_on_transient_failures_;
};
diff --git a/test/cpp/interop/stress_interop_client.cc b/test/cpp/interop/stress_interop_client.cc
index 9d373c3cd9..7dc1956f78 100644
--- a/test/cpp/interop/stress_interop_client.cc
+++ b/test/cpp/interop/stress_interop_client.cc
@@ -68,13 +68,13 @@ TestCaseType WeightedRandomTestSelector::GetNextTest() const {
StressTestInteropClient::StressTestInteropClient(
int test_id, const grpc::string& server_address,
- const std::shared_ptr<Channel>& channel,
+ ChannelCreationFunc channel_creation_func,
const WeightedRandomTestSelector& test_selector, long test_duration_secs,
long sleep_duration_ms, bool do_not_abort_on_transient_failures)
: test_id_(test_id),
server_address_(server_address),
- channel_(channel),
- interop_client_(new InteropClient(channel, false,
+ channel_creation_func_(channel_creation_func),
+ interop_client_(new InteropClient(channel_creation_func_, false,
do_not_abort_on_transient_failures)),
test_selector_(test_selector),
test_duration_secs_(test_duration_secs),
diff --git a/test/cpp/interop/stress_interop_client.h b/test/cpp/interop/stress_interop_client.h
index e4fa7d0973..58680d8093 100644
--- a/test/cpp/interop/stress_interop_client.h
+++ b/test/cpp/interop/stress_interop_client.h
@@ -91,7 +91,7 @@ class WeightedRandomTestSelector {
class StressTestInteropClient {
public:
StressTestInteropClient(int test_id, const grpc::string& server_address,
- const std::shared_ptr<Channel>& channel,
+ ChannelCreationFunc channel_creation_func,
const WeightedRandomTestSelector& test_selector,
long test_duration_secs, long sleep_duration_ms,
bool do_not_abort_on_transient_failures);
@@ -105,7 +105,7 @@ class StressTestInteropClient {
int test_id_;
const grpc::string& server_address_;
- std::shared_ptr<Channel> channel_;
+ ChannelCreationFunc channel_creation_func_;
std::unique_ptr<InteropClient> interop_client_;
const WeightedRandomTestSelector& test_selector_;
long test_duration_secs_;
diff --git a/test/cpp/interop/stress_test.cc b/test/cpp/interop/stress_test.cc
index 023e0c8f0b..ebbd14beba 100644
--- a/test/cpp/interop/stress_test.cc
+++ b/test/cpp/interop/stress_test.cc
@@ -283,15 +283,20 @@ int main(int argc, char** argv) {
channel_idx++) {
gpr_log(GPR_INFO, "Starting test with %s channel_idx=%d..", it->c_str(),
channel_idx);
- std::shared_ptr<grpc::Channel> channel = grpc::CreateTestChannel(
+ grpc::testing::ChannelCreationFunc channel_creation_func = std::bind(
+ static_cast<std::shared_ptr<grpc::Channel> (*)(
+ const grpc::string&, const grpc::string&,
+ grpc::testing::transport_security, bool)>(
+ grpc::CreateTestChannel),
*it, FLAGS_server_host_override, security_type, !FLAGS_use_test_ca);
// Create stub(s) for each channel
for (int stub_idx = 0; stub_idx < FLAGS_num_stubs_per_channel;
stub_idx++) {
clients.emplace_back(new StressTestInteropClient(
- ++thread_idx, *it, channel, test_selector, FLAGS_test_duration_secs,
- FLAGS_sleep_duration_ms, FLAGS_do_not_abort_on_transient_failures));
+ ++thread_idx, *it, channel_creation_func, test_selector,
+ FLAGS_test_duration_secs, FLAGS_sleep_duration_ms,
+ FLAGS_do_not_abort_on_transient_failures));
bool is_already_created = false;
// QpsGauge name
diff --git a/test/cpp/naming/address_sorting_test.cc b/test/cpp/naming/address_sorting_test.cc
index a92e9e3b3e..04c300876c 100644
--- a/test/cpp/naming/address_sorting_test.cc
+++ b/test/cpp/naming/address_sorting_test.cc
@@ -24,10 +24,8 @@
#include <grpc/support/time.h>
#include <string.h>
-#include <arpa/inet.h>
#include <gflags/gflags.h>
#include <gmock/gmock.h>
-#include <sys/socket.h>
#include <sys/types.h>
#include <vector>
@@ -51,6 +49,11 @@
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
+#ifndef GPR_WINDOWS
+#include <arpa/inet.h>
+#include <sys/socket.h>
+#endif
+
namespace {
struct TestAddress {
@@ -190,10 +193,18 @@ void VerifyLbAddrOutputs(grpc_lb_addresses* lb_addrs,
grpc_lb_addresses_destroy(lb_addrs);
}
-} // namespace
+/* We need to run each test case inside of its own
+ * isolated grpc_init/grpc_shutdown pair, so that
+ * the "address sorting source addr factory" can be
+ * restored to its default for each test case. */
+class AddressSortingTest : public ::testing::Test {
+ protected:
+ void SetUp() override { grpc_init(); }
+ void TearDown() override { grpc_shutdown(); }
+};
/* Tests for rule 1 */
-TEST(AddressSortingTest, TestDepriotizesUnreachableAddresses) {
+TEST_F(AddressSortingTest, TestDepriotizesUnreachableAddresses) {
bool ipv4_supported = true;
bool ipv6_supported = true;
OverrideAddressSortingSourceAddrFactory(
@@ -212,7 +223,7 @@ TEST(AddressSortingTest, TestDepriotizesUnreachableAddresses) {
});
}
-TEST(AddressSortingTest, TestDepriotizesUnsupportedDomainIpv6) {
+TEST_F(AddressSortingTest, TestDepriotizesUnsupportedDomainIpv6) {
bool ipv4_supported = true;
bool ipv6_supported = false;
OverrideAddressSortingSourceAddrFactory(
@@ -231,7 +242,7 @@ TEST(AddressSortingTest, TestDepriotizesUnsupportedDomainIpv6) {
});
}
-TEST(AddressSortingTest, TestDepriotizesUnsupportedDomainIpv4) {
+TEST_F(AddressSortingTest, TestDepriotizesUnsupportedDomainIpv4) {
bool ipv4_supported = false;
bool ipv6_supported = true;
OverrideAddressSortingSourceAddrFactory(
@@ -253,7 +264,7 @@ TEST(AddressSortingTest, TestDepriotizesUnsupportedDomainIpv4) {
/* Tests for rule 2 */
-TEST(AddressSortingTest, TestDepriotizesNonMatchingScope) {
+TEST_F(AddressSortingTest, TestDepriotizesNonMatchingScope) {
bool ipv4_supported = true;
bool ipv6_supported = true;
OverrideAddressSortingSourceAddrFactory(
@@ -277,7 +288,7 @@ TEST(AddressSortingTest, TestDepriotizesNonMatchingScope) {
/* Tests for rule 5 */
-TEST(AddressSortingTest, TestUsesLabelFromDefaultTable) {
+TEST_F(AddressSortingTest, TestUsesLabelFromDefaultTable) {
bool ipv4_supported = true;
bool ipv6_supported = true;
OverrideAddressSortingSourceAddrFactory(
@@ -300,7 +311,7 @@ TEST(AddressSortingTest, TestUsesLabelFromDefaultTable) {
/* Flip the input on the test above to reorder the sort function's
* comparator's inputs. */
-TEST(AddressSortingTest, TestUsesLabelFromDefaultTableInputFlipped) {
+TEST_F(AddressSortingTest, TestUsesLabelFromDefaultTableInputFlipped) {
bool ipv4_supported = true;
bool ipv6_supported = true;
OverrideAddressSortingSourceAddrFactory(
@@ -323,8 +334,8 @@ TEST(AddressSortingTest, TestUsesLabelFromDefaultTableInputFlipped) {
/* Tests for rule 6 */
-TEST(AddressSortingTest,
- TestUsesDestinationWithHigherPrecedenceWithAnIpv4Address) {
+TEST_F(AddressSortingTest,
+ TestUsesDestinationWithHigherPrecedenceWithAnIpv4Address) {
bool ipv4_supported = true;
bool ipv6_supported = true;
OverrideAddressSortingSourceAddrFactory(
@@ -348,8 +359,8 @@ TEST(AddressSortingTest,
});
}
-TEST(AddressSortingTest,
- TestUsesDestinationWithHigherPrecedenceWithV4CompatAndLocalhostAddress) {
+TEST_F(AddressSortingTest,
+ TestUsesDestinationWithHigherPrecedenceWithV4CompatAndLocalhostAddress) {
bool ipv4_supported = true;
bool ipv6_supported = true;
// Handle unique observed behavior of inet_ntop(v4-compatible-address) on OS X.
@@ -377,8 +388,8 @@ TEST(AddressSortingTest,
});
}
-TEST(AddressSortingTest,
- TestUsesDestinationWithHigherPrecedenceWithCatchAllAndLocalhostAddress) {
+TEST_F(AddressSortingTest,
+ TestUsesDestinationWithHigherPrecedenceWithCatchAllAndLocalhostAddress) {
bool ipv4_supported = true;
bool ipv6_supported = true;
OverrideAddressSortingSourceAddrFactory(
@@ -403,8 +414,8 @@ TEST(AddressSortingTest,
});
}
-TEST(AddressSortingTest,
- TestUsesDestinationWithHigherPrecedenceWith2000PrefixedAddress) {
+TEST_F(AddressSortingTest,
+ TestUsesDestinationWithHigherPrecedenceWith2000PrefixedAddress) {
bool ipv4_supported = true;
bool ipv6_supported = true;
OverrideAddressSortingSourceAddrFactory(
@@ -426,7 +437,7 @@ TEST(AddressSortingTest,
});
}
-TEST(
+TEST_F(
AddressSortingTest,
TestUsesDestinationWithHigherPrecedenceWith2000PrefixedAddressEnsurePrefixMatchHasNoEffect) {
bool ipv4_supported = true;
@@ -448,8 +459,8 @@ TEST(
});
}
-TEST(AddressSortingTest,
- TestUsesDestinationWithHigherPrecedenceWithLinkAndSiteLocalAddresses) {
+TEST_F(AddressSortingTest,
+ TestUsesDestinationWithHigherPrecedenceWithLinkAndSiteLocalAddresses) {
bool ipv4_supported = true;
bool ipv6_supported = true;
OverrideAddressSortingSourceAddrFactory(
@@ -469,19 +480,22 @@ TEST(AddressSortingTest,
});
}
-TEST(
+TEST_F(
AddressSortingTest,
TestUsesDestinationWithHigherPrecedenceWithCatchAllAndAndV4MappedAddresses) {
bool ipv4_supported = true;
bool ipv6_supported = true;
+ // Use embedded ipv4 addresses with leading 1's instead of zero's to be
+ // compatible with inet_ntop implementations that can display such
+ // addresses with leading zero's as e.g.: "::ffff:0:2", as on windows.
OverrideAddressSortingSourceAddrFactory(
ipv4_supported, ipv6_supported,
{
- {"[::ffff:0.0.0.2]:443", {"[::ffff:0.0.0.3]:0", AF_INET6}},
+ {"[::ffff:1.1.1.2]:443", {"[::ffff:1.1.1.3]:0", AF_INET6}},
{"[1234::2]:443", {"[1234::3]:0", AF_INET6}},
});
grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
- {"[::ffff:0.0.0.2]:443", AF_INET6},
+ {"[::ffff:1.1.1.2]:443", AF_INET6},
{"[1234::2]:443", AF_INET6},
});
grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs);
@@ -489,13 +503,13 @@ TEST(
// ::ffff:0:2 should match the v4-mapped
// precedence entry and be deprioritized.
"[1234::2]:443",
- "[::ffff:0.0.0.2]:443",
+ "[::ffff:1.1.1.2]:443",
});
}
/* Tests for rule 8 */
-TEST(AddressSortingTest, TestPrefersSmallerScope) {
+TEST_F(AddressSortingTest, TestPrefersSmallerScope) {
bool ipv4_supported = true;
bool ipv6_supported = true;
OverrideAddressSortingSourceAddrFactory(
@@ -520,7 +534,7 @@ TEST(AddressSortingTest, TestPrefersSmallerScope) {
/* Tests for rule 9 */
-TEST(AddressSortingTest, TestPrefersLongestMatchingSrcDstPrefix) {
+TEST_F(AddressSortingTest, TestPrefersLongestMatchingSrcDstPrefix) {
bool ipv4_supported = true;
bool ipv6_supported = true;
OverrideAddressSortingSourceAddrFactory(
@@ -543,8 +557,8 @@ TEST(AddressSortingTest, TestPrefersLongestMatchingSrcDstPrefix) {
});
}
-TEST(AddressSortingTest,
- TestPrefersLongestMatchingSrcDstPrefixMatchesWholeAddress) {
+TEST_F(AddressSortingTest,
+ TestPrefersLongestMatchingSrcDstPrefixMatchesWholeAddress) {
bool ipv4_supported = true;
bool ipv6_supported = true;
OverrideAddressSortingSourceAddrFactory(
@@ -564,7 +578,7 @@ TEST(AddressSortingTest,
});
}
-TEST(AddressSortingTest, TestPrefersLongestPrefixStressInnerBytePrefix) {
+TEST_F(AddressSortingTest, TestPrefersLongestPrefixStressInnerBytePrefix) {
bool ipv4_supported = true;
bool ipv6_supported = true;
OverrideAddressSortingSourceAddrFactory(
@@ -584,7 +598,7 @@ TEST(AddressSortingTest, TestPrefersLongestPrefixStressInnerBytePrefix) {
});
}
-TEST(AddressSortingTest, TestPrefersLongestPrefixDiffersOnHighestBitOfByte) {
+TEST_F(AddressSortingTest, TestPrefersLongestPrefixDiffersOnHighestBitOfByte) {
bool ipv4_supported = true;
bool ipv6_supported = true;
OverrideAddressSortingSourceAddrFactory(
@@ -604,7 +618,7 @@ TEST(AddressSortingTest, TestPrefersLongestPrefixDiffersOnHighestBitOfByte) {
});
}
-TEST(AddressSortingTest, TestPrefersLongestPrefixDiffersByLastBit) {
+TEST_F(AddressSortingTest, TestPrefersLongestPrefixDiffersByLastBit) {
bool ipv4_supported = true;
bool ipv6_supported = true;
OverrideAddressSortingSourceAddrFactory(
@@ -628,7 +642,7 @@ TEST(AddressSortingTest, TestPrefersLongestPrefixDiffersByLastBit) {
/* Tests for rule 10 */
-TEST(AddressSortingTest, TestStableSort) {
+TEST_F(AddressSortingTest, TestStableSort) {
bool ipv4_supported = true;
bool ipv6_supported = true;
OverrideAddressSortingSourceAddrFactory(
@@ -648,7 +662,7 @@ TEST(AddressSortingTest, TestStableSort) {
});
}
-TEST(AddressSortingTest, TestStableSortFiveElements) {
+TEST_F(AddressSortingTest, TestStableSortFiveElements) {
bool ipv4_supported = true;
bool ipv6_supported = true;
OverrideAddressSortingSourceAddrFactory(
@@ -677,7 +691,7 @@ TEST(AddressSortingTest, TestStableSortFiveElements) {
});
}
-TEST(AddressSortingTest, TestStableSortNoSrcAddrsExist) {
+TEST_F(AddressSortingTest, TestStableSortNoSrcAddrsExist) {
bool ipv4_supported = true;
bool ipv6_supported = true;
OverrideAddressSortingSourceAddrFactory(ipv4_supported, ipv6_supported, {});
@@ -698,7 +712,7 @@ TEST(AddressSortingTest, TestStableSortNoSrcAddrsExist) {
});
}
-TEST(AddressSortingTest, TestStableSortNoSrcAddrsExistWithIpv4) {
+TEST_F(AddressSortingTest, TestStableSortNoSrcAddrsExistWithIpv4) {
bool ipv4_supported = true;
bool ipv6_supported = true;
OverrideAddressSortingSourceAddrFactory(ipv4_supported, ipv6_supported, {});
@@ -713,7 +727,7 @@ TEST(AddressSortingTest, TestStableSortNoSrcAddrsExistWithIpv4) {
});
}
-TEST(AddressSortingTest, TestStableSortV4CompatAndSiteLocalAddresses) {
+TEST_F(AddressSortingTest, TestStableSortV4CompatAndSiteLocalAddresses) {
bool ipv4_supported = true;
bool ipv6_supported = true;
// Handle unique observed behavior of inet_ntop(v4-compatible-address) on OS X.
@@ -744,6 +758,78 @@ TEST(AddressSortingTest, TestStableSortV4CompatAndSiteLocalAddresses) {
});
}
+/* TestPrefersIpv6Loopback tests the actual "address probing" code
+ * for the current platform, without any mocks.
+ * This test relies on the assumption that the ipv6 loopback address is
+ * available in the hosts/containers that grpc C/C++ tests run on
+ * (whether ipv4 loopback is available or not, an available ipv6
+ * loopback should be preferred). */
+TEST_F(AddressSortingTest, TestPrefersIpv6Loopback) {
+ grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ {"[::1]:443", AF_INET6},
+ {"127.0.0.1:443", AF_INET},
+ });
+ grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs);
+ VerifyLbAddrOutputs(lb_addrs, {
+ "[::1]:443",
+ "127.0.0.1:443",
+ });
+}
+
+/* Flip the order of the inputs above and expect the same output order
+ * (try to rule out influence of arbitrary qsort ordering) */
+TEST_F(AddressSortingTest, TestPrefersIpv6LoopbackInputsFlipped) {
+ grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ {"127.0.0.1:443", AF_INET},
+ {"[::1]:443", AF_INET6},
+ });
+ grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs);
+ VerifyLbAddrOutputs(lb_addrs, {
+ "[::1]:443",
+ "127.0.0.1:443",
+ });
+}
+
+/* Try to rule out false positives in the above two tests in which
+ * the sorter might think that neither ipv6 or ipv4 loopback is
+ * available, but ipv6 loopback is still preferred only due
+ * to precedance table lookups. */
+TEST_F(AddressSortingTest, TestSorterKnowsIpv6LoopbackIsAvailable) {
+ sockaddr_in6 ipv6_loopback;
+ memset(&ipv6_loopback, 0, sizeof(ipv6_loopback));
+ ipv6_loopback.sin6_family = AF_INET6;
+ ((char*)&ipv6_loopback.sin6_addr)[15] = 1;
+ ipv6_loopback.sin6_port = htons(443);
+ // Set up the source and destination parameters of
+ // address_sorting_get_source_addr
+ address_sorting_address sort_input_dest;
+ memcpy(&sort_input_dest.addr, &ipv6_loopback, sizeof(ipv6_loopback));
+ sort_input_dest.len = sizeof(ipv6_loopback);
+ address_sorting_address source_for_sort_input_dest;
+ memset(&source_for_sort_input_dest, 0, sizeof(source_for_sort_input_dest));
+ // address_sorting_get_source_addr returns true if a source address was found
+ // for the destination address, otherwise false.
+ EXPECT_TRUE(address_sorting_get_source_addr_for_testing(
+ &sort_input_dest, &source_for_sort_input_dest));
+ // Now also check that the source address was filled in correctly.
+ EXPECT_GT(source_for_sort_input_dest.len, 0u);
+ sockaddr_in6* source_addr_output =
+ (sockaddr_in6*)source_for_sort_input_dest.addr;
+ EXPECT_EQ(source_addr_output->sin6_family, AF_INET6);
+ char* buf = static_cast<char*>(gpr_zalloc(100));
+ EXPECT_NE(inet_ntop(AF_INET6, &source_addr_output->sin6_addr, buf, 100),
+ nullptr)
+ << "inet_ntop failed. Errno: " + std::to_string(errno);
+ std::string source_addr_str(buf);
+ gpr_free(buf);
+ // This test
+ // assumes that the source address for any loopback destination is also the
+ // loopback address.
+ EXPECT_EQ(source_addr_str, "::1");
+}
+
+} // namespace
+
int main(int argc, char** argv) {
char* resolver = gpr_getenv("GRPC_DNS_RESOLVER");
if (resolver == nullptr || strlen(resolver) == 0) {
@@ -754,9 +840,7 @@ int main(int argc, char** argv) {
gpr_free(resolver);
grpc_test_init(argc, argv);
::testing::InitGoogleTest(&argc, argv);
- grpc_init();
auto result = RUN_ALL_TESTS();
- grpc_shutdown();
// Test sequential and nested inits and shutdowns.
grpc_init();
grpc_init();
diff --git a/test/cpp/naming/gen_build_yaml.py b/test/cpp/naming/gen_build_yaml.py
index baa6512f62..5dad2ea7af 100755
--- a/test/cpp/naming/gen_build_yaml.py
+++ b/test/cpp/naming/gen_build_yaml.py
@@ -110,7 +110,7 @@ def main():
'gtest': True,
'run': True,
'src': ['test/cpp/naming/address_sorting_test.cc'],
- 'platforms': ['linux', 'posix', 'mac'],
+ 'platforms': ['linux', 'posix', 'mac', 'windows'],
'deps': [
'grpc++_test_util' + unsecure_build_config_suffix,
'grpc_test_util' + unsecure_build_config_suffix,
diff --git a/test/cpp/qps/BUILD b/test/cpp/qps/BUILD
index e7d093c71a..b958c75fc7 100644
--- a/test/cpp/qps/BUILD
+++ b/test/cpp/qps/BUILD
@@ -34,11 +34,13 @@ grpc_cc_library(
"qps_worker.cc",
"server_async.cc",
"server_sync.cc",
+ "qps_server_builder.cc",
],
hdrs = [
"client.h",
"qps_worker.h",
"server.h",
+ "qps_server_builder.h",
],
deps = [
":histogram",
@@ -55,6 +57,10 @@ grpc_cc_library(
"//test/core/util:gpr_test_util",
"//test/core/util:grpc_test_util",
"//test/cpp/util:test_util",
+ "//test/cpp/util:test_config",
+ ],
+ external_deps = [
+ "gflags",
],
)
diff --git a/test/cpp/qps/benchmark_config.cc b/test/cpp/qps/benchmark_config.cc
index a4fd9de820..5fd0f00038 100644
--- a/test/cpp/qps/benchmark_config.cc
+++ b/test/cpp/qps/benchmark_config.cc
@@ -22,6 +22,8 @@
#include <grpcpp/create_channel.h>
#include <grpcpp/security/credentials.h>
+#include "test/cpp/util/test_credentials_provider.h"
+
DEFINE_bool(enable_log_reporter, true,
"Enable reporting of benchmark results through GprLog");
@@ -44,6 +46,10 @@ DEFINE_string(rpc_reporter_server_address, "",
DEFINE_bool(enable_rpc_reporter, false, "Enable use of RPC reporter");
+DEFINE_string(
+ rpc_reporter_credential_type, grpc::testing::kInsecureCredentialsType,
+ "Credential type for communication to the QPS benchmark report server");
+
// In some distros, gflags is in the namespace google, and in some others,
// in gflags. This hack is enabling us to find both.
namespace google {}
@@ -65,11 +71,14 @@ static std::shared_ptr<Reporter> InitBenchmarkReporters() {
new JsonReporter("JsonReporter", FLAGS_scenario_result_file)));
}
if (FLAGS_enable_rpc_reporter) {
+ ChannelArguments channel_args;
+ std::shared_ptr<ChannelCredentials> channel_creds =
+ testing::GetCredentialsProvider()->GetChannelCredentials(
+ FLAGS_rpc_reporter_credential_type, &channel_args);
GPR_ASSERT(!FLAGS_rpc_reporter_server_address.empty());
composite_reporter->add(std::unique_ptr<Reporter>(new RpcReporter(
- "RpcReporter",
- grpc::CreateChannel(FLAGS_rpc_reporter_server_address,
- grpc::InsecureChannelCredentials()))));
+ "RpcReporter", grpc::CreateChannel(FLAGS_rpc_reporter_server_address,
+ channel_creds))));
}
return std::shared_ptr<Reporter>(composite_reporter);
diff --git a/test/cpp/qps/client.h b/test/cpp/qps/client.h
index 9d58ea8882..9d7469c9b5 100644
--- a/test/cpp/qps/client.h
+++ b/test/cpp/qps/client.h
@@ -19,6 +19,8 @@
#ifndef TEST_QPS_CLIENT_H
#define TEST_QPS_CLIENT_H
+#include <stdlib.h>
+
#include <condition_variable>
#include <mutex>
#include <unordered_map>
@@ -34,6 +36,7 @@
#include "src/proto/grpc/testing/benchmark_service.grpc.pb.h"
#include "src/proto/grpc/testing/payloads.pb.h"
+#include "src/core/lib/gpr/env.h"
#include "src/cpp/util/core_stats.h"
#include "test/cpp/qps/histogram.h"
#include "test/cpp/qps/interarrival.h"
@@ -441,9 +444,24 @@ class ClientImpl : public Client {
std::unique_ptr<std::thread> WaitForReady() {
return std::unique_ptr<std::thread>(new std::thread([this]() {
if (!is_inproc_) {
- GPR_ASSERT(channel_->WaitForConnected(
- gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
- gpr_time_from_seconds(10, GPR_TIMESPAN))));
+ int connect_deadline = 10;
+ /* Allow optionally overriding connect_deadline in order
+ * to deal with benchmark environments in which the server
+ * can take a long time to become ready. */
+ char* channel_connect_timeout_str =
+ gpr_getenv("QPS_WORKER_CHANNEL_CONNECT_TIMEOUT");
+ if (channel_connect_timeout_str != nullptr &&
+ strcmp(channel_connect_timeout_str, "") != 0) {
+ connect_deadline = atoi(channel_connect_timeout_str);
+ }
+ gpr_log(GPR_INFO,
+ "Waiting for up to %d seconds for the channel %p to connect",
+ connect_deadline, channel_.get());
+ gpr_free(channel_connect_timeout_str);
+ GPR_ASSERT(channel_->WaitForConnected(gpr_time_add(
+ gpr_now(GPR_CLOCK_REALTIME),
+ gpr_time_from_seconds(connect_deadline, GPR_TIMESPAN))));
+ gpr_log(GPR_INFO, "Channel %p connected!", channel_.get());
}
}));
}
diff --git a/test/cpp/qps/qps_server_builder.cc b/test/cpp/qps/qps_server_builder.cc
new file mode 100644
index 0000000000..5fbc682b75
--- /dev/null
+++ b/test/cpp/qps/qps_server_builder.cc
@@ -0,0 +1,45 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#include "qps_server_builder.h"
+
+using grpc::ServerBuilder;
+
+namespace grpc {
+namespace testing {
+
+namespace {
+std::unique_ptr<ServerBuilder> DefaultCreateQpsServerBuilder() {
+ return std::unique_ptr<ServerBuilder>(new ServerBuilder());
+}
+
+std::function<std::unique_ptr<ServerBuilder>()> g_create_qps_server_builder =
+ DefaultCreateQpsServerBuilder;
+} // namespace
+
+std::unique_ptr<ServerBuilder> CreateQpsServerBuilder() {
+ return g_create_qps_server_builder();
+}
+
+void SetCreateQpsServerBuilderFunc(
+ std::function<std::unique_ptr<ServerBuilder>()> create_qps_server_builder) {
+ g_create_qps_server_builder = std::move(create_qps_server_builder);
+}
+
+} // namespace testing
+} // namespace grpc
diff --git a/test/cpp/qps/qps_server_builder.h b/test/cpp/qps/qps_server_builder.h
new file mode 100644
index 0000000000..98f9fa72e9
--- /dev/null
+++ b/test/cpp/qps/qps_server_builder.h
@@ -0,0 +1,46 @@
+/*
+ *
+ * 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.
+ *
+ */
+
+#ifndef GRPC_QPS_SERVER_BUILDER_H
+#define GRPC_QPS_SERVER_BUILDER_H
+
+#include <functional>
+#include <memory>
+
+#include <grpcpp/server_builder.h>
+
+namespace grpc {
+namespace testing {
+
+// CreateQpsServerBuilder creates a new ServerBuilder.
+// This uses the "create ServerBuilder" func that was set
+// in SetCreateQpsServerBuilderFunc if one has been set,
+// otherwise, this defaults to creating a new ServerBuilder
+// with only its default constructor.
+std::unique_ptr<ServerBuilder> CreateQpsServerBuilder();
+
+// SetCreateQpsServerBuilderFunc sets a function to use to create new
+// ServerBuilders in "CreateQpsServerBuilder". It can be used to modify options
+// that the server is built with.
+void SetCreateQpsServerBuilderFunc(
+ std::function<std::unique_ptr<ServerBuilder>()>);
+
+} // namespace testing
+} // namespace grpc
+
+#endif // GRPC_QPS_SERVER_BUILDER_H
diff --git a/test/cpp/qps/qps_worker.cc b/test/cpp/qps/qps_worker.cc
index d3f0380474..7ddf3c1cf3 100644
--- a/test/cpp/qps/qps_worker.cc
+++ b/test/cpp/qps/qps_worker.cc
@@ -39,6 +39,7 @@
#include "test/core/util/grpc_profiler.h"
#include "test/core/util/histogram.h"
#include "test/cpp/qps/client.h"
+#include "test/cpp/qps/qps_server_builder.h"
#include "test/cpp/qps/server.h"
#include "test/cpp/util/create_test_channel.h"
#include "test/cpp/util/test_credentials_provider.h"
@@ -272,18 +273,18 @@ QpsWorker::QpsWorker(int driver_port, int server_port,
impl_.reset(new WorkerServiceImpl(server_port, this));
gpr_atm_rel_store(&done_, static_cast<gpr_atm>(0));
- ServerBuilder builder;
+ std::unique_ptr<ServerBuilder> builder = CreateQpsServerBuilder();
if (driver_port >= 0) {
char* server_address = nullptr;
gpr_join_host_port(&server_address, "::", driver_port);
- builder.AddListeningPort(
+ builder->AddListeningPort(
server_address,
GetCredentialsProvider()->GetServerCredentials(credential_type));
gpr_free(server_address);
}
- builder.RegisterService(impl_.get());
+ builder->RegisterService(impl_.get());
- server_ = builder.BuildAndStart();
+ server_ = builder->BuildAndStart();
}
QpsWorker::~QpsWorker() {}
diff --git a/test/cpp/qps/server_async.cc b/test/cpp/qps/server_async.cc
index 1dfef6cfc1..5cd975cf74 100644
--- a/test/cpp/qps/server_async.cc
+++ b/test/cpp/qps/server_async.cc
@@ -38,6 +38,7 @@
#include "src/core/lib/surface/completion_queue.h"
#include "src/proto/grpc/testing/benchmark_service.grpc.pb.h"
#include "test/core/util/test_config.h"
+#include "test/cpp/qps/qps_server_builder.h"
#include "test/cpp/qps/server.h"
namespace grpc {
@@ -74,19 +75,19 @@ class AsyncQpsServerTest final : public grpc::testing::Server {
ResponseType*)>
process_rpc)
: Server(config) {
- ServerBuilder builder;
+ std::unique_ptr<ServerBuilder> builder = CreateQpsServerBuilder();
auto port_num = port();
// Negative port number means inproc server, so no listen port needed
if (port_num >= 0) {
char* server_address = nullptr;
gpr_join_host_port(&server_address, "::", port_num);
- builder.AddListeningPort(server_address,
- Server::CreateServerCredentials(config));
+ builder->AddListeningPort(server_address,
+ Server::CreateServerCredentials(config));
gpr_free(server_address);
}
- register_service(&builder, &async_service_);
+ register_service(builder.get(), &async_service_);
int num_threads = config.async_server_threads();
if (num_threads <= 0) { // dynamic sizing
@@ -97,15 +98,15 @@ class AsyncQpsServerTest final : public grpc::testing::Server {
int tpc = std::max(1, config.threads_per_cq()); // 1 if unspecified
int num_cqs = (num_threads + tpc - 1) / tpc; // ceiling operator
for (int i = 0; i < num_cqs; i++) {
- srv_cqs_.emplace_back(builder.AddCompletionQueue());
+ srv_cqs_.emplace_back(builder->AddCompletionQueue());
}
for (int i = 0; i < num_threads; i++) {
cq_.emplace_back(i % srv_cqs_.size());
}
- ApplyConfigToBuilder(config, &builder);
+ ApplyConfigToBuilder(config, builder.get());
- server_ = builder.BuildAndStart();
+ server_ = builder->BuildAndStart();
auto process_rpc_bound =
std::bind(process_rpc, config.payload_config(), std::placeholders::_1,
diff --git a/test/cpp/qps/server_sync.cc b/test/cpp/qps/server_sync.cc
index b8facf9b56..2e63f5ec86 100644
--- a/test/cpp/qps/server_sync.cc
+++ b/test/cpp/qps/server_sync.cc
@@ -27,6 +27,7 @@
#include "src/core/lib/gpr/host_port.h"
#include "src/proto/grpc/testing/benchmark_service.grpc.pb.h"
+#include "test/cpp/qps/qps_server_builder.h"
#include "test/cpp/qps/server.h"
#include "test/cpp/qps/usage_timer.h"
@@ -154,23 +155,23 @@ class BenchmarkServiceImpl final : public BenchmarkService::Service {
class SynchronousServer final : public grpc::testing::Server {
public:
explicit SynchronousServer(const ServerConfig& config) : Server(config) {
- ServerBuilder builder;
+ std::unique_ptr<ServerBuilder> builder = CreateQpsServerBuilder();
auto port_num = port();
// Negative port number means inproc server, so no listen port needed
if (port_num >= 0) {
char* server_address = nullptr;
gpr_join_host_port(&server_address, "::", port_num);
- builder.AddListeningPort(server_address,
- Server::CreateServerCredentials(config));
+ builder->AddListeningPort(server_address,
+ Server::CreateServerCredentials(config));
gpr_free(server_address);
}
- ApplyConfigToBuilder(config, &builder);
+ ApplyConfigToBuilder(config, builder.get());
- builder.RegisterService(&service_);
+ builder->RegisterService(&service_);
- impl_ = builder.BuildAndStart();
+ impl_ = builder->BuildAndStart();
}
std::shared_ptr<Channel> InProcessChannel(
diff --git a/test/cpp/server/load_reporter/load_reporter_test.cc b/test/cpp/server/load_reporter/load_reporter_test.cc
index 719c3a67d9..0d56cdf431 100644
--- a/test/cpp/server/load_reporter/load_reporter_test.cc
+++ b/test/cpp/server/load_reporter/load_reporter_test.cc
@@ -172,9 +172,9 @@ class LbFeedbackTest : public LoadReporterTest {
// TODO(juanlishen): The error is big because we use sleep(). It should be
// much smaller when we use fake clock.
ASSERT_THAT(static_cast<double>(lb_feedback.calls_per_second()),
- DoubleNear(expected_qps, expected_qps / 50));
+ DoubleNear(expected_qps, expected_qps * 0.05));
ASSERT_THAT(static_cast<double>(lb_feedback.errors_per_second()),
- DoubleNear(expected_eps, expected_eps / 50));
+ DoubleNear(expected_eps, expected_eps * 0.05));
gpr_log(GPR_INFO,
"Verified LB feedback matches the samples of index [%lu, %lu).",
start, start + count);
diff --git a/test/cpp/util/BUILD b/test/cpp/util/BUILD
index 9b42bb28b1..c3bfeb7615 100644
--- a/test/cpp/util/BUILD
+++ b/test/cpp/util/BUILD
@@ -177,6 +177,7 @@ grpc_cc_test(
"//:grpc++_reflection",
"//src/proto/grpc/testing:echo_messages_proto",
"//src/proto/grpc/testing:echo_proto",
+ "//test/core/end2end:ssl_test_data",
"//test/core/util:grpc_test_util",
],
)
diff --git a/test/cpp/util/channel_trace_proto_helper.cc b/test/cpp/util/channel_trace_proto_helper.cc
index ee310784c2..b4704bfe6a 100644
--- a/test/cpp/util/channel_trace_proto_helper.cc
+++ b/test/cpp/util/channel_trace_proto_helper.cc
@@ -64,13 +64,22 @@ void VaidateProtoJsonTranslation(char* json_c_str) {
} // namespace
-void ValidateChannelTraceProtoJsonTranslation(char* tracer_json_c_str) {
- VaidateProtoJsonTranslation<grpc::channelz::v1::ChannelTrace>(
- tracer_json_c_str);
+void ValidateChannelTraceProtoJsonTranslation(char* json_c_str) {
+ VaidateProtoJsonTranslation<grpc::channelz::v1::ChannelTrace>(json_c_str);
}
-void ValidateChannelProtoJsonTranslation(char* channel_json_c_str) {
- VaidateProtoJsonTranslation<grpc::channelz::v1::Channel>(channel_json_c_str);
+void ValidateChannelProtoJsonTranslation(char* json_c_str) {
+ VaidateProtoJsonTranslation<grpc::channelz::v1::Channel>(json_c_str);
+}
+
+void ValidateGetTopChannelsResponseProtoJsonTranslation(char* json_c_str) {
+ VaidateProtoJsonTranslation<grpc::channelz::v1::GetTopChannelsResponse>(
+ json_c_str);
+}
+
+void ValidateGetChannelResponseProtoJsonTranslation(char* json_c_str) {
+ VaidateProtoJsonTranslation<grpc::channelz::v1::GetChannelResponse>(
+ json_c_str);
}
} // namespace testing
diff --git a/test/cpp/util/channel_trace_proto_helper.h b/test/cpp/util/channel_trace_proto_helper.h
index d1a3603372..18e3d54b6b 100644
--- a/test/cpp/util/channel_trace_proto_helper.h
+++ b/test/cpp/util/channel_trace_proto_helper.h
@@ -22,8 +22,10 @@
namespace grpc {
namespace testing {
-void ValidateChannelTraceProtoJsonTranslation(char* tracer_json_c_str);
-void ValidateChannelProtoJsonTranslation(char* channel_json_c_str);
+void ValidateChannelTraceProtoJsonTranslation(char* json_c_str);
+void ValidateChannelProtoJsonTranslation(char* json_c_str);
+void ValidateGetTopChannelsResponseProtoJsonTranslation(char* json_c_str);
+void ValidateGetChannelResponseProtoJsonTranslation(char* json_c_str);
} // namespace testing
} // namespace grpc
diff --git a/test/cpp/util/cli_credentials.cc b/test/cpp/util/cli_credentials.cc
index aa4eafb756..d14dc18f16 100644
--- a/test/cpp/util/cli_credentials.cc
+++ b/test/cpp/util/cli_credentials.cc
@@ -25,6 +25,10 @@ DEFINE_bool(use_auth, false, "Whether to create default google credentials.");
DEFINE_string(
access_token, "",
"The access token that will be sent to the server to authenticate RPCs.");
+DEFINE_string(
+ ssl_target, "",
+ "If not empty, treat the server host name as this for ssl/tls certificate "
+ "validation.");
namespace grpc {
namespace testing {
@@ -58,7 +62,15 @@ const grpc::string CliCredentials::GetCredentialUsage() const {
" --use_auth ; Set whether to create default google"
" credentials\n"
" --access_token ; Set the access token in metadata,"
- " overrides --use_auth\n";
+ " overrides --use_auth\n"
+ " --ssl_target ; Set server host for tls validation\n";
+}
+
+const grpc::string CliCredentials::GetSslTargetNameOverride() const {
+ bool use_tls =
+ FLAGS_enable_ssl || (FLAGS_access_token.empty() && FLAGS_use_auth);
+ return use_tls ? FLAGS_ssl_target : "";
}
+
} // namespace testing
} // namespace grpc
diff --git a/test/cpp/util/cli_credentials.h b/test/cpp/util/cli_credentials.h
index b1358e77d8..8d662356de 100644
--- a/test/cpp/util/cli_credentials.h
+++ b/test/cpp/util/cli_credentials.h
@@ -30,6 +30,7 @@ class CliCredentials {
virtual ~CliCredentials() {}
virtual std::shared_ptr<grpc::ChannelCredentials> GetCredentials() const;
virtual const grpc::string GetCredentialUsage() const;
+ virtual const grpc::string GetSslTargetNameOverride() const;
};
} // namespace testing
diff --git a/test/cpp/util/grpc_tool.cc b/test/cpp/util/grpc_tool.cc
index 840ca07d2b..ccc60cca27 100644
--- a/test/cpp/util/grpc_tool.cc
+++ b/test/cpp/util/grpc_tool.cc
@@ -206,6 +206,15 @@ void ReadResponse(CliCall* call, const grpc::string& method_name,
}
}
+std::shared_ptr<grpc::Channel> CreateCliChannel(
+ const grpc::string& server_address, const CliCredentials& cred) {
+ grpc::ChannelArguments args;
+ if (!cred.GetSslTargetNameOverride().empty()) {
+ args.SetSslTargetNameOverride(cred.GetSslTargetNameOverride());
+ }
+ return grpc::CreateCustomChannel(server_address, cred.GetCredentials(), args);
+}
+
struct Command {
const char* command;
std::function<bool(GrpcTool*, int, const char**, const CliCredentials&,
@@ -324,7 +333,7 @@ bool GrpcTool::ListServices(int argc, const char** argv,
grpc::string server_address(argv[0]);
std::shared_ptr<grpc::Channel> channel =
- grpc::CreateChannel(server_address, cred.GetCredentials());
+ CreateCliChannel(server_address, cred);
grpc::ProtoReflectionDescriptorDatabase desc_db(channel);
grpc::protobuf::DescriptorPool desc_pool(&desc_db);
@@ -422,7 +431,7 @@ bool GrpcTool::PrintType(int argc, const char** argv,
grpc::string server_address(argv[0]);
std::shared_ptr<grpc::Channel> channel =
- grpc::CreateChannel(server_address, cred.GetCredentials());
+ CreateCliChannel(server_address, cred);
grpc::ProtoReflectionDescriptorDatabase desc_db(channel);
grpc::protobuf::DescriptorPool desc_pool(&desc_db);
@@ -469,7 +478,7 @@ bool GrpcTool::CallMethod(int argc, const char** argv,
bool print_mode = false;
std::shared_ptr<grpc::Channel> channel =
- grpc::CreateChannel(server_address, cred.GetCredentials());
+ CreateCliChannel(server_address, cred);
if (!FLAGS_binary_input || !FLAGS_binary_output) {
parser.reset(
@@ -820,7 +829,7 @@ bool GrpcTool::ParseMessage(int argc, const char** argv,
if (!FLAGS_binary_input || !FLAGS_binary_output) {
std::shared_ptr<grpc::Channel> channel =
- grpc::CreateChannel(server_address, cred.GetCredentials());
+ CreateCliChannel(server_address, cred);
parser.reset(
new grpc::testing::ProtoFileParser(FLAGS_remotedb ? channel : nullptr,
FLAGS_proto_path, FLAGS_protofiles));
diff --git a/test/cpp/util/grpc_tool_test.cc b/test/cpp/util/grpc_tool_test.cc
index 6574d1bb44..7e7f44551e 100644
--- a/test/cpp/util/grpc_tool_test.cc
+++ b/test/cpp/util/grpc_tool_test.cc
@@ -35,6 +35,7 @@
#include "src/core/lib/gpr/env.h"
#include "src/proto/grpc/testing/echo.grpc.pb.h"
#include "src/proto/grpc/testing/echo.pb.h"
+#include "test/core/end2end/data/ssl_test_data.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
#include "test/cpp/util/cli_credentials.h"
@@ -80,6 +81,9 @@ using grpc::testing::EchoResponse;
" peer: \"peer\"\n" \
"}\n\n"
+DECLARE_bool(enable_ssl);
+DECLARE_string(ssl_target);
+
namespace grpc {
namespace testing {
@@ -97,10 +101,18 @@ const int kServerDefaultResponseStreamsToSend = 3;
class TestCliCredentials final : public grpc::testing::CliCredentials {
public:
+ TestCliCredentials(bool secure = false) : secure_(secure) {}
std::shared_ptr<grpc::ChannelCredentials> GetCredentials() const override {
- return InsecureChannelCredentials();
+ if (!secure_) {
+ return InsecureChannelCredentials();
+ }
+ SslCredentialsOptions ssl_opts = {test_root_cert, "", ""};
+ return SslCredentials(grpc::SslCredentialsOptions(ssl_opts));
}
const grpc::string GetCredentialUsage() const override { return ""; }
+
+ private:
+ const bool secure_;
};
bool PrintStream(std::stringstream* ss, const grpc::string& output) {
@@ -206,13 +218,24 @@ class GrpcToolTest : public ::testing::Test {
// SetUpServer cannot be used with EXPECT_EXIT. grpc_pick_unused_port_or_die()
// uses atexit() to free chosen ports, and it will spawn a new thread in
// resolve_address_posix.c:192 at exit time.
- const grpc::string SetUpServer() {
+ const grpc::string SetUpServer(bool secure = false) {
std::ostringstream server_address;
int port = grpc_pick_unused_port_or_die();
server_address << "localhost:" << port;
// Setup server
ServerBuilder builder;
- builder.AddListeningPort(server_address.str(), InsecureServerCredentials());
+ std::shared_ptr<grpc::ServerCredentials> creds;
+ if (secure) {
+ SslServerCredentialsOptions::PemKeyCertPair pkcp = {test_server1_key,
+ test_server1_cert};
+ SslServerCredentialsOptions ssl_opts;
+ ssl_opts.pem_root_certs = "";
+ ssl_opts.pem_key_cert_pairs.push_back(pkcp);
+ creds = SslServerCredentials(ssl_opts);
+ } else {
+ creds = InsecureServerCredentials();
+ }
+ builder.AddListeningPort(server_address.str(), creds);
builder.RegisterService(&service_);
server_ = builder.BuildAndStart();
return server_address.str();
@@ -743,6 +766,29 @@ TEST_F(GrpcToolTest, CallCommandWithBadMetadata) {
gpr_free(test_srcdir);
}
+TEST_F(GrpcToolTest, ListCommand_OverrideSslHostName) {
+ const grpc::string server_address = SetUpServer(true);
+
+ // Test input "grpc_cli ls localhost:<port> --enable_ssl
+ // --ssl_target=z.test.google.fr"
+ std::stringstream output_stream;
+ const char* argv[] = {"grpc_cli", "ls", server_address.c_str()};
+ FLAGS_l = false;
+ FLAGS_enable_ssl = true;
+ FLAGS_ssl_target = "z.test.google.fr";
+ EXPECT_TRUE(
+ 0 == GrpcToolMainLib(
+ ArraySize(argv), argv, TestCliCredentials(true),
+ std::bind(PrintStream, &output_stream, std::placeholders::_1)));
+ EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(),
+ "grpc.testing.EchoTestService\n"
+ "grpc.reflection.v1alpha.ServerReflection\n"));
+
+ FLAGS_enable_ssl = false;
+ FLAGS_ssl_target = "";
+ ShutdownServer();
+}
+
} // namespace testing
} // namespace grpc
diff --git a/third_party/BUILD b/third_party/BUILD
index f06c5e9c67..5ec919dc48 100644
--- a/third_party/BUILD
+++ b/third_party/BUILD
@@ -8,4 +8,5 @@ exports_files([
"incremental.BUILD",
"zope_interface.BUILD",
"constantly.BUILD",
+ "cython.BUILD",
])
diff --git a/third_party/address_sorting/address_sorting.c b/third_party/address_sorting/address_sorting.c
index e4f3b53799..9aee0a5419 100644
--- a/third_party/address_sorting/address_sorting.c
+++ b/third_party/address_sorting/address_sorting.c
@@ -55,12 +55,17 @@ static const int kIPv6AddrScopeGlobal = 3;
static address_sorting_source_addr_factory* g_current_source_addr_factory =
NULL;
-static int address_sorting_get_source_addr(const address_sorting_address* dest,
- address_sorting_address* source) {
+static bool address_sorting_get_source_addr(const address_sorting_address* dest,
+ address_sorting_address* source) {
return g_current_source_addr_factory->vtable->get_source_addr(
g_current_source_addr_factory, dest, source);
}
+bool address_sorting_get_source_addr_for_testing(
+ const address_sorting_address* dest, address_sorting_address* source) {
+ return address_sorting_get_source_addr(dest, source);
+}
+
static int ipv6_prefix_match_length(const struct sockaddr_in6* sa,
const struct sockaddr_in6* sb) {
unsigned char* a = (unsigned char*)&sa->sin6_addr;
diff --git a/third_party/address_sorting/address_sorting_windows.c b/third_party/address_sorting/address_sorting_windows.c
index b2f5708649..662a88248e 100644
--- a/third_party/address_sorting/address_sorting_windows.c
+++ b/third_party/address_sorting/address_sorting_windows.c
@@ -42,14 +42,54 @@
#if defined(ADDRESS_SORTING_WINDOWS)
+#include <errno.h>
+#include <inttypes.h>
+#include <limits.h>
#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
-/* TODO : Add address sorting functionality to work on windows. */
+static bool windows_source_addr_factory_get_source_addr(
+ address_sorting_source_addr_factory* factory,
+ const address_sorting_address* dest_addr,
+ address_sorting_address* source_addr) {
+ bool source_addr_exists = false;
+ SOCKET s = socket(((struct sockaddr_in6*)dest_addr)->sin6_family, SOCK_DGRAM,
+ IPPROTO_UDP);
+ if (s != INVALID_SOCKET) {
+ if (connect(s, (struct sockaddr*)dest_addr, (int)dest_addr->len) == 0) {
+ address_sorting_address found_source_addr;
+ memset(&found_source_addr, 0, sizeof(found_source_addr));
+ found_source_addr.len = sizeof(found_source_addr.addr);
+ if (getsockname(s, (struct sockaddr*)&found_source_addr.addr,
+ (socklen_t*)&found_source_addr.len) == 0) {
+ source_addr_exists = true;
+ *source_addr = found_source_addr;
+ }
+ }
+ closesocket(s);
+ }
+ return source_addr_exists;
+}
+
+static void windows_source_addr_factory_destroy(
+ address_sorting_source_addr_factory* self) {
+ free(self);
+}
+
+static const address_sorting_source_addr_factory_vtable
+ windows_source_addr_factory_vtable = {
+ windows_source_addr_factory_get_source_addr,
+ windows_source_addr_factory_destroy,
+};
address_sorting_source_addr_factory*
address_sorting_create_source_addr_factory_for_current_platform() {
- abort();
- return NULL;
+ address_sorting_source_addr_factory* factory =
+ malloc(sizeof(address_sorting_source_addr_factory));
+ memset(factory, 0, sizeof(address_sorting_source_addr_factory));
+ factory->vtable = &windows_source_addr_factory_vtable;
+ return factory;
}
#endif // defined(ADDRESS_SORTING_WINDOWS)
diff --git a/third_party/address_sorting/include/address_sorting/address_sorting.h b/third_party/address_sorting/include/address_sorting/address_sorting.h
index f11cd424b5..c58fafe3f7 100644
--- a/third_party/address_sorting/include/address_sorting/address_sorting.h
+++ b/third_party/address_sorting/include/address_sorting/address_sorting.h
@@ -103,6 +103,9 @@ address_sorting_family address_sorting_abstract_get_family(
void address_sorting_override_source_addr_factory_for_testing(
address_sorting_source_addr_factory* factory);
+bool address_sorting_get_source_addr_for_testing(
+ const address_sorting_address* dest, address_sorting_address* source);
+
#ifdef __cplusplus
}
#endif
diff --git a/third_party/cython.BUILD b/third_party/cython.BUILD
new file mode 100644
index 0000000000..ce9283e2a4
--- /dev/null
+++ b/third_party/cython.BUILD
@@ -0,0 +1,29 @@
+# Adapted with modifications from tensorflow/third_party/cython.BUILD
+
+py_library(
+ name="cython_lib",
+ srcs=glob(
+ ["Cython/**/*.py"],
+ exclude=[
+ "**/Tests/*.py",
+ ],
+ ) + ["cython.py"],
+ data=glob([
+ "Cython/**/*.pyx",
+ "Cython/Utility/*.*",
+ "Cython/Includes/**/*.pxd",
+ ]),
+ srcs_version="PY2AND3",
+ visibility=["//visibility:public"],
+)
+
+# May not be named "cython", since that conflicts with Cython/ on OSX
+py_binary(
+ name="cython_binary",
+ srcs=["cython.py"],
+ main="cython.py",
+ srcs_version="PY2AND3",
+ visibility=["//visibility:public"],
+ deps=["cython_lib"],
+)
+
diff --git a/third_party/py/BUILD b/third_party/py/BUILD
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/third_party/py/BUILD
diff --git a/third_party/py/BUILD.tpl b/third_party/py/BUILD.tpl
new file mode 100644
index 0000000000..2283c573bc
--- /dev/null
+++ b/third_party/py/BUILD.tpl
@@ -0,0 +1,36 @@
+# Adapted with modifications from tensorflow/third_party/py/
+
+package(default_visibility=["//visibility:public"])
+
+# To build Python C/C++ extension on Windows, we need to link to python import library pythonXY.lib
+# See https://docs.python.org/3/extending/windows.html
+cc_import(
+ name="python_lib",
+ interface_library=select({
+ ":windows": ":python_import_lib",
+ # A placeholder for Unix platforms which makes --no_build happy.
+ "//conditions:default": "not-existing.lib",
+ }),
+ system_provided=1,
+)
+
+cc_library(
+ name="python_headers",
+ hdrs=[":python_include"],
+ deps=select({
+ ":windows": [":python_lib"],
+ "//conditions:default": [],
+ }),
+ includes=["python_include"],
+)
+
+config_setting(
+ name="windows",
+ values={"cpu": "x64_windows"},
+ visibility=["//visibility:public"],
+)
+
+%{PYTHON_INCLUDE_GENRULE}
+%{PYTHON_IMPORT_LIB_GENRULE}
+
+
diff --git a/third_party/py/python_configure.bzl b/third_party/py/python_configure.bzl
new file mode 100644
index 0000000000..2ba1e07049
--- /dev/null
+++ b/third_party/py/python_configure.bzl
@@ -0,0 +1,305 @@
+# Adapted with modifications from tensorflow/third_party/py/
+"""Repository rule for Python autoconfiguration.
+
+`python_configure` depends on the following environment variables:
+
+ * `PYTHON_BIN_PATH`: location of python binary.
+ * `PYTHON_LIB_PATH`: Location of python libraries.
+"""
+
+_BAZEL_SH = "BAZEL_SH"
+_PYTHON_BIN_PATH = "PYTHON_BIN_PATH"
+_PYTHON_LIB_PATH = "PYTHON_LIB_PATH"
+_PYTHON_CONFIG_REPO = "PYTHON_CONFIG_REPO"
+
+
+def _tpl(repository_ctx, tpl, substitutions={}, out=None):
+ if not out:
+ out = tpl
+ repository_ctx.template(out, Label("//third_party/py:%s.tpl" % tpl),
+ substitutions)
+
+
+def _fail(msg):
+ """Output failure message when auto configuration fails."""
+ red = "\033[0;31m"
+ no_color = "\033[0m"
+ fail("%sPython Configuration Error:%s %s\n" % (red, no_color, msg))
+
+
+def _is_windows(repository_ctx):
+ """Returns true if the host operating system is windows."""
+ os_name = repository_ctx.os.name.lower()
+ return os_name.find("windows") != -1
+
+
+def _execute(repository_ctx,
+ cmdline,
+ error_msg=None,
+ error_details=None,
+ empty_stdout_fine=False):
+ """Executes an arbitrary shell command.
+
+ Args:
+ repository_ctx: the repository_ctx object
+ cmdline: list of strings, the command to execute
+ error_msg: string, a summary of the error if the command fails
+ error_details: string, details about the error or steps to fix it
+ empty_stdout_fine: bool, if True, an empty stdout result is fine, otherwise
+ it's an error
+ Return:
+ the result of repository_ctx.execute(cmdline)
+ """
+ result = repository_ctx.execute(cmdline)
+ if result.stderr or not (empty_stdout_fine or result.stdout):
+ _fail("\n".join([
+ error_msg.strip() if error_msg else "Repository command failed",
+ result.stderr.strip(), error_details if error_details else ""
+ ]))
+ else:
+ return result
+
+
+def _read_dir(repository_ctx, src_dir):
+ """Returns a string with all files in a directory.
+
+ Finds all files inside a directory, traversing subfolders and following
+ symlinks. The returned string contains the full path of all files
+ separated by line breaks.
+ """
+ if _is_windows(repository_ctx):
+ src_dir = src_dir.replace("/", "\\")
+ find_result = _execute(
+ repository_ctx,
+ ["cmd.exe", "/c", "dir", src_dir, "/b", "/s", "/a-d"],
+ empty_stdout_fine=True)
+ # src_files will be used in genrule.outs where the paths must
+ # use forward slashes.
+ return find_result.stdout.replace("\\", "/")
+ else:
+ find_result = _execute(
+ repository_ctx, ["find", src_dir, "-follow", "-type", "f"],
+ empty_stdout_fine=True)
+ return find_result.stdout
+
+
+def _genrule(src_dir, genrule_name, command, outs):
+ """Returns a string with a genrule.
+
+ Genrule executes the given command and produces the given outputs.
+ """
+ return ('genrule(\n' + ' name = "' + genrule_name + '",\n' +
+ ' outs = [\n' + outs + '\n ],\n' + ' cmd = """\n' +
+ command + '\n """,\n' + ')\n')
+
+
+def _normalize_path(path):
+ """Returns a path with '/' and remove the trailing slash."""
+ path = path.replace("\\", "/")
+ if path[-1] == "/":
+ path = path[:-1]
+ return path
+
+
+def _symlink_genrule_for_dir(repository_ctx,
+ src_dir,
+ dest_dir,
+ genrule_name,
+ src_files=[],
+ dest_files=[]):
+ """Returns a genrule to symlink(or copy if on Windows) a set of files.
+
+ If src_dir is passed, files will be read from the given directory; otherwise
+ we assume files are in src_files and dest_files
+ """
+ if src_dir != None:
+ src_dir = _normalize_path(src_dir)
+ dest_dir = _normalize_path(dest_dir)
+ files = '\n'.join(
+ sorted(_read_dir(repository_ctx, src_dir).splitlines()))
+ # Create a list with the src_dir stripped to use for outputs.
+ dest_files = files.replace(src_dir, '').splitlines()
+ src_files = files.splitlines()
+ command = []
+ outs = []
+ for i in range(len(dest_files)):
+ if dest_files[i] != "":
+ # If we have only one file to link we do not want to use the dest_dir, as
+ # $(@D) will include the full path to the file.
+ dest = '$(@D)/' + dest_dir + dest_files[i] if len(
+ dest_files) != 1 else '$(@D)/' + dest_files[i]
+ # On Windows, symlink is not supported, so we just copy all the files.
+ cmd = 'cp -f' if _is_windows(repository_ctx) else 'ln -s'
+ command.append(cmd + ' "%s" "%s"' % (src_files[i], dest))
+ outs.append(' "' + dest_dir + dest_files[i] + '",')
+ return _genrule(src_dir, genrule_name, " && ".join(command),
+ "\n".join(outs))
+
+
+def _get_python_bin(repository_ctx):
+ """Gets the python bin path."""
+ python_bin = repository_ctx.os.environ.get(_PYTHON_BIN_PATH)
+ if python_bin != None:
+ return python_bin
+ python_bin_path = repository_ctx.which("python")
+ if python_bin_path != None:
+ return str(python_bin_path)
+ _fail("Cannot find python in PATH, please make sure " +
+ "python is installed and add its directory in PATH, or --define " +
+ "%s='/something/else'.\nPATH=%s" %
+ (_PYTHON_BIN_PATH, repository_ctx.os.environ.get("PATH", "")))
+
+
+def _get_bash_bin(repository_ctx):
+ """Gets the bash bin path."""
+ bash_bin = repository_ctx.os.environ.get(_BAZEL_SH)
+ if bash_bin != None:
+ return bash_bin
+ else:
+ bash_bin_path = repository_ctx.which("bash")
+ if bash_bin_path != None:
+ return str(bash_bin_path)
+ else:
+ _fail(
+ "Cannot find bash in PATH, please make sure " +
+ "bash is installed and add its directory in PATH, or --define "
+ + "%s='/path/to/bash'.\nPATH=%s" %
+ (_BAZEL_SH, repository_ctx.os.environ.get("PATH", "")))
+
+
+def _get_python_lib(repository_ctx, python_bin):
+ """Gets the python lib path."""
+ python_lib = repository_ctx.os.environ.get(_PYTHON_LIB_PATH)
+ if python_lib != None:
+ return python_lib
+ print_lib = (
+ "<<END\n" + "from __future__ import print_function\n" +
+ "import site\n" + "import os\n" + "\n" + "try:\n" +
+ " input = raw_input\n" + "except NameError:\n" + " pass\n" + "\n" +
+ "python_paths = []\n" + "if os.getenv('PYTHONPATH') is not None:\n" +
+ " python_paths = os.getenv('PYTHONPATH').split(':')\n" + "try:\n" +
+ " library_paths = site.getsitepackages()\n" +
+ "except AttributeError:\n" +
+ " from distutils.sysconfig import get_python_lib\n" +
+ " library_paths = [get_python_lib()]\n" +
+ "all_paths = set(python_paths + library_paths)\n" + "paths = []\n" +
+ "for path in all_paths:\n" + " if os.path.isdir(path):\n" +
+ " paths.append(path)\n" + "if len(paths) >=1:\n" +
+ " print(paths[0])\n" + "END")
+ cmd = '%s - %s' % (python_bin, print_lib)
+ result = repository_ctx.execute([_get_bash_bin(repository_ctx), "-c", cmd])
+ return result.stdout.strip('\n')
+
+
+def _check_python_lib(repository_ctx, python_lib):
+ """Checks the python lib path."""
+ cmd = 'test -d "%s" -a -x "%s"' % (python_lib, python_lib)
+ result = repository_ctx.execute([_get_bash_bin(repository_ctx), "-c", cmd])
+ if result.return_code == 1:
+ _fail("Invalid python library path: %s" % python_lib)
+
+
+def _check_python_bin(repository_ctx, python_bin):
+ """Checks the python bin path."""
+ cmd = '[[ -x "%s" ]] && [[ ! -d "%s" ]]' % (python_bin, python_bin)
+ result = repository_ctx.execute([_get_bash_bin(repository_ctx), "-c", cmd])
+ if result.return_code == 1:
+ _fail("--define %s='%s' is not executable. Is it the python binary?" %
+ (_PYTHON_BIN_PATH, python_bin))
+
+
+def _get_python_include(repository_ctx, python_bin):
+ """Gets the python include path."""
+ result = _execute(
+ repository_ctx, [
+ python_bin, "-c", 'from __future__ import print_function;' +
+ 'from distutils import sysconfig;' +
+ 'print(sysconfig.get_python_inc())'
+ ],
+ error_msg="Problem getting python include path.",
+ error_details=(
+ "Is the Python binary path set up right? " + "(See ./configure or "
+ + _PYTHON_BIN_PATH + ".) " + "Is distutils installed?"))
+ return result.stdout.splitlines()[0]
+
+
+def _get_python_import_lib_name(repository_ctx, python_bin):
+ """Get Python import library name (pythonXY.lib) on Windows."""
+ result = _execute(
+ repository_ctx, [
+ python_bin, "-c",
+ 'import sys;' + 'print("python" + str(sys.version_info[0]) + ' +
+ ' str(sys.version_info[1]) + ".lib")'
+ ],
+ error_msg="Problem getting python import library.",
+ error_details=("Is the Python binary path set up right? " +
+ "(See ./configure or " + _PYTHON_BIN_PATH + ".) "))
+ return result.stdout.splitlines()[0]
+
+
+def _create_local_python_repository(repository_ctx):
+ """Creates the repository containing files set up to build with Python."""
+ python_bin = _get_python_bin(repository_ctx)
+ _check_python_bin(repository_ctx, python_bin)
+ python_lib = _get_python_lib(repository_ctx, python_bin)
+ _check_python_lib(repository_ctx, python_lib)
+ python_include = _get_python_include(repository_ctx, python_bin)
+ python_include_rule = _symlink_genrule_for_dir(
+ repository_ctx, python_include, 'python_include', 'python_include')
+ python_import_lib_genrule = ""
+ # To build Python C/C++ extension on Windows, we need to link to python import library pythonXY.lib
+ # See https://docs.python.org/3/extending/windows.html
+ if _is_windows(repository_ctx):
+ python_include = _normalize_path(python_include)
+ python_import_lib_name = _get_python_import_lib_name(
+ repository_ctx, python_bin)
+ python_import_lib_src = python_include.rsplit(
+ '/', 1)[0] + "/libs/" + python_import_lib_name
+ python_import_lib_genrule = _symlink_genrule_for_dir(
+ repository_ctx, None, '', 'python_import_lib',
+ [python_import_lib_src], [python_import_lib_name])
+ _tpl(
+ repository_ctx, "BUILD", {
+ "%{PYTHON_INCLUDE_GENRULE}": python_include_rule,
+ "%{PYTHON_IMPORT_LIB_GENRULE}": python_import_lib_genrule,
+ })
+
+
+def _create_remote_python_repository(repository_ctx, remote_config_repo):
+ """Creates pointers to a remotely configured repo set up to build with Python.
+ """
+ _tpl(repository_ctx, "remote.BUILD", {
+ "%{REMOTE_PYTHON_REPO}": remote_config_repo,
+ }, "BUILD")
+
+
+def _python_autoconf_impl(repository_ctx):
+ """Implementation of the python_autoconf repository rule."""
+ if _PYTHON_CONFIG_REPO in repository_ctx.os.environ:
+ _create_remote_python_repository(
+ repository_ctx, repository_ctx.os.environ[_PYTHON_CONFIG_REPO])
+ else:
+ _create_local_python_repository(repository_ctx)
+
+
+python_configure = repository_rule(
+ implementation=_python_autoconf_impl,
+ environ=[
+ _BAZEL_SH,
+ _PYTHON_BIN_PATH,
+ _PYTHON_LIB_PATH,
+ _PYTHON_CONFIG_REPO,
+ ],
+)
+"""Detects and configures the local Python.
+
+Add the following to your WORKSPACE FILE:
+
+```python
+python_configure(name = "local_config_python")
+```
+
+Args:
+ name: A unique name for this workspace rule.
+"""
+
diff --git a/third_party/py/remote.BUILD.tpl b/third_party/py/remote.BUILD.tpl
new file mode 100644
index 0000000000..1bfe1f0bf6
--- /dev/null
+++ b/third_party/py/remote.BUILD.tpl
@@ -0,0 +1,10 @@
+# Adapted with modifications from tensorflow/third_party/py/
+
+package(default_visibility=["//visibility:public"])
+
+alias(
+ name="python_headers",
+ actual="%{REMOTE_PYTHON_REPO}:python_headers",
+)
+
+
diff --git a/third_party/toolchains/BUILD b/third_party/toolchains/BUILD
index 29fc4fdaf3..02cd87a7b9 100644
--- a/third_party/toolchains/BUILD
+++ b/third_party/toolchains/BUILD
@@ -42,7 +42,7 @@ platform(
}
properties: {
name: "gceMachineType" # Small machines for majority of tests.
- value: "n1-standard-1"
+ value: "n1-highmem-2"
}
properties: {
name: "gceMachineType_LARGE" # Large machines for a small set of resource-consuming tests such as combiner_tests under TSAN.
diff --git a/tools/distrib/check_copyright.py b/tools/distrib/check_copyright.py
index e6388251cf..77f602ad1f 100755
--- a/tools/distrib/check_copyright.py
+++ b/tools/distrib/check_copyright.py
@@ -100,6 +100,10 @@ _EXEMPT = frozenset((
# Gradle wrappers used to build for Android
'examples/android/helloworld/gradlew.bat',
'src/android/test/interop/gradlew.bat',
+
+ # Designer-generated source
+ 'examples/csharp/HelloworldXamarin/Droid/Resources/Resource.designer.cs',
+ 'examples/csharp/HelloworldXamarin/iOS/ViewController.designer.cs',
))
RE_YEAR = r'Copyright (?P<first_year>[0-9]+\-)?(?P<last_year>[0-9]+) ([Tt]he )?gRPC [Aa]uthors(\.|)'
diff --git a/tools/distrib/python/grpcio_tools/grpc_version.py b/tools/distrib/python/grpcio_tools/grpc_version.py
index f1f6526527..ccb69a8ebc 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.14.0'
+VERSION = '1.15.0.dev0'
diff --git a/tools/dockerfile/grpc_artifact_android_ndk/Dockerfile b/tools/dockerfile/grpc_artifact_android_ndk/Dockerfile
index 77b6acfb16..be96f131f9 100644
--- a/tools/dockerfile/grpc_artifact_android_ndk/Dockerfile
+++ b/tools/dockerfile/grpc_artifact_android_ndk/Dockerfile
@@ -12,9 +12,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-# Docker file for building gRPC artifacts.
+# Docker file for building gRPC artifacts for Android.
-# Recent enough cmake (>=3.9) needed by Android SDK
FROM debian:sid
RUN apt-get update && apt-get install -y debian-keyring && apt-key update
@@ -47,20 +46,26 @@ RUN apt-get update && apt-key update && apt-get install -y \
wget \
zip && apt-get clean
-# Cmake for cross-compilation
-RUN apt-get update && apt-get install -y cmake golang && apt-get clean
+# golang needed to build BoringSSL with cmake
+RUN apt-get update && apt-get install -y golang && apt-get clean
-##################
-# Android NDK
+# Java required by Android SDK
+RUN apt-get update && apt-get -y install openjdk-8-jdk && apt-get clean
-# Download and install Android NDK
-RUN wget -q https://dl.google.com/android/repository/android-ndk-r16b-linux-x86_64.zip -O android_ndk.zip \
- && unzip -q android_ndk.zip \
- && rm android_ndk.zip \
- && mv ./android-ndk-r16b /opt
-ENV ANDROID_NDK_PATH /opt/android-ndk-r16b
+# Install Android SDK
+ENV ANDROID_SDK_VERSION 4333796
+RUN mkdir -p /opt/android-sdk && cd /opt/android-sdk && \
+ wget -q https://dl.google.com/android/repository/sdk-tools-linux-${ANDROID_SDK_VERSION}.zip && \
+ unzip -q sdk-tools-linux-${ANDROID_SDK_VERSION}.zip && \
+ rm sdk-tools-linux-${ANDROID_SDK_VERSION}.zip
+ENV ANDROID_SDK_PATH /opt/android-sdk
-RUN apt-get update && apt-get install -y libpthread-stubs0-dev && apt-get clean
+# Install Android NDK and cmake using sdkmanager
+RUN mkdir -p ~/.android && touch ~/.android/repositories.cfg
+RUN yes | ${ANDROID_SDK_PATH}/tools/bin/sdkmanager --licenses # accept all licenses
+RUN ${ANDROID_SDK_PATH}/tools/bin/sdkmanager ndk-bundle 'cmake;3.6.4111459'
+ENV ANDROID_NDK_PATH ${ANDROID_SDK_PATH}/ndk-bundle
+ENV ANDROID_SDK_CMAKE ${ANDROID_SDK_PATH}/cmake/3.6.4111459/bin/cmake
RUN mkdir /var/local/jenkins
diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++
index 0a051e892a..2f06bda016 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.14.0
+PROJECT_NUMBER = 1.15.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
diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal
index 8547dbd4c2..a46ebe6197 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.14.0
+PROJECT_NUMBER = 1.15.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
diff --git a/tools/doxygen/Doxyfile.core b/tools/doxygen/Doxyfile.core
index cfe3455a75..4899eee3ea 100644
--- a/tools/doxygen/Doxyfile.core
+++ b/tools/doxygen/Doxyfile.core
@@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC Core"
# could be handy for archiving the generated documentation or if some version
# control system is used.
-PROJECT_NUMBER = 6.0.0
+PROJECT_NUMBER = 6.0.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
diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal
index 453adf14d3..18f56984fe 100644
--- a/tools/doxygen/Doxyfile.core.internal
+++ b/tools/doxygen/Doxyfile.core.internal
@@ -40,7 +40,7 @@ PROJECT_NAME = "GRPC Core"
# could be handy for archiving the generated documentation or if some version
# control system is used.
-PROJECT_NUMBER = 6.0.0
+PROJECT_NUMBER = 6.0.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
@@ -924,9 +924,12 @@ src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc \
+src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h \
src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc \
+src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc \
+src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc \
src/core/ext/filters/client_channel/resolver/dns/native/README.md \
src/core/ext/filters/client_channel/resolver/dns/native/dns_resolver.cc \
src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc \
diff --git a/tools/internal_ci/helper_scripts/prepare_build_macos_rc b/tools/internal_ci/helper_scripts/prepare_build_macos_rc
index 7cdb2e0cf7..3212e80854 100644
--- a/tools/internal_ci/helper_scripts/prepare_build_macos_rc
+++ b/tools/internal_ci/helper_scripts/prepare_build_macos_rc
@@ -39,11 +39,17 @@ pip install google-api-python-client==1.6.7 --user python
export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/GrpcTesting-d0eeee2db331.json
# If this is a PR using RUN_TESTS_FLAGS var, then add flags to filter tests
-if [ -n "$KOKORO_GITHUB_PULL_REQUEST_NUMBER" ] && [ -n "$RUN_TESTS_FLAGS" ]; then
+if [ -n "$KOKORO_GITHUB_PULL_REQUEST_NUMBER" ]; then
+ set +x
brew update
brew install jq
ghprbTargetBranch=$(curl -s https://api.github.com/repos/grpc/grpc/pulls/$KOKORO_GITHUB_PULL_REQUEST_NUMBER | jq -r .base.ref)
export RUN_TESTS_FLAGS="$RUN_TESTS_FLAGS --filter_pr_tests --base_branch origin/$ghprbTargetBranch"
+
+ # TODO(matt-kwong): rename this to GITHUB_OAUTH_TOKEN after Jenkins deprecation
+ export JENKINS_OAUTH_TOKEN=$(cat ${KOKORO_GFILE_DIR}/oauth_token.txt)
+ export ghprbPullId=$KOKORO_GITHUB_PULL_REQUEST_NUMBER
+ set -x
fi
set +ex # rvm script is very verbose and exits with errorcode
@@ -83,3 +89,10 @@ export DOTNET_CLI_TELEMETRY_OPTOUT=true
date
git submodule update --init
+
+# Store intermediate build files of ObjC tests into /tmpfs
+mkdir /tmpfs/Build-ios-binary-size
+ln -s /tmpfs/Build-ios-binary-size src/objective-c/examples/Sample/Build
+mkdir /tmpfs/DerivedData
+rm -rf ~/Library/Developer/Xcode/DerivedData
+ln -s /tmpfs/DerivedData ~/Library/Developer/Xcode/DerivedData
diff --git a/tools/internal_ci/linux/grpc_publish_packages.cfg b/tools/internal_ci/linux/grpc_publish_packages.cfg
new file mode 100644
index 0000000000..82d571d642
--- /dev/null
+++ b/tools/internal_ci/linux/grpc_publish_packages.cfg
@@ -0,0 +1,26 @@
+# 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.
+
+# Config file for the internal CI (in protobuf text format)
+
+# Location of the continuous shell script in repository.
+build_file: "grpc/tools/internal_ci/linux/grpc_publish_packages.sh"
+timeout_mins: 120
+action {
+ define_artifacts {
+ regex: "**/*sponge_log.xml"
+ regex: "github/grpc/reports/**"
+ regex: "github/grpc/artifacts/**"
+ }
+}
diff --git a/tools/internal_ci/linux/grpc_publish_packages.sh b/tools/internal_ci/linux/grpc_publish_packages.sh
new file mode 100755
index 0000000000..14492301cc
--- /dev/null
+++ b/tools/internal_ci/linux/grpc_publish_packages.sh
@@ -0,0 +1,235 @@
+#!/bin/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.
+# 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.
+
+set -ex
+
+shopt -s nullglob
+
+cd "$(dirname "$0")/../../.."
+
+GRPC_VERSION=$(grep -e "^ *version: " build.yaml | head -n 1 | sed 's/.*: //')
+
+INPUT_ARTIFACTS=$KOKORO_GFILE_DIR/github/grpc/artifacts
+INDEX_FILENAME=index.xml
+
+BUILD_ID=${KOKORO_BUILD_ID:-$(uuidgen)}
+BUILD_BRANCH_NAME=master
+BUILD_GIT_COMMIT=${KOKORO_GIT_COMMIT:-unknown}
+BUILD_TIMESTAMP=$(date -Iseconds)
+BUILD_RELPATH=$(date "+%Y/%m")/$BUILD_GIT_COMMIT-$BUILD_ID/
+
+GCS_ROOT=gs://packages.grpc.io/
+GCS_ARCHIVE_PREFIX=archive/
+GCS_ARCHIVE_ROOT=$GCS_ROOT$GCS_ARCHIVE_PREFIX
+GCS_INDEX=$GCS_ROOT$INDEX_FILENAME
+
+LOCAL_STAGING_TEMPDIR=$(mktemp -d)
+LOCAL_BUILD_ROOT=$LOCAL_STAGING_TEMPDIR/$BUILD_RELPATH
+LOCAL_BUILD_INDEX=$LOCAL_BUILD_ROOT$INDEX_FILENAME
+
+mkdir -p "$LOCAL_BUILD_ROOT"
+
+find "$INPUT_ARTIFACTS" -type f
+
+# protoc Plugins
+PROTOC_PLUGINS_ZIPPED_PACKAGES=$(mktemp -d)
+for zip_dir in protoc_windows_{x86,x64}
+do
+ zip -jr "$PROTOC_PLUGINS_ZIPPED_PACKAGES/grpc-$zip_dir-$GRPC_VERSION.zip" "$INPUT_ARTIFACTS/$zip_dir/"*
+done
+for tar_dir in protoc_{linux,macos}_{x86,x64}
+do
+ chmod +x "$INPUT_ARTIFACTS/$tar_dir"/*
+ tar -cvzf "$PROTOC_PLUGINS_ZIPPED_PACKAGES/grpc-$tar_dir-$GRPC_VERSION.tar.gz" -C "$INPUT_ARTIFACTS/$tar_dir" .
+done
+
+PROTOC_PACKAGES=(
+ "$PROTOC_PLUGINS_ZIPPED_PACKAGES"/grpc-protoc_windows_{x86,x64}-"$GRPC_VERSION.zip"
+ "$PROTOC_PLUGINS_ZIPPED_PACKAGES"/grpc-protoc_{linux,macos}_{x86,x64}-"$GRPC_VERSION.tar.gz"
+)
+
+# C#
+UNZIPPED_CSHARP_PACKAGES=$(mktemp -d)
+unzip "$INPUT_ARTIFACTS/csharp_nugets_windows_dotnetcli.zip" -d "$UNZIPPED_CSHARP_PACKAGES"
+CSHARP_PACKAGES=(
+ "$UNZIPPED_CSHARP_PACKAGES"/*
+ "$INPUT_ARTIFACTS"/grpc_unity_package.[0-9]*.zip
+)
+
+# Python
+PYTHON_GRPCIO_PACKAGES=(
+ "$INPUT_ARTIFACTS"/grpcio-[0-9]*.tar.gz
+ "$INPUT_ARTIFACTS"/grpcio-[0-9]*.whl
+ "$INPUT_ARTIFACTS"/python_linux_extra_arm*/grpcio-[0-9]*.whl
+)
+PYTHON_GRPCIO_TOOLS_PACKAGES=(
+ "$INPUT_ARTIFACTS"/grpcio-tools-[0-9]*.tar.gz
+ "$INPUT_ARTIFACTS"/grpcio_tools-[0-9]*.whl
+ "$INPUT_ARTIFACTS"/python_linux_extra_arm*/grpcio_tools-[0-9]*.whl
+)
+PYTHON_GRPCIO_HEALTH_CHECKING_PACKAGES=(
+ "$INPUT_ARTIFACTS"/grpcio-health-checking-[0-9]*.tar.gz
+)
+PYTHON_GRPCIO_REFLECTION_PACKAGES=(
+ "$INPUT_ARTIFACTS"/grpcio-reflection-[0-9]*.tar.gz
+)
+PYTHON_GRPCIO_TESTING_PACKAGES=(
+ "$INPUT_ARTIFACTS"/grpcio-testing-[0-9]*.tar.gz
+)
+
+# PHP
+PHP_PACKAGES=(
+ "$INPUT_ARTIFACTS"/grpc-[0-9]*.tgz
+)
+
+# Ruby
+RUBY_PACKAGES=(
+ "$INPUT_ARTIFACTS"/grpc-[0-9]*.gem
+ "$INPUT_ARTIFACTS"/grpc-tools-[0-9]*.gem
+)
+
+function add_to_manifest() {
+ local artifact_type=$1
+ local artifact_file=$2
+ local artifact_prefix=$3
+ local artifact_name
+ artifact_name=$(basename "$artifact_file")
+ local artifact_size
+ artifact_size=$(stat -c%s "$artifact_file")
+ local artifact_sha256
+ artifact_sha256=$(openssl sha256 -r "$artifact_file" | cut -d " " -f 1)
+ local artifact_target=$LOCAL_BUILD_ROOT/$artifact_type/$artifact_prefix
+ mkdir -p "$artifact_target"
+ cp "$artifact_file" "$artifact_target"
+ cat <<EOF
+ <artifact name='$artifact_name'
+ type='$artifact_type'
+ path='$artifact_type/$artifact_prefix$artifact_name'
+ size='$artifact_size'
+ sha256='$artifact_sha256' />
+EOF
+}
+
+{
+ cat <<EOF
+<?xml version="1.0"?>
+<?xml-stylesheet href="/web-assets/build-201807.xsl" type="text/xsl"?>
+<build id='$BUILD_ID' timestamp='$BUILD_TIMESTAMP' version="201807">
+ <metadata>
+ <project>gRPC</project>
+ <repository>https://github.com/grpc/grpc</repository>
+ <branch>$BUILD_BRANCH_NAME</branch>
+ <commit>$BUILD_GIT_COMMIT</commit>
+ </metadata>
+ <artifacts>
+EOF
+
+ for pkg in "${PROTOC_PACKAGES[@]}"; do add_to_manifest protoc "$pkg"; done
+ for pkg in "${CSHARP_PACKAGES[@]}"; do add_to_manifest csharp "$pkg"; done
+ for pkg in "${PHP_PACKAGES[@]}"; do add_to_manifest php "$pkg"; done
+ for pkg in "${PYTHON_GRPCIO_PACKAGES[@]}"; do add_to_manifest python "$pkg" grpcio/; done
+ for pkg in "${PYTHON_GRPCIO_TOOLS_PACKAGES[@]}"; do add_to_manifest python "$pkg" grpcio-tools/; done
+ for pkg in "${PYTHON_GRPCIO_HEALTH_CHECKING_PACKAGES[@]}"; do add_to_manifest python "$pkg" grpcio-health-checking/; done
+ for pkg in "${PYTHON_GRPCIO_REFLECTION_PACKAGES[@]}"; do add_to_manifest python "$pkg" grpcio-reflection/; done
+ for pkg in "${PYTHON_GRPCIO_TESTING_PACKAGES[@]}"; do add_to_manifest python "$pkg" grpcio-testing/; done
+ for pkg in "${RUBY_PACKAGES[@]}"; do add_to_manifest ruby "$pkg"; done
+
+ cat <<EOF
+ </artifacts>
+</build>
+EOF
+}> "$LOCAL_BUILD_INDEX"
+
+LOCAL_BUILD_INDEX_SIZE=$(stat -c%s "$LOCAL_BUILD_INDEX")
+LOCAL_BUILD_INDEX_SHA256=$(openssl sha256 -r "$LOCAL_BUILD_INDEX" | cut -d " " -f 1)
+
+OLD_INDEX=$(mktemp)
+NEW_INDEX=$(mktemp)
+
+# Download the current /index.xml into $OLD_INDEX
+gsutil cp "$GCS_INDEX" "$OLD_INDEX"
+
+{
+ # we want to add an entry as the first child under <builds> tag
+ # we can get by without a real XML parser by rewriting the header,
+ # injecting our new tag, and then dumping the rest of the file as is.
+ cat <<EOF
+<?xml version="1.0"?>
+<?xml-stylesheet href="/web-assets/home.xsl" type="text/xsl"?>
+<packages>
+ <builds>
+ <build id='$BUILD_ID'
+ timestamp='$BUILD_TIMESTAMP'
+ branch='$BUILD_BRANCH_NAME'
+ commit='$BUILD_GIT_COMMIT'
+ path='$GCS_ARCHIVE_PREFIX$BUILD_RELPATH$INDEX_FILENAME'
+ size='$LOCAL_BUILD_INDEX_SIZE'
+ sha256='$LOCAL_BUILD_INDEX_SHA256' />
+EOF
+ tail --lines=+5 "$OLD_INDEX"
+}> "$NEW_INDEX"
+
+
+function generate_directory_index()
+{
+ local target_dir=$1
+ local current_directory_name
+ current_directory_name=$(basename "$target_dir")
+ cat <<EOF
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <title>Index of $current_directory_name - packages.grpc.io</title>
+ <link rel="stylesheet" type="text/css" href="/web-assets/dirindex.css" />
+ </head>
+ <body>
+ <h1>Index of <a href="#"><code>$current_directory_name</code></a></h1>
+ <ul>
+ <li><a href="#">.</a></li>
+ <li><a href="..">..</a></li>
+EOF
+
+(
+ cd "$target_dir"
+ find * -maxdepth 0 -type d -print | sort | while read -r line
+ do
+ echo " <li><a href='$line/'>$line/</a></li>"
+ done
+ find * -maxdepth 0 -type f -print | sort | while read -r line
+ do
+ echo " <li><a href='$line'>$line</a></li>"
+ done
+)
+
+cat <<EOF
+ </ul>
+ </body>
+</html>
+EOF
+}
+
+# Upload the current build artifacts
+gsutil -m cp -r "$LOCAL_STAGING_TEMPDIR/${BUILD_RELPATH%%/*}" "$GCS_ARCHIVE_ROOT"
+# Upload directory indicies for subdirectories
+(
+ cd "$LOCAL_BUILD_ROOT"
+ find * -type d | while read -r directory
+ do
+ generate_directory_index "$directory" | gsutil -h 'Content-Type:text/html' cp - "$GCS_ARCHIVE_ROOT$BUILD_RELPATH$directory/$INDEX_FILENAME"
+ done
+)
+# Upload the new /index.xml
+gsutil -h "Content-Type:application/xml" cp "$NEW_INDEX" "$GCS_INDEX"
diff --git a/tools/internal_ci/macos/grpc_ios_binary_size.sh b/tools/internal_ci/macos/grpc_ios_binary_size.sh
new file mode 100755
index 0000000000..ea39b0d6e9
--- /dev/null
+++ b/tools/internal_ci/macos/grpc_ios_binary_size.sh
@@ -0,0 +1,27 @@
+#!/usr/bin/env bash
+# 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.
+#
+# This script is invoked by Jenkins and runs a diff on the microbenchmarks
+set -ex
+
+# List of benchmarks that provide good signal for analyzing performance changes in pull requests
+
+# Enter the gRPC repo root
+cd $(dirname $0)/../../..
+
+source tools/internal_ci/helper_scripts/prepare_build_macos_rc
+
+tools/profiling/ios_bin/binary_size.py \
+ -d origin/$ghprbTargetBranch
diff --git a/tools/internal_ci/macos/pull_request/grpc_ios_binary_size.cfg b/tools/internal_ci/macos/pull_request/grpc_ios_binary_size.cfg
new file mode 100644
index 0000000000..8942bc7ba7
--- /dev/null
+++ b/tools/internal_ci/macos/pull_request/grpc_ios_binary_size.cfg
@@ -0,0 +1,26 @@
+# 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.
+
+# Config file for the internal CI (in protobuf text format)
+
+# Location of the continuous shell script in repository.
+build_file: "grpc/tools/internal_ci/macos/grpc_ios_binary_size.sh"
+timeout_mins: 60
+gfile_resources: "/bigstore/grpc-testing-secrets/github_credentials/oauth_token.txt"
+action {
+ define_artifacts {
+ regex: "**/*sponge_log.xml"
+ regex: "github/grpc/reports/**"
+ }
+}
diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py
index fae78909da..26bd483203 100644
--- a/tools/interop_matrix/client_matrix.py
+++ b/tools/interop_matrix/client_matrix.py
@@ -178,6 +178,9 @@ LANG_RELEASE_MATRIX = {
{
'v1.13.1': None
},
+ {
+ 'v1.14.0': None
+ },
],
'python': [
{
diff --git a/tools/package_hosting/404.html b/tools/package_hosting/404.html
new file mode 100644
index 0000000000..44d986c4b0
--- /dev/null
+++ b/tools/package_hosting/404.html
@@ -0,0 +1 @@
+404 Not Found
diff --git a/tools/package_hosting/build-201807.xsl b/tools/package_hosting/build-201807.xsl
new file mode 100644
index 0000000000..69a190446f
--- /dev/null
+++ b/tools/package_hosting/build-201807.xsl
@@ -0,0 +1,114 @@
+<?xml version="1.0"?>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+<xsl:template match="//build">
+ <html>
+ <head>
+ <title>Artifacts for gRPC Build <xsl:value-of select="@id"/> </title>
+ <link rel="stylesheet" type="text/css" href="/web-assets/style.css" />
+ <link rel="apple-touch-icon" href="/web-assets/favicons/apple-touch-icon.png" sizes="180x180" />
+ <link rel="icon" type="image/png" href="/web-assets/favicons/android-chrome-192x192.png" sizes="192x192" />
+ <link rel="icon" type="image/png" href="/web-assets/favicons/favicon-32x32.png" sizes="32x32" />
+ <link rel="icon" type="image/png" href="/web-assets/favicons/favicon-16x16.png" sizes="16x16" />
+ <link rel="manifest" href="/web-assets/favicons/manifest.json" />
+ <link rel="mask-icon" href="/web-assets/favicons/safari-pinned-tab.svg" color="#2DA6B0" />
+ <meta name="msapplication-TileColor" content="#ffffff" />
+ <meta name="msapplication-TileImage" content="/web-assets/favicons/mstile-150x150.png" />
+
+ <meta name="og:title" content="gRPC Package Build"/>
+ <meta name="og:image" content="https://grpc.io/img/grpc_square_reverse_4x.png"/>
+ <meta name="og:description" content="gRPC Package Build"/>
+ </head>
+ <body bgcolor="#ffffff">
+ <div id="topbar">
+ <span class="title">Artifacts for gRPC Build <xsl:value-of select="@id"/></span>
+ </div>
+ <div id="main">
+ <div id="metadata">
+ <span class="fieldname">Build: </span> <a href='#'><xsl:value-of select="@id"/></a>
+ [<a href="https://source.cloud.google.com/results/invocations/{@id}">invocation</a>]<br />
+ <span class="fieldname">Timestamp: </span>
+ <xsl:value-of select="@timestamp"/> <br />
+ <span class="fieldname">Branch: </span>
+ <a href="https://github.com/grpc/grpc/tree/{./metadata/branch[text()]}">
+ <xsl:value-of select="./metadata/branch[text()]" />
+ </a><br />
+ <span class="fieldname">Commit: </span>
+ <a href="https://github.com/grpc/grpc/tree/{./metadata/commit[text()]}">
+ <xsl:value-of select="./metadata/commit[text()]" /><br /></a>
+ </div>
+ <xsl:apply-templates select="artifacts" />
+ <br />
+ <br />
+
+ <p class="description"><a href="https://grpc.io">gRPC</a> is a <a href="https://www.cncf.io" class="external">Cloud Native Computing Foundation</a> project. <a href="https://policies.google.com/privacy" class="external">Privacy Policy</a>.</p>
+ <p class="description">
+ Copyright &#169;&#160;<xsl:value-of select="substring(@timestamp, 1, 4)" />&#160;<a href="https://github.com/grpc/grpc/blob/{./metadata/commit[text()]}/AUTHORS">The gRPC Authors</a></p>
+ <br />
+ <br />
+ </div>
+ </body>
+ </html>
+</xsl:template>
+
+<xsl:template match="artifacts">
+<h2> gRPC <code>protoc</code> Plugins </h2>
+<table>
+<xsl:apply-templates select="artifact[@type='protoc']">
+ <xsl:sort select="artifact/@name" />
+ </xsl:apply-templates>
+</table>
+
+<h2> C# </h2>
+<table>
+<xsl:apply-templates select="artifact[@type='csharp']">
+ <xsl:sort select="artifact/@name" />
+ </xsl:apply-templates>
+</table>
+
+<h2> PHP </h2>
+<table>
+<xsl:apply-templates select="artifact[@type='php']">
+ <xsl:sort select="artifact/@name" />
+ </xsl:apply-templates>
+</table>
+
+<h2> Python </h2>
+<script type="text/javascript">
+// <![CDATA[
+var pythonRepoLink = document.createElement("a");
+pythonRepoLink.href = './python';
+var pythonRepo = pythonRepoLink.href;
+document.write("<p><code>" +
+"$ pip install --pre --upgrade --force-reinstall --extra-index-url \\<br />" +
+"&nbsp;&nbsp;&nbsp;&nbsp;<a href='" + pythonRepo + "'>" + pythonRepo + "</a> \\<br />" +
+"&nbsp;&nbsp;&nbsp;&nbsp;grpcio grpcio-{tools,health-checking,reflection,testing}</code></p>");
+// ]]>
+</script>
+<table>
+ <xsl:apply-templates select="artifact[@type='python']">
+ <xsl:sort select="artifact/@name" />
+ </xsl:apply-templates>
+</table>
+
+<h2> Ruby </h2>
+<table>
+<xsl:apply-templates select="artifact[@type='ruby']">
+ <xsl:sort select="artifact/@name" />
+ </xsl:apply-templates>
+</table>
+
+</xsl:template>
+
+
+<xsl:template match="artifact">
+<tr>
+<td class="name"> <a href="{@path}"><xsl:value-of select="@name" /></a> </td>
+<td class="hash"> <xsl:value-of select="@sha256"/> </td>
+</tr>
+</xsl:template>
+
+<xsl:template match="metadata">
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/tools/package_hosting/dirindex.css b/tools/package_hosting/dirindex.css
new file mode 100644
index 0000000000..6c4b04ea32
--- /dev/null
+++ b/tools/package_hosting/dirindex.css
@@ -0,0 +1,16 @@
+ul {
+ list-style-type: none;
+}
+a{
+ text-decoration: none;
+}
+a:hover {
+ text-decoration: underline;
+}
+ul li a {
+ font-family: 'SF Mono', 'Menlo', 'Monaco', 'Consolas', 'Courier New', Courier, monospace
+}
+h1 {
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif
+}
+
diff --git a/tools/package_hosting/home.xsl b/tools/package_hosting/home.xsl
new file mode 100644
index 0000000000..3f79303b1b
--- /dev/null
+++ b/tools/package_hosting/home.xsl
@@ -0,0 +1,86 @@
+<?xml version="1.0"?>
+<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+
+<xsl:template match="//packages">
+ <html>
+ <head>
+ <title>gRPC Packages</title>
+ <link rel="stylesheet" type="text/css" href="/web-assets/style.css" />
+ <link rel="apple-touch-icon" href="/web-assets/favicons/apple-touch-icon.png" sizes="180x180" />
+ <link rel="icon" type="image/png" href="/web-assets/favicons/android-chrome-192x192.png" sizes="192x192" />
+ <link rel="icon" type="image/png" href="/web-assets/favicons/favicon-32x32.png" sizes="32x32" />
+ <link rel="icon" type="image/png" href="/web-assets/favicons/favicon-16x16.png" sizes="16x16" />
+ <link rel="manifest" href="/web-assets/favicons/manifest.json" />
+ <link rel="mask-icon" href="/web-assets/favicons/safari-pinned-tab.svg" color="#2DA6B0" />
+ <meta name="msapplication-TileColor" content="#ffffff" />
+ <meta name="msapplication-TileImage" content="/web-assets/favicons/mstile-150x150.png" />
+ <meta name="og:title" content="gRPC Packages"/>
+ <meta name="og:image" content="https://grpc.io/img/grpc_square_reverse_4x.png"/>
+ <meta name="og:description" content="gRPC Packages"/>
+ </head>
+ <body bgcolor="#ffffff">
+ <div id="topbar">
+ <span class="title">gRPC Packages</span>
+ </div>
+ <div id="main">
+ <xsl:apply-templates select="releases" />
+ <xsl:apply-templates select="builds" />
+ <br />
+ <br />
+ <p class="description"><a href="https://grpc.io">gRPC</a> is a <a href="https://www.cncf.io" class="external">Cloud Native Computing Foundation</a> project. <a href="https://policies.google.com/privacy" class="external">Privacy Policy</a>.</p>
+ <p class="description">Copyright &#169; 2018 <a href="https://github.com/grpc/grpc/blob/master/AUTHORS">The gRPC Authors</a></p>
+ </div>
+ </body>
+ </html>
+</xsl:template>
+
+<xsl:template match="releases">
+ <h2>Official gRPC Releases</h2>
+ <p>Commits corresponding to <a href="https://github.com/grpc/grpc/releases">official gRPC release points and release candidates</a> are tagged on GitHub.</p>
+ <p>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.</p>
+ <p>For instructions on how to use the language-specific gRPC runtime in your project, please refer to the following:</p>
+ <ul>
+ <li><a href="https://github.com/grpc/grpc/blob/master/src/cpp">C++</a>: follow the instructions under the <a href="https://github.com/grpc/grpc/tree/master/src/cpp"><code>src/cpp</code> directory</a></li>
+ <li><a href="https://github.com/grpc/grpc/blob/master/src/csharp">C#</a>: NuGet package <code>Grpc</code></li>
+ <li><a href="https://github.com/grpc/grpc-dart">Dart</a>: pub package <code>grpc</code></li>
+ <li><a href="https://github.com/grpc/grpc-go">Go</a>: <code>go get google.golang.org/grpc</code></li>
+ <li><a href="https://github.com/grpc/grpc-java">Java</a>: Use JARs from <a href="https://mvnrepository.com/artifact/io.grpc">gRPC Maven Central Repository</a></li>
+ <li><a href="https://github.com/grpc/grpc-node">Node</a>: <code>npm install grpc</code></li>
+ <li><a href="https://github.com/grpc/grpc/blob/master/src/objective-c">Objective-C</a>: Add <code>gRPC-ProtoRPC</code> dependency to podspec</li>
+ <li><a href="https://github.com/grpc/grpc/blob/master/src/php">PHP</a>: <code>pecl install grpc</code></li>
+ <li><a href="https://github.com/grpc/grpc/blob/master/src/python/grpcio">Python</a>: <code>pip install grpcio</code></li>
+ <li><a href="https://github.com/grpc/grpc/blob/master/src/ruby">Ruby</a>: <code>gem install grpc</code></li>
+ <li><a href="https://github.com/grpc/grpc-web">WebJS</a>: follow the <a href="https://github.com/grpc/grpc-web">instructions in <code>grpc-web</code> repository</a></li>
+ </ul>
+</xsl:template>
+
+<xsl:template match="builds">
+ <h2> Daily Builds of <a href="https://github.com/grpc/grpc/tree/master"><code>master</code></a> Branch</h2>
+ <p>gRPC packages are built on a daily basis at the <code>HEAD</code> of <a href="https://github.com/grpc/grpc/tree/master">the <code>master</code> branch</a> and are archived here.</p>
+ <p>
+ <a href="#">The current document</a> (view source) is an XML feed pointing to the packages as they get built and uploaded.
+ You can subscribe to this feed and fetch, deploy, and test the precompiled packages with your continuous integration infrastructure.
+ </p>
+ <p>For stable release packages, please consult the above section and the common package manager for your language.</p>
+ <table style="border:solid black 1px">
+ <tr style="background-color:lightgray">
+ <td>Timestamp</td>
+ <td>Commit</td>
+ <td>Build ID</td>
+ </tr>
+ <xsl:apply-templates select="build[@branch='master']">
+ <xsl:sort select="@timestamp" data-type="text" order="descending" />
+ </xsl:apply-templates>
+ </table>
+</xsl:template>
+
+<xsl:template match="build">
+ <tr>
+ <td class="name"><xsl:value-of select="@timestamp" /></td>
+ <td class="name"> <a href="https://github.com/grpc/grpc/tree/{@commit}"><xsl:value-of select="@commit" /></a></td>
+ <td class="name"> <a href="{@path}"><xsl:value-of select="@id" /></a></td>
+ </tr>
+</xsl:template>
+
+</xsl:stylesheet>
diff --git a/tools/package_hosting/style.css b/tools/package_hosting/style.css
new file mode 100644
index 0000000000..dbd26d50cf
--- /dev/null
+++ b/tools/package_hosting/style.css
@@ -0,0 +1,76 @@
+html, body
+{
+ margin: 0;
+ font-family: sans-serif;
+}
+
+a, a:visited, a:link, a:active {
+ color: #2da6b0;
+ text-decoration: none;
+}
+
+a:hover {
+ color: #2da6b0;
+ text-decoration: underline;
+}
+
+#topbar {
+ background-color: #2da6b0;
+ height: 60px;
+ margin:auto;
+}
+
+#topbar .title {
+ position: relative;
+ top: 24px;
+ left: 24px;
+ color: white;
+ font-family: sans-serif;
+ font-weight: bold;
+}
+
+#main {
+ max-width:1100px;
+ margin:auto;
+}
+
+#main h2 {
+ text-align: left;
+}
+
+#main table {
+ width:100%;
+ border-collapse: collapse;
+ font-size: small;
+ font-family: 'SF Mono', 'Menlo', 'Monaco', 'Courier New', Courier, monospace;
+}
+#main table tr td {
+ border: solid black 1px;
+ padding: 5px;
+}
+
+#main table tr td.hash {
+ text-align: right;
+ border-left: none;
+ font-size: x-small;
+}
+
+#main table tr td.name {
+ text-align: left;
+ border-right: none;
+}
+
+p.description
+{
+ font-size: smaller;
+}
+
+#metadata {
+ margin-top: 15px;
+ padding: 15px;
+ font-family: 'SF Mono', 'Menlo', 'Monaco', 'Courier New', Courier, monospace;
+}
+
+#metadata span.fieldname {
+ font-family: sans-serif;
+} \ No newline at end of file
diff --git a/tools/package_hosting/upload_web_assets.sh b/tools/package_hosting/upload_web_assets.sh
new file mode 100755
index 0000000000..dcf258e38e
--- /dev/null
+++ b/tools/package_hosting/upload_web_assets.sh
@@ -0,0 +1,30 @@
+#!/bin/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.
+# 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.
+
+set -ex
+
+cd "$(dirname "$0")"
+
+GCS_WEB_ASSETS=gs://packages.grpc.io/web-assets/
+
+WEB_ASSETS=(
+ 404.html
+ build-201807.xsl
+ dirindex.css
+ home.xsl
+ style.css
+)
+
+gsutil -m cp "${WEB_ASSETS[@]}" "$GCS_WEB_ASSETS"
diff --git a/tools/profiling/ios_bin/binary_diff.py b/tools/profiling/ios_bin/binary_size.py
index 6d5ae65e46..91c43f4424 100755
--- a/tools/profiling/ios_bin/binary_diff.py
+++ b/tools/profiling/ios_bin/binary_size.py
@@ -28,6 +28,9 @@ sys.path.append(
os.path.dirname(sys.argv[0]), '..', '..', 'run_tests', 'python_utils'))
import comment_on_pr
+# Only show diff 1KB or greater
+diff_threshold = 1000
+
size_labels = ('Core', 'ObjC', 'BoringSSL', 'Protobuf', 'Total')
argp = argparse.ArgumentParser(
@@ -52,7 +55,7 @@ def dir_size(dir):
def get_size(where, frameworks):
- build_dir = 'src/objective-c/examples/Sample/Build-%s/' % where
+ build_dir = 'src/objective-c/examples/Sample/Build/Build-%s/' % where
if not frameworks:
link_map_filename = 'Build/Intermediates.noindex/Sample.build/Release-iphoneos/Sample.build/Sample-LinkMap-normal-arm64.txt'
return parse_link_map(build_dir + link_map_filename)
@@ -73,17 +76,18 @@ def get_size(where, frameworks):
def build(where, frameworks):
shutil.rmtree(
- 'src/objective-c/examples/Sample/Build-%s' % where, ignore_errors=True)
+ 'src/objective-c/examples/Sample/Build/Build-%s' % where,
+ ignore_errors=True)
subprocess.check_call(
'CONFIG=opt EXAMPLE_PATH=src/objective-c/examples/Sample SCHEME=Sample FRAMEWORKS=%s ./build_one_example.sh'
% ('YES' if frameworks else 'NO'),
shell=True,
cwd='src/objective-c/tests')
- os.rename('src/objective-c/examples/Sample/Build',
- 'src/objective-c/examples/Sample/Build-%s' % where)
+ os.rename('src/objective-c/examples/Sample/Build/Build',
+ 'src/objective-c/examples/Sample/Build/Build-%s' % where)
-text = ''
+text = 'Objective-C binary sizes\n'
for frameworks in [False, True]:
build('new', frameworks)
new_size = get_size('new', frameworks)
@@ -104,22 +108,40 @@ for frameworks in [False, True]:
subprocess.check_call(['git', 'checkout', where_am_i])
subprocess.check_call(['git', 'submodule', 'update'])
- text += ('****************FRAMEWORKS*****************\n'
- if frameworks else '******************STATIC*******************\n')
+ text += ('***************FRAMEWORKS****************\n'
+ if frameworks else '*****************STATIC******************\n')
row_format = "{:>10}{:>15}{:>15}" + '\n'
text += row_format.format('New size', '', 'Old size')
- for i in range(0, len(size_labels)):
- if old_size == None:
- diff_sign = ' '
- elif new_size[i] == old_size[i]:
- diff_sign = ' (=)'
- elif new_size[i] > old_size[i]:
+ if old_size == None:
+ for i in range(0, len(size_labels)):
+ text += ('\n'
+ if i == len(size_labels) - 1 else '') + row_format.format(
+ '{:,}'.format(new_size[i]), size_labels[i], '')
+ else:
+ has_diff = False
+ for i in range(0, len(size_labels) - 1):
+ if abs(new_size[i] - old_size[i]) < diff_threshold:
+ continue
+ if new_size[i] > old_size[i]:
+ diff_sign = ' (>)'
+ else:
+ diff_sign = ' (<)'
+ has_diff = True
+ text += row_format.format('{:,}'.format(new_size[i]),
+ size_labels[i] + diff_sign, '{:,}'.format(
+ old_size[i]))
+ i = len(size_labels) - 1
+ if new_size[i] > old_size[i]:
diff_sign = ' (>)'
- else:
+ elif new_size[i] < old_size[i]:
diff_sign = ' (<)'
- text += ('\n' if i == len(size_labels) - 1 else '') + row_format.format(
+ else:
+ diff_sign = ' (=)'
+ text += ('\n' if has_diff else '') + row_format.format(
'{:,}'.format(new_size[i]), size_labels[i] + diff_sign,
- '{:,}'.format(old_size[i]) if old_size != None else '')
+ '{:,}'.format(old_size[i]))
+ if not has_diff:
+ text += '\n No significant differences in binary sizes\n'
text += '\n'
print text
diff --git a/tools/run_tests/artifacts/artifact_targets.py b/tools/run_tests/artifacts/artifact_targets.py
index 40cbfa0021..a37098d9bf 100644
--- a/tools/run_tests/artifacts/artifact_targets.py
+++ b/tools/run_tests/artifacts/artifact_targets.py
@@ -212,11 +212,15 @@ class RubyArtifact:
class CSharpExtArtifact:
"""Builds C# native extension library"""
- def __init__(self, platform, arch):
+ def __init__(self, platform, arch, arch_abi=None):
self.name = 'csharp_ext_%s_%s' % (platform, arch)
self.platform = platform
self.arch = arch
+ self.arch_abi = arch_abi
self.labels = ['artifact', 'csharp', platform, arch]
+ if arch_abi:
+ self.name += '_%s' % arch_abi
+ self.labels.append(arch_abi)
def pre_build_jobspecs(self):
return []
@@ -227,7 +231,14 @@ class CSharpExtArtifact:
self.name,
'tools/dockerfile/grpc_artifact_android_ndk',
'tools/run_tests/artifacts/build_artifact_csharp_android.sh',
- environ={})
+ environ={
+ 'ANDROID_ABI': self.arch_abi
+ })
+ elif self.arch == 'ios':
+ return create_jobspec(
+ self.name,
+ ['tools/run_tests/artifacts/build_artifact_csharp_ios.sh'],
+ use_workspace=True)
elif self.platform == 'windows':
cmake_arch_option = 'Win32' if self.arch == 'x86' else self.arch
return create_jobspec(
@@ -348,7 +359,10 @@ def targets():
for Cls in (CSharpExtArtifact, ProtocArtifact)
for platform in ('linux', 'macos', 'windows') for arch in ('x86', 'x64')
] + [
- CSharpExtArtifact('linux', 'android'),
+ CSharpExtArtifact('linux', 'android', arch_abi='arm64-v8a'),
+ CSharpExtArtifact('linux', 'android', arch_abi='armeabi-v7a'),
+ CSharpExtArtifact('linux', 'android', arch_abi='x86'),
+ CSharpExtArtifact('macos', 'ios'),
PythonArtifact('linux', 'x86', 'cp27-cp27m'),
PythonArtifact('linux', 'x86', 'cp27-cp27mu'),
PythonArtifact('linux', 'x86', 'cp34-cp34m'),
diff --git a/tools/run_tests/artifacts/build_artifact_csharp_android.sh b/tools/run_tests/artifacts/build_artifact_csharp_android.sh
index ba598e76a4..067eb30edc 100755
--- a/tools/run_tests/artifacts/build_artifact_csharp_android.sh
+++ b/tools/run_tests/artifacts/build_artifact_csharp_android.sh
@@ -17,6 +17,7 @@ set -ex
cd "$(dirname "$0")/../../.."
+# ANDROID_ABI is set by the job definition in artifact_targets.py
src/csharp/experimental/build_native_ext_for_android.sh
mkdir -p "${ARTIFACTS_OUT}"
diff --git a/tools/run_tests/artifacts/build_artifact_csharp_ios.sh b/tools/run_tests/artifacts/build_artifact_csharp_ios.sh
new file mode 100755
index 0000000000..c902a45db7
--- /dev/null
+++ b/tools/run_tests/artifacts/build_artifact_csharp_ios.sh
@@ -0,0 +1,23 @@
+#!/bin/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.
+# 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.
+
+set -ex
+
+cd "$(dirname "$0")/../../.."
+
+src/csharp/experimental/build_native_ext_for_ios.sh
+
+mkdir -p "${ARTIFACTS_OUT}"
+cp libs/ios/libgrpc_csharp_ext.a libs/ios/libgrpc.a "${ARTIFACTS_OUT}"
diff --git a/tools/run_tests/artifacts/build_package_php.sh b/tools/run_tests/artifacts/build_package_php.sh
index 9a8f25a6f8..e263e09a35 100755
--- a/tools/run_tests/artifacts/build_package_php.sh
+++ b/tools/run_tests/artifacts/build_package_php.sh
@@ -20,7 +20,4 @@ cd "$(dirname "$0")/../../.."
# All the PHP packages have been built in the artifact phase already
# and we only collect them here to deliver them to the distribtest phase.
mkdir -p artifacts/
-# Jenkins flow (deprecated)
-cp -r "${EXTERNAL_GIT_ROOT}"/platform={windows,linux,macos}/artifacts/php_*/* artifacts/ || true
-# Kokoro flow
cp -r "${EXTERNAL_GIT_ROOT}"/input_artifacts/php_*/* artifacts/ || true
diff --git a/tools/run_tests/artifacts/build_package_python.sh b/tools/run_tests/artifacts/build_package_python.sh
index 15627881e8..29801a5b86 100755
--- a/tools/run_tests/artifacts/build_package_python.sh
+++ b/tools/run_tests/artifacts/build_package_python.sh
@@ -21,9 +21,6 @@ mkdir -p artifacts/
# All the python packages have been built in the artifact phase already
# and we only collect them here to deliver them to the distribtest phase.
-# Jenkins flow (deprecated)
-cp -r "${EXTERNAL_GIT_ROOT}"/platform={windows,linux,macos}/artifacts/python_*/* artifacts/ || true
-# Kokoro flow
cp -r "${EXTERNAL_GIT_ROOT}"/input_artifacts/python_*/* artifacts/ || true
# TODO: all the artifact builder configurations generate a grpcio-VERSION.tar.gz
diff --git a/tools/run_tests/artifacts/build_package_ruby.sh b/tools/run_tests/artifacts/build_package_ruby.sh
index 4f74f08276..bd62ec1ff4 100755
--- a/tools/run_tests/artifacts/build_package_ruby.sh
+++ b/tools/run_tests/artifacts/build_package_ruby.sh
@@ -23,9 +23,6 @@ mkdir -p artifacts/
# All the ruby packages have been built in the artifact phase already
# and we only collect them here to deliver them to the distribtest phase.
-# Jenkins flow (deprecated)
-cp -r "${EXTERNAL_GIT_ROOT}"/platform={windows,linux,macos}/artifacts/ruby_native_gem_*/* artifacts/ || true
-# Kokoro flow
cp -r "${EXTERNAL_GIT_ROOT}"/input_artifacts/ruby_native_gem_*/* artifacts/ || true
well_known_protos=( any api compiler/plugin descriptor duration empty field_mask source_context struct timestamp type wrappers )
@@ -44,12 +41,7 @@ for arch in {x86,x64}; do
;;
esac
for plat in {windows,linux,macos}; do
- if [ "${KOKORO_JOB_NAME}" != "" ]
- then
- input_dir="${EXTERNAL_GIT_ROOT}/input_artifacts/protoc_${plat}_${arch}"
- else
- input_dir="${EXTERNAL_GIT_ROOT}/platform=${plat}/artifacts/protoc_${plat}_${arch}"
- fi
+ input_dir="${EXTERNAL_GIT_ROOT}/input_artifacts/protoc_${plat}_${arch}"
output_dir="$base/src/ruby/tools/bin/${ruby_arch}-${plat}"
mkdir -p "$output_dir"/google/protobuf
mkdir -p "$output_dir"/google/protobuf/compiler # needed for plugin.proto
diff --git a/tools/run_tests/artifacts/package_targets.py b/tools/run_tests/artifacts/package_targets.py
index abf1b5ebed..70f1fc8a4b 100644
--- a/tools/run_tests/artifacts/package_targets.py
+++ b/tools/run_tests/artifacts/package_targets.py
@@ -56,7 +56,8 @@ def create_jobspec(name,
cwd=None,
shell=False,
flake_retries=0,
- timeout_retries=0):
+ timeout_retries=0,
+ cpu_cost=1.0):
"""Creates jobspec."""
jobspec = jobset.JobSpec(
cmdline=cmdline,
@@ -66,31 +67,36 @@ def create_jobspec(name,
timeout_seconds=10 * 60,
flake_retries=flake_retries,
timeout_retries=timeout_retries,
+ cpu_cost=cpu_cost,
shell=shell)
return jobspec
class CSharpPackage:
- """Builds C# nuget packages."""
-
- def __init__(self, linux=False):
- self.linux = linux
- self.labels = ['package', 'csharp']
- if linux:
- self.name = 'csharp_package_dotnetcli_linux'
- self.labels += ['linux']
+ """Builds C# packages."""
+
+ def __init__(self, unity=False):
+ self.unity = unity
+ self.labels = ['package', 'csharp', 'windows']
+ if unity:
+ self.name = 'csharp_package_unity_windows'
+ self.labels += ['unity']
else:
- self.name = 'csharp_package_dotnetcli_windows'
- self.labels += ['windows']
+ self.name = 'csharp_package_nuget_windows'
+ self.labels += ['nuget']
def pre_build_jobspecs(self):
return []
def build_jobspec(self):
- if self.linux:
- return create_docker_jobspec(
- self.name, 'tools/dockerfile/test/csharp_jessie_x64',
- 'src/csharp/build_packages_dotnetcli.sh')
+ if self.unity:
+ # use very high CPU cost to avoid running nuget package build
+ # and unity build concurrently
+ return create_jobspec(
+ self.name, ['build_unitypackage.bat'],
+ cwd='src\\csharp',
+ cpu_cost=1e6,
+ shell=True)
else:
return create_jobspec(
self.name, ['build_packages_dotnetcli.bat'],
@@ -153,7 +159,7 @@ def targets():
"""Gets list of supported targets"""
return [
CSharpPackage(),
- CSharpPackage(linux=True),
+ CSharpPackage(unity=True),
RubyPackage(),
PythonPackage(),
PHPPackage()
diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json
index 7953fa3772..a686dae8b4 100644
--- a/tools/run_tests/generated/sources_and_headers.json
+++ b/tools/run_tests/generated/sources_and_headers.json
@@ -1042,6 +1042,23 @@
"headers": [],
"is_filegroup": false,
"language": "c",
+ "name": "grpc_ipv6_loopback_available_test",
+ "src": [
+ "test/core/iomgr/grpc_ipv6_loopback_available_test.cc"
+ ],
+ "third_party": false,
+ "type": "target"
+ },
+ {
+ "deps": [
+ "gpr",
+ "gpr_test_util",
+ "grpc",
+ "grpc_test_util"
+ ],
+ "headers": [],
+ "is_filegroup": false,
+ "language": "c",
"name": "grpc_json_token_test",
"src": [
"test/core/security/json_token_test.cc"
@@ -3124,10 +3141,10 @@
"gpr_test_util",
"grpc",
"grpc++",
- "grpc++_channelz_proto",
"grpc++_test",
"grpc++_test_util",
- "grpc_test_util"
+ "grpc_test_util",
+ "grpcpp_channelz_proto"
],
"headers": [],
"is_filegroup": false,
@@ -3165,10 +3182,31 @@
"gpr_test_util",
"grpc",
"grpc++",
- "grpc++_channelz_proto",
+ "grpc++_test_util",
+ "grpc_test_util",
+ "grpcpp_channelz",
+ "grpcpp_channelz_proto"
+ ],
+ "headers": [],
+ "is_filegroup": false,
+ "language": "c++",
+ "name": "channelz_service_test",
+ "src": [
+ "test/cpp/end2end/channelz_service_test.cc"
+ ],
+ "third_party": false,
+ "type": "target"
+ },
+ {
+ "deps": [
+ "gpr",
+ "gpr_test_util",
+ "grpc",
+ "grpc++",
"grpc++_test",
"grpc++_test_util",
- "grpc_test_util"
+ "grpc_test_util",
+ "grpcpp_channelz_proto"
],
"headers": [],
"is_filegroup": false,
@@ -7532,6 +7570,28 @@
"deps": [
"grpc",
"grpc++",
+ "grpcpp_channelz_proto"
+ ],
+ "headers": [
+ "include/grpcpp/ext/channelz_service_plugin.h",
+ "src/cpp/server/channelz/channelz_service.h"
+ ],
+ "is_filegroup": false,
+ "language": "c++",
+ "name": "grpcpp_channelz",
+ "src": [
+ "include/grpcpp/ext/channelz_service_plugin.h",
+ "src/cpp/server/channelz/channelz_service.cc",
+ "src/cpp/server/channelz/channelz_service.h",
+ "src/cpp/server/channelz/channelz_service_plugin.cc"
+ ],
+ "third_party": false,
+ "type": "lib"
+ },
+ {
+ "deps": [
+ "grpc",
+ "grpc++",
"grpc++_test_config",
"grpc++_test_util",
"grpc_test_util"
@@ -7718,6 +7778,7 @@
"test/cpp/qps/histogram.h",
"test/cpp/qps/interarrival.h",
"test/cpp/qps/parse_json.h",
+ "test/cpp/qps/qps_server_builder.h",
"test/cpp/qps/qps_worker.h",
"test/cpp/qps/report.h",
"test/cpp/qps/server.h",
@@ -7739,6 +7800,8 @@
"test/cpp/qps/interarrival.h",
"test/cpp/qps/parse_json.cc",
"test/cpp/qps/parse_json.h",
+ "test/cpp/qps/qps_server_builder.cc",
+ "test/cpp/qps/qps_server_builder.h",
"test/cpp/qps/qps_worker.cc",
"test/cpp/qps/qps_worker.h",
"test/cpp/qps/report.cc",
@@ -10208,9 +10271,12 @@
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.cc",
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver.h",
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.cc",
+ "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_windows.cc",
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.cc",
"src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.h",
- "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc"
+ "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_fallback.cc",
+ "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_posix.cc",
+ "src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper_windows.cc"
],
"third_party": false,
"type": "filegroup"
@@ -10889,20 +10955,6 @@
"type": "filegroup"
},
{
- "deps": [],
- "headers": [
- "src/proto/grpc/channelz/channelz.grpc.pb.h",
- "src/proto/grpc/channelz/channelz.pb.h",
- "src/proto/grpc/channelz/channelz_mock.grpc.pb.h"
- ],
- "is_filegroup": true,
- "language": "c++",
- "name": "grpc++_channelz_proto",
- "src": [],
- "third_party": false,
- "type": "filegroup"
- },
- {
"deps": [
"grpc_codegen"
],
@@ -11377,5 +11429,19 @@
],
"third_party": false,
"type": "filegroup"
+ },
+ {
+ "deps": [],
+ "headers": [
+ "src/proto/grpc/channelz/channelz.grpc.pb.h",
+ "src/proto/grpc/channelz/channelz.pb.h",
+ "src/proto/grpc/channelz/channelz_mock.grpc.pb.h"
+ ],
+ "is_filegroup": true,
+ "language": "c++",
+ "name": "grpcpp_channelz_proto",
+ "src": [],
+ "third_party": false,
+ "type": "filegroup"
}
]
diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json
index 5c556a2f52..5815f82fef 100644
--- a/tools/run_tests/generated/tests.json
+++ b/tools/run_tests/generated/tests.json
@@ -1319,6 +1319,32 @@
"ci_platforms": [
"linux",
"mac",
+ "posix",
+ "windows"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [
+ "uv"
+ ],
+ "flaky": false,
+ "gtest": false,
+ "language": "c",
+ "name": "grpc_ipv6_loopback_available_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix",
+ "windows"
+ ],
+ "uses_polling": true
+ },
+ {
+ "args": [],
+ "benchmark": false,
+ "ci_platforms": [
+ "linux",
+ "mac",
"posix"
],
"cpu_cost": 1.0,
@@ -3770,6 +3796,30 @@
"flaky": false,
"gtest": true,
"language": "c++",
+ "name": "channelz_service_test",
+ "platforms": [
+ "linux",
+ "mac",
+ "posix",
+ "windows"
+ ],
+ "uses_polling": true
+ },
+ {
+ "args": [],
+ "benchmark": false,
+ "ci_platforms": [
+ "linux",
+ "mac",
+ "posix",
+ "windows"
+ ],
+ "cpu_cost": 1.0,
+ "exclude_configs": [],
+ "exclude_iomgrs": [],
+ "flaky": false,
+ "gtest": true,
+ "language": "c++",
"name": "channelz_test",
"platforms": [
"linux",
@@ -5686,7 +5736,8 @@
"ci_platforms": [
"linux",
"mac",
- "posix"
+ "posix",
+ "windows"
],
"cpu_cost": 1.0,
"exclude_configs": [],
@@ -5698,7 +5749,8 @@
"platforms": [
"linux",
"mac",
- "posix"
+ "posix",
+ "windows"
],
"uses_polling": true
},
@@ -5708,7 +5760,8 @@
"ci_platforms": [
"linux",
"mac",
- "posix"
+ "posix",
+ "windows"
],
"cpu_cost": 1.0,
"exclude_configs": [],
@@ -5720,7 +5773,8 @@
"platforms": [
"linux",
"mac",
- "posix"
+ "posix",
+ "windows"
],
"uses_polling": true
},
diff --git a/tools/run_tests/performance/README.md b/tools/run_tests/performance/README.md
index 2fc1a27c9b..791270ab38 100644
--- a/tools/run_tests/performance/README.md
+++ b/tools/run_tests/performance/README.md
@@ -104,3 +104,31 @@ Example memory profile of grpc-go server, with `go tools pprof`:
```
$ go tool pprof --text --alloc_space http://localhost:<pprof_port>/debug/heap
```
+
+### Configuration environment variables:
+
+* QPS_WORKER_CHANNEL_CONNECT_TIMEOUT
+
+ Consuming process: qps_worker
+
+ Type: integer (number of seconds)
+
+ This can be used to configure the amount of time that benchmark
+ clients wait for channels to the benchmark server to become ready.
+ This is useful in certain benchmark environments in which the
+ server can take a long time to become ready. Note: if setting
+ this to a high value, then the scenario config under test should
+ probably also have a large "warmup_seconds".
+
+* QPS_WORKERS
+
+ Consuming process: qps_json_driver
+
+ Type: comma separated list of host:port
+
+ Set this to a comma separated list of QPS worker processes/machines.
+ Each scenario in a scenario config has specifies a certain number
+ of servers, `num_servers`, and the driver will start
+ "benchmark servers"'s on the first `num_server` `host:port` pairs in
+ the comma separated list. The rest will be told to run as clients
+ against the benchmark server.