aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--BUILD1271
-rw-r--r--Makefile216
-rw-r--r--build.json68
-rw-r--r--src/compiler/cpp_generator.cc59
-rw-r--r--src/core/iomgr/pollset_multipoller_with_poll_posix.c4
-rw-r--r--src/core/iomgr/pollset_posix.c4
-rw-r--r--src/core/iomgr/tcp_server.h6
-rw-r--r--src/core/iomgr/tcp_server_posix.c60
-rw-r--r--src/core/iomgr/tcp_server_windows.c36
-rw-r--r--src/core/security/server_secure_chttp2.c19
-rw-r--r--src/core/surface/completion_queue.c8
-rw-r--r--src/core/surface/completion_queue.h4
-rw-r--r--src/core/surface/server.c55
-rw-r--r--src/core/surface/server.h7
-rw-r--r--src/core/surface/server_chttp2.c7
-rw-r--r--src/cpp/client/secure_credentials.cc35
-rw-r--r--src/cpp/client/secure_credentials.h61
-rw-r--r--src/cpp/server/secure_server_credentials.cc31
-rw-r--r--src/cpp/server/secure_server_credentials.h60
-rw-r--r--src/ruby/ext/grpc/rb_byte_buffer.c204
-rw-r--r--src/ruby/ext/grpc/rb_byte_buffer.h16
-rw-r--r--src/ruby/ext/grpc/rb_call.c715
-rw-r--r--src/ruby/ext/grpc/rb_call.h9
-rw-r--r--src/ruby/ext/grpc/rb_channel.c35
-rw-r--r--src/ruby/ext/grpc/rb_completion_queue.c20
-rw-r--r--src/ruby/ext/grpc/rb_completion_queue.h8
-rw-r--r--src/ruby/ext/grpc/rb_event.c361
-rw-r--r--src/ruby/ext/grpc/rb_grpc.c13
-rw-r--r--src/ruby/ext/grpc/rb_grpc.h9
-rw-r--r--src/ruby/ext/grpc/rb_metadata.c215
-rw-r--r--src/ruby/ext/grpc/rb_server.c85
-rw-r--r--src/ruby/lib/grpc.rb1
-rw-r--r--src/ruby/lib/grpc/core/event.rb44
-rw-r--r--src/ruby/lib/grpc/errors.rb4
-rw-r--r--src/ruby/lib/grpc/generic/active_call.rb183
-rw-r--r--src/ruby/lib/grpc/generic/bidi_call.rb69
-rw-r--r--src/ruby/lib/grpc/generic/client_stub.rb52
-rw-r--r--src/ruby/lib/grpc/generic/rpc_desc.rb9
-rw-r--r--src/ruby/lib/grpc/generic/rpc_server.rb91
-rw-r--r--src/ruby/spec/alloc_spec.rb44
-rw-r--r--src/ruby/spec/byte_buffer_spec.rb67
-rw-r--r--src/ruby/spec/call_spec.rb63
-rw-r--r--src/ruby/spec/channel_spec.rb29
-rw-r--r--src/ruby/spec/client_server_spec.rb356
-rw-r--r--src/ruby/spec/event_spec.rb53
-rw-r--r--src/ruby/spec/generic/active_call_spec.rb144
-rw-r--r--src/ruby/spec/generic/client_stub_spec.rb136
-rw-r--r--src/ruby/spec/generic/rpc_desc_spec.rb57
-rw-r--r--src/ruby/spec/generic/rpc_server_spec.rb2
-rw-r--r--src/ruby/spec/metadata_spec.rb64
-rw-r--r--templates/BUILD.template79
-rw-r--r--templates/Makefile.template1
-rw-r--r--test/core/end2end/tests/cancel_after_invoke.c6
-rw-r--r--test/core/end2end/tests/cancel_test_helpers.h9
-rw-r--r--test/core/iomgr/tcp_server_posix_test.c10
-rw-r--r--test/cpp/interop/client.cc394
-rw-r--r--test/cpp/interop/client_helper.cc119
-rw-r--r--test/cpp/interop/client_helper.h (renamed from src/ruby/ext/grpc/rb_event.h)28
-rw-r--r--test/cpp/interop/interop_client.cc311
-rw-r--r--test/cpp/interop/interop_client.h79
-rw-r--r--test/cpp/interop/server.cc13
-rw-r--r--test/cpp/interop/server_helper.cc69
-rw-r--r--test/cpp/interop/server_helper.h (renamed from src/ruby/ext/grpc/rb_metadata.h)24
-rw-r--r--test/cpp/qps/client.h32
-rw-r--r--test/cpp/qps/client_async.cc36
-rw-r--r--test/cpp/qps/client_sync.cc13
-rw-r--r--test/cpp/qps/histogram.h4
-rw-r--r--test/cpp/qps/qps_driver.cc37
-rw-r--r--test/cpp/qps/report.cc94
-rw-r--r--test/cpp/qps/report.h57
-rw-r--r--test/cpp/qps/server_async.cc20
-rw-r--r--test/cpp/qps/smoke_test.cc149
-rwxr-xr-xtest/cpp/qps/smoke_test.sh28
-rw-r--r--tools/dockerfile/grpc_python/Dockerfile3
-rwxr-xr-xtools/gce_setup/grpc_docker.sh4
-rwxr-xr-xtools/gce_setup/interop_test_runner.sh2
-rw-r--r--vsprojects/vs2010/grpc++.vcxproj8
-rw-r--r--vsprojects/vs2010/grpc++.vcxproj.filters24
-rw-r--r--vsprojects/vs2013/grpc++.vcxproj8
-rw-r--r--vsprojects/vs2013/grpc++.vcxproj.filters24
80 files changed, 3658 insertions, 3196 deletions
diff --git a/BUILD b/BUILD
index ccff9c05c6..233cf65045 100644
--- a/BUILD
+++ b/BUILD
@@ -32,535 +32,782 @@
licenses(["notice"]) # 3-clause BSD
+package(default_visibility = ["//visibility:public"])
+
+
+
+
+cc_library(
+ name = "gpr",
+ srcs = [
+ "src/core/support/env.h",
+ "src/core/support/file.h",
+ "src/core/support/murmur_hash.h",
+ "src/core/support/string.h",
+ "src/core/support/string_win32.h",
+ "src/core/support/thd_internal.h",
+ "src/core/support/alloc.c",
+ "src/core/support/cancellable.c",
+ "src/core/support/cmdline.c",
+ "src/core/support/cpu_iphone.c",
+ "src/core/support/cpu_linux.c",
+ "src/core/support/cpu_posix.c",
+ "src/core/support/cpu_windows.c",
+ "src/core/support/env_linux.c",
+ "src/core/support/env_posix.c",
+ "src/core/support/env_win32.c",
+ "src/core/support/file.c",
+ "src/core/support/file_posix.c",
+ "src/core/support/file_win32.c",
+ "src/core/support/histogram.c",
+ "src/core/support/host_port.c",
+ "src/core/support/log.c",
+ "src/core/support/log_android.c",
+ "src/core/support/log_linux.c",
+ "src/core/support/log_posix.c",
+ "src/core/support/log_win32.c",
+ "src/core/support/murmur_hash.c",
+ "src/core/support/slice.c",
+ "src/core/support/slice_buffer.c",
+ "src/core/support/string.c",
+ "src/core/support/string_posix.c",
+ "src/core/support/string_win32.c",
+ "src/core/support/sync.c",
+ "src/core/support/sync_posix.c",
+ "src/core/support/sync_win32.c",
+ "src/core/support/thd.c",
+ "src/core/support/thd_posix.c",
+ "src/core/support/thd_win32.c",
+ "src/core/support/time.c",
+ "src/core/support/time_posix.c",
+ "src/core/support/time_win32.c",
+ ],
+ hdrs = [
+ "include/grpc/support/alloc.h",
+ "include/grpc/support/atm.h",
+ "include/grpc/support/atm_gcc_atomic.h",
+ "include/grpc/support/atm_gcc_sync.h",
+ "include/grpc/support/atm_win32.h",
+ "include/grpc/support/cancellable_platform.h",
+ "include/grpc/support/cmdline.h",
+ "include/grpc/support/cpu.h",
+ "include/grpc/support/histogram.h",
+ "include/grpc/support/host_port.h",
+ "include/grpc/support/log.h",
+ "include/grpc/support/log_win32.h",
+ "include/grpc/support/port_platform.h",
+ "include/grpc/support/slice.h",
+ "include/grpc/support/slice_buffer.h",
+ "include/grpc/support/sync.h",
+ "include/grpc/support/sync_generic.h",
+ "include/grpc/support/sync_posix.h",
+ "include/grpc/support/sync_win32.h",
+ "include/grpc/support/thd.h",
+ "include/grpc/support/time.h",
+ "include/grpc/support/useful.h",
+ ],
+ includes = [
+ "include",
+ ".",
+ ],
+ deps = [
+ ],
+)
+
+
+cc_library(
+ name = "grpc",
+ srcs = [
+ "src/core/httpcli/format_request.h",
+ "src/core/httpcli/httpcli.h",
+ "src/core/httpcli/httpcli_security_context.h",
+ "src/core/httpcli/parser.h",
+ "src/core/security/auth.h",
+ "src/core/security/base64.h",
+ "src/core/security/credentials.h",
+ "src/core/security/json_token.h",
+ "src/core/security/secure_endpoint.h",
+ "src/core/security/secure_transport_setup.h",
+ "src/core/security/security_context.h",
+ "src/core/tsi/fake_transport_security.h",
+ "src/core/tsi/ssl_transport_security.h",
+ "src/core/tsi/transport_security.h",
+ "src/core/tsi/transport_security_interface.h",
+ "src/core/channel/census_filter.h",
+ "src/core/channel/channel_args.h",
+ "src/core/channel/channel_stack.h",
+ "src/core/channel/child_channel.h",
+ "src/core/channel/client_channel.h",
+ "src/core/channel/client_setup.h",
+ "src/core/channel/connected_channel.h",
+ "src/core/channel/http_client_filter.h",
+ "src/core/channel/http_filter.h",
+ "src/core/channel/http_server_filter.h",
+ "src/core/channel/metadata_buffer.h",
+ "src/core/channel/noop_filter.h",
+ "src/core/compression/algorithm.h",
+ "src/core/compression/message_compress.h",
+ "src/core/debug/trace.h",
+ "src/core/iomgr/alarm.h",
+ "src/core/iomgr/alarm_heap.h",
+ "src/core/iomgr/alarm_internal.h",
+ "src/core/iomgr/endpoint.h",
+ "src/core/iomgr/endpoint_pair.h",
+ "src/core/iomgr/fd_posix.h",
+ "src/core/iomgr/iocp_windows.h",
+ "src/core/iomgr/iomgr.h",
+ "src/core/iomgr/iomgr_internal.h",
+ "src/core/iomgr/iomgr_posix.h",
+ "src/core/iomgr/pollset.h",
+ "src/core/iomgr/pollset_kick.h",
+ "src/core/iomgr/pollset_kick_posix.h",
+ "src/core/iomgr/pollset_kick_windows.h",
+ "src/core/iomgr/pollset_posix.h",
+ "src/core/iomgr/pollset_windows.h",
+ "src/core/iomgr/resolve_address.h",
+ "src/core/iomgr/sockaddr.h",
+ "src/core/iomgr/sockaddr_posix.h",
+ "src/core/iomgr/sockaddr_utils.h",
+ "src/core/iomgr/sockaddr_win32.h",
+ "src/core/iomgr/socket_utils_posix.h",
+ "src/core/iomgr/socket_windows.h",
+ "src/core/iomgr/tcp_client.h",
+ "src/core/iomgr/tcp_posix.h",
+ "src/core/iomgr/tcp_server.h",
+ "src/core/iomgr/tcp_windows.h",
+ "src/core/iomgr/time_averaged_stats.h",
+ "src/core/iomgr/wakeup_fd_pipe.h",
+ "src/core/iomgr/wakeup_fd_posix.h",
+ "src/core/json/json.h",
+ "src/core/json/json_common.h",
+ "src/core/json/json_reader.h",
+ "src/core/json/json_writer.h",
+ "src/core/statistics/census_interface.h",
+ "src/core/statistics/census_log.h",
+ "src/core/statistics/census_rpc_stats.h",
+ "src/core/statistics/census_tracing.h",
+ "src/core/statistics/hash_table.h",
+ "src/core/statistics/window_stats.h",
+ "src/core/surface/byte_buffer_queue.h",
+ "src/core/surface/call.h",
+ "src/core/surface/channel.h",
+ "src/core/surface/client.h",
+ "src/core/surface/completion_queue.h",
+ "src/core/surface/event_string.h",
+ "src/core/surface/init.h",
+ "src/core/surface/server.h",
+ "src/core/surface/surface_trace.h",
+ "src/core/transport/chttp2/alpn.h",
+ "src/core/transport/chttp2/bin_encoder.h",
+ "src/core/transport/chttp2/frame.h",
+ "src/core/transport/chttp2/frame_data.h",
+ "src/core/transport/chttp2/frame_goaway.h",
+ "src/core/transport/chttp2/frame_ping.h",
+ "src/core/transport/chttp2/frame_rst_stream.h",
+ "src/core/transport/chttp2/frame_settings.h",
+ "src/core/transport/chttp2/frame_window_update.h",
+ "src/core/transport/chttp2/hpack_parser.h",
+ "src/core/transport/chttp2/hpack_table.h",
+ "src/core/transport/chttp2/http2_errors.h",
+ "src/core/transport/chttp2/huffsyms.h",
+ "src/core/transport/chttp2/status_conversion.h",
+ "src/core/transport/chttp2/stream_encoder.h",
+ "src/core/transport/chttp2/stream_map.h",
+ "src/core/transport/chttp2/timeout_encoding.h",
+ "src/core/transport/chttp2/varint.h",
+ "src/core/transport/chttp2_transport.h",
+ "src/core/transport/metadata.h",
+ "src/core/transport/stream_op.h",
+ "src/core/transport/transport.h",
+ "src/core/transport/transport_impl.h",
+ "src/core/httpcli/format_request.c",
+ "src/core/httpcli/httpcli.c",
+ "src/core/httpcli/httpcli_security_context.c",
+ "src/core/httpcli/parser.c",
+ "src/core/security/auth.c",
+ "src/core/security/base64.c",
+ "src/core/security/credentials.c",
+ "src/core/security/credentials_posix.c",
+ "src/core/security/credentials_win32.c",
+ "src/core/security/factories.c",
+ "src/core/security/google_default_credentials.c",
+ "src/core/security/json_token.c",
+ "src/core/security/secure_endpoint.c",
+ "src/core/security/secure_transport_setup.c",
+ "src/core/security/security_context.c",
+ "src/core/security/server_secure_chttp2.c",
+ "src/core/surface/init_secure.c",
+ "src/core/surface/secure_channel_create.c",
+ "src/core/tsi/fake_transport_security.c",
+ "src/core/tsi/ssl_transport_security.c",
+ "src/core/tsi/transport_security.c",
+ "src/core/channel/call_op_string.c",
+ "src/core/channel/census_filter.c",
+ "src/core/channel/channel_args.c",
+ "src/core/channel/channel_stack.c",
+ "src/core/channel/child_channel.c",
+ "src/core/channel/client_channel.c",
+ "src/core/channel/client_setup.c",
+ "src/core/channel/connected_channel.c",
+ "src/core/channel/http_client_filter.c",
+ "src/core/channel/http_filter.c",
+ "src/core/channel/http_server_filter.c",
+ "src/core/channel/metadata_buffer.c",
+ "src/core/channel/noop_filter.c",
+ "src/core/compression/algorithm.c",
+ "src/core/compression/message_compress.c",
+ "src/core/debug/trace.c",
+ "src/core/iomgr/alarm.c",
+ "src/core/iomgr/alarm_heap.c",
+ "src/core/iomgr/endpoint.c",
+ "src/core/iomgr/endpoint_pair_posix.c",
+ "src/core/iomgr/fd_posix.c",
+ "src/core/iomgr/iocp_windows.c",
+ "src/core/iomgr/iomgr.c",
+ "src/core/iomgr/iomgr_posix.c",
+ "src/core/iomgr/iomgr_windows.c",
+ "src/core/iomgr/pollset_kick.c",
+ "src/core/iomgr/pollset_multipoller_with_epoll.c",
+ "src/core/iomgr/pollset_multipoller_with_poll_posix.c",
+ "src/core/iomgr/pollset_posix.c",
+ "src/core/iomgr/pollset_windows.c",
+ "src/core/iomgr/resolve_address_posix.c",
+ "src/core/iomgr/resolve_address_windows.c",
+ "src/core/iomgr/sockaddr_utils.c",
+ "src/core/iomgr/socket_utils_common_posix.c",
+ "src/core/iomgr/socket_utils_linux.c",
+ "src/core/iomgr/socket_utils_posix.c",
+ "src/core/iomgr/socket_windows.c",
+ "src/core/iomgr/tcp_client_posix.c",
+ "src/core/iomgr/tcp_client_windows.c",
+ "src/core/iomgr/tcp_posix.c",
+ "src/core/iomgr/tcp_server_posix.c",
+ "src/core/iomgr/tcp_server_windows.c",
+ "src/core/iomgr/tcp_windows.c",
+ "src/core/iomgr/time_averaged_stats.c",
+ "src/core/iomgr/wakeup_fd_eventfd.c",
+ "src/core/iomgr/wakeup_fd_nospecial.c",
+ "src/core/iomgr/wakeup_fd_pipe.c",
+ "src/core/iomgr/wakeup_fd_posix.c",
+ "src/core/json/json.c",
+ "src/core/json/json_reader.c",
+ "src/core/json/json_string.c",
+ "src/core/json/json_writer.c",
+ "src/core/statistics/census_init.c",
+ "src/core/statistics/census_log.c",
+ "src/core/statistics/census_rpc_stats.c",
+ "src/core/statistics/census_tracing.c",
+ "src/core/statistics/hash_table.c",
+ "src/core/statistics/window_stats.c",
+ "src/core/surface/byte_buffer.c",
+ "src/core/surface/byte_buffer_queue.c",
+ "src/core/surface/byte_buffer_reader.c",
+ "src/core/surface/call.c",
+ "src/core/surface/call_details.c",
+ "src/core/surface/call_log_batch.c",
+ "src/core/surface/channel.c",
+ "src/core/surface/channel_create.c",
+ "src/core/surface/client.c",
+ "src/core/surface/completion_queue.c",
+ "src/core/surface/event_string.c",
+ "src/core/surface/init.c",
+ "src/core/surface/lame_client.c",
+ "src/core/surface/metadata_array.c",
+ "src/core/surface/server.c",
+ "src/core/surface/server_chttp2.c",
+ "src/core/surface/server_create.c",
+ "src/core/surface/surface_trace.c",
+ "src/core/transport/chttp2/alpn.c",
+ "src/core/transport/chttp2/bin_encoder.c",
+ "src/core/transport/chttp2/frame_data.c",
+ "src/core/transport/chttp2/frame_goaway.c",
+ "src/core/transport/chttp2/frame_ping.c",
+ "src/core/transport/chttp2/frame_rst_stream.c",
+ "src/core/transport/chttp2/frame_settings.c",
+ "src/core/transport/chttp2/frame_window_update.c",
+ "src/core/transport/chttp2/hpack_parser.c",
+ "src/core/transport/chttp2/hpack_table.c",
+ "src/core/transport/chttp2/huffsyms.c",
+ "src/core/transport/chttp2/status_conversion.c",
+ "src/core/transport/chttp2/stream_encoder.c",
+ "src/core/transport/chttp2/stream_map.c",
+ "src/core/transport/chttp2/timeout_encoding.c",
+ "src/core/transport/chttp2/varint.c",
+ "src/core/transport/chttp2_transport.c",
+ "src/core/transport/metadata.c",
+ "src/core/transport/stream_op.c",
+ "src/core/transport/transport.c",
+ ],
+ hdrs = [
+ "include/grpc/grpc_security.h",
+ "include/grpc/byte_buffer.h",
+ "include/grpc/byte_buffer_reader.h",
+ "include/grpc/grpc.h",
+ "include/grpc/grpc_http.h",
+ "include/grpc/status.h",
+ ],
+ includes = [
+ "include",
+ ".",
+ ],
+ deps = [
+ "//external:libssl",
+ ":gpr",
+ ],
+)
cc_library(
- name = "gpr",
- srcs = [
- "src/core/support/env.h",
- "src/core/support/file.h",
- "src/core/support/murmur_hash.h",
- "src/core/support/string.h",
- "src/core/support/string_win32.h",
- "src/core/support/thd_internal.h",
- "src/core/support/alloc.c",
- "src/core/support/cancellable.c",
- "src/core/support/cmdline.c",
- "src/core/support/cpu_iphone.c",
- "src/core/support/cpu_linux.c",
- "src/core/support/cpu_posix.c",
- "src/core/support/cpu_windows.c",
- "src/core/support/env_linux.c",
- "src/core/support/env_posix.c",
- "src/core/support/env_win32.c",
- "src/core/support/file.c",
- "src/core/support/file_posix.c",
- "src/core/support/file_win32.c",
- "src/core/support/histogram.c",
- "src/core/support/host_port.c",
- "src/core/support/log.c",
- "src/core/support/log_android.c",
- "src/core/support/log_linux.c",
- "src/core/support/log_posix.c",
- "src/core/support/log_win32.c",
- "src/core/support/murmur_hash.c",
- "src/core/support/slice.c",
- "src/core/support/slice_buffer.c",
- "src/core/support/string.c",
- "src/core/support/string_posix.c",
- "src/core/support/string_win32.c",
- "src/core/support/sync.c",
- "src/core/support/sync_posix.c",
- "src/core/support/sync_win32.c",
- "src/core/support/thd.c",
- "src/core/support/thd_posix.c",
- "src/core/support/thd_win32.c",
- "src/core/support/time.c",
- "src/core/support/time_posix.c",
- "src/core/support/time_win32.c",
- ],
- hdrs = [
- "include/grpc/support/alloc.h",
- "include/grpc/support/atm.h",
- "include/grpc/support/atm_gcc_atomic.h",
- "include/grpc/support/atm_gcc_sync.h",
- "include/grpc/support/atm_win32.h",
- "include/grpc/support/cancellable_platform.h",
- "include/grpc/support/cmdline.h",
- "include/grpc/support/cpu.h",
- "include/grpc/support/histogram.h",
- "include/grpc/support/host_port.h",
- "include/grpc/support/log.h",
- "include/grpc/support/log_win32.h",
- "include/grpc/support/port_platform.h",
- "include/grpc/support/slice.h",
- "include/grpc/support/slice_buffer.h",
- "include/grpc/support/sync.h",
- "include/grpc/support/sync_generic.h",
- "include/grpc/support/sync_posix.h",
- "include/grpc/support/sync_win32.h",
- "include/grpc/support/thd.h",
- "include/grpc/support/time.h",
- "include/grpc/support/useful.h",
- ],
- includes = [
- "include",
- ".",
- ],
- deps = [
- ],
+ name = "grpc_unsecure",
+ srcs = [
+ "src/core/channel/census_filter.h",
+ "src/core/channel/channel_args.h",
+ "src/core/channel/channel_stack.h",
+ "src/core/channel/child_channel.h",
+ "src/core/channel/client_channel.h",
+ "src/core/channel/client_setup.h",
+ "src/core/channel/connected_channel.h",
+ "src/core/channel/http_client_filter.h",
+ "src/core/channel/http_filter.h",
+ "src/core/channel/http_server_filter.h",
+ "src/core/channel/metadata_buffer.h",
+ "src/core/channel/noop_filter.h",
+ "src/core/compression/algorithm.h",
+ "src/core/compression/message_compress.h",
+ "src/core/debug/trace.h",
+ "src/core/iomgr/alarm.h",
+ "src/core/iomgr/alarm_heap.h",
+ "src/core/iomgr/alarm_internal.h",
+ "src/core/iomgr/endpoint.h",
+ "src/core/iomgr/endpoint_pair.h",
+ "src/core/iomgr/fd_posix.h",
+ "src/core/iomgr/iocp_windows.h",
+ "src/core/iomgr/iomgr.h",
+ "src/core/iomgr/iomgr_internal.h",
+ "src/core/iomgr/iomgr_posix.h",
+ "src/core/iomgr/pollset.h",
+ "src/core/iomgr/pollset_kick.h",
+ "src/core/iomgr/pollset_kick_posix.h",
+ "src/core/iomgr/pollset_kick_windows.h",
+ "src/core/iomgr/pollset_posix.h",
+ "src/core/iomgr/pollset_windows.h",
+ "src/core/iomgr/resolve_address.h",
+ "src/core/iomgr/sockaddr.h",
+ "src/core/iomgr/sockaddr_posix.h",
+ "src/core/iomgr/sockaddr_utils.h",
+ "src/core/iomgr/sockaddr_win32.h",
+ "src/core/iomgr/socket_utils_posix.h",
+ "src/core/iomgr/socket_windows.h",
+ "src/core/iomgr/tcp_client.h",
+ "src/core/iomgr/tcp_posix.h",
+ "src/core/iomgr/tcp_server.h",
+ "src/core/iomgr/tcp_windows.h",
+ "src/core/iomgr/time_averaged_stats.h",
+ "src/core/iomgr/wakeup_fd_pipe.h",
+ "src/core/iomgr/wakeup_fd_posix.h",
+ "src/core/json/json.h",
+ "src/core/json/json_common.h",
+ "src/core/json/json_reader.h",
+ "src/core/json/json_writer.h",
+ "src/core/statistics/census_interface.h",
+ "src/core/statistics/census_log.h",
+ "src/core/statistics/census_rpc_stats.h",
+ "src/core/statistics/census_tracing.h",
+ "src/core/statistics/hash_table.h",
+ "src/core/statistics/window_stats.h",
+ "src/core/surface/byte_buffer_queue.h",
+ "src/core/surface/call.h",
+ "src/core/surface/channel.h",
+ "src/core/surface/client.h",
+ "src/core/surface/completion_queue.h",
+ "src/core/surface/event_string.h",
+ "src/core/surface/init.h",
+ "src/core/surface/server.h",
+ "src/core/surface/surface_trace.h",
+ "src/core/transport/chttp2/alpn.h",
+ "src/core/transport/chttp2/bin_encoder.h",
+ "src/core/transport/chttp2/frame.h",
+ "src/core/transport/chttp2/frame_data.h",
+ "src/core/transport/chttp2/frame_goaway.h",
+ "src/core/transport/chttp2/frame_ping.h",
+ "src/core/transport/chttp2/frame_rst_stream.h",
+ "src/core/transport/chttp2/frame_settings.h",
+ "src/core/transport/chttp2/frame_window_update.h",
+ "src/core/transport/chttp2/hpack_parser.h",
+ "src/core/transport/chttp2/hpack_table.h",
+ "src/core/transport/chttp2/http2_errors.h",
+ "src/core/transport/chttp2/huffsyms.h",
+ "src/core/transport/chttp2/status_conversion.h",
+ "src/core/transport/chttp2/stream_encoder.h",
+ "src/core/transport/chttp2/stream_map.h",
+ "src/core/transport/chttp2/timeout_encoding.h",
+ "src/core/transport/chttp2/varint.h",
+ "src/core/transport/chttp2_transport.h",
+ "src/core/transport/metadata.h",
+ "src/core/transport/stream_op.h",
+ "src/core/transport/transport.h",
+ "src/core/transport/transport_impl.h",
+ "src/core/surface/init_unsecure.c",
+ "src/core/channel/call_op_string.c",
+ "src/core/channel/census_filter.c",
+ "src/core/channel/channel_args.c",
+ "src/core/channel/channel_stack.c",
+ "src/core/channel/child_channel.c",
+ "src/core/channel/client_channel.c",
+ "src/core/channel/client_setup.c",
+ "src/core/channel/connected_channel.c",
+ "src/core/channel/http_client_filter.c",
+ "src/core/channel/http_filter.c",
+ "src/core/channel/http_server_filter.c",
+ "src/core/channel/metadata_buffer.c",
+ "src/core/channel/noop_filter.c",
+ "src/core/compression/algorithm.c",
+ "src/core/compression/message_compress.c",
+ "src/core/debug/trace.c",
+ "src/core/iomgr/alarm.c",
+ "src/core/iomgr/alarm_heap.c",
+ "src/core/iomgr/endpoint.c",
+ "src/core/iomgr/endpoint_pair_posix.c",
+ "src/core/iomgr/fd_posix.c",
+ "src/core/iomgr/iocp_windows.c",
+ "src/core/iomgr/iomgr.c",
+ "src/core/iomgr/iomgr_posix.c",
+ "src/core/iomgr/iomgr_windows.c",
+ "src/core/iomgr/pollset_kick.c",
+ "src/core/iomgr/pollset_multipoller_with_epoll.c",
+ "src/core/iomgr/pollset_multipoller_with_poll_posix.c",
+ "src/core/iomgr/pollset_posix.c",
+ "src/core/iomgr/pollset_windows.c",
+ "src/core/iomgr/resolve_address_posix.c",
+ "src/core/iomgr/resolve_address_windows.c",
+ "src/core/iomgr/sockaddr_utils.c",
+ "src/core/iomgr/socket_utils_common_posix.c",
+ "src/core/iomgr/socket_utils_linux.c",
+ "src/core/iomgr/socket_utils_posix.c",
+ "src/core/iomgr/socket_windows.c",
+ "src/core/iomgr/tcp_client_posix.c",
+ "src/core/iomgr/tcp_client_windows.c",
+ "src/core/iomgr/tcp_posix.c",
+ "src/core/iomgr/tcp_server_posix.c",
+ "src/core/iomgr/tcp_server_windows.c",
+ "src/core/iomgr/tcp_windows.c",
+ "src/core/iomgr/time_averaged_stats.c",
+ "src/core/iomgr/wakeup_fd_eventfd.c",
+ "src/core/iomgr/wakeup_fd_nospecial.c",
+ "src/core/iomgr/wakeup_fd_pipe.c",
+ "src/core/iomgr/wakeup_fd_posix.c",
+ "src/core/json/json.c",
+ "src/core/json/json_reader.c",
+ "src/core/json/json_string.c",
+ "src/core/json/json_writer.c",
+ "src/core/statistics/census_init.c",
+ "src/core/statistics/census_log.c",
+ "src/core/statistics/census_rpc_stats.c",
+ "src/core/statistics/census_tracing.c",
+ "src/core/statistics/hash_table.c",
+ "src/core/statistics/window_stats.c",
+ "src/core/surface/byte_buffer.c",
+ "src/core/surface/byte_buffer_queue.c",
+ "src/core/surface/byte_buffer_reader.c",
+ "src/core/surface/call.c",
+ "src/core/surface/call_details.c",
+ "src/core/surface/call_log_batch.c",
+ "src/core/surface/channel.c",
+ "src/core/surface/channel_create.c",
+ "src/core/surface/client.c",
+ "src/core/surface/completion_queue.c",
+ "src/core/surface/event_string.c",
+ "src/core/surface/init.c",
+ "src/core/surface/lame_client.c",
+ "src/core/surface/metadata_array.c",
+ "src/core/surface/server.c",
+ "src/core/surface/server_chttp2.c",
+ "src/core/surface/server_create.c",
+ "src/core/surface/surface_trace.c",
+ "src/core/transport/chttp2/alpn.c",
+ "src/core/transport/chttp2/bin_encoder.c",
+ "src/core/transport/chttp2/frame_data.c",
+ "src/core/transport/chttp2/frame_goaway.c",
+ "src/core/transport/chttp2/frame_ping.c",
+ "src/core/transport/chttp2/frame_rst_stream.c",
+ "src/core/transport/chttp2/frame_settings.c",
+ "src/core/transport/chttp2/frame_window_update.c",
+ "src/core/transport/chttp2/hpack_parser.c",
+ "src/core/transport/chttp2/hpack_table.c",
+ "src/core/transport/chttp2/huffsyms.c",
+ "src/core/transport/chttp2/status_conversion.c",
+ "src/core/transport/chttp2/stream_encoder.c",
+ "src/core/transport/chttp2/stream_map.c",
+ "src/core/transport/chttp2/timeout_encoding.c",
+ "src/core/transport/chttp2/varint.c",
+ "src/core/transport/chttp2_transport.c",
+ "src/core/transport/metadata.c",
+ "src/core/transport/stream_op.c",
+ "src/core/transport/transport.c",
+ ],
+ hdrs = [
+ "include/grpc/byte_buffer.h",
+ "include/grpc/byte_buffer_reader.h",
+ "include/grpc/grpc.h",
+ "include/grpc/grpc_http.h",
+ "include/grpc/status.h",
+ ],
+ includes = [
+ "include",
+ ".",
+ ],
+ deps = [
+ ":gpr",
+ ],
)
+cc_library(
+ name = "grpc++",
+ srcs = [
+ "src/cpp/client/secure_credentials.h",
+ "src/cpp/server/secure_server_credentials.h",
+ "src/cpp/client/channel.h",
+ "src/cpp/proto/proto_utils.h",
+ "src/cpp/server/thread_pool.h",
+ "src/cpp/util/time.h",
+ "src/cpp/client/secure_credentials.cc",
+ "src/cpp/server/secure_server_credentials.cc",
+ "src/cpp/client/channel.cc",
+ "src/cpp/client/channel_arguments.cc",
+ "src/cpp/client/client_context.cc",
+ "src/cpp/client/client_unary_call.cc",
+ "src/cpp/client/create_channel.cc",
+ "src/cpp/client/credentials.cc",
+ "src/cpp/client/generic_stub.cc",
+ "src/cpp/client/insecure_credentials.cc",
+ "src/cpp/client/internal_stub.cc",
+ "src/cpp/common/call.cc",
+ "src/cpp/common/completion_queue.cc",
+ "src/cpp/common/rpc_method.cc",
+ "src/cpp/proto/proto_utils.cc",
+ "src/cpp/server/async_generic_service.cc",
+ "src/cpp/server/insecure_server_credentials.cc",
+ "src/cpp/server/server.cc",
+ "src/cpp/server/server_builder.cc",
+ "src/cpp/server/server_context.cc",
+ "src/cpp/server/server_credentials.cc",
+ "src/cpp/server/thread_pool.cc",
+ "src/cpp/util/byte_buffer.cc",
+ "src/cpp/util/slice.cc",
+ "src/cpp/util/status.cc",
+ "src/cpp/util/time.cc",
+ ],
+ hdrs = [
+ "include/grpc++/async_generic_service.h",
+ "include/grpc++/async_unary_call.h",
+ "include/grpc++/byte_buffer.h",
+ "include/grpc++/channel_arguments.h",
+ "include/grpc++/channel_interface.h",
+ "include/grpc++/client_context.h",
+ "include/grpc++/completion_queue.h",
+ "include/grpc++/config.h",
+ "include/grpc++/create_channel.h",
+ "include/grpc++/credentials.h",
+ "include/grpc++/generic_stub.h",
+ "include/grpc++/impl/call.h",
+ "include/grpc++/impl/client_unary_call.h",
+ "include/grpc++/impl/internal_stub.h",
+ "include/grpc++/impl/rpc_method.h",
+ "include/grpc++/impl/rpc_service_method.h",
+ "include/grpc++/impl/service_type.h",
+ "include/grpc++/server.h",
+ "include/grpc++/server_builder.h",
+ "include/grpc++/server_context.h",
+ "include/grpc++/server_credentials.h",
+ "include/grpc++/slice.h",
+ "include/grpc++/status.h",
+ "include/grpc++/status_code_enum.h",
+ "include/grpc++/stream.h",
+ "include/grpc++/thread_pool_interface.h",
+ ],
+ includes = [
+ "include",
+ ".",
+ ],
+ deps = [
+ "//external:protobuf_clib",
+ ":gpr",
+ ":grpc",
+ ],
+)
cc_library(
- name = "grpc",
- srcs = [
- "src/core/httpcli/format_request.h",
- "src/core/httpcli/httpcli.h",
- "src/core/httpcli/httpcli_security_context.h",
- "src/core/httpcli/parser.h",
- "src/core/security/auth.h",
- "src/core/security/base64.h",
- "src/core/security/credentials.h",
- "src/core/security/json_token.h",
- "src/core/security/secure_endpoint.h",
- "src/core/security/secure_transport_setup.h",
- "src/core/security/security_context.h",
- "src/core/tsi/fake_transport_security.h",
- "src/core/tsi/ssl_transport_security.h",
- "src/core/tsi/transport_security.h",
- "src/core/tsi/transport_security_interface.h",
- "src/core/channel/census_filter.h",
- "src/core/channel/channel_args.h",
- "src/core/channel/channel_stack.h",
- "src/core/channel/child_channel.h",
- "src/core/channel/client_channel.h",
- "src/core/channel/client_setup.h",
- "src/core/channel/connected_channel.h",
- "src/core/channel/http_client_filter.h",
- "src/core/channel/http_filter.h",
- "src/core/channel/http_server_filter.h",
- "src/core/channel/metadata_buffer.h",
- "src/core/channel/noop_filter.h",
- "src/core/compression/algorithm.h",
- "src/core/compression/message_compress.h",
- "src/core/debug/trace.h",
- "src/core/iomgr/alarm.h",
- "src/core/iomgr/alarm_heap.h",
- "src/core/iomgr/alarm_internal.h",
- "src/core/iomgr/endpoint.h",
- "src/core/iomgr/endpoint_pair.h",
- "src/core/iomgr/fd_posix.h",
- "src/core/iomgr/iocp_windows.h",
- "src/core/iomgr/iomgr.h",
- "src/core/iomgr/iomgr_internal.h",
- "src/core/iomgr/iomgr_posix.h",
- "src/core/iomgr/pollset.h",
- "src/core/iomgr/pollset_kick.h",
- "src/core/iomgr/pollset_kick_posix.h",
- "src/core/iomgr/pollset_kick_windows.h",
- "src/core/iomgr/pollset_posix.h",
- "src/core/iomgr/pollset_windows.h",
- "src/core/iomgr/resolve_address.h",
- "src/core/iomgr/sockaddr.h",
- "src/core/iomgr/sockaddr_posix.h",
- "src/core/iomgr/sockaddr_utils.h",
- "src/core/iomgr/sockaddr_win32.h",
- "src/core/iomgr/socket_utils_posix.h",
- "src/core/iomgr/socket_windows.h",
- "src/core/iomgr/tcp_client.h",
- "src/core/iomgr/tcp_posix.h",
- "src/core/iomgr/tcp_server.h",
- "src/core/iomgr/tcp_windows.h",
- "src/core/iomgr/time_averaged_stats.h",
- "src/core/iomgr/wakeup_fd_pipe.h",
- "src/core/iomgr/wakeup_fd_posix.h",
- "src/core/json/json.h",
- "src/core/json/json_common.h",
- "src/core/json/json_reader.h",
- "src/core/json/json_writer.h",
- "src/core/statistics/census_interface.h",
- "src/core/statistics/census_log.h",
- "src/core/statistics/census_rpc_stats.h",
- "src/core/statistics/census_tracing.h",
- "src/core/statistics/hash_table.h",
- "src/core/statistics/window_stats.h",
- "src/core/surface/byte_buffer_queue.h",
- "src/core/surface/call.h",
- "src/core/surface/channel.h",
- "src/core/surface/client.h",
- "src/core/surface/completion_queue.h",
- "src/core/surface/event_string.h",
- "src/core/surface/init.h",
- "src/core/surface/server.h",
- "src/core/surface/surface_trace.h",
- "src/core/transport/chttp2/alpn.h",
- "src/core/transport/chttp2/bin_encoder.h",
- "src/core/transport/chttp2/frame.h",
- "src/core/transport/chttp2/frame_data.h",
- "src/core/transport/chttp2/frame_goaway.h",
- "src/core/transport/chttp2/frame_ping.h",
- "src/core/transport/chttp2/frame_rst_stream.h",
- "src/core/transport/chttp2/frame_settings.h",
- "src/core/transport/chttp2/frame_window_update.h",
- "src/core/transport/chttp2/hpack_parser.h",
- "src/core/transport/chttp2/hpack_table.h",
- "src/core/transport/chttp2/http2_errors.h",
- "src/core/transport/chttp2/huffsyms.h",
- "src/core/transport/chttp2/status_conversion.h",
- "src/core/transport/chttp2/stream_encoder.h",
- "src/core/transport/chttp2/stream_map.h",
- "src/core/transport/chttp2/timeout_encoding.h",
- "src/core/transport/chttp2/varint.h",
- "src/core/transport/chttp2_transport.h",
- "src/core/transport/metadata.h",
- "src/core/transport/stream_op.h",
- "src/core/transport/transport.h",
- "src/core/transport/transport_impl.h",
- "src/core/httpcli/format_request.c",
- "src/core/httpcli/httpcli.c",
- "src/core/httpcli/httpcli_security_context.c",
- "src/core/httpcli/parser.c",
- "src/core/security/auth.c",
- "src/core/security/base64.c",
- "src/core/security/credentials.c",
- "src/core/security/credentials_posix.c",
- "src/core/security/credentials_win32.c",
- "src/core/security/factories.c",
- "src/core/security/google_default_credentials.c",
- "src/core/security/json_token.c",
- "src/core/security/secure_endpoint.c",
- "src/core/security/secure_transport_setup.c",
- "src/core/security/security_context.c",
- "src/core/security/server_secure_chttp2.c",
- "src/core/surface/init_secure.c",
- "src/core/surface/secure_channel_create.c",
- "src/core/tsi/fake_transport_security.c",
- "src/core/tsi/ssl_transport_security.c",
- "src/core/tsi/transport_security.c",
- "src/core/channel/call_op_string.c",
- "src/core/channel/census_filter.c",
- "src/core/channel/channel_args.c",
- "src/core/channel/channel_stack.c",
- "src/core/channel/child_channel.c",
- "src/core/channel/client_channel.c",
- "src/core/channel/client_setup.c",
- "src/core/channel/connected_channel.c",
- "src/core/channel/http_client_filter.c",
- "src/core/channel/http_filter.c",
- "src/core/channel/http_server_filter.c",
- "src/core/channel/metadata_buffer.c",
- "src/core/channel/noop_filter.c",
- "src/core/compression/algorithm.c",
- "src/core/compression/message_compress.c",
- "src/core/debug/trace.c",
- "src/core/iomgr/alarm.c",
- "src/core/iomgr/alarm_heap.c",
- "src/core/iomgr/endpoint.c",
- "src/core/iomgr/endpoint_pair_posix.c",
- "src/core/iomgr/fd_posix.c",
- "src/core/iomgr/iocp_windows.c",
- "src/core/iomgr/iomgr.c",
- "src/core/iomgr/iomgr_posix.c",
- "src/core/iomgr/iomgr_windows.c",
- "src/core/iomgr/pollset_kick.c",
- "src/core/iomgr/pollset_multipoller_with_epoll.c",
- "src/core/iomgr/pollset_multipoller_with_poll_posix.c",
- "src/core/iomgr/pollset_posix.c",
- "src/core/iomgr/pollset_windows.c",
- "src/core/iomgr/resolve_address_posix.c",
- "src/core/iomgr/resolve_address_windows.c",
- "src/core/iomgr/sockaddr_utils.c",
- "src/core/iomgr/socket_utils_common_posix.c",
- "src/core/iomgr/socket_utils_linux.c",
- "src/core/iomgr/socket_utils_posix.c",
- "src/core/iomgr/socket_windows.c",
- "src/core/iomgr/tcp_client_posix.c",
- "src/core/iomgr/tcp_client_windows.c",
- "src/core/iomgr/tcp_posix.c",
- "src/core/iomgr/tcp_server_posix.c",
- "src/core/iomgr/tcp_server_windows.c",
- "src/core/iomgr/tcp_windows.c",
- "src/core/iomgr/time_averaged_stats.c",
- "src/core/iomgr/wakeup_fd_eventfd.c",
- "src/core/iomgr/wakeup_fd_nospecial.c",
- "src/core/iomgr/wakeup_fd_pipe.c",
- "src/core/iomgr/wakeup_fd_posix.c",
- "src/core/json/json.c",
- "src/core/json/json_reader.c",
- "src/core/json/json_string.c",
- "src/core/json/json_writer.c",
- "src/core/statistics/census_init.c",
- "src/core/statistics/census_log.c",
- "src/core/statistics/census_rpc_stats.c",
- "src/core/statistics/census_tracing.c",
- "src/core/statistics/hash_table.c",
- "src/core/statistics/window_stats.c",
- "src/core/surface/byte_buffer.c",
- "src/core/surface/byte_buffer_queue.c",
- "src/core/surface/byte_buffer_reader.c",
- "src/core/surface/call.c",
- "src/core/surface/call_details.c",
- "src/core/surface/call_log_batch.c",
- "src/core/surface/channel.c",
- "src/core/surface/channel_create.c",
- "src/core/surface/client.c",
- "src/core/surface/completion_queue.c",
- "src/core/surface/event_string.c",
- "src/core/surface/init.c",
- "src/core/surface/lame_client.c",
- "src/core/surface/metadata_array.c",
- "src/core/surface/server.c",
- "src/core/surface/server_chttp2.c",
- "src/core/surface/server_create.c",
- "src/core/surface/surface_trace.c",
- "src/core/transport/chttp2/alpn.c",
- "src/core/transport/chttp2/bin_encoder.c",
- "src/core/transport/chttp2/frame_data.c",
- "src/core/transport/chttp2/frame_goaway.c",
- "src/core/transport/chttp2/frame_ping.c",
- "src/core/transport/chttp2/frame_rst_stream.c",
- "src/core/transport/chttp2/frame_settings.c",
- "src/core/transport/chttp2/frame_window_update.c",
- "src/core/transport/chttp2/hpack_parser.c",
- "src/core/transport/chttp2/hpack_table.c",
- "src/core/transport/chttp2/huffsyms.c",
- "src/core/transport/chttp2/status_conversion.c",
- "src/core/transport/chttp2/stream_encoder.c",
- "src/core/transport/chttp2/stream_map.c",
- "src/core/transport/chttp2/timeout_encoding.c",
- "src/core/transport/chttp2/varint.c",
- "src/core/transport/chttp2_transport.c",
- "src/core/transport/metadata.c",
- "src/core/transport/stream_op.c",
- "src/core/transport/transport.c",
- ],
- hdrs = [
- "include/grpc/grpc_security.h",
- "include/grpc/byte_buffer.h",
- "include/grpc/byte_buffer_reader.h",
- "include/grpc/grpc.h",
- "include/grpc/grpc_http.h",
- "include/grpc/status.h",
- ],
- includes = [
- "include",
- ".",
- ],
- deps = [
- ":gpr",
- ],
+ name = "grpc++_unsecure",
+ srcs = [
+ "src/cpp/client/channel.h",
+ "src/cpp/proto/proto_utils.h",
+ "src/cpp/server/thread_pool.h",
+ "src/cpp/util/time.h",
+ "src/cpp/client/channel.cc",
+ "src/cpp/client/channel_arguments.cc",
+ "src/cpp/client/client_context.cc",
+ "src/cpp/client/client_unary_call.cc",
+ "src/cpp/client/create_channel.cc",
+ "src/cpp/client/credentials.cc",
+ "src/cpp/client/generic_stub.cc",
+ "src/cpp/client/insecure_credentials.cc",
+ "src/cpp/client/internal_stub.cc",
+ "src/cpp/common/call.cc",
+ "src/cpp/common/completion_queue.cc",
+ "src/cpp/common/rpc_method.cc",
+ "src/cpp/proto/proto_utils.cc",
+ "src/cpp/server/async_generic_service.cc",
+ "src/cpp/server/insecure_server_credentials.cc",
+ "src/cpp/server/server.cc",
+ "src/cpp/server/server_builder.cc",
+ "src/cpp/server/server_context.cc",
+ "src/cpp/server/server_credentials.cc",
+ "src/cpp/server/thread_pool.cc",
+ "src/cpp/util/byte_buffer.cc",
+ "src/cpp/util/slice.cc",
+ "src/cpp/util/status.cc",
+ "src/cpp/util/time.cc",
+ ],
+ hdrs = [
+ "include/grpc++/async_generic_service.h",
+ "include/grpc++/async_unary_call.h",
+ "include/grpc++/byte_buffer.h",
+ "include/grpc++/channel_arguments.h",
+ "include/grpc++/channel_interface.h",
+ "include/grpc++/client_context.h",
+ "include/grpc++/completion_queue.h",
+ "include/grpc++/config.h",
+ "include/grpc++/create_channel.h",
+ "include/grpc++/credentials.h",
+ "include/grpc++/generic_stub.h",
+ "include/grpc++/impl/call.h",
+ "include/grpc++/impl/client_unary_call.h",
+ "include/grpc++/impl/internal_stub.h",
+ "include/grpc++/impl/rpc_method.h",
+ "include/grpc++/impl/rpc_service_method.h",
+ "include/grpc++/impl/service_type.h",
+ "include/grpc++/server.h",
+ "include/grpc++/server_builder.h",
+ "include/grpc++/server_context.h",
+ "include/grpc++/server_credentials.h",
+ "include/grpc++/slice.h",
+ "include/grpc++/status.h",
+ "include/grpc++/status_code_enum.h",
+ "include/grpc++/stream.h",
+ "include/grpc++/thread_pool_interface.h",
+ ],
+ includes = [
+ "include",
+ ".",
+ ],
+ deps = [
+ "//external:protobuf_clib",
+ ":gpr",
+ ":grpc_unsecure",
+ ],
)
+cc_library(
+ name = "grpc_plugin_support",
+ srcs = [
+ "src/compiler/config.h",
+ "src/compiler/cpp_generator.h",
+ "src/compiler/cpp_generator_helpers.h",
+ "src/compiler/generator_helpers.h",
+ "src/compiler/objective_c_generator.h",
+ "src/compiler/objective_c_generator_helpers.h",
+ "src/compiler/python_generator.h",
+ "src/compiler/ruby_generator.h",
+ "src/compiler/ruby_generator_helpers-inl.h",
+ "src/compiler/ruby_generator_map-inl.h",
+ "src/compiler/ruby_generator_string-inl.h",
+ "src/compiler/cpp_generator.cc",
+ "src/compiler/objective_c_generator.cc",
+ "src/compiler/python_generator.cc",
+ "src/compiler/ruby_generator.cc",
+ ],
+ hdrs = [
+ ],
+ includes = [
+ "include",
+ ".",
+ ],
+ deps = [
+ "//external:protobuf_compiler",
+ ],
+)
cc_library(
- name = "grpc_unsecure",
- srcs = [
- "src/core/channel/census_filter.h",
- "src/core/channel/channel_args.h",
- "src/core/channel/channel_stack.h",
- "src/core/channel/child_channel.h",
- "src/core/channel/client_channel.h",
- "src/core/channel/client_setup.h",
- "src/core/channel/connected_channel.h",
- "src/core/channel/http_client_filter.h",
- "src/core/channel/http_filter.h",
- "src/core/channel/http_server_filter.h",
- "src/core/channel/metadata_buffer.h",
- "src/core/channel/noop_filter.h",
- "src/core/compression/algorithm.h",
- "src/core/compression/message_compress.h",
- "src/core/debug/trace.h",
- "src/core/iomgr/alarm.h",
- "src/core/iomgr/alarm_heap.h",
- "src/core/iomgr/alarm_internal.h",
- "src/core/iomgr/endpoint.h",
- "src/core/iomgr/endpoint_pair.h",
- "src/core/iomgr/fd_posix.h",
- "src/core/iomgr/iocp_windows.h",
- "src/core/iomgr/iomgr.h",
- "src/core/iomgr/iomgr_internal.h",
- "src/core/iomgr/iomgr_posix.h",
- "src/core/iomgr/pollset.h",
- "src/core/iomgr/pollset_kick.h",
- "src/core/iomgr/pollset_kick_posix.h",
- "src/core/iomgr/pollset_kick_windows.h",
- "src/core/iomgr/pollset_posix.h",
- "src/core/iomgr/pollset_windows.h",
- "src/core/iomgr/resolve_address.h",
- "src/core/iomgr/sockaddr.h",
- "src/core/iomgr/sockaddr_posix.h",
- "src/core/iomgr/sockaddr_utils.h",
- "src/core/iomgr/sockaddr_win32.h",
- "src/core/iomgr/socket_utils_posix.h",
- "src/core/iomgr/socket_windows.h",
- "src/core/iomgr/tcp_client.h",
- "src/core/iomgr/tcp_posix.h",
- "src/core/iomgr/tcp_server.h",
- "src/core/iomgr/tcp_windows.h",
- "src/core/iomgr/time_averaged_stats.h",
- "src/core/iomgr/wakeup_fd_pipe.h",
- "src/core/iomgr/wakeup_fd_posix.h",
- "src/core/json/json.h",
- "src/core/json/json_common.h",
- "src/core/json/json_reader.h",
- "src/core/json/json_writer.h",
- "src/core/statistics/census_interface.h",
- "src/core/statistics/census_log.h",
- "src/core/statistics/census_rpc_stats.h",
- "src/core/statistics/census_tracing.h",
- "src/core/statistics/hash_table.h",
- "src/core/statistics/window_stats.h",
- "src/core/surface/byte_buffer_queue.h",
- "src/core/surface/call.h",
- "src/core/surface/channel.h",
- "src/core/surface/client.h",
- "src/core/surface/completion_queue.h",
- "src/core/surface/event_string.h",
- "src/core/surface/init.h",
- "src/core/surface/server.h",
- "src/core/surface/surface_trace.h",
- "src/core/transport/chttp2/alpn.h",
- "src/core/transport/chttp2/bin_encoder.h",
- "src/core/transport/chttp2/frame.h",
- "src/core/transport/chttp2/frame_data.h",
- "src/core/transport/chttp2/frame_goaway.h",
- "src/core/transport/chttp2/frame_ping.h",
- "src/core/transport/chttp2/frame_rst_stream.h",
- "src/core/transport/chttp2/frame_settings.h",
- "src/core/transport/chttp2/frame_window_update.h",
- "src/core/transport/chttp2/hpack_parser.h",
- "src/core/transport/chttp2/hpack_table.h",
- "src/core/transport/chttp2/http2_errors.h",
- "src/core/transport/chttp2/huffsyms.h",
- "src/core/transport/chttp2/status_conversion.h",
- "src/core/transport/chttp2/stream_encoder.h",
- "src/core/transport/chttp2/stream_map.h",
- "src/core/transport/chttp2/timeout_encoding.h",
- "src/core/transport/chttp2/varint.h",
- "src/core/transport/chttp2_transport.h",
- "src/core/transport/metadata.h",
- "src/core/transport/stream_op.h",
- "src/core/transport/transport.h",
- "src/core/transport/transport_impl.h",
- "src/core/surface/init_unsecure.c",
- "src/core/channel/call_op_string.c",
- "src/core/channel/census_filter.c",
- "src/core/channel/channel_args.c",
- "src/core/channel/channel_stack.c",
- "src/core/channel/child_channel.c",
- "src/core/channel/client_channel.c",
- "src/core/channel/client_setup.c",
- "src/core/channel/connected_channel.c",
- "src/core/channel/http_client_filter.c",
- "src/core/channel/http_filter.c",
- "src/core/channel/http_server_filter.c",
- "src/core/channel/metadata_buffer.c",
- "src/core/channel/noop_filter.c",
- "src/core/compression/algorithm.c",
- "src/core/compression/message_compress.c",
- "src/core/debug/trace.c",
- "src/core/iomgr/alarm.c",
- "src/core/iomgr/alarm_heap.c",
- "src/core/iomgr/endpoint.c",
- "src/core/iomgr/endpoint_pair_posix.c",
- "src/core/iomgr/fd_posix.c",
- "src/core/iomgr/iocp_windows.c",
- "src/core/iomgr/iomgr.c",
- "src/core/iomgr/iomgr_posix.c",
- "src/core/iomgr/iomgr_windows.c",
- "src/core/iomgr/pollset_kick.c",
- "src/core/iomgr/pollset_multipoller_with_epoll.c",
- "src/core/iomgr/pollset_multipoller_with_poll_posix.c",
- "src/core/iomgr/pollset_posix.c",
- "src/core/iomgr/pollset_windows.c",
- "src/core/iomgr/resolve_address_posix.c",
- "src/core/iomgr/resolve_address_windows.c",
- "src/core/iomgr/sockaddr_utils.c",
- "src/core/iomgr/socket_utils_common_posix.c",
- "src/core/iomgr/socket_utils_linux.c",
- "src/core/iomgr/socket_utils_posix.c",
- "src/core/iomgr/socket_windows.c",
- "src/core/iomgr/tcp_client_posix.c",
- "src/core/iomgr/tcp_client_windows.c",
- "src/core/iomgr/tcp_posix.c",
- "src/core/iomgr/tcp_server_posix.c",
- "src/core/iomgr/tcp_server_windows.c",
- "src/core/iomgr/tcp_windows.c",
- "src/core/iomgr/time_averaged_stats.c",
- "src/core/iomgr/wakeup_fd_eventfd.c",
- "src/core/iomgr/wakeup_fd_nospecial.c",
- "src/core/iomgr/wakeup_fd_pipe.c",
- "src/core/iomgr/wakeup_fd_posix.c",
- "src/core/json/json.c",
- "src/core/json/json_reader.c",
- "src/core/json/json_string.c",
- "src/core/json/json_writer.c",
- "src/core/statistics/census_init.c",
- "src/core/statistics/census_log.c",
- "src/core/statistics/census_rpc_stats.c",
- "src/core/statistics/census_tracing.c",
- "src/core/statistics/hash_table.c",
- "src/core/statistics/window_stats.c",
- "src/core/surface/byte_buffer.c",
- "src/core/surface/byte_buffer_queue.c",
- "src/core/surface/byte_buffer_reader.c",
- "src/core/surface/call.c",
- "src/core/surface/call_details.c",
- "src/core/surface/call_log_batch.c",
- "src/core/surface/channel.c",
- "src/core/surface/channel_create.c",
- "src/core/surface/client.c",
- "src/core/surface/completion_queue.c",
- "src/core/surface/event_string.c",
- "src/core/surface/init.c",
- "src/core/surface/lame_client.c",
- "src/core/surface/metadata_array.c",
- "src/core/surface/server.c",
- "src/core/surface/server_chttp2.c",
- "src/core/surface/server_create.c",
- "src/core/surface/surface_trace.c",
- "src/core/transport/chttp2/alpn.c",
- "src/core/transport/chttp2/bin_encoder.c",
- "src/core/transport/chttp2/frame_data.c",
- "src/core/transport/chttp2/frame_goaway.c",
- "src/core/transport/chttp2/frame_ping.c",
- "src/core/transport/chttp2/frame_rst_stream.c",
- "src/core/transport/chttp2/frame_settings.c",
- "src/core/transport/chttp2/frame_window_update.c",
- "src/core/transport/chttp2/hpack_parser.c",
- "src/core/transport/chttp2/hpack_table.c",
- "src/core/transport/chttp2/huffsyms.c",
- "src/core/transport/chttp2/status_conversion.c",
- "src/core/transport/chttp2/stream_encoder.c",
- "src/core/transport/chttp2/stream_map.c",
- "src/core/transport/chttp2/timeout_encoding.c",
- "src/core/transport/chttp2/varint.c",
- "src/core/transport/chttp2_transport.c",
- "src/core/transport/metadata.c",
- "src/core/transport/stream_op.c",
- "src/core/transport/transport.c",
- ],
- hdrs = [
- "include/grpc/byte_buffer.h",
- "include/grpc/byte_buffer_reader.h",
- "include/grpc/grpc.h",
- "include/grpc/grpc_http.h",
- "include/grpc/status.h",
- ],
- includes = [
- "include",
- ".",
- ],
- deps = [
- ":gpr",
- ],
+ name = "grpc_csharp_ext",
+ srcs = [
+ "src/csharp/ext/grpc_csharp_ext.c",
+ ],
+ hdrs = [
+ ],
+ includes = [
+ "include",
+ ".",
+ ],
+ deps = [
+ ":gpr",
+ ":grpc",
+ ],
)
+cc_binary(
+ name = "grpc_cpp_plugin",
+ srcs = [
+ "src/compiler/cpp_plugin.cc",
+ ],
+ deps = [
+ "//external:protobuf_compiler",
+ ":grpc_plugin_support",
+ ],
+)
+
+
+cc_binary(
+ name = "grpc_objective_c_plugin",
+ srcs = [
+ "src/compiler/objective_c_plugin.cc",
+ ],
+ deps = [
+ "//external:protobuf_compiler",
+ ":grpc_plugin_support",
+ ],
+)
+
+
+cc_binary(
+ name = "grpc_python_plugin",
+ srcs = [
+ "src/compiler/python_plugin.cc",
+ ],
+ deps = [
+ "//external:protobuf_compiler",
+ ":grpc_plugin_support",
+ ],
+)
+
+
+cc_binary(
+ name = "grpc_ruby_plugin",
+ srcs = [
+ "src/compiler/ruby_plugin.cc",
+ ],
+ deps = [
+ "//external:protobuf_compiler",
+ ":grpc_plugin_support",
+ ],
+)
+
+
+
+
diff --git a/Makefile b/Makefile
index e4f1b5dd67..20e5e369b6 100644
--- a/Makefile
+++ b/Makefile
@@ -642,6 +642,7 @@ pubsub_client: $(BINDIR)/$(CONFIG)/pubsub_client
pubsub_publisher_test: $(BINDIR)/$(CONFIG)/pubsub_publisher_test
pubsub_subscriber_test: $(BINDIR)/$(CONFIG)/pubsub_subscriber_test
qps_driver: $(BINDIR)/$(CONFIG)/qps_driver
+qps_smoke_test: $(BINDIR)/$(CONFIG)/qps_smoke_test
qps_worker: $(BINDIR)/$(CONFIG)/qps_worker
status_test: $(BINDIR)/$(CONFIG)/status_test
thread_pool_test: $(BINDIR)/$(CONFIG)/thread_pool_test
@@ -1076,13 +1077,13 @@ privatelibs: privatelibs_c privatelibs_cxx
privatelibs_c: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_chttp2_fake_security.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_chttp2_fullstack.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_chttp2_fullstack_uds.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_chttp2_simple_ssl_fullstack.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_chttp2_simple_ssl_with_oauth2_fullstack.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_chttp2_socket_pair.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_chttp2_socket_pair_one_byte_at_a_time.a $(LIBDIR)/$(CONFIG)/libend2end_test_bad_hostname.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_after_accept.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_after_accept_and_writes_closed.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_after_invoke.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_before_invoke.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_in_a_vacuum.a $(LIBDIR)/$(CONFIG)/libend2end_test_census_simple_request.a $(LIBDIR)/$(CONFIG)/libend2end_test_disappearing_server.a $(LIBDIR)/$(CONFIG)/libend2end_test_early_server_shutdown_finishes_inflight_calls.a $(LIBDIR)/$(CONFIG)/libend2end_test_early_server_shutdown_finishes_tags.a $(LIBDIR)/$(CONFIG)/libend2end_test_empty_batch.a $(LIBDIR)/$(CONFIG)/libend2end_test_graceful_server_shutdown.a $(LIBDIR)/$(CONFIG)/libend2end_test_invoke_large_request.a $(LIBDIR)/$(CONFIG)/libend2end_test_max_concurrent_streams.a $(LIBDIR)/$(CONFIG)/libend2end_test_no_op.a $(LIBDIR)/$(CONFIG)/libend2end_test_ping_pong_streaming.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_response_with_binary_metadata_and_payload.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_response_with_metadata_and_payload.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_response_with_payload.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_with_large_metadata.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_with_payload.a $(LIBDIR)/$(CONFIG)/libend2end_test_simple_delayed_request.a $(LIBDIR)/$(CONFIG)/libend2end_test_simple_request.a $(LIBDIR)/$(CONFIG)/libend2end_test_thread_stress.a $(LIBDIR)/$(CONFIG)/libend2end_test_writes_done_hangs_with_pending_read.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_after_accept_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_after_accept_and_writes_closed_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_after_invoke_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_before_invoke_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_in_a_vacuum_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_census_simple_request_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_disappearing_server_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_early_server_shutdown_finishes_inflight_calls_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_early_server_shutdown_finishes_tags_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_graceful_server_shutdown_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_invoke_large_request_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_max_concurrent_streams_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_no_op_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_ping_pong_streaming_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_response_with_binary_metadata_and_payload_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_response_with_metadata_and_payload_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_response_with_payload_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_response_with_trailing_metadata_and_payload_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_with_large_metadata_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_with_payload_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_simple_delayed_request_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_simple_request_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_thread_stress_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_writes_done_hangs_with_pending_read_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a
-privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libpubsub_client_lib.a $(LIBDIR)/$(CONFIG)/libqps.a
+privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libinterop_client_lib.a $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBDIR)/$(CONFIG)/libpubsub_client_lib.a $(LIBDIR)/$(CONFIG)/libqps.a
buildtests: buildtests_c buildtests_cxx
buildtests_c: privatelibs_c $(BINDIR)/$(CONFIG)/alarm_heap_test $(BINDIR)/$(CONFIG)/alarm_list_test $(BINDIR)/$(CONFIG)/alarm_test $(BINDIR)/$(CONFIG)/alpn_test $(BINDIR)/$(CONFIG)/bin_encoder_test $(BINDIR)/$(CONFIG)/census_hash_table_test $(BINDIR)/$(CONFIG)/census_statistics_multiple_writers_circular_buffer_test $(BINDIR)/$(CONFIG)/census_statistics_multiple_writers_test $(BINDIR)/$(CONFIG)/census_statistics_performance_test $(BINDIR)/$(CONFIG)/census_statistics_quick_test $(BINDIR)/$(CONFIG)/census_statistics_small_log_test $(BINDIR)/$(CONFIG)/census_stub_test $(BINDIR)/$(CONFIG)/census_window_stats_test $(BINDIR)/$(CONFIG)/chttp2_status_conversion_test $(BINDIR)/$(CONFIG)/chttp2_stream_encoder_test $(BINDIR)/$(CONFIG)/chttp2_stream_map_test $(BINDIR)/$(CONFIG)/chttp2_transport_end2end_test $(BINDIR)/$(CONFIG)/dualstack_socket_test $(BINDIR)/$(CONFIG)/echo_client $(BINDIR)/$(CONFIG)/echo_server $(BINDIR)/$(CONFIG)/echo_test $(BINDIR)/$(CONFIG)/fd_posix_test $(BINDIR)/$(CONFIG)/fling_client $(BINDIR)/$(CONFIG)/fling_server $(BINDIR)/$(CONFIG)/fling_stream_test $(BINDIR)/$(CONFIG)/fling_test $(BINDIR)/$(CONFIG)/gpr_cancellable_test $(BINDIR)/$(CONFIG)/gpr_cmdline_test $(BINDIR)/$(CONFIG)/gpr_env_test $(BINDIR)/$(CONFIG)/gpr_file_test $(BINDIR)/$(CONFIG)/gpr_histogram_test $(BINDIR)/$(CONFIG)/gpr_host_port_test $(BINDIR)/$(CONFIG)/gpr_log_test $(BINDIR)/$(CONFIG)/gpr_slice_buffer_test $(BINDIR)/$(CONFIG)/gpr_slice_test $(BINDIR)/$(CONFIG)/gpr_string_test $(BINDIR)/$(CONFIG)/gpr_sync_test $(BINDIR)/$(CONFIG)/gpr_thd_test $(BINDIR)/$(CONFIG)/gpr_time_test $(BINDIR)/$(CONFIG)/gpr_tls_test $(BINDIR)/$(CONFIG)/gpr_useful_test $(BINDIR)/$(CONFIG)/grpc_base64_test $(BINDIR)/$(CONFIG)/grpc_byte_buffer_reader_test $(BINDIR)/$(CONFIG)/grpc_channel_stack_test $(BINDIR)/$(CONFIG)/grpc_completion_queue_test $(BINDIR)/$(CONFIG)/grpc_credentials_test $(BINDIR)/$(CONFIG)/grpc_json_token_test $(BINDIR)/$(CONFIG)/grpc_stream_op_test $(BINDIR)/$(CONFIG)/hpack_parser_test $(BINDIR)/$(CONFIG)/hpack_table_test $(BINDIR)/$(CONFIG)/httpcli_format_request_test $(BINDIR)/$(CONFIG)/httpcli_parser_test $(BINDIR)/$(CONFIG)/httpcli_test $(BINDIR)/$(CONFIG)/json_rewrite $(BINDIR)/$(CONFIG)/json_rewrite_test $(BINDIR)/$(CONFIG)/json_test $(BINDIR)/$(CONFIG)/lame_client_test $(BINDIR)/$(CONFIG)/message_compress_test $(BINDIR)/$(CONFIG)/metadata_buffer_test $(BINDIR)/$(CONFIG)/multi_init_test $(BINDIR)/$(CONFIG)/murmur_hash_test $(BINDIR)/$(CONFIG)/no_server_test $(BINDIR)/$(CONFIG)/poll_kick_posix_test $(BINDIR)/$(CONFIG)/resolve_address_test $(BINDIR)/$(CONFIG)/secure_endpoint_test $(BINDIR)/$(CONFIG)/sockaddr_utils_test $(BINDIR)/$(CONFIG)/tcp_client_posix_test $(BINDIR)/$(CONFIG)/tcp_posix_test $(BINDIR)/$(CONFIG)/tcp_server_posix_test $(BINDIR)/$(CONFIG)/time_averaged_stats_test $(BINDIR)/$(CONFIG)/time_test $(BINDIR)/$(CONFIG)/timeout_encoding_test $(BINDIR)/$(CONFIG)/transport_metadata_test $(BINDIR)/$(CONFIG)/transport_security_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_no_op_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_no_op_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_no_op_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_bad_hostname_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_no_op_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_legacy_test
-buildtests_cxx: privatelibs_cxx $(BINDIR)/$(CONFIG)/async_end2end_test $(BINDIR)/$(CONFIG)/channel_arguments_test $(BINDIR)/$(CONFIG)/cli_call_test $(BINDIR)/$(CONFIG)/credentials_test $(BINDIR)/$(CONFIG)/cxx_time_test $(BINDIR)/$(CONFIG)/end2end_test $(BINDIR)/$(CONFIG)/generic_end2end_test $(BINDIR)/$(CONFIG)/grpc_cli $(BINDIR)/$(CONFIG)/interop_client $(BINDIR)/$(CONFIG)/interop_server $(BINDIR)/$(CONFIG)/interop_test $(BINDIR)/$(CONFIG)/pubsub_client $(BINDIR)/$(CONFIG)/pubsub_publisher_test $(BINDIR)/$(CONFIG)/pubsub_subscriber_test $(BINDIR)/$(CONFIG)/qps_driver $(BINDIR)/$(CONFIG)/qps_worker $(BINDIR)/$(CONFIG)/status_test $(BINDIR)/$(CONFIG)/thread_pool_test
+buildtests_cxx: privatelibs_cxx $(BINDIR)/$(CONFIG)/async_end2end_test $(BINDIR)/$(CONFIG)/channel_arguments_test $(BINDIR)/$(CONFIG)/cli_call_test $(BINDIR)/$(CONFIG)/credentials_test $(BINDIR)/$(CONFIG)/cxx_time_test $(BINDIR)/$(CONFIG)/end2end_test $(BINDIR)/$(CONFIG)/generic_end2end_test $(BINDIR)/$(CONFIG)/grpc_cli $(BINDIR)/$(CONFIG)/interop_client $(BINDIR)/$(CONFIG)/interop_server $(BINDIR)/$(CONFIG)/interop_test $(BINDIR)/$(CONFIG)/pubsub_client $(BINDIR)/$(CONFIG)/pubsub_publisher_test $(BINDIR)/$(CONFIG)/pubsub_subscriber_test $(BINDIR)/$(CONFIG)/qps_driver $(BINDIR)/$(CONFIG)/qps_smoke_test $(BINDIR)/$(CONFIG)/qps_worker $(BINDIR)/$(CONFIG)/status_test $(BINDIR)/$(CONFIG)/thread_pool_test
test: test_c test_cxx
@@ -2230,6 +2231,7 @@ else
$(Q) $(INSTALL) -d $(prefix)/lib
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT) $(prefix)/lib/libgpr.$(SHARED_EXT)
ifneq ($(SYSTEM),Darwin)
+ $(Q) ln -sf libgpr.$(SHARED_EXT) $(prefix)/lib/libgpr.so.0
$(Q) ln -sf libgpr.$(SHARED_EXT) $(prefix)/lib/libgpr.so
endif
endif
@@ -2243,6 +2245,7 @@ else
$(Q) $(INSTALL) -d $(prefix)/lib
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT) $(prefix)/lib/libgrpc.$(SHARED_EXT)
ifneq ($(SYSTEM),Darwin)
+ $(Q) ln -sf libgrpc.$(SHARED_EXT) $(prefix)/lib/libgrpc.so.0
$(Q) ln -sf libgrpc.$(SHARED_EXT) $(prefix)/lib/libgrpc.so
endif
endif
@@ -2256,6 +2259,7 @@ else
$(Q) $(INSTALL) -d $(prefix)/lib
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT) $(prefix)/lib/libgrpc_unsecure.$(SHARED_EXT)
ifneq ($(SYSTEM),Darwin)
+ $(Q) ln -sf libgrpc_unsecure.$(SHARED_EXT) $(prefix)/lib/libgrpc_unsecure.so.0
$(Q) ln -sf libgrpc_unsecure.$(SHARED_EXT) $(prefix)/lib/libgrpc_unsecure.so
endif
endif
@@ -2277,6 +2281,7 @@ else
$(Q) $(INSTALL) -d $(prefix)/lib
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT) $(prefix)/lib/libgrpc++.$(SHARED_EXT)
ifneq ($(SYSTEM),Darwin)
+ $(Q) ln -sf libgrpc++.$(SHARED_EXT) $(prefix)/lib/libgrpc++.so.0
$(Q) ln -sf libgrpc++.$(SHARED_EXT) $(prefix)/lib/libgrpc++.so
endif
endif
@@ -2290,6 +2295,7 @@ else
$(Q) $(INSTALL) -d $(prefix)/lib
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.$(SHARED_EXT) $(prefix)/lib/libgrpc++_unsecure.$(SHARED_EXT)
ifneq ($(SYSTEM),Darwin)
+ $(Q) ln -sf libgrpc++_unsecure.$(SHARED_EXT) $(prefix)/lib/libgrpc++_unsecure.so.0
$(Q) ln -sf libgrpc++_unsecure.$(SHARED_EXT) $(prefix)/lib/libgrpc++_unsecure.so
endif
endif
@@ -2311,6 +2317,7 @@ else
$(Q) $(INSTALL) -d $(prefix)/lib
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT) $(prefix)/lib/libgrpc_csharp_ext.$(SHARED_EXT)
ifneq ($(SYSTEM),Darwin)
+ $(Q) ln -sf libgrpc_csharp_ext.$(SHARED_EXT) $(prefix)/lib/libgrpc_csharp_ext.so.0
$(Q) ln -sf libgrpc_csharp_ext.$(SHARED_EXT) $(prefix)/lib/libgrpc_csharp_ext.so
endif
endif
@@ -3344,6 +3351,12 @@ PUBLIC_HEADERS_CXX += \
include/grpc++/impl/rpc_method.h \
include/grpc++/impl/rpc_service_method.h \
include/grpc++/impl/service_type.h \
+ include/grpc++/impl/sync.h \
+ include/grpc++/impl/sync_cxx11.h \
+ include/grpc++/impl/sync_no_cxx11.h \
+ include/grpc++/impl/thd.h \
+ include/grpc++/impl/thd_cxx11.h \
+ include/grpc++/impl/thd_no_cxx11.h \
include/grpc++/server.h \
include/grpc++/server_builder.h \
include/grpc++/server_context.h \
@@ -3595,6 +3608,12 @@ PUBLIC_HEADERS_CXX += \
include/grpc++/impl/rpc_method.h \
include/grpc++/impl/rpc_service_method.h \
include/grpc++/impl/service_type.h \
+ include/grpc++/impl/sync.h \
+ include/grpc++/impl/sync_cxx11.h \
+ include/grpc++/impl/sync_no_cxx11.h \
+ include/grpc++/impl/thd.h \
+ include/grpc++/impl/thd_cxx11.h \
+ include/grpc++/impl/thd_no_cxx11.h \
include/grpc++/server.h \
include/grpc++/server_builder.h \
include/grpc++/server_context.h \
@@ -3724,6 +3743,130 @@ $(OBJDIR)/$(CONFIG)/src/compiler/python_generator.o:
$(OBJDIR)/$(CONFIG)/src/compiler/ruby_generator.o:
+LIBINTEROP_CLIENT_LIB_SRC = \
+ $(GENDIR)/test/cpp/interop/empty.pb.cc $(GENDIR)/test/cpp/interop/empty.grpc.pb.cc \
+ $(GENDIR)/test/cpp/interop/messages.pb.cc $(GENDIR)/test/cpp/interop/messages.grpc.pb.cc \
+ $(GENDIR)/test/cpp/interop/test.pb.cc $(GENDIR)/test/cpp/interop/test.grpc.pb.cc \
+ test/cpp/interop/client_helper.cc \
+ test/cpp/interop/interop_client.cc \
+
+
+LIBINTEROP_CLIENT_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBINTEROP_CLIENT_LIB_SRC))))
+
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure libraries if you don't have OpenSSL with ALPN.
+
+$(LIBDIR)/$(CONFIG)/libinterop_client_lib.a: 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)/libinterop_client_lib.a: protobuf_dep_error
+
+
+else
+
+ifneq ($(OPENSSL_DEP),)
+# This is to ensure the embedded OpenSSL is built beforehand, properly
+# installing headers to their final destination on the drive. We need this
+# otherwise parallel compilation will fail if a source is compiled first.
+test/cpp/interop/empty.proto: $(OPENSSL_DEP)
+test/cpp/interop/messages.proto: $(OPENSSL_DEP)
+test/cpp/interop/test.proto: $(OPENSSL_DEP)
+test/cpp/interop/client_helper.cc: $(OPENSSL_DEP)
+test/cpp/interop/interop_client.cc: $(OPENSSL_DEP)
+endif
+
+$(LIBDIR)/$(CONFIG)/libinterop_client_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBUF_DEP) $(LIBINTEROP_CLIENT_LIB_OBJS)
+ $(E) "[AR] Creating $@"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) rm -f $(LIBDIR)/$(CONFIG)/libinterop_client_lib.a
+ $(Q) $(AR) rcs $(LIBDIR)/$(CONFIG)/libinterop_client_lib.a $(LIBINTEROP_CLIENT_LIB_OBJS)
+ifeq ($(SYSTEM),Darwin)
+ $(Q) ranlib $(LIBDIR)/$(CONFIG)/libinterop_client_lib.a
+endif
+
+
+
+
+endif
+
+endif
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(LIBINTEROP_CLIENT_LIB_OBJS:.o=.dep)
+endif
+endif
+
+
+
+
+$(OBJDIR)/$(CONFIG)/test/cpp/interop/client_helper.o: $(GENDIR)/test/cpp/interop/empty.pb.cc $(GENDIR)/test/cpp/interop/empty.grpc.pb.cc $(GENDIR)/test/cpp/interop/messages.pb.cc $(GENDIR)/test/cpp/interop/messages.grpc.pb.cc $(GENDIR)/test/cpp/interop/test.pb.cc $(GENDIR)/test/cpp/interop/test.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/interop/interop_client.o: $(GENDIR)/test/cpp/interop/empty.pb.cc $(GENDIR)/test/cpp/interop/empty.grpc.pb.cc $(GENDIR)/test/cpp/interop/messages.pb.cc $(GENDIR)/test/cpp/interop/messages.grpc.pb.cc $(GENDIR)/test/cpp/interop/test.pb.cc $(GENDIR)/test/cpp/interop/test.grpc.pb.cc
+
+
+LIBINTEROP_SERVER_LIB_SRC = \
+ test/cpp/interop/server_helper.cc \
+
+
+LIBINTEROP_SERVER_LIB_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBINTEROP_SERVER_LIB_SRC))))
+
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure libraries if you don't have OpenSSL with ALPN.
+
+$(LIBDIR)/$(CONFIG)/libinterop_server_lib.a: 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)/libinterop_server_lib.a: protobuf_dep_error
+
+
+else
+
+ifneq ($(OPENSSL_DEP),)
+# This is to ensure the embedded OpenSSL is built beforehand, properly
+# installing headers to their final destination on the drive. We need this
+# otherwise parallel compilation will fail if a source is compiled first.
+test/cpp/interop/server_helper.cc: $(OPENSSL_DEP)
+endif
+
+$(LIBDIR)/$(CONFIG)/libinterop_server_lib.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBUF_DEP) $(LIBINTEROP_SERVER_LIB_OBJS)
+ $(E) "[AR] Creating $@"
+ $(Q) mkdir -p `dirname $@`
+ $(Q) rm -f $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a
+ $(Q) $(AR) rcs $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a $(LIBINTEROP_SERVER_LIB_OBJS)
+ifeq ($(SYSTEM),Darwin)
+ $(Q) ranlib $(LIBDIR)/$(CONFIG)/libinterop_server_lib.a
+endif
+
+
+
+
+endif
+
+endif
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(LIBINTEROP_SERVER_LIB_OBJS:.o=.dep)
+endif
+endif
+
+$(OBJDIR)/$(CONFIG)/test/cpp/interop/server_helper.o:
+
+
LIBPUBSUB_CLIENT_LIB_SRC = \
$(GENDIR)/examples/pubsub/label.pb.cc $(GENDIR)/examples/pubsub/label.grpc.pb.cc \
$(GENDIR)/examples/pubsub/empty.pb.cc $(GENDIR)/examples/pubsub/empty.grpc.pb.cc \
@@ -3795,6 +3938,7 @@ $(OBJDIR)/$(CONFIG)/examples/pubsub/subscriber.o: $(GENDIR)/examples/pubsub/
LIBQPS_SRC = \
$(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc \
test/cpp/qps/driver.cc \
+ test/cpp/qps/report.cc \
test/cpp/qps/timer.cc \
@@ -3824,6 +3968,7 @@ ifneq ($(OPENSSL_DEP),)
# otherwise parallel compilation will fail if a source is compiled first.
test/cpp/qps/qpstest.proto: $(OPENSSL_DEP)
test/cpp/qps/driver.cc: $(OPENSSL_DEP)
+test/cpp/qps/report.cc: $(OPENSSL_DEP)
test/cpp/qps/timer.cc: $(OPENSSL_DEP)
endif
@@ -3851,6 +3996,7 @@ endif
$(OBJDIR)/$(CONFIG)/test/cpp/qps/driver.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/report.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc
$(OBJDIR)/$(CONFIG)/test/cpp/qps/timer.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc $(GENDIR)/test/cpp/qps/qpstest.grpc.pb.cc
@@ -8524,9 +8670,6 @@ endif
INTEROP_CLIENT_SRC = \
- $(GENDIR)/test/cpp/interop/empty.pb.cc $(GENDIR)/test/cpp/interop/empty.grpc.pb.cc \
- $(GENDIR)/test/cpp/interop/messages.pb.cc $(GENDIR)/test/cpp/interop/messages.grpc.pb.cc \
- $(GENDIR)/test/cpp/interop/test.pb.cc $(GENDIR)/test/cpp/interop/test.grpc.pb.cc \
test/cpp/interop/client.cc \
INTEROP_CLIENT_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(INTEROP_CLIENT_SRC))))
@@ -8548,19 +8691,16 @@ $(BINDIR)/$(CONFIG)/interop_client: protobuf_dep_error
else
-$(BINDIR)/$(CONFIG)/interop_client: $(PROTOBUF_DEP) $(INTEROP_CLIENT_OBJS) $(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
+$(BINDIR)/$(CONFIG)/interop_client: $(PROTOBUF_DEP) $(INTEROP_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libinterop_client_lib.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) $(INTEROP_CLIENT_OBJS) $(GTEST_LIB) $(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) -o $(BINDIR)/$(CONFIG)/interop_client
+ $(Q) $(LDXX) $(LDFLAGS) $(INTEROP_CLIENT_OBJS) $(GTEST_LIB) $(LIBDIR)/$(CONFIG)/libinterop_client_lib.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) -o $(BINDIR)/$(CONFIG)/interop_client
endif
endif
-$(OBJDIR)/$(CONFIG)/test/cpp/interop/empty.o: $(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)/test/cpp/interop/messages.o: $(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)/test/cpp/interop/test.o: $(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)/test/cpp/interop/client.o: $(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)/test/cpp/interop/client.o: $(LIBDIR)/$(CONFIG)/libinterop_client_lib.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_interop_client: $(INTEROP_CLIENT_OBJS:.o=.dep)
@@ -8596,19 +8736,19 @@ $(BINDIR)/$(CONFIG)/interop_server: protobuf_dep_error
else
-$(BINDIR)/$(CONFIG)/interop_server: $(PROTOBUF_DEP) $(INTEROP_SERVER_OBJS) $(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
+$(BINDIR)/$(CONFIG)/interop_server: $(PROTOBUF_DEP) $(INTEROP_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libinterop_server_lib.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) $(INTEROP_SERVER_OBJS) $(GTEST_LIB) $(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) -o $(BINDIR)/$(CONFIG)/interop_server
+ $(Q) $(LDXX) $(LDFLAGS) $(INTEROP_SERVER_OBJS) $(GTEST_LIB) $(LIBDIR)/$(CONFIG)/libinterop_server_lib.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) -o $(BINDIR)/$(CONFIG)/interop_server
endif
endif
-$(OBJDIR)/$(CONFIG)/test/cpp/interop/empty.o: $(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)/test/cpp/interop/messages.o: $(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)/test/cpp/interop/test.o: $(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)/test/cpp/interop/server.o: $(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)/test/cpp/interop/empty.o: $(LIBDIR)/$(CONFIG)/libinterop_server_lib.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)/test/cpp/interop/messages.o: $(LIBDIR)/$(CONFIG)/libinterop_server_lib.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)/test/cpp/interop/test.o: $(LIBDIR)/$(CONFIG)/libinterop_server_lib.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)/test/cpp/interop/server.o: $(LIBDIR)/$(CONFIG)/libinterop_server_lib.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_interop_server: $(INTEROP_SERVER_OBJS:.o=.dep)
@@ -8829,6 +8969,48 @@ endif
endif
+QPS_SMOKE_TEST_SRC = \
+ test/cpp/qps/smoke_test.cc \
+
+QPS_SMOKE_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(QPS_SMOKE_TEST_SRC))))
+
+ifeq ($(NO_SECURE),true)
+
+# You can't build secure targets if you don't have OpenSSL with ALPN.
+
+$(BINDIR)/$(CONFIG)/qps_smoke_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.0.0+.
+
+$(BINDIR)/$(CONFIG)/qps_smoke_test: protobuf_dep_error
+
+else
+
+$(BINDIR)/$(CONFIG)/qps_smoke_test: $(PROTOBUF_DEP) $(QPS_SMOKE_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libqps.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) $(QPS_SMOKE_TEST_OBJS) $(GTEST_LIB) $(LIBDIR)/$(CONFIG)/libqps.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) -o $(BINDIR)/$(CONFIG)/qps_smoke_test
+
+endif
+
+endif
+
+$(OBJDIR)/$(CONFIG)/test/cpp/qps/smoke_test.o: $(LIBDIR)/$(CONFIG)/libqps.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_qps_smoke_test: $(QPS_SMOKE_TEST_OBJS:.o=.dep)
+
+ifneq ($(NO_SECURE),true)
+ifneq ($(NO_DEPS),true)
+-include $(QPS_SMOKE_TEST_OBJS:.o=.dep)
+endif
+endif
+
+
QPS_WORKER_SRC = \
test/cpp/qps/client_async.cc \
test/cpp/qps/client_sync.cc \
diff --git a/build.json b/build.json
index 0a1c346bdf..94b66b068f 100644
--- a/build.json
+++ b/build.json
@@ -29,6 +29,12 @@
"include/grpc++/impl/rpc_method.h",
"include/grpc++/impl/rpc_service_method.h",
"include/grpc++/impl/service_type.h",
+ "include/grpc++/impl/sync.h",
+ "include/grpc++/impl/sync_cxx11.h",
+ "include/grpc++/impl/sync_no_cxx11.h",
+ "include/grpc++/impl/thd.h",
+ "include/grpc++/impl/thd_cxx11.h",
+ "include/grpc++/impl/thd_no_cxx11.h",
"include/grpc++/server.h",
"include/grpc++/server_builder.h",
"include/grpc++/server_context.h",
@@ -468,6 +474,10 @@
"name": "grpc++",
"build": "all",
"language": "c++",
+ "headers": [
+ "src/cpp/client/secure_credentials.h",
+ "src/cpp/server/secure_server_credentials.h"
+ ],
"src": [
"src/cpp/client/secure_credentials.cc",
"src/cpp/server/secure_server_credentials.cc"
@@ -536,6 +546,39 @@
"secure": "no"
},
{
+ "name": "interop_client_lib",
+ "build": "private",
+ "language": "c++",
+ "src": [
+ "test/cpp/interop/empty.proto",
+ "test/cpp/interop/messages.proto",
+ "test/cpp/interop/test.proto",
+ "test/cpp/interop/client_helper.cc",
+ "test/cpp/interop/interop_client.cc"
+ ],
+ "deps": [
+ "grpc++_test_util",
+ "grpc_test_util",
+ "grpc++",
+ "grpc",
+ "gpr"
+ ]
+ },
+ {
+ "name": "interop_server_lib",
+ "build": "private",
+ "language": "c++",
+ "src": [
+ "test/cpp/interop/server_helper.cc"
+ ],
+ "deps": [
+ "grpc_test_util",
+ "grpc++",
+ "grpc",
+ "gpr"
+ ]
+ },
+ {
"name": "pubsub_client_lib",
"build": "private",
"language": "c++",
@@ -558,11 +601,13 @@
"language": "c++",
"headers": [
"test/cpp/qps/driver.h",
+ "test/cpp/qps/report.h",
"test/cpp/qps/timer.h"
],
"src": [
"test/cpp/qps/qpstest.proto",
"test/cpp/qps/driver.cc",
+ "test/cpp/qps/report.cc",
"test/cpp/qps/timer.cc"
]
},
@@ -1878,12 +1923,10 @@
"run": false,
"language": "c++",
"src": [
- "test/cpp/interop/empty.proto",
- "test/cpp/interop/messages.proto",
- "test/cpp/interop/test.proto",
"test/cpp/interop/client.cc"
],
"deps": [
+ "interop_client_lib",
"grpc++_test_util",
"grpc_test_util",
"grpc++",
@@ -1904,6 +1947,7 @@
"test/cpp/interop/server.cc"
],
"deps": [
+ "interop_server_lib",
"grpc++_test_util",
"grpc_test_util",
"grpc++",
@@ -1996,6 +2040,24 @@
]
},
{
+ "name": "qps_smoke_test",
+ "build": "test",
+ "run": false,
+ "language": "c++",
+ "src": [
+ "test/cpp/qps/smoke_test.cc"
+ ],
+ "deps": [
+ "qps",
+ "grpc++_test_util",
+ "grpc_test_util",
+ "grpc++",
+ "grpc",
+ "gpr_test_util",
+ "gpr"
+ ]
+ },
+ {
"name": "qps_worker",
"build": "test",
"run": false,
diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc
index c78f0333d8..bd8bf65349 100644
--- a/src/compiler/cpp_generator.cc
+++ b/src/compiler/cpp_generator.cc
@@ -198,17 +198,18 @@ grpc::string GetHeaderIncludes(const grpc::protobuf::FileDescriptor *file,
temp.append("\n");
- std::vector<grpc::string> parts =
- grpc_generator::tokenize(file->package(), ".");
+ if (!file->package().empty()) {
+ std::vector<grpc::string> parts =
+ grpc_generator::tokenize(file->package(), ".");
- for (auto part = parts.begin(); part != parts.end(); part++) {
- temp.append("namespace ");
- temp.append(*part);
- temp.append(" {\n");
+ for (auto part = parts.begin(); part != parts.end(); part++) {
+ temp.append("namespace ");
+ temp.append(*part);
+ temp.append(" {\n");
+ }
+ temp.append("\n");
}
- temp.append("\n");
-
return temp;
}
@@ -431,15 +432,18 @@ grpc::string GetHeaderEpilogue(const grpc::protobuf::FileDescriptor *file,
vars["filename"] = file->name();
vars["filename_identifier"] = FilenameIdentifier(file->name());
- std::vector<grpc::string> parts =
- grpc_generator::tokenize(file->package(), ".");
+ if (!file->package().empty()) {
+ std::vector<grpc::string> parts =
+ grpc_generator::tokenize(file->package(), ".");
- for (auto part = parts.rbegin(); part != parts.rend(); part++) {
- vars["part"] = *part;
- printer.Print(vars, "} // namespace $part$\n");
+ for (auto part = parts.rbegin(); part != parts.rend(); part++) {
+ vars["part"] = *part;
+ printer.Print(vars, "} // namespace $part$\n");
+ }
+ printer.Print(vars, "\n");
}
- printer.Print(vars, "\n\n");
+ printer.Print(vars, "\n");
printer.Print(vars, "#endif // GRPC_$filename_identifier$__INCLUDED\n");
return output;
@@ -480,12 +484,14 @@ grpc::string GetSourceIncludes(const grpc::protobuf::FileDescriptor *file,
printer.Print(vars, "#include <grpc++/impl/service_type.h>\n");
printer.Print(vars, "#include <grpc++/stream.h>\n");
- std::vector<grpc::string> parts =
- grpc_generator::tokenize(file->package(), ".");
+ if (!file->package().empty()) {
+ std::vector<grpc::string> parts =
+ grpc_generator::tokenize(file->package(), ".");
- for (auto part = parts.begin(); part != parts.end(); part++) {
- vars["part"] = *part;
- printer.Print(vars, "namespace $part$ {\n");
+ for (auto part = parts.begin(); part != parts.end(); part++) {
+ vars["part"] = *part;
+ printer.Print(vars, "namespace $part$ {\n");
+ }
}
printer.Print(vars, "\n");
@@ -860,17 +866,18 @@ grpc::string GetSourceEpilogue(const grpc::protobuf::FileDescriptor *file,
const Parameters &params) {
grpc::string temp;
- std::vector<grpc::string> parts =
- grpc_generator::tokenize(file->package(), ".");
+ if (!file->package().empty()) {
+ std::vector<grpc::string> parts =
+ grpc_generator::tokenize(file->package(), ".");
- for (auto part = parts.begin(); part != parts.end(); part++) {
- temp.append("} // namespace ");
- temp.append(*part);
+ for (auto part = parts.begin(); part != parts.end(); part++) {
+ temp.append("} // namespace ");
+ temp.append(*part);
+ temp.append("\n");
+ }
temp.append("\n");
}
- temp.append("\n");
-
return temp;
}
diff --git a/src/core/iomgr/pollset_multipoller_with_poll_posix.c b/src/core/iomgr/pollset_multipoller_with_poll_posix.c
index 7570ff18c5..bcef7c35b5 100644
--- a/src/core/iomgr/pollset_multipoller_with_poll_posix.c
+++ b/src/core/iomgr/pollset_multipoller_with_poll_posix.c
@@ -172,6 +172,9 @@ static int multipoll_with_poll_pollset_maybe_work(
}
r = poll(h->pfds, h->pfd_count, timeout);
+
+ end_polling(pollset);
+
if (r < 0) {
if (errno != EINTR) {
gpr_log(GPR_ERROR, "poll() failed: %s", strerror(errno));
@@ -192,7 +195,6 @@ static int multipoll_with_poll_pollset_maybe_work(
}
}
grpc_pollset_kick_post_poll(&pollset->kick_state);
- end_polling(pollset);
gpr_mu_lock(&pollset->mu);
pollset->counter = 0;
diff --git a/src/core/iomgr/pollset_posix.c b/src/core/iomgr/pollset_posix.c
index 0bb722e2b1..03fd94f136 100644
--- a/src/core/iomgr/pollset_posix.c
+++ b/src/core/iomgr/pollset_posix.c
@@ -396,6 +396,9 @@ static int unary_poll_pollset_maybe_work(grpc_pollset *pollset,
pfd[1].events = grpc_fd_begin_poll(fd, pollset, POLLIN, POLLOUT, &fd_watcher);
r = poll(pfd, GPR_ARRAY_SIZE(pfd), timeout);
+
+ grpc_fd_end_poll(&fd_watcher);
+
if (r < 0) {
if (errno != EINTR) {
gpr_log(GPR_ERROR, "poll() failed: %s", strerror(errno));
@@ -415,7 +418,6 @@ static int unary_poll_pollset_maybe_work(grpc_pollset *pollset,
}
grpc_pollset_kick_post_poll(&pollset->kick_state);
- grpc_fd_end_poll(&fd_watcher);
gpr_mu_lock(&pollset->mu);
pollset->counter = 0;
diff --git a/src/core/iomgr/tcp_server.h b/src/core/iomgr/tcp_server.h
index 68ee85c5a7..66bb3ef701 100644
--- a/src/core/iomgr/tcp_server.h
+++ b/src/core/iomgr/tcp_server.h
@@ -71,6 +71,8 @@ int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr,
up when grpc_tcp_server_destroy is called. */
int grpc_tcp_server_get_fd(grpc_tcp_server *s, unsigned index);
-void grpc_tcp_server_destroy(grpc_tcp_server *server);
+void grpc_tcp_server_destroy(grpc_tcp_server *server,
+ void (*shutdown_done)(void *shutdown_done_arg),
+ void *shutdown_done_arg);
-#endif /* GRPC_INTERNAL_CORE_IOMGR_TCP_SERVER_H */
+#endif /* GRPC_INTERNAL_CORE_IOMGR_TCP_SERVER_H */
diff --git a/src/core/iomgr/tcp_server_posix.c b/src/core/iomgr/tcp_server_posix.c
index 90b7eb451d..895f85fc68 100644
--- a/src/core/iomgr/tcp_server_posix.c
+++ b/src/core/iomgr/tcp_server_posix.c
@@ -102,12 +102,18 @@ struct grpc_tcp_server {
gpr_cv cv;
/* active port count: how many ports are actually still listening */
- int active_ports;
+ size_t active_ports;
+ /* destroyed port count: how many ports are completely destroyed */
+ size_t destroyed_ports;
/* all listening ports */
server_port *ports;
size_t nports;
size_t port_capacity;
+
+ /* shutdown callback */
+ void (*shutdown_complete)(void *);
+ void *shutdown_complete_arg;
};
grpc_tcp_server *grpc_tcp_server_create(void) {
@@ -115,6 +121,7 @@ grpc_tcp_server *grpc_tcp_server_create(void) {
gpr_mu_init(&s->mu);
gpr_cv_init(&s->cv);
s->active_ports = 0;
+ s->destroyed_ports = 0;
s->cb = NULL;
s->cb_arg = NULL;
s->ports = gpr_malloc(sizeof(server_port) * INIT_PORT_CAP);
@@ -123,29 +130,64 @@ grpc_tcp_server *grpc_tcp_server_create(void) {
return s;
}
-void grpc_tcp_server_destroy(grpc_tcp_server *s) {
+static void finish_shutdown(grpc_tcp_server *s) {
+ s->shutdown_complete(s->shutdown_complete_arg);
+
+ gpr_mu_destroy(&s->mu);
+ gpr_cv_destroy(&s->cv);
+
+ gpr_free(s->ports);
+ gpr_free(s);
+}
+
+static void destroyed_port(void *server, int success) {
+ grpc_tcp_server *s = server;
+ gpr_mu_lock(&s->mu);
+ s->destroyed_ports++;
+ if (s->destroyed_ports == s->nports) {
+ gpr_mu_unlock(&s->mu);
+ finish_shutdown(s);
+ } else {
+ gpr_mu_unlock(&s->mu);
+ }
+}
+
+static void dont_care_about_shutdown_completion(void *ignored) {}
+
+void grpc_tcp_server_destroy(
+ grpc_tcp_server *s, void (*shutdown_complete)(void *shutdown_complete_arg),
+ void *shutdown_complete_arg) {
size_t i;
gpr_mu_lock(&s->mu);
+
+ s->shutdown_complete = shutdown_complete
+ ? shutdown_complete
+ : dont_care_about_shutdown_completion;
+ s->shutdown_complete_arg = shutdown_complete_arg;
+
/* shutdown all fd's */
for (i = 0; i < s->nports; i++) {
grpc_fd_shutdown(s->ports[i].emfd);
}
/* wait while that happens */
+ /* TODO(ctiller): make this asynchronous also */
while (s->active_ports) {
gpr_cv_wait(&s->cv, &s->mu, gpr_inf_future);
}
gpr_mu_unlock(&s->mu);
/* delete ALL the things */
- for (i = 0; i < s->nports; i++) {
- server_port *sp = &s->ports[i];
- if (sp->addr.sockaddr.sa_family == AF_UNIX) {
- unlink_if_unix_domain_socket(&sp->addr.un);
+ if (s->nports) {
+ for (i = 0; i < s->nports; i++) {
+ server_port *sp = &s->ports[i];
+ if (sp->addr.sockaddr.sa_family == AF_UNIX) {
+ unlink_if_unix_domain_socket(&sp->addr.un);
+ }
+ grpc_fd_orphan(sp->emfd, destroyed_port, s);
}
- grpc_fd_orphan(sp->emfd, NULL, NULL);
+ } else {
+ finish_shutdown(s);
}
- gpr_free(s->ports);
- gpr_free(s);
}
/* get max listen queue size on linux */
diff --git a/src/core/iomgr/tcp_server_windows.c b/src/core/iomgr/tcp_server_windows.c
index 0c3ab1dc91..a43d5670a4 100644
--- a/src/core/iomgr/tcp_server_windows.c
+++ b/src/core/iomgr/tcp_server_windows.c
@@ -92,7 +92,9 @@ grpc_tcp_server *grpc_tcp_server_create(void) {
return s;
}
-void grpc_tcp_server_destroy(grpc_tcp_server *s) {
+void grpc_tcp_server_destroy(grpc_tcp_server *s,
+ void (*shutdown_done)(void *shutdown_done_arg),
+ void *shutdown_done_arg) {
size_t i;
gpr_mu_lock(&s->mu);
/* shutdown all fd's */
@@ -112,11 +114,15 @@ void grpc_tcp_server_destroy(grpc_tcp_server *s) {
}
gpr_free(s->ports);
gpr_free(s);
+
+ if (shutdown_done) {
+ shutdown_done(shutdown_done_arg);
+ }
}
/* Prepare a recently-created socket for listening. */
-static int prepare_socket(SOCKET sock,
- const struct sockaddr *addr, int addr_len) {
+static int prepare_socket(SOCKET sock, const struct sockaddr *addr,
+ int addr_len) {
struct sockaddr_storage sockname_temp;
socklen_t sockname_len;
@@ -147,15 +153,15 @@ static int prepare_socket(SOCKET sock,
}
sockname_len = sizeof(sockname_temp);
- if (getsockname(sock, (struct sockaddr *) &sockname_temp, &sockname_len)
- == SOCKET_ERROR) {
+ if (getsockname(sock, (struct sockaddr *)&sockname_temp, &sockname_len) ==
+ SOCKET_ERROR) {
char *utf8_message = gpr_format_message(WSAGetLastError());
gpr_log(GPR_ERROR, "getsockname: %s", utf8_message);
gpr_free(utf8_message);
goto error;
}
- return grpc_sockaddr_get_port((struct sockaddr *) &sockname_temp);
+ return grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp);
error:
if (sock != INVALID_SOCKET) closesocket(sock);
@@ -221,8 +227,7 @@ static void on_accept(void *arg, int success) {
DWORD transfered_bytes = 0;
DWORD flags;
BOOL wsa_success = WSAGetOverlappedResult(sock, &info->overlapped,
- &transfered_bytes, FALSE,
- &flags);
+ &transfered_bytes, FALSE, &flags);
if (!wsa_success) {
char *utf8_message = gpr_format_message(WSAGetLastError());
gpr_log(GPR_ERROR, "on_accept error: %s", utf8_message);
@@ -257,9 +262,9 @@ static int add_socket_to_server(grpc_tcp_server *s, SOCKET sock,
if (sock == INVALID_SOCKET) return -1;
- status = WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER,
- &guid, sizeof(guid), &AcceptEx, sizeof(AcceptEx),
- &ioctl_num_bytes, NULL, NULL);
+ status =
+ WSAIoctl(sock, SIO_GET_EXTENSION_FUNCTION_POINTER, &guid, sizeof(guid),
+ &AcceptEx, sizeof(AcceptEx), &ioctl_num_bytes, NULL, NULL);
if (status != 0) {
char *utf8_message = gpr_format_message(WSAGetLastError());
@@ -307,9 +312,8 @@ int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr,
for (i = 0; i < s->nports; i++) {
sockname_len = sizeof(sockname_temp);
if (0 == getsockname(s->ports[i].socket->socket,
- (struct sockaddr *) &sockname_temp,
- &sockname_len)) {
- port = grpc_sockaddr_get_port((struct sockaddr *) &sockname_temp);
+ (struct sockaddr *)&sockname_temp, &sockname_len)) {
+ port = grpc_sockaddr_get_port((struct sockaddr *)&sockname_temp);
if (port > 0) {
allocated_addr = malloc(addr_len);
memcpy(allocated_addr, addr, addr_len);
@@ -330,7 +334,7 @@ int grpc_tcp_server_add_port(grpc_tcp_server *s, const void *addr,
if (grpc_sockaddr_is_wildcard(addr, &port)) {
grpc_sockaddr_make_wildcard6(port, &wildcard);
- addr = (struct sockaddr *) &wildcard;
+ addr = (struct sockaddr *)&wildcard;
addr_len = sizeof(wildcard);
}
@@ -369,4 +373,4 @@ void grpc_tcp_server_start(grpc_tcp_server *s, grpc_pollset **pollset,
gpr_mu_unlock(&s->mu);
}
-#endif /* GPR_WINSOCK_SOCKET */
+#endif /* GPR_WINSOCK_SOCKET */
diff --git a/src/core/security/server_secure_chttp2.c b/src/core/security/server_secure_chttp2.c
index c155b80b7e..081272724c 100644
--- a/src/core/security/server_secure_chttp2.c
+++ b/src/core/security/server_secure_chttp2.c
@@ -85,10 +85,10 @@ static void on_secure_transport_setup_done(void *statep,
if (status == GRPC_SECURITY_OK) {
gpr_mu_lock(&state->mu);
if (!state->is_shutdown) {
- grpc_create_chttp2_transport(
- setup_transport, state->server,
- grpc_server_get_channel_args(state->server),
- secure_endpoint, NULL, 0, grpc_mdctx_create(), 0);
+ grpc_create_chttp2_transport(setup_transport, state->server,
+ grpc_server_get_channel_args(state->server),
+ secure_endpoint, NULL, 0,
+ grpc_mdctx_create(), 0);
} else {
/* We need to consume this here, because the server may already have gone
* away. */
@@ -104,7 +104,8 @@ static void on_secure_transport_setup_done(void *statep,
static void on_accept(void *statep, grpc_endpoint *tcp) {
grpc_server_secure_state *state = statep;
state_ref(state);
- grpc_setup_secure_transport(state->ctx, tcp, on_secure_transport_setup_done, state);
+ grpc_setup_secure_transport(state->ctx, tcp, on_secure_transport_setup_done,
+ state);
}
/* Server callback: start listening on our ports */
@@ -120,12 +121,14 @@ static void destroy(grpc_server *server, void *statep) {
grpc_server_secure_state *state = statep;
gpr_mu_lock(&state->mu);
state->is_shutdown = 1;
- grpc_tcp_server_destroy(state->tcp);
+ grpc_tcp_server_destroy(state->tcp, grpc_server_listener_destroy_done,
+ server);
gpr_mu_unlock(&state->mu);
state_unref(state);
}
-int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr, grpc_server_credentials *creds) {
+int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr,
+ grpc_server_credentials *creds) {
grpc_resolved_addresses *resolved = NULL;
grpc_tcp_server *tcp = NULL;
grpc_server_secure_state *state = NULL;
@@ -213,7 +216,7 @@ error:
grpc_resolved_addresses_destroy(resolved);
}
if (tcp) {
- grpc_tcp_server_destroy(tcp);
+ grpc_tcp_server_destroy(tcp, NULL, NULL);
}
if (state) {
gpr_free(state);
diff --git a/src/core/surface/completion_queue.c b/src/core/surface/completion_queue.c
index 6a1d83ce5d..24f4a05071 100644
--- a/src/core/surface/completion_queue.c
+++ b/src/core/surface/completion_queue.c
@@ -432,3 +432,11 @@ void grpc_cq_dump_pending_ops(grpc_completion_queue *cc) {
grpc_pollset *grpc_cq_pollset(grpc_completion_queue *cc) {
return &cc->pollset;
}
+
+void grpc_cq_hack_spin_pollset(grpc_completion_queue *cc) {
+ gpr_mu_lock(GRPC_POLLSET_MU(&cc->pollset));
+ grpc_pollset_kick(&cc->pollset);
+ grpc_pollset_work(&cc->pollset,
+ gpr_time_add(gpr_now(), gpr_time_from_millis(100)));
+ gpr_mu_unlock(GRPC_POLLSET_MU(&cc->pollset));
+}
diff --git a/src/core/surface/completion_queue.h b/src/core/surface/completion_queue.h
index 3054264cad..3a7cc99dda 100644
--- a/src/core/surface/completion_queue.h
+++ b/src/core/surface/completion_queue.h
@@ -114,4 +114,6 @@ void grpc_cq_dump_pending_ops(grpc_completion_queue *cc);
grpc_pollset *grpc_cq_pollset(grpc_completion_queue *cc);
-#endif /* GRPC_INTERNAL_CORE_SURFACE_COMPLETION_QUEUE_H */
+void grpc_cq_hack_spin_pollset(grpc_completion_queue *cc);
+
+#endif /* GRPC_INTERNAL_CORE_SURFACE_COMPLETION_QUEUE_H */
diff --git a/src/core/surface/server.c b/src/core/surface/server.c
index 424734c54c..17cba9a505 100644
--- a/src/core/surface/server.c
+++ b/src/core/surface/server.c
@@ -137,6 +137,7 @@ struct grpc_server {
size_t cq_count;
gpr_mu mu;
+ gpr_cv cv;
registered_method *registered_methods;
requested_call_array requested_calls;
@@ -149,6 +150,7 @@ struct grpc_server {
channel_data root_channel_data;
listener *listeners;
+ int listeners_destroyed;
gpr_refcount internal_refcount;
};
@@ -263,6 +265,7 @@ static void server_unref(grpc_server *server) {
if (gpr_unref(&server->internal_refcount)) {
grpc_channel_args_destroy(server->channel_args);
gpr_mu_destroy(&server->mu);
+ gpr_cv_destroy(&server->cv);
gpr_free(server->channel_filters);
requested_call_array_destroy(&server->requested_calls);
while ((rm = server->registered_methods) != NULL) {
@@ -589,9 +592,8 @@ static void destroy_channel_elem(grpc_channel_element *elem) {
}
static const grpc_channel_filter server_surface_filter = {
- call_op, channel_op, sizeof(call_data),
- init_call_elem, destroy_call_elem, sizeof(channel_data),
- init_channel_elem, destroy_channel_elem, "server",
+ call_op, channel_op, sizeof(call_data), init_call_elem, destroy_call_elem,
+ sizeof(channel_data), init_channel_elem, destroy_channel_elem, "server",
};
static void addcq(grpc_server *server, grpc_completion_queue *cq) {
@@ -620,6 +622,7 @@ grpc_server *grpc_server_create_from_filters(grpc_completion_queue *cq,
if (cq) addcq(server, cq);
gpr_mu_init(&server->mu);
+ gpr_cv_init(&server->cv);
server->unregistered_cq = cq;
/* decremented by grpc_server_destroy */
@@ -733,7 +736,8 @@ grpc_transport_setup_result grpc_server_setup_transport(
channel = grpc_channel_create_from_filters(filters, num_filters,
s->channel_args, mdctx, 0);
chand = (channel_data *)grpc_channel_stack_element(
- grpc_channel_get_channel_stack(channel), 0)->channel_data;
+ grpc_channel_get_channel_stack(channel), 0)
+ ->channel_data;
chand->server = s;
server_ref(s);
chand->channel = channel;
@@ -754,7 +758,7 @@ grpc_transport_setup_result grpc_server_setup_transport(
method = grpc_mdstr_from_string(mdctx, rm->method);
hash = GRPC_MDSTR_KV_HASH(host ? host->hash : 0, method->hash);
for (probes = 0; chand->registered_methods[(hash + probes) % slots]
- .server_registered_method != NULL;
+ .server_registered_method != NULL;
probes++)
;
if (probes > max_probes) max_probes = probes;
@@ -781,6 +785,15 @@ grpc_transport_setup_result grpc_server_setup_transport(
return result;
}
+static int num_listeners(grpc_server *server) {
+ listener *l;
+ int n = 0;
+ for (l = server->listeners; l; l = l->next) {
+ n++;
+ }
+ return n;
+}
+
static void shutdown_internal(grpc_server *server, gpr_uint8 have_shutdown_tag,
void *shutdown_tag) {
listener *l;
@@ -878,11 +891,6 @@ static void shutdown_internal(grpc_server *server, gpr_uint8 have_shutdown_tag,
for (l = server->listeners; l; l = l->next) {
l->destroy(server, l->arg);
}
- while (server->listeners) {
- l = server->listeners;
- server->listeners = l->next;
- gpr_free(l);
- }
}
void grpc_server_shutdown(grpc_server *server) {
@@ -893,8 +901,18 @@ void grpc_server_shutdown_and_notify(grpc_server *server, void *tag) {
shutdown_internal(server, 1, tag);
}
+void grpc_server_listener_destroy_done(void *s) {
+ grpc_server *server = s;
+ gpr_mu_lock(&server->mu);
+ server->listeners_destroyed++;
+ gpr_cv_signal(&server->cv);
+ gpr_mu_unlock(&server->mu);
+}
+
void grpc_server_destroy(grpc_server *server) {
channel_data *c;
+ listener *l;
+ size_t i;
gpr_mu_lock(&server->mu);
if (!server->shutdown) {
gpr_mu_unlock(&server->mu);
@@ -902,6 +920,23 @@ void grpc_server_destroy(grpc_server *server) {
gpr_mu_lock(&server->mu);
}
+ while (server->listeners_destroyed != num_listeners(server)) {
+ for (i = 0; i < server->cq_count; i++) {
+ gpr_mu_unlock(&server->mu);
+ grpc_cq_hack_spin_pollset(server->cqs[i]);
+ gpr_mu_lock(&server->mu);
+ }
+
+ gpr_cv_wait(&server->cv, &server->mu,
+ gpr_time_add(gpr_now(), gpr_time_from_millis(100)));
+ }
+
+ while (server->listeners) {
+ l = server->listeners;
+ server->listeners = l->next;
+ gpr_free(l);
+ }
+
for (c = server->root_channel_data.next; c != &server->root_channel_data;
c = c->next) {
shutdown_channel(c);
diff --git a/src/core/surface/server.h b/src/core/surface/server.h
index e33f69b8c7..2cfa38fa43 100644
--- a/src/core/surface/server.h
+++ b/src/core/surface/server.h
@@ -48,9 +48,12 @@ grpc_server *grpc_server_create_from_filters(grpc_completion_queue *cq,
and when it shuts down, it will call destroy */
void grpc_server_add_listener(grpc_server *server, void *listener,
void (*start)(grpc_server *server, void *arg,
- grpc_pollset **pollsets, size_t npollsets),
+ grpc_pollset **pollsets,
+ size_t npollsets),
void (*destroy)(grpc_server *server, void *arg));
+void grpc_server_listener_destroy_done(void *server);
+
/* Setup a transport - creates a channel stack, binds the transport to the
server */
grpc_transport_setup_result grpc_server_setup_transport(
@@ -60,4 +63,4 @@ grpc_transport_setup_result grpc_server_setup_transport(
const grpc_channel_args *grpc_server_get_channel_args(grpc_server *server);
-#endif /* GRPC_INTERNAL_CORE_SURFACE_SERVER_H */
+#endif /* GRPC_INTERNAL_CORE_SURFACE_SERVER_H */
diff --git a/src/core/surface/server_chttp2.c b/src/core/surface/server_chttp2.c
index 27434b39e2..f3b9219f8b 100644
--- a/src/core/surface/server_chttp2.c
+++ b/src/core/surface/server_chttp2.c
@@ -66,7 +66,8 @@ static void new_transport(void *server, grpc_endpoint *tcp) {
}
/* Server callback: start listening on our ports */
-static void start(grpc_server *server, void *tcpp, grpc_pollset **pollsets, size_t pollset_count) {
+static void start(grpc_server *server, void *tcpp, grpc_pollset **pollsets,
+ size_t pollset_count) {
grpc_tcp_server *tcp = tcpp;
grpc_tcp_server_start(tcp, pollsets, pollset_count, new_transport, server);
}
@@ -75,7 +76,7 @@ static void start(grpc_server *server, void *tcpp, grpc_pollset **pollsets, size
callbacks) */
static void destroy(grpc_server *server, void *tcpp) {
grpc_tcp_server *tcp = tcpp;
- grpc_tcp_server_destroy(tcp);
+ grpc_tcp_server_destroy(tcp, grpc_server_listener_destroy_done, server);
}
int grpc_server_add_http2_port(grpc_server *server, const char *addr) {
@@ -131,7 +132,7 @@ error:
grpc_resolved_addresses_destroy(resolved);
}
if (tcp) {
- grpc_tcp_server_destroy(tcp);
+ grpc_tcp_server_destroy(tcp, NULL, NULL);
}
return 0;
}
diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc
index d6f9acc675..0a73b2c0f6 100644
--- a/src/cpp/client/secure_credentials.cc
+++ b/src/cpp/client/secure_credentials.cc
@@ -31,38 +31,23 @@
*
*/
-#include <grpc/grpc_security.h>
#include <grpc/support/log.h>
#include <grpc++/channel_arguments.h>
-#include <grpc++/config.h>
-#include <grpc++/credentials.h>
#include "src/cpp/client/channel.h"
+#include "src/cpp/client/secure_credentials.h"
namespace grpc {
-class SecureCredentials GRPC_FINAL : public Credentials {
- public:
- explicit SecureCredentials(grpc_credentials* c_creds) : c_creds_(c_creds) {}
- ~SecureCredentials() GRPC_OVERRIDE { grpc_credentials_release(c_creds_); }
- grpc_credentials* GetRawCreds() { return c_creds_; }
-
- std::shared_ptr<grpc::ChannelInterface> CreateChannel(
- const string& target, const grpc::ChannelArguments& args) GRPC_OVERRIDE {
- grpc_channel_args channel_args;
- args.SetChannelArgs(&channel_args);
- return std::shared_ptr<ChannelInterface>(new Channel(
- args.GetSslTargetNameOverride().empty()
- ? target
- : args.GetSslTargetNameOverride(),
- grpc_secure_channel_create(c_creds_, target.c_str(), &channel_args)));
- }
-
- SecureCredentials* AsSecureCredentials() GRPC_OVERRIDE { return this; }
-
- private:
- grpc_credentials* const c_creds_;
-};
+std::shared_ptr<grpc::ChannelInterface> SecureCredentials::CreateChannel(
+ const string& target, const grpc::ChannelArguments& args) {
+ grpc_channel_args channel_args;
+ args.SetChannelArgs(&channel_args);
+ return std::shared_ptr<ChannelInterface>(new Channel(
+ args.GetSslTargetNameOverride().empty() ? target
+ : args.GetSslTargetNameOverride(),
+ grpc_secure_channel_create(c_creds_, target.c_str(), &channel_args)));
+}
namespace {
std::unique_ptr<Credentials> WrapCredentials(grpc_credentials* creds) {
diff --git a/src/cpp/client/secure_credentials.h b/src/cpp/client/secure_credentials.h
new file mode 100644
index 0000000000..77d575813e
--- /dev/null
+++ b/src/cpp/client/secure_credentials.h
@@ -0,0 +1,61 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_INTERNAL_CPP_CLIENT_SECURE_CREDENTIALS_H
+#define GRPC_INTERNAL_CPP_CLIENT_SECURE_CREDENTIALS_H
+
+#include <grpc/grpc_security.h>
+
+#include <grpc++/config.h>
+#include <grpc++/credentials.h>
+
+namespace grpc {
+
+class SecureCredentials GRPC_FINAL : public Credentials {
+ public:
+ explicit SecureCredentials(grpc_credentials* c_creds) : c_creds_(c_creds) {}
+ ~SecureCredentials() GRPC_OVERRIDE { grpc_credentials_release(c_creds_); }
+ grpc_credentials* GetRawCreds() { return c_creds_; }
+
+ std::shared_ptr<grpc::ChannelInterface> CreateChannel(
+ const string& target, const grpc::ChannelArguments& args) GRPC_OVERRIDE;
+ SecureCredentials* AsSecureCredentials() GRPC_OVERRIDE { return this; }
+
+ private:
+ grpc_credentials* const c_creds_;
+};
+
+} // namespace grpc
+
+#endif // GRPC_INTERNAL_CPP_CLIENT_SECURE_CREDENTIALS_H
+
diff --git a/src/cpp/server/secure_server_credentials.cc b/src/cpp/server/secure_server_credentials.cc
index 49d69a3fb9..3e262dd74f 100644
--- a/src/cpp/server/secure_server_credentials.cc
+++ b/src/cpp/server/secure_server_credentials.cc
@@ -31,39 +31,22 @@
*
*/
-#include <grpc/grpc_security.h>
-
-#include <grpc++/server_credentials.h>
+#include "src/cpp/server/secure_server_credentials.h"
namespace grpc {
-namespace {
-class SecureServerCredentials GRPC_FINAL : public ServerCredentials {
- public:
- explicit SecureServerCredentials(grpc_server_credentials* creds)
- : creds_(creds) {}
- ~SecureServerCredentials() GRPC_OVERRIDE {
- grpc_server_credentials_release(creds_);
- }
-
- int AddPortToServer(const grpc::string& addr,
- grpc_server* server) GRPC_OVERRIDE {
- return grpc_server_add_secure_http2_port(server, addr.c_str(), creds_);
- }
-
- private:
- grpc_server_credentials* const creds_;
-};
-} // namespace
+int SecureServerCredentials::AddPortToServer(
+ const grpc::string& addr, grpc_server* server) {
+ return grpc_server_add_secure_http2_port(server, addr.c_str(), creds_);
+}
std::shared_ptr<ServerCredentials> SslServerCredentials(
const SslServerCredentialsOptions& options) {
std::vector<grpc_ssl_pem_key_cert_pair> pem_key_cert_pairs;
for (auto key_cert_pair = options.pem_key_cert_pairs.begin();
- key_cert_pair != options.pem_key_cert_pairs.end();
- key_cert_pair++) {
+ key_cert_pair != options.pem_key_cert_pairs.end(); key_cert_pair++) {
grpc_ssl_pem_key_cert_pair p = {key_cert_pair->private_key.c_str(),
- key_cert_pair->cert_chain.c_str()};
+ key_cert_pair->cert_chain.c_str()};
pem_key_cert_pairs.push_back(p);
}
grpc_server_credentials* c_creds = grpc_ssl_server_credentials_create(
diff --git a/src/cpp/server/secure_server_credentials.h b/src/cpp/server/secure_server_credentials.h
new file mode 100644
index 0000000000..b9803f107e
--- /dev/null
+++ b/src/cpp/server/secure_server_credentials.h
@@ -0,0 +1,60 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_INTERNAL_CPP_SERVER_SECURE_SERVER_CREDENTIALS_H
+#define GRPC_INTERNAL_CPP_SERVER_SECURE_SERVER_CREDENTIALS_H
+
+#include <grpc/grpc_security.h>
+
+#include <grpc++/server_credentials.h>
+
+namespace grpc {
+
+class SecureServerCredentials GRPC_FINAL : public ServerCredentials {
+ public:
+ explicit SecureServerCredentials(grpc_server_credentials* creds)
+ : creds_(creds) {}
+ ~SecureServerCredentials() GRPC_OVERRIDE {
+ grpc_server_credentials_release(creds_);
+ }
+
+ int AddPortToServer(const grpc::string& addr,
+ grpc_server* server) GRPC_OVERRIDE;
+
+ private:
+ grpc_server_credentials* const creds_;
+};
+
+} // namespace grpc
+
+#endif // GRPC_INTERNAL_CPP_SERVER_SECURE_SERVER_CREDENTIALS_H
diff --git a/src/ruby/ext/grpc/rb_byte_buffer.c b/src/ruby/ext/grpc/rb_byte_buffer.c
index ff5a114de5..e3a5277f54 100644
--- a/src/ruby/ext/grpc/rb_byte_buffer.c
+++ b/src/ruby/ext/grpc/rb_byte_buffer.c
@@ -39,203 +39,29 @@
#include <grpc/support/slice.h>
#include "rb_grpc.h"
-/* grpc_rb_byte_buffer wraps a grpc_byte_buffer. It provides a peer ruby
- * object, 'mark' to minimize copying when a byte_buffer is created from
- * ruby. */
-typedef struct grpc_rb_byte_buffer {
- /* Holder of ruby objects involved in constructing the status */
- VALUE mark;
- /* The actual status */
- grpc_byte_buffer *wrapped;
-} grpc_rb_byte_buffer;
-
-/* Destroys ByteBuffer instances. */
-static void grpc_rb_byte_buffer_free(void *p) {
- grpc_rb_byte_buffer *bb = NULL;
- if (p == NULL) {
- return;
- };
- bb = (grpc_rb_byte_buffer *)p;
-
- /* Deletes the wrapped object if the mark object is Qnil, which indicates
- * that no other object is the actual owner. */
- if (bb->wrapped != NULL && bb->mark == Qnil) {
- grpc_byte_buffer_destroy(bb->wrapped);
- }
-
- xfree(p);
-}
-
-/* Protects the mark object from GC */
-static void grpc_rb_byte_buffer_mark(void *p) {
- grpc_rb_byte_buffer *bb = NULL;
- if (p == NULL) {
- return;
- }
- bb = (grpc_rb_byte_buffer *)p;
-
- /* If it's not already cleaned up, mark the mark object */
- if (bb->mark != Qnil && BUILTIN_TYPE(bb->mark) != T_NONE) {
- rb_gc_mark(bb->mark);
- }
+grpc_byte_buffer* grpc_rb_s_to_byte_buffer(char *string, size_t length) {
+ gpr_slice slice = gpr_slice_from_copied_buffer(string, length);
+ grpc_byte_buffer *buffer = grpc_byte_buffer_create(&slice, 1);
+ gpr_slice_unref(slice);
+ return buffer;
}
-/* id_source is the name of the hidden ivar the preserves the original
- * byte_buffer source string */
-static ID id_source;
-
-/* Allocates ByteBuffer instances.
-
- Provides safe default values for the byte_buffer fields. */
-static VALUE grpc_rb_byte_buffer_alloc(VALUE cls) {
- grpc_rb_byte_buffer *wrapper = ALLOC(grpc_rb_byte_buffer);
- wrapper->wrapped = NULL;
- wrapper->mark = Qnil;
- return Data_Wrap_Struct(cls, grpc_rb_byte_buffer_mark,
- grpc_rb_byte_buffer_free, wrapper);
-}
-
-/* Clones ByteBuffer instances.
-
- Gives ByteBuffer a consistent implementation of Ruby's object copy/dup
- protocol. */
-static VALUE grpc_rb_byte_buffer_init_copy(VALUE copy, VALUE orig) {
- grpc_rb_byte_buffer *orig_bb = NULL;
- grpc_rb_byte_buffer *copy_bb = NULL;
-
- if (copy == orig) {
- return copy;
- }
-
- /* Raise an error if orig is not a metadata object or a subclass. */
- if (TYPE(orig) != T_DATA ||
- RDATA(orig)->dfree != (RUBY_DATA_FUNC)grpc_rb_byte_buffer_free) {
- rb_raise(rb_eTypeError, "not a %s", rb_obj_classname(rb_cByteBuffer));
- }
-
- Data_Get_Struct(orig, grpc_rb_byte_buffer, orig_bb);
- Data_Get_Struct(copy, grpc_rb_byte_buffer, copy_bb);
-
- /* use ruby's MEMCPY to make a byte-for-byte copy of the metadata wrapper
- * object. */
- MEMCPY(copy_bb, orig_bb, grpc_rb_byte_buffer, 1);
- return copy;
-}
-
-/* id_empty is used to return the empty string from to_s when necessary. */
-static ID id_empty;
-
-static VALUE grpc_rb_byte_buffer_to_s(VALUE self) {
- grpc_rb_byte_buffer *wrapper = NULL;
- grpc_byte_buffer *bb = NULL;
- grpc_byte_buffer_reader *reader = NULL;
- char *output = NULL;
+VALUE grpc_rb_byte_buffer_to_s(grpc_byte_buffer *buffer) {
size_t length = 0;
+ char *string = NULL;
size_t offset = 0;
- VALUE output_obj = Qnil;
+ grpc_byte_buffer_reader *reader = NULL;
gpr_slice next;
+ if (buffer == NULL) {
+ return Qnil;
- Data_Get_Struct(self, grpc_rb_byte_buffer, wrapper);
- output_obj = rb_ivar_get(wrapper->mark, id_source);
- if (output_obj != Qnil) {
- /* From ruby, ByteBuffers are immutable so if a source is set, return that
- * as the to_s value */
- return output_obj;
- }
-
- /* Read the bytes. */
- bb = wrapper->wrapped;
- if (bb == NULL) {
- return rb_id2str(id_empty);
- }
- length = grpc_byte_buffer_length(bb);
- if (length == 0) {
- return rb_id2str(id_empty);
}
- reader = grpc_byte_buffer_reader_create(bb);
- output = xmalloc(length);
+ length = grpc_byte_buffer_length(buffer);
+ string = xmalloc(length + 1);
+ reader = grpc_byte_buffer_reader_create(buffer);
while (grpc_byte_buffer_reader_next(reader, &next) != 0) {
- memcpy(output + offset, GPR_SLICE_START_PTR(next), GPR_SLICE_LENGTH(next));
+ memcpy(string + offset, GPR_SLICE_START_PTR(next), GPR_SLICE_LENGTH(next));
offset += GPR_SLICE_LENGTH(next);
}
- output_obj = rb_str_new(output, length);
-
- /* Save a references to the computed string in the mark object so that the
- * calling to_s does not do any allocations. */
- wrapper->mark = rb_class_new_instance(0, NULL, rb_cObject);
- rb_ivar_set(wrapper->mark, id_source, output_obj);
-
- return output_obj;
-}
-
-/* Initializes ByteBuffer instances. */
-static VALUE grpc_rb_byte_buffer_init(VALUE self, VALUE src) {
- gpr_slice a_slice;
- grpc_rb_byte_buffer *wrapper = NULL;
- grpc_byte_buffer *byte_buffer = NULL;
-
- if (TYPE(src) != T_STRING) {
- rb_raise(rb_eTypeError, "bad byte_buffer arg: got <%s>, want <String>",
- rb_obj_classname(src));
- return Qnil;
- }
- Data_Get_Struct(self, grpc_rb_byte_buffer, wrapper);
- a_slice = gpr_slice_malloc(RSTRING_LEN(src));
- memcpy(GPR_SLICE_START_PTR(a_slice), RSTRING_PTR(src), RSTRING_LEN(src));
- byte_buffer = grpc_byte_buffer_create(&a_slice, 1);
- gpr_slice_unref(a_slice);
-
- if (byte_buffer == NULL) {
- rb_raise(rb_eArgError, "could not create a byte_buffer, not sure why");
- return Qnil;
- }
- wrapper->wrapped = byte_buffer;
-
- /* Save a references to the original string in the mark object so that the
- * pointers used there is valid for the lifetime of the object. */
- wrapper->mark = rb_class_new_instance(0, NULL, rb_cObject);
- rb_ivar_set(wrapper->mark, id_source, src);
-
- return self;
-}
-
-/* rb_cByteBuffer is the ruby class that proxies grpc_byte_buffer. */
-VALUE rb_cByteBuffer = Qnil;
-
-void Init_grpc_byte_buffer() {
- rb_cByteBuffer =
- rb_define_class_under(rb_mGrpcCore, "ByteBuffer", rb_cObject);
-
- /* Allocates an object managed by the ruby runtime */
- rb_define_alloc_func(rb_cByteBuffer, grpc_rb_byte_buffer_alloc);
-
- /* Provides a ruby constructor and support for dup/clone. */
- rb_define_method(rb_cByteBuffer, "initialize", grpc_rb_byte_buffer_init, 1);
- rb_define_method(rb_cByteBuffer, "initialize_copy",
- grpc_rb_byte_buffer_init_copy, 1);
-
- /* Provides a to_s method that returns the buffer value */
- rb_define_method(rb_cByteBuffer, "to_s", grpc_rb_byte_buffer_to_s, 0);
-
- id_source = rb_intern("__source");
- id_empty = rb_intern("");
-}
-
-VALUE grpc_rb_byte_buffer_create_with_mark(VALUE mark, grpc_byte_buffer *bb) {
- grpc_rb_byte_buffer *byte_buffer = NULL;
- if (bb == NULL) {
- return Qnil;
- }
- byte_buffer = ALLOC(grpc_rb_byte_buffer);
- byte_buffer->wrapped = bb;
- byte_buffer->mark = mark;
- return Data_Wrap_Struct(rb_cByteBuffer, grpc_rb_byte_buffer_mark,
- grpc_rb_byte_buffer_free, byte_buffer);
-}
-
-/* Gets the wrapped byte_buffer from the ruby wrapper */
-grpc_byte_buffer *grpc_rb_get_wrapped_byte_buffer(VALUE v) {
- grpc_rb_byte_buffer *wrapper = NULL;
- Data_Get_Struct(v, grpc_rb_byte_buffer, wrapper);
- return wrapper->wrapped;
+ return rb_str_new(string, length);
}
diff --git a/src/ruby/ext/grpc/rb_byte_buffer.h b/src/ruby/ext/grpc/rb_byte_buffer.h
index 6ef72f3e75..96b9009dae 100644
--- a/src/ruby/ext/grpc/rb_byte_buffer.h
+++ b/src/ruby/ext/grpc/rb_byte_buffer.h
@@ -37,18 +37,10 @@
#include <grpc/grpc.h>
#include <ruby.h>
-/* rb_cByteBuffer is the ByteBuffer class whose instances proxy
- grpc_byte_buffer. */
-extern VALUE rb_cByteBuffer;
+/* Converts a char* with a length to a grpc_byte_buffer */
+grpc_byte_buffer *grpc_rb_s_to_byte_buffer(char *string, size_t length);
-/* Initializes the ByteBuffer class. */
-void Init_grpc_byte_buffer();
-
-/* grpc_rb_byte_buffer_create_with_mark creates a grpc_rb_byte_buffer with a
- * ruby mark object that will be kept alive while the byte_buffer is alive. */
-VALUE grpc_rb_byte_buffer_create_with_mark(VALUE mark, grpc_byte_buffer* bb);
-
-/* Gets the wrapped byte_buffer from its ruby object. */
-grpc_byte_buffer* grpc_rb_get_wrapped_byte_buffer(VALUE v);
+/* Converts a grpc_byte_buffer to a ruby string */
+VALUE grpc_rb_byte_buffer_to_s(grpc_byte_buffer *buffer);
#endif /* GRPC_RB_BYTE_BUFFER_H_ */
diff --git a/src/ruby/ext/grpc/rb_call.c b/src/ruby/ext/grpc/rb_call.c
index b5a256d5a6..18cb4ec4f2 100644
--- a/src/ruby/ext/grpc/rb_call.c
+++ b/src/ruby/ext/grpc/rb_call.c
@@ -36,11 +36,19 @@
#include <ruby.h>
#include <grpc/grpc.h>
+#include <grpc/support/alloc.h>
+
#include "rb_byte_buffer.h"
#include "rb_completion_queue.h"
-#include "rb_metadata.h"
#include "rb_grpc.h"
+/* rb_sBatchResult is struct class used to hold the results of a batch call */
+static VALUE rb_sBatchResult;
+
+/* rb_cMdAry is the MetadataArray class whose instances proxy
+ * grpc_metadata_array. */
+static VALUE rb_cMdAry;
+
/* id_cq is the name of the hidden ivar that preserves a reference to a
* completion queue */
static ID id_cq;
@@ -62,6 +70,15 @@ static ID id_metadata;
* received by the call and subsequently saved on it. */
static ID id_status;
+/* sym_* are the symbol for attributes of rb_sBatchResult. */
+static VALUE sym_send_message;
+static VALUE sym_send_metadata;
+static VALUE sym_send_close;
+static VALUE sym_send_status;
+static VALUE sym_message;
+static VALUE sym_status;
+static VALUE sym_cancelled;
+
/* hash_all_calls is a hash of Call address -> reference count that is used to
* track the creation and destruction of rb_call instances.
*/
@@ -101,84 +118,6 @@ const char *grpc_call_error_detail_of(grpc_call_error err) {
return detail;
}
-/* grpc_rb_call_add_metadata_hash_cb is the hash iteration callback used by
- grpc_rb_call_add_metadata.
-*/
-int grpc_rb_call_add_metadata_hash_cb(VALUE key, VALUE val, VALUE call_obj) {
- grpc_call *call = NULL;
- grpc_metadata *md = NULL;
- VALUE md_obj = Qnil;
- VALUE md_obj_args[2];
- VALUE flags = rb_ivar_get(call_obj, id_flags);
- grpc_call_error err;
- int array_length;
- int i;
-
- /* Construct a metadata object from key and value and add it */
- Data_Get_Struct(call_obj, grpc_call, call);
- md_obj_args[0] = key;
-
- if (TYPE(val) == T_ARRAY) {
- /* If the value is an array, add each value in the array separately */
- array_length = RARRAY_LEN(val);
- for (i = 0; i < array_length; i++) {
- md_obj_args[1] = rb_ary_entry(val, i);
- md_obj = rb_class_new_instance(2, md_obj_args, rb_cMetadata);
- md = grpc_rb_get_wrapped_metadata(md_obj);
- err = grpc_call_add_metadata_old(call, md, NUM2UINT(flags));
- if (err != GRPC_CALL_OK) {
- rb_raise(rb_eCallError, "add metadata failed: %s (code=%d)",
- grpc_call_error_detail_of(err), err);
- return ST_STOP;
- }
- }
- } else {
- md_obj_args[1] = val;
- md_obj = rb_class_new_instance(2, md_obj_args, rb_cMetadata);
- md = grpc_rb_get_wrapped_metadata(md_obj);
- err = grpc_call_add_metadata_old(call, md, NUM2UINT(flags));
- if (err != GRPC_CALL_OK) {
- rb_raise(rb_eCallError, "add metadata failed: %s (code=%d)",
- grpc_call_error_detail_of(err), err);
- return ST_STOP;
- }
- }
-
- return ST_CONTINUE;
-}
-
-/*
- call-seq:
- call.add_metadata(completion_queue, hash_elements, flags=nil)
-
- Add metadata elements to the call from a ruby hash, to be sent upon
- invocation. flags is a bit-field combination of the write flags defined
- above. REQUIRES: grpc_call_invoke/grpc_call_accept have not been
- called on this call. Produces no events. */
-
-static VALUE grpc_rb_call_add_metadata(int argc, VALUE *argv, VALUE self) {
- VALUE metadata;
- VALUE flags = Qnil;
- ID id_size = rb_intern("size");
-
- /* "11" == 1 mandatory args, 1 (flags) is optional */
- rb_scan_args(argc, argv, "11", &metadata, &flags);
- if (NIL_P(flags)) {
- flags = UINT2NUM(0); /* Default to no flags */
- }
- if (TYPE(metadata) != T_HASH) {
- rb_raise(rb_eTypeError, "add metadata failed: metadata should be a hash");
- return Qnil;
- }
- if (NUM2UINT(rb_funcall(metadata, id_size, 0)) == 0) {
- return Qnil;
- }
- rb_ivar_set(self, id_flags, flags);
- rb_ivar_set(self, id_input_md, metadata);
- rb_hash_foreach(metadata, grpc_rb_call_add_metadata_hash_cb, self);
- return Qnil;
-}
-
/* Called by clients to cancel an RPC on the server.
Can be called multiple times, from any thread. */
static VALUE grpc_rb_call_cancel(VALUE self) {
@@ -196,75 +135,18 @@ static VALUE grpc_rb_call_cancel(VALUE self) {
/*
call-seq:
- call.invoke(completion_queue, tag, flags=nil)
-
- Invoke the RPC. Starts sending metadata and request headers on the wire.
- flags is a bit-field combination of the write flags defined above.
- REQUIRES: Can be called at most once per call.
- Can only be called on the client.
- Produces a GRPC_INVOKE_ACCEPTED event on completion. */
-static VALUE grpc_rb_call_invoke(int argc, VALUE *argv, VALUE self) {
- VALUE cqueue = Qnil;
- VALUE metadata_read_tag = Qnil;
- VALUE finished_tag = Qnil;
- VALUE flags = Qnil;
- grpc_call *call = NULL;
- grpc_completion_queue *cq = NULL;
- grpc_call_error err;
+ status = call.status
- /* "31" == 3 mandatory args, 1 (flags) is optional */
- rb_scan_args(argc, argv, "31", &cqueue, &metadata_read_tag, &finished_tag,
- &flags);
- if (NIL_P(flags)) {
- flags = UINT2NUM(0); /* Default to no flags */
- }
- cq = grpc_rb_get_wrapped_completion_queue(cqueue);
- Data_Get_Struct(self, grpc_call, call);
- err = grpc_call_invoke_old(call, cq, ROBJECT(metadata_read_tag),
- ROBJECT(finished_tag), NUM2UINT(flags));
- if (err != GRPC_CALL_OK) {
- rb_raise(rb_eCallError, "invoke failed: %s (code=%d)",
- grpc_call_error_detail_of(err), err);
- }
-
- /* Add the completion queue as an instance attribute, prevents it from being
- * GCed until this call object is GCed */
- rb_ivar_set(self, id_cq, cqueue);
-
- return Qnil;
-}
-
-/* Initiate a read on a call. Output event contains a byte buffer with the
- result of the read.
- REQUIRES: No other reads are pending on the call. It is only safe to start
- the next read after the corresponding read event is received. */
-static VALUE grpc_rb_call_start_read(VALUE self, VALUE tag) {
- grpc_call *call = NULL;
- grpc_call_error err;
- Data_Get_Struct(self, grpc_call, call);
- err = grpc_call_start_read_old(call, ROBJECT(tag));
- if (err != GRPC_CALL_OK) {
- rb_raise(rb_eCallError, "start read failed: %s (code=%d)",
- grpc_call_error_detail_of(err), err);
- }
-
- return Qnil;
-}
-
-/*
- call-seq:
- status = call.status
-
- Gets the status object saved the call. */
+ Gets the status object saved the call. */
static VALUE grpc_rb_call_get_status(VALUE self) {
return rb_ivar_get(self, id_status);
}
/*
call-seq:
- call.status = status
+ call.status = status
- Saves a status object on the call. */
+ Saves a status object on the call. */
static VALUE grpc_rb_call_set_status(VALUE self, VALUE status) {
if (!NIL_P(status) && rb_obj_class(status) != rb_sStatus) {
rb_raise(rb_eTypeError, "bad status: got:<%s> want: <Struct::Status>",
@@ -277,18 +159,18 @@ static VALUE grpc_rb_call_set_status(VALUE self, VALUE status) {
/*
call-seq:
- metadata = call.metadata
+ metadata = call.metadata
- Gets the metadata object saved the call. */
+ Gets the metadata object saved the call. */
static VALUE grpc_rb_call_get_metadata(VALUE self) {
return rb_ivar_get(self, id_metadata);
}
/*
call-seq:
- call.metadata = metadata
+ call.metadata = metadata
- Saves the metadata hash on the call. */
+ Saves the metadata hash on the call. */
static VALUE grpc_rb_call_set_metadata(VALUE self, VALUE metadata) {
if (!NIL_P(metadata) && TYPE(metadata) != T_HASH) {
rb_raise(rb_eTypeError, "bad metadata: got:<%s> want: <Hash>",
@@ -299,147 +181,402 @@ static VALUE grpc_rb_call_set_metadata(VALUE self, VALUE metadata) {
return rb_ivar_set(self, id_metadata, metadata);
}
-/*
- call-seq:
- call.start_write(byte_buffer, tag, flags=nil)
-
- Queue a byte buffer for writing.
- flags is a bit-field combination of the write flags defined above.
- A write with byte_buffer null is allowed, and will not send any bytes on the
- wire. If this is performed without GRPC_WRITE_BUFFER_HINT flag it provides
- a mechanism to flush any previously buffered writes to outgoing flow control.
- REQUIRES: No other writes are pending on the call. It is only safe to
- start the next write after the corresponding write_accepted event
- is received.
- GRPC_INVOKE_ACCEPTED must have been received by the application
- prior to calling this on the client. On the server,
- grpc_call_accept must have been called successfully.
- Produces a GRPC_WRITE_ACCEPTED event. */
-static VALUE grpc_rb_call_start_write(int argc, VALUE *argv, VALUE self) {
- VALUE byte_buffer = Qnil;
- VALUE tag = Qnil;
- VALUE flags = Qnil;
- grpc_call *call = NULL;
- grpc_byte_buffer *bfr = NULL;
- grpc_call_error err;
+/* grpc_rb_md_ary_fill_hash_cb is the hash iteration callback used
+ to fill grpc_metadata_array.
+
+ it's capacity should have been computed via a prior call to
+ grpc_rb_md_ary_fill_hash_cb
+*/
+int grpc_rb_md_ary_fill_hash_cb(VALUE key, VALUE val, VALUE md_ary_obj) {
+ grpc_metadata_array *md_ary = NULL;
+ int array_length;
+ int i;
+
+ /* Construct a metadata object from key and value and add it */
+ Data_Get_Struct(md_ary_obj, grpc_metadata_array, md_ary);
- /* "21" == 2 mandatory args, 1 (flags) is optional */
- rb_scan_args(argc, argv, "21", &byte_buffer, &tag, &flags);
- if (NIL_P(flags)) {
- flags = UINT2NUM(0); /* Default to no flags */
+ if (TYPE(val) == T_ARRAY) {
+ /* If the value is an array, add capacity for each value in the array */
+ array_length = RARRAY_LEN(val);
+ for (i = 0; i < array_length; i++) {
+ if (TYPE(key) == T_SYMBOL) {
+ md_ary->metadata[md_ary->count].key = (char *)rb_id2name(SYM2ID(key));
+ } else { /* StringValueCStr does all other type exclusions for us */
+ md_ary->metadata[md_ary->count].key = StringValueCStr(key);
+ }
+ md_ary->metadata[md_ary->count].value = RSTRING_PTR(rb_ary_entry(val, i));
+ md_ary->metadata[md_ary->count].value_length =
+ RSTRING_LEN(rb_ary_entry(val, i));
+ md_ary->count += 1;
+ }
+ } else {
+ if (TYPE(key) == T_SYMBOL) {
+ md_ary->metadata[md_ary->count].key = (char *)rb_id2name(SYM2ID(key));
+ } else { /* StringValueCStr does all other type exclusions for us */
+ md_ary->metadata[md_ary->count].key = StringValueCStr(key);
+ }
+ md_ary->metadata[md_ary->count].value = RSTRING_PTR(val);
+ md_ary->metadata[md_ary->count].value_length = RSTRING_LEN(val);
+ md_ary->count += 1;
}
- bfr = grpc_rb_get_wrapped_byte_buffer(byte_buffer);
- Data_Get_Struct(self, grpc_call, call);
- err = grpc_call_start_write_old(call, bfr, ROBJECT(tag), NUM2UINT(flags));
- if (err != GRPC_CALL_OK) {
- rb_raise(rb_eCallError, "start write failed: %s (code=%d)",
- grpc_call_error_detail_of(err), err);
+
+ return ST_CONTINUE;
+}
+
+/* grpc_rb_md_ary_capacity_hash_cb is the hash iteration callback used
+ to pre-compute the capacity a grpc_metadata_array.
+*/
+int grpc_rb_md_ary_capacity_hash_cb(VALUE key, VALUE val, VALUE md_ary_obj) {
+ grpc_metadata_array *md_ary = NULL;
+
+ /* Construct a metadata object from key and value and add it */
+ Data_Get_Struct(md_ary_obj, grpc_metadata_array, md_ary);
+
+ if (TYPE(val) == T_ARRAY) {
+ /* If the value is an array, add capacity for each value in the array */
+ md_ary->capacity += RARRAY_LEN(val);
+ } else {
+ md_ary->capacity += 1;
+ }
+ return ST_CONTINUE;
+}
+
+/* grpc_rb_md_ary_convert converts a ruby metadata hash into
+ a grpc_metadata_array.
+*/
+void grpc_rb_md_ary_convert(VALUE md_ary_hash, grpc_metadata_array *md_ary) {
+ VALUE md_ary_obj = Qnil;
+ if (md_ary_hash == Qnil) {
+ return; /* Do nothing if the expected has value is nil */
+ }
+ if (TYPE(md_ary_hash) != T_HASH) {
+ rb_raise(rb_eTypeError, "md_ary_convert: got <%s>, want <Hash>",
+ rb_obj_classname(md_ary_hash));
+ return;
}
- return Qnil;
+ /* Initialize the array, compute it's capacity, then fill it. */
+ grpc_metadata_array_init(md_ary);
+ md_ary_obj = Data_Wrap_Struct(rb_cMdAry, GC_NOT_MARKED, GC_DONT_FREE, md_ary);
+ rb_hash_foreach(md_ary_hash, grpc_rb_md_ary_capacity_hash_cb, md_ary_obj);
+ md_ary->metadata = gpr_malloc(md_ary->capacity * sizeof(grpc_metadata));
+ rb_hash_foreach(md_ary_hash, grpc_rb_md_ary_fill_hash_cb, md_ary_obj);
}
-/* Queue a status for writing.
-
- call-seq:
- tag = Object.new
- call.write_status(200, "OK", tag)
-
- REQUIRES: No other writes are pending on the call. It is only safe to
- start the next write after the corresponding write_accepted event
- is received.
- GRPC_INVOKE_ACCEPTED must have been received by the application
- prior to calling this.
- Only callable on the server.
- Produces a GRPC_FINISHED event when the status is sent and the stream is
- fully closed */
-static VALUE grpc_rb_call_start_write_status(VALUE self, VALUE code,
- VALUE status, VALUE tag) {
- grpc_call *call = NULL;
- grpc_call_error err;
- Data_Get_Struct(self, grpc_call, call);
- err = grpc_call_start_write_status_old(call, NUM2UINT(code),
- StringValueCStr(status), ROBJECT(tag));
- if (err != GRPC_CALL_OK) {
- rb_raise(rb_eCallError, "start write status: %s (code=%d)",
- grpc_call_error_detail_of(err), err);
+/* Converts a metadata array to a hash. */
+VALUE grpc_rb_md_ary_to_h(grpc_metadata_array *md_ary) {
+ VALUE key = Qnil;
+ VALUE new_ary = Qnil;
+ VALUE value = Qnil;
+ VALUE result = rb_hash_new();
+ size_t i;
+
+ for (i = 0; i < md_ary->count; i++) {
+ key = rb_str_new2(md_ary->metadata[i].key);
+ value = rb_hash_aref(result, key);
+ if (value == Qnil) {
+ value = rb_str_new(md_ary->metadata[i].value,
+ md_ary->metadata[i].value_length);
+ rb_hash_aset(result, key, value);
+ } else if (TYPE(value) == T_ARRAY) {
+ /* Add the string to the returned array */
+ rb_ary_push(value,
+ rb_str_new(md_ary->metadata[i].value,
+ md_ary->metadata[i].value_length));
+ } else {
+ /* Add the current value with this key and the new one to an array */
+ new_ary = rb_ary_new();
+ rb_ary_push(new_ary, value);
+ rb_ary_push(new_ary,
+ rb_str_new(md_ary->metadata[i].value,
+ md_ary->metadata[i].value_length));
+ rb_hash_aset(result, key, new_ary);
+ }
}
+ return result;
+}
- return Qnil;
+/* grpc_rb_call_check_op_keys_hash_cb is a hash iteration func that checks
+ each key of an ops hash is valid.
+*/
+int grpc_rb_call_check_op_keys_hash_cb(VALUE key, VALUE val, VALUE ops_ary) {
+ /* Update the capacity; the value is an array, add capacity for each value in
+ * the array */
+ if (TYPE(key) != T_FIXNUM) {
+ rb_raise(rb_eTypeError, "invalid operation : got <%s>, want <Fixnum>",
+ rb_obj_classname(key));
+ return ST_STOP;
+ }
+ switch(NUM2INT(key)) {
+ case GRPC_OP_SEND_INITIAL_METADATA:
+ case GRPC_OP_SEND_MESSAGE:
+ case GRPC_OP_SEND_CLOSE_FROM_CLIENT:
+ case GRPC_OP_SEND_STATUS_FROM_SERVER:
+ case GRPC_OP_RECV_INITIAL_METADATA:
+ case GRPC_OP_RECV_MESSAGE:
+ case GRPC_OP_RECV_STATUS_ON_CLIENT:
+ case GRPC_OP_RECV_CLOSE_ON_SERVER:
+ rb_ary_push(ops_ary, key);
+ return ST_CONTINUE;
+ default:
+ rb_raise(rb_eTypeError, "invalid operation : bad value %d",
+ NUM2INT(key));
+ };
+ return ST_STOP;
}
-/* No more messages to send.
- REQUIRES: No other writes are pending on the call. */
-static VALUE grpc_rb_call_writes_done(VALUE self, VALUE tag) {
- grpc_call *call = NULL;
- grpc_call_error err;
- Data_Get_Struct(self, grpc_call, call);
- err = grpc_call_writes_done_old(call, ROBJECT(tag));
- if (err != GRPC_CALL_OK) {
- rb_raise(rb_eCallError, "writes done: %s (code=%d)",
- grpc_call_error_detail_of(err), err);
+/* grpc_rb_op_update_status_from_server adds the values in a ruby status
+ struct to the 'send_status_from_server' portion of an op.
+*/
+void grpc_rb_op_update_status_from_server(grpc_op *op,
+ grpc_metadata_array* md_ary,
+ VALUE status) {
+ VALUE code = rb_struct_aref(status, sym_code);
+ VALUE details = rb_struct_aref(status, sym_details);
+ VALUE metadata_hash = rb_struct_aref(status, sym_metadata);
+
+ /* TODO: add check to ensure status is the correct struct type */
+ if (TYPE(code) != T_FIXNUM) {
+ rb_raise(rb_eTypeError, "invalid code : got <%s>, want <Fixnum>",
+ rb_obj_classname(code));
+ return;
+ }
+ if (TYPE(details) != T_STRING) {
+ rb_raise(rb_eTypeError, "invalid details : got <%s>, want <String>",
+ rb_obj_classname(code));
+ return;
}
+ op->data.send_status_from_server.status = NUM2INT(code);
+ op->data.send_status_from_server.status_details = StringValueCStr(details);
+ grpc_rb_md_ary_convert(metadata_hash, md_ary);
+ op->data.send_status_from_server.trailing_metadata_count = md_ary->count;
+ op->data.send_status_from_server.trailing_metadata = md_ary->metadata;
+}
- return Qnil;
+/* run_batch_stack holds various values used by the
+ * grpc_rb_call_run_batch function */
+typedef struct run_batch_stack {
+ /* The batch ops */
+ grpc_op ops[8]; /* 8 is the maximum number of operations */
+ size_t op_num; /* tracks the last added operation */
+
+ /* Data being sent */
+ grpc_metadata_array send_metadata;
+ grpc_metadata_array send_trailing_metadata;
+
+ /* Data being received */
+ grpc_byte_buffer *recv_message;
+ grpc_metadata_array recv_metadata;
+ grpc_metadata_array recv_trailing_metadata;
+ int recv_cancelled;
+ grpc_status_code recv_status;
+ char *recv_status_details;
+ size_t recv_status_details_capacity;
+} run_batch_stack;
+
+/* grpc_run_batch_stack_init ensures the run_batch_stack is properly
+ * initialized */
+static void grpc_run_batch_stack_init(run_batch_stack* st) {
+ MEMZERO(st, run_batch_stack, 1);
+ grpc_metadata_array_init(&st->send_metadata);
+ grpc_metadata_array_init(&st->send_trailing_metadata);
+ grpc_metadata_array_init(&st->recv_metadata);
+ grpc_metadata_array_init(&st->recv_trailing_metadata);
+ st->op_num = 0;
}
-/* call-seq:
- call.server_end_initial_metadata(flag)
-
- Only to be called on servers, before sending messages.
- flags is a bit-field combination of the write flags defined above.
-
- REQUIRES: Can be called at most once per call.
- Can only be called on the server, must be called after
- grpc_call_server_accept
- Produces no events */
-static VALUE grpc_rb_call_server_end_initial_metadata(int argc, VALUE *argv,
- VALUE self) {
- VALUE flags = Qnil;
- grpc_call *call = NULL;
- grpc_call_error err;
+/* grpc_run_batch_stack_cleanup ensures the run_batch_stack is properly
+ * cleaned up */
+static void grpc_run_batch_stack_cleanup(run_batch_stack* st) {
+ grpc_metadata_array_destroy(&st->send_metadata);
+ grpc_metadata_array_destroy(&st->send_trailing_metadata);
+ grpc_metadata_array_destroy(&st->recv_metadata);
+ grpc_metadata_array_destroy(&st->recv_trailing_metadata);
+ if (st->recv_status_details != NULL) {
+ gpr_free(st->recv_status_details);
+ }
+}
- /* "01" == 1 (flags) is optional */
- rb_scan_args(argc, argv, "01", &flags);
- if (NIL_P(flags)) {
- flags = UINT2NUM(0); /* Default to no flags */
+/* grpc_run_batch_stack_fill_ops fills the run_batch_stack ops array from
+ * ops_hash */
+static void grpc_run_batch_stack_fill_ops(run_batch_stack* st, VALUE ops_hash) {
+ VALUE this_op = Qnil;
+ VALUE this_value = Qnil;
+ VALUE ops_ary = rb_ary_new();
+ size_t i = 0;
+
+ /* Create a ruby array with just the operation keys */
+ rb_hash_foreach(ops_hash, grpc_rb_call_check_op_keys_hash_cb, ops_ary);
+
+ /* Fill the ops array */
+ for (i = 0; i < (size_t)RARRAY_LEN(ops_ary); i++) {
+ this_op = rb_ary_entry(ops_ary, i);
+ this_value = rb_hash_aref(ops_hash, this_op);
+ switch(NUM2INT(this_op)) {
+ case GRPC_OP_SEND_INITIAL_METADATA:
+ /* N.B. later there is no need to explicitly delete the metadata keys
+ * and values, they are references to data in ruby objects. */
+ grpc_rb_md_ary_convert(this_value, &st->send_metadata);
+ st->ops[st->op_num].data.send_initial_metadata.count =
+ st->send_metadata.count;
+ st->ops[st->op_num].data.send_initial_metadata.metadata =
+ st->send_metadata.metadata;
+ break;
+ case GRPC_OP_SEND_MESSAGE:
+ st->ops[st->op_num].data.send_message =
+ grpc_rb_s_to_byte_buffer(RSTRING_PTR(this_value),
+ RSTRING_LEN(this_value));
+ break;
+ case GRPC_OP_SEND_CLOSE_FROM_CLIENT:
+ break;
+ case GRPC_OP_SEND_STATUS_FROM_SERVER:
+ /* N.B. later there is no need to explicitly delete the metadata keys
+ * and values, they are references to data in ruby objects. */
+ grpc_rb_op_update_status_from_server(&st->ops[st->op_num],
+ &st->send_trailing_metadata,
+ this_value);
+ break;
+ case GRPC_OP_RECV_INITIAL_METADATA:
+ st->ops[st->op_num].data.recv_initial_metadata = &st->recv_metadata;
+ break;
+ case GRPC_OP_RECV_MESSAGE:
+ st->ops[st->op_num].data.recv_message = &st->recv_message;
+ break;
+ case GRPC_OP_RECV_STATUS_ON_CLIENT:
+ st->ops[st->op_num].data.recv_status_on_client.trailing_metadata =
+ &st->recv_trailing_metadata;
+ st->ops[st->op_num].data.recv_status_on_client.status =
+ &st->recv_status;
+ st->ops[st->op_num].data.recv_status_on_client.status_details =
+ &st->recv_status_details;
+ st->ops[st->op_num].data.recv_status_on_client.status_details_capacity =
+ &st->recv_status_details_capacity;
+ break;
+ case GRPC_OP_RECV_CLOSE_ON_SERVER:
+ st->ops[st->op_num].data.recv_close_on_server.cancelled =
+ &st->recv_cancelled;
+ break;
+ default:
+ grpc_run_batch_stack_cleanup(st);
+ rb_raise(rb_eTypeError, "invalid operation : bad value %d",
+ NUM2INT(this_op));
+ };
+ st->ops[st->op_num].op = (grpc_op_type)NUM2INT(this_op);
+ st->op_num++;
}
- Data_Get_Struct(self, grpc_call, call);
- err = grpc_call_server_end_initial_metadata_old(call, NUM2UINT(flags));
- if (err != GRPC_CALL_OK) {
- rb_raise(rb_eCallError, "end_initial_metadata failed: %s (code=%d)",
- grpc_call_error_detail_of(err), err);
+}
+
+/* grpc_run_batch_stack_build_result fills constructs a ruby BatchResult struct
+ after the results have run */
+static VALUE grpc_run_batch_stack_build_result(run_batch_stack* st) {
+ size_t i = 0;
+ VALUE result = rb_struct_new(rb_sBatchResult, Qnil, Qnil, Qnil, Qnil, Qnil,
+ Qnil, Qnil, Qnil, NULL);
+ for (i = 0; i < st->op_num; i++) {
+ switch(st->ops[i].op) {
+ case GRPC_OP_SEND_INITIAL_METADATA:
+ rb_struct_aset(result, sym_send_metadata, Qtrue);
+ break;
+ case GRPC_OP_SEND_MESSAGE:
+ rb_struct_aset(result, sym_send_message, Qtrue);
+ grpc_byte_buffer_destroy(st->ops[i].data.send_message);
+ break;
+ case GRPC_OP_SEND_CLOSE_FROM_CLIENT:
+ rb_struct_aset(result, sym_send_close, Qtrue);
+ break;
+ case GRPC_OP_SEND_STATUS_FROM_SERVER:
+ rb_struct_aset(result, sym_send_status, Qtrue);
+ break;
+ case GRPC_OP_RECV_INITIAL_METADATA:
+ rb_struct_aset(result, sym_metadata,
+ grpc_rb_md_ary_to_h(&st->recv_metadata));
+ case GRPC_OP_RECV_MESSAGE:
+ rb_struct_aset(result, sym_message,
+ grpc_rb_byte_buffer_to_s(st->recv_message));
+ break;
+ case GRPC_OP_RECV_STATUS_ON_CLIENT:
+ rb_struct_aset(
+ result,
+ sym_status,
+ rb_struct_new(rb_sStatus,
+ UINT2NUM(st->recv_status),
+ (st->recv_status_details == NULL
+ ? Qnil
+ : rb_str_new2(st->recv_status_details)),
+ grpc_rb_md_ary_to_h(&st->recv_trailing_metadata),
+ NULL));
+ break;
+ case GRPC_OP_RECV_CLOSE_ON_SERVER:
+ rb_struct_aset(result, sym_send_close, Qtrue);
+ break;
+ default:
+ break;
+ }
}
- return Qnil;
+ return result;
}
/* call-seq:
- call.server_accept(completion_queue, finished_tag)
-
- Accept an incoming RPC, binding a completion queue to it.
- To be called before sending or receiving messages.
-
- REQUIRES: Can be called at most once per call.
- Can only be called on the server.
- Produces a GRPC_FINISHED event with finished_tag when the call has been
- completed (there may be other events for the call pending at this
- time) */
-static VALUE grpc_rb_call_server_accept(VALUE self, VALUE cqueue,
- VALUE finished_tag) {
+ cq = CompletionQueue.new
+ ops = {
+ GRPC::Core::CallOps::SEND_INITIAL_METADATA => <op_value>,
+ GRPC::Core::CallOps::SEND_MESSAGE => <op_value>,
+ ...
+ }
+ tag = Object.new
+ timeout = 10
+ call.start_batch(cqueue, tag, timeout, ops)
+
+ Start a batch of operations defined in the array ops; when complete, post a
+ completion of type 'tag' to the completion queue bound to the call.
+
+ Also waits for the batch to complete, until timeout is reached.
+ The order of ops specified in the batch has no significance.
+ Only one operation of each type can be active at once in any given
+ batch */
+static VALUE grpc_rb_call_run_batch(VALUE self, VALUE cqueue, VALUE tag,
+ VALUE timeout, VALUE ops_hash) {
+ run_batch_stack st;
grpc_call *call = NULL;
- grpc_completion_queue *cq = grpc_rb_get_wrapped_completion_queue(cqueue);
+ grpc_event *ev = NULL;
grpc_call_error err;
+ VALUE result = Qnil;
Data_Get_Struct(self, grpc_call, call);
- err = grpc_call_server_accept_old(call, cq, ROBJECT(finished_tag));
+
+ /* Validate the ops args, adding them to a ruby array */
+ if (TYPE(ops_hash) != T_HASH) {
+ rb_raise(rb_eTypeError, "call#run_batch: ops hash should be a hash");
+ return Qnil;
+ }
+ grpc_run_batch_stack_init(&st);
+ grpc_run_batch_stack_fill_ops(&st, ops_hash);
+
+ /* call grpc_call_start_batch, then wait for it to complete using
+ * pluck_event */
+ err = grpc_call_start_batch(call, st.ops, st.op_num, ROBJECT(tag));
if (err != GRPC_CALL_OK) {
- rb_raise(rb_eCallError, "server_accept failed: %s (code=%d)",
+ grpc_run_batch_stack_cleanup(&st);
+ rb_raise(rb_eCallError, "grpc_call_start_batch failed with %s (code=%d)",
grpc_call_error_detail_of(err), err);
+ return;
+ }
+ ev = grpc_rb_completion_queue_pluck_event(cqueue, tag, timeout);
+ if (ev == NULL) {
+ grpc_run_batch_stack_cleanup(&st);
+ rb_raise(rb_eOutOfTime, "grpc_call_start_batch timed out");
+ return;
+ }
+ if (ev->data.op_complete != GRPC_OP_OK) {
+ grpc_run_batch_stack_cleanup(&st);
+ rb_raise(rb_eCallError, "start_batch completion failed, (code=%d)",
+ ev->data.op_complete);
+ return;
}
- /* Add the completion queue as an instance attribute, prevents it from being
- * GCed until this call object is GCed */
- rb_ivar_set(self, id_cq, cqueue);
- return Qnil;
+ /* Build and return the BatchResult struct result */
+ result = grpc_run_batch_stack_build_result(&st);
+ grpc_run_batch_stack_cleanup(&st);
+ return result;
}
/* rb_cCall is the ruby class that proxies grpc_call. */
@@ -449,6 +586,10 @@ VALUE rb_cCall = Qnil;
operations; */
VALUE rb_eCallError = Qnil;
+/* rb_eOutOfTime is the ruby class of the exception thrown to indicate
+ a timeout. */
+VALUE rb_eOutOfTime = Qnil;
+
void Init_grpc_error_codes() {
/* Constants representing the error codes of grpc_call_error in grpc.h */
VALUE rb_RpcErrors = rb_define_module_under(rb_mGrpcCore, "RpcErrors");
@@ -500,11 +641,35 @@ void Init_grpc_error_codes() {
rb_obj_freeze(rb_error_code_details);
}
+void Init_grpc_op_codes() {
+ /* Constants representing operation type codes in grpc.h */
+ VALUE rb_CallOps = rb_define_module_under(rb_mGrpcCore, "CallOps");
+ rb_define_const(rb_CallOps, "SEND_INITIAL_METADATA",
+ UINT2NUM(GRPC_OP_SEND_INITIAL_METADATA));
+ rb_define_const(rb_CallOps, "SEND_MESSAGE", UINT2NUM(GRPC_OP_SEND_MESSAGE));
+ rb_define_const(rb_CallOps, "SEND_CLOSE_FROM_CLIENT",
+ UINT2NUM(GRPC_OP_SEND_CLOSE_FROM_CLIENT));
+ rb_define_const(rb_CallOps, "SEND_STATUS_FROM_SERVER",
+ UINT2NUM(GRPC_OP_SEND_STATUS_FROM_SERVER));
+ rb_define_const(rb_CallOps, "RECV_INITIAL_METADATA",
+ UINT2NUM(GRPC_OP_RECV_INITIAL_METADATA));
+ rb_define_const(rb_CallOps, "RECV_MESSAGE",
+ UINT2NUM(GRPC_OP_RECV_MESSAGE));
+ rb_define_const(rb_CallOps, "RECV_STATUS_ON_CLIENT",
+ UINT2NUM(GRPC_OP_RECV_STATUS_ON_CLIENT));
+ rb_define_const(rb_CallOps, "RECV_CLOSE_ON_SERVER",
+ UINT2NUM(GRPC_OP_RECV_CLOSE_ON_SERVER));
+}
+
void Init_grpc_call() {
/* CallError inherits from Exception to signal that it is non-recoverable */
rb_eCallError =
rb_define_class_under(rb_mGrpcCore, "CallError", rb_eException);
+ rb_eOutOfTime =
+ rb_define_class_under(rb_mGrpcCore, "OutOfTime", rb_eException);
rb_cCall = rb_define_class_under(rb_mGrpcCore, "Call", rb_cObject);
+ rb_cMdAry = rb_define_class_under(rb_mGrpcCore, "MetadataArray",
+ rb_cObject);
/* Prevent allocation or inialization of the Call class */
rb_define_alloc_func(rb_cCall, grpc_rb_cannot_alloc);
@@ -512,17 +677,8 @@ void Init_grpc_call() {
rb_define_method(rb_cCall, "initialize_copy", grpc_rb_cannot_init_copy, 1);
/* Add ruby analogues of the Call methods. */
- rb_define_method(rb_cCall, "server_accept", grpc_rb_call_server_accept, 2);
- rb_define_method(rb_cCall, "server_end_initial_metadata",
- grpc_rb_call_server_end_initial_metadata, -1);
- rb_define_method(rb_cCall, "add_metadata", grpc_rb_call_add_metadata, -1);
+ rb_define_method(rb_cCall, "run_batch", grpc_rb_call_run_batch, 4);
rb_define_method(rb_cCall, "cancel", grpc_rb_call_cancel, 0);
- rb_define_method(rb_cCall, "invoke", grpc_rb_call_invoke, -1);
- rb_define_method(rb_cCall, "start_read", grpc_rb_call_start_read, 1);
- rb_define_method(rb_cCall, "start_write", grpc_rb_call_start_write, -1);
- rb_define_method(rb_cCall, "start_write_status",
- grpc_rb_call_start_write_status, 3);
- rb_define_method(rb_cCall, "writes_done", grpc_rb_call_writes_done, 1);
rb_define_method(rb_cCall, "status", grpc_rb_call_get_status, 0);
rb_define_method(rb_cCall, "status=", grpc_rb_call_set_status, 1);
rb_define_method(rb_cCall, "metadata", grpc_rb_call_get_metadata, 0);
@@ -537,12 +693,35 @@ void Init_grpc_call() {
id_flags = rb_intern("__flags");
id_input_md = rb_intern("__input_md");
+ /* Ids used in constructing the batch result. */
+ sym_send_message = ID2SYM(rb_intern("send_message"));
+ sym_send_metadata = ID2SYM(rb_intern("send_metadata"));
+ sym_send_close = ID2SYM(rb_intern("send_close"));
+ sym_send_status = ID2SYM(rb_intern("send_status"));
+ sym_message = ID2SYM(rb_intern("message"));
+ sym_status = ID2SYM(rb_intern("status"));
+ sym_cancelled = ID2SYM(rb_intern("cancelled"));
+
+ /* The Struct used to return the run_batch result. */
+ rb_sBatchResult = rb_struct_define(
+ "BatchResult",
+ "send_message",
+ "send_metadata",
+ "send_close",
+ "send_status",
+ "message",
+ "metadata",
+ "status",
+ "cancelled",
+ NULL);
+
/* The hash for reference counting calls, to ensure they can't be destroyed
* more than once */
hash_all_calls = rb_hash_new();
rb_define_const(rb_cCall, "INTERNAL_ALL_CALLs", hash_all_calls);
Init_grpc_error_codes();
+ Init_grpc_op_codes();
}
/* Gets the call from the ruby object */
diff --git a/src/ruby/ext/grpc/rb_call.h b/src/ruby/ext/grpc/rb_call.h
index bb51759a46..03e570863c 100644
--- a/src/ruby/ext/grpc/rb_call.h
+++ b/src/ruby/ext/grpc/rb_call.h
@@ -46,13 +46,20 @@ VALUE grpc_rb_wrap_call(grpc_call* c);
/* Provides the details of an call error */
const char* grpc_call_error_detail_of(grpc_call_error err);
+/* Converts a metadata array to a hash. */
+VALUE grpc_rb_md_ary_to_h(grpc_metadata_array *md_ary);
+
/* rb_cCall is the Call class whose instances proxy grpc_call. */
extern VALUE rb_cCall;
-/* rb_cCallError is the ruby class of the exception thrown during call
+/* rb_eCallError is the ruby class of the exception thrown during call
operations. */
extern VALUE rb_eCallError;
+/* rb_eOutOfTime is the ruby class of the exception thrown to indicate
+ a timeout. */
+extern VALUE rb_eOutOfTime;
+
/* Initializes the Call class. */
void Init_grpc_call();
diff --git a/src/ruby/ext/grpc/rb_channel.c b/src/ruby/ext/grpc/rb_channel.c
index 2a48f46ce2..76a65fe6fe 100644
--- a/src/ruby/ext/grpc/rb_channel.c
+++ b/src/ruby/ext/grpc/rb_channel.c
@@ -49,10 +49,16 @@
static ID id_channel;
/* id_target is the name of the hidden ivar that preserves a reference to the
- * target string used to create the call, preserved so that is does not get
+ * target string used to create the call, preserved so that it does not get
* GCed before the channel */
static ID id_target;
+/* id_cqueue is the name of the hidden ivar that preserves a reference to the
+ * completion queue used to create the call, preserved so that it does not get
+ * GCed before the channel */
+static ID id_cqueue;
+
+
/* Used during the conversion of a hash to channel args during channel setup */
static VALUE rb_cChannelArgs;
@@ -142,6 +148,7 @@ static VALUE grpc_rb_channel_init(int argc, VALUE *argv, VALUE self) {
if (ch == NULL) {
rb_raise(rb_eRuntimeError, "could not create an rpc channel to target:%s",
target_chars);
+ return Qnil;
}
rb_ivar_set(self, id_target, target);
wrapper->wrapped = ch;
@@ -164,6 +171,7 @@ static VALUE grpc_rb_channel_init_copy(VALUE copy, VALUE orig) {
if (TYPE(orig) != T_DATA ||
RDATA(orig)->dfree != (RUBY_DATA_FUNC)grpc_rb_channel_free) {
rb_raise(rb_eTypeError, "not a %s", rb_obj_classname(rb_cChannel));
+ return Qnil;
}
Data_Get_Struct(orig, grpc_rb_channel, orig_ch);
@@ -177,34 +185,42 @@ static VALUE grpc_rb_channel_init_copy(VALUE copy, VALUE orig) {
/* Create a call given a grpc_channel, in order to call method. The request
is not sent until grpc_call_invoke is called. */
-static VALUE grpc_rb_channel_create_call(VALUE self, VALUE method, VALUE host,
- VALUE deadline) {
+static VALUE grpc_rb_channel_create_call(VALUE self, VALUE cqueue, VALUE method,
+ VALUE host, VALUE deadline) {
VALUE res = Qnil;
grpc_rb_channel *wrapper = NULL;
- grpc_channel *ch = NULL;
grpc_call *call = NULL;
+ grpc_channel *ch = NULL;
+ grpc_completion_queue *cq = NULL;
char *method_chars = StringValueCStr(method);
char *host_chars = StringValueCStr(host);
+ cq = grpc_rb_get_wrapped_completion_queue(cqueue);
Data_Get_Struct(self, grpc_rb_channel, wrapper);
ch = wrapper->wrapped;
if (ch == NULL) {
rb_raise(rb_eRuntimeError, "closed!");
+ return Qnil;
}
call =
- grpc_channel_create_call_old(ch, method_chars, host_chars,
- grpc_rb_time_timeval(deadline,
- /* absolute time */ 0));
+ grpc_channel_create_call(ch, cq, method_chars, host_chars,
+ grpc_rb_time_timeval(deadline,
+ /* absolute time */ 0));
if (call == NULL) {
rb_raise(rb_eRuntimeError, "cannot create call with method %s",
method_chars);
+ return Qnil;
}
res = grpc_rb_wrap_call(call);
- /* Make this channel an instance attribute of the call so that is is not GCed
+ /* Make this channel an instance attribute of the call so that it is not GCed
* before the call. */
rb_ivar_set(res, id_channel, self);
+
+ /* Make the completion queue an instance attribute of the call so that it is
+ * not GCed before the call. */
+ rb_ivar_set(res, id_cqueue, cqueue);
return res;
}
@@ -240,11 +256,12 @@ void Init_grpc_channel() {
1);
/* Add ruby analogues of the Channel methods. */
- rb_define_method(rb_cChannel, "create_call", grpc_rb_channel_create_call, 3);
+ rb_define_method(rb_cChannel, "create_call", grpc_rb_channel_create_call, 4);
rb_define_method(rb_cChannel, "destroy", grpc_rb_channel_destroy, 0);
rb_define_alias(rb_cChannel, "close", "destroy");
id_channel = rb_intern("__channel");
+ id_cqueue = rb_intern("__cqueue");
id_target = rb_intern("__target");
rb_define_const(rb_cChannel, "SSL_TARGET",
ID2SYM(rb_intern(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG)));
diff --git a/src/ruby/ext/grpc/rb_completion_queue.c b/src/ruby/ext/grpc/rb_completion_queue.c
index 3fdbdd837a..688db94851 100644
--- a/src/ruby/ext/grpc/rb_completion_queue.c
+++ b/src/ruby/ext/grpc/rb_completion_queue.c
@@ -38,7 +38,6 @@
#include <grpc/grpc.h>
#include <grpc/support/time.h>
#include "rb_grpc.h"
-#include "rb_event.h"
/* Used to allow grpc_completion_queue_next call to release the GIL */
typedef struct next_call_stack {
@@ -140,8 +139,19 @@ static VALUE grpc_rb_completion_queue_next(VALUE self, VALUE timeout) {
/* Blocks until the next event for given tag is available, and returns the
* event. */
-static VALUE grpc_rb_completion_queue_pluck(VALUE self, VALUE tag,
- VALUE timeout) {
+VALUE grpc_rb_completion_queue_pluck(VALUE self, VALUE tag,
+ VALUE timeout) {
+ grpc_event *ev = grpc_rb_completion_queue_pluck_event(self, tag, timeout);
+ if (ev == NULL) {
+ return Qnil;
+ }
+ return grpc_rb_new_event(ev);
+}
+
+/* Blocks until the next event for given tag is available, and returns the
+ * event. */
+grpc_event* grpc_rb_completion_queue_pluck_event(VALUE self, VALUE tag,
+ VALUE timeout) {
next_call_stack next_call;
MEMZERO(&next_call, next_call_stack, 1);
Data_Get_Struct(self, grpc_completion_queue, next_call.cq);
@@ -151,9 +161,9 @@ static VALUE grpc_rb_completion_queue_pluck(VALUE self, VALUE tag,
rb_thread_call_without_gvl(grpc_rb_completion_queue_pluck_no_gil,
(void *)&next_call, NULL, NULL);
if (next_call.event == NULL) {
- return Qnil;
+ return NULL;
}
- return grpc_rb_new_event(next_call.event);
+ return next_call.event;
}
/* rb_cCompletionQueue is the ruby class that proxies grpc_completion_queue. */
diff --git a/src/ruby/ext/grpc/rb_completion_queue.h b/src/ruby/ext/grpc/rb_completion_queue.h
index 38025ea2d2..13715ccaa7 100644
--- a/src/ruby/ext/grpc/rb_completion_queue.h
+++ b/src/ruby/ext/grpc/rb_completion_queue.h
@@ -40,6 +40,14 @@
/* Gets the wrapped completion queue from the ruby wrapper */
grpc_completion_queue *grpc_rb_get_wrapped_completion_queue(VALUE v);
+/**
+ * Makes the implementation of CompletionQueue#pluck available in other files
+ *
+ * This avoids having code that holds the GIL repeated at multiple sites.
+ */
+grpc_event* grpc_rb_completion_queue_pluck_event(VALUE cqueue, VALUE tag,
+ VALUE timeout);
+
/* rb_cCompletionQueue is the CompletionQueue class whose instances proxy
grpc_completion_queue. */
extern VALUE rb_cCompletionQueue;
diff --git a/src/ruby/ext/grpc/rb_event.c b/src/ruby/ext/grpc/rb_event.c
deleted file mode 100644
index 2e64af4c84..0000000000
--- a/src/ruby/ext/grpc/rb_event.c
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "rb_event.h"
-
-#include <ruby.h>
-
-#include <grpc/grpc.h>
-#include "rb_grpc.h"
-#include "rb_byte_buffer.h"
-#include "rb_call.h"
-#include "rb_metadata.h"
-
-/* grpc_rb_event wraps a grpc_event. It provides a peer ruby object,
- * 'mark' to minimize copying when an event is created from ruby. */
-typedef struct grpc_rb_event {
- /* Holder of ruby objects involved in constructing the channel */
- VALUE mark;
- /* The actual event */
- grpc_event *wrapped;
-} grpc_rb_event;
-
-/* rb_mCompletionType is a ruby module that holds the completion type values */
-VALUE rb_mCompletionType = Qnil;
-
-/* Destroys Event instances. */
-static void grpc_rb_event_free(void *p) {
- grpc_rb_event *ev = NULL;
- if (p == NULL) {
- return;
- };
- ev = (grpc_rb_event *)p;
-
- /* Deletes the wrapped object if the mark object is Qnil, which indicates
- * that no other object is the actual owner. */
- if (ev->wrapped != NULL && ev->mark == Qnil) {
- grpc_event_finish(ev->wrapped);
- rb_warning("event gc: destroyed the c event");
- } else {
- rb_warning("event gc: did not destroy the c event");
- }
-
- xfree(p);
-}
-
-/* Protects the mark object from GC */
-static void grpc_rb_event_mark(void *p) {
- grpc_rb_event *event = NULL;
- if (p == NULL) {
- return;
- }
- event = (grpc_rb_event *)p;
- if (event->mark != Qnil) {
- rb_gc_mark(event->mark);
- }
-}
-
-static VALUE grpc_rb_event_result(VALUE self);
-
-/* Obtains the type of an event. */
-static VALUE grpc_rb_event_type(VALUE self) {
- grpc_event *event = NULL;
- grpc_rb_event *wrapper = NULL;
- Data_Get_Struct(self, grpc_rb_event, wrapper);
- if (wrapper->wrapped == NULL) {
- rb_raise(rb_eRuntimeError, "finished!");
- return Qnil;
- }
-
- event = wrapper->wrapped;
- switch (event->type) {
- case GRPC_QUEUE_SHUTDOWN:
- return rb_const_get(rb_mCompletionType, rb_intern("QUEUE_SHUTDOWN"));
-
- case GRPC_READ:
- return rb_const_get(rb_mCompletionType, rb_intern("READ"));
-
- case GRPC_WRITE_ACCEPTED:
- grpc_rb_event_result(self); /* validates the result */
- return rb_const_get(rb_mCompletionType, rb_intern("WRITE_ACCEPTED"));
-
- case GRPC_FINISH_ACCEPTED:
- grpc_rb_event_result(self); /* validates the result */
- return rb_const_get(rb_mCompletionType, rb_intern("FINISH_ACCEPTED"));
-
- case GRPC_CLIENT_METADATA_READ:
- return rb_const_get(rb_mCompletionType,
- rb_intern("CLIENT_METADATA_READ"));
-
- case GRPC_FINISHED:
- return rb_const_get(rb_mCompletionType, rb_intern("FINISHED"));
-
- case GRPC_SERVER_RPC_NEW:
- return rb_const_get(rb_mCompletionType, rb_intern("SERVER_RPC_NEW"));
-
- default:
- rb_raise(rb_eRuntimeError, "unrecognized event code for an rpc event:%d",
- event->type);
- }
- return Qnil; /* should not be reached */
-}
-
-/* Obtains the tag associated with an event. */
-static VALUE grpc_rb_event_tag(VALUE self) {
- grpc_event *event = NULL;
- grpc_rb_event *wrapper = NULL;
- Data_Get_Struct(self, grpc_rb_event, wrapper);
- if (wrapper->wrapped == NULL) {
- rb_raise(rb_eRuntimeError, "finished!");
- return Qnil;
- }
-
- event = wrapper->wrapped;
- if (event->tag == NULL) {
- return Qnil;
- }
- return (VALUE)event->tag;
-}
-
-/* Obtains the call associated with an event. */
-static VALUE grpc_rb_event_call(VALUE self) {
- grpc_event *event = NULL;
- grpc_rb_event *wrapper = NULL;
- Data_Get_Struct(self, grpc_rb_event, wrapper);
- if (wrapper->wrapped == NULL) {
- rb_raise(rb_eRuntimeError, "finished!");
- return Qnil;
- }
-
- event = wrapper->wrapped;
- if (event->call != NULL) {
- return grpc_rb_wrap_call(event->call);
- }
- return Qnil;
-}
-
-/* Obtains the metadata associated with an event. */
-static VALUE grpc_rb_event_metadata(VALUE self) {
- grpc_event *event = NULL;
- grpc_rb_event *wrapper = NULL;
- grpc_metadata *metadata = NULL;
- VALUE key = Qnil;
- VALUE new_ary = Qnil;
- VALUE result = Qnil;
- VALUE value = Qnil;
- size_t count = 0;
- size_t i = 0;
- Data_Get_Struct(self, grpc_rb_event, wrapper);
- if (wrapper->wrapped == NULL) {
- rb_raise(rb_eRuntimeError, "finished!");
- return Qnil;
- }
-
- /* Figure out which metadata to read. */
- event = wrapper->wrapped;
- switch (event->type) {
- case GRPC_CLIENT_METADATA_READ:
- count = event->data.client_metadata_read.count;
- metadata = event->data.client_metadata_read.elements;
- break;
-
- case GRPC_FINISHED:
- count = event->data.finished.metadata_count;
- metadata = event->data.finished.metadata_elements;
- break;
-
- case GRPC_SERVER_RPC_NEW:
- count = event->data.server_rpc_new.metadata_count;
- metadata = event->data.server_rpc_new.metadata_elements;
- break;
-
- default:
- rb_raise(rb_eRuntimeError,
- "bug: bad event type metadata. got %d; want %d|%d:%d",
- event->type, GRPC_CLIENT_METADATA_READ, GRPC_FINISHED,
- GRPC_SERVER_RPC_NEW);
- return Qnil;
- }
-
- result = rb_hash_new();
- for (i = 0; i < count; i++) {
- key = rb_str_new2(metadata[i].key);
- value = rb_hash_aref(result, key);
- if (value == Qnil) {
- value = rb_str_new(metadata[i].value, metadata[i].value_length);
- rb_hash_aset(result, key, value);
- } else if (TYPE(value) == T_ARRAY) {
- /* Add the string to the returned array */
- rb_ary_push(value,
- rb_str_new(metadata[i].value, metadata[i].value_length));
- } else {
- /* Add the current value with this key and the new one to an array */
- new_ary = rb_ary_new();
- rb_ary_push(new_ary, value);
- rb_ary_push(new_ary,
- rb_str_new(metadata[i].value, metadata[i].value_length));
- rb_hash_aset(result, key, new_ary);
- }
- }
- return result;
-}
-
-/* Obtains the data associated with an event. */
-static VALUE grpc_rb_event_result(VALUE self) {
- grpc_event *event = NULL;
- grpc_rb_event *wrapper = NULL;
- Data_Get_Struct(self, grpc_rb_event, wrapper);
- if (wrapper->wrapped == NULL) {
- rb_raise(rb_eRuntimeError, "finished!");
- return Qnil;
- }
- event = wrapper->wrapped;
-
- switch (event->type) {
- case GRPC_QUEUE_SHUTDOWN:
- return Qnil;
-
- case GRPC_READ:
- return grpc_rb_byte_buffer_create_with_mark(self, event->data.read);
-
- case GRPC_FINISH_ACCEPTED:
- if (event->data.finish_accepted == GRPC_OP_OK) {
- return Qnil;
- }
- rb_raise(rb_eEventError, "finish failed, not sure why (code=%d)",
- event->data.finish_accepted);
- break;
-
- case GRPC_WRITE_ACCEPTED:
- if (event->data.write_accepted == GRPC_OP_OK) {
- return Qnil;
- }
- rb_raise(rb_eEventError, "write failed, not sure why (code=%d)",
- event->data.write_accepted);
- break;
-
- case GRPC_CLIENT_METADATA_READ:
- return grpc_rb_event_metadata(self);
-
- case GRPC_FINISHED:
- return rb_struct_new(rb_sStatus, UINT2NUM(event->data.finished.status),
- (event->data.finished.details == NULL
- ? Qnil
- : rb_str_new2(event->data.finished.details)),
- grpc_rb_event_metadata(self), NULL);
- break;
-
- case GRPC_SERVER_RPC_NEW:
- return rb_struct_new(
- rb_sNewServerRpc, rb_str_new2(event->data.server_rpc_new.method),
- rb_str_new2(event->data.server_rpc_new.host),
- Data_Wrap_Struct(rb_cTimeVal, GC_NOT_MARKED, GC_DONT_FREE,
- (void *)&event->data.server_rpc_new.deadline),
- grpc_rb_event_metadata(self), NULL);
-
- default:
- rb_raise(rb_eRuntimeError, "unrecognized event code for an rpc event:%d",
- event->type);
- }
-
- return Qfalse;
-}
-
-static VALUE grpc_rb_event_finish(VALUE self) {
- grpc_event *event = NULL;
- grpc_rb_event *wrapper = NULL;
- Data_Get_Struct(self, grpc_rb_event, wrapper);
- if (wrapper->wrapped == NULL) { /* already closed */
- return Qnil;
- }
- event = wrapper->wrapped;
- grpc_event_finish(event);
- wrapper->wrapped = NULL;
- wrapper->mark = Qnil;
- return Qnil;
-}
-
-/* rb_cEvent is the Event class whose instances proxy grpc_event */
-VALUE rb_cEvent = Qnil;
-
-/* rb_eEventError is the ruby class of the exception thrown on failures during
- rpc event processing. */
-VALUE rb_eEventError = Qnil;
-
-void Init_grpc_event() {
- rb_eEventError =
- rb_define_class_under(rb_mGrpcCore, "EventError", rb_eStandardError);
- rb_cEvent = rb_define_class_under(rb_mGrpcCore, "Event", rb_cObject);
-
- /* Prevent allocation or inialization from ruby. */
- rb_define_alloc_func(rb_cEvent, grpc_rb_cannot_alloc);
- rb_define_method(rb_cEvent, "initialize", grpc_rb_cannot_init, 0);
- rb_define_method(rb_cEvent, "initialize_copy", grpc_rb_cannot_init_copy, 1);
-
- /* Accessors for the data available in an event. */
- rb_define_method(rb_cEvent, "call", grpc_rb_event_call, 0);
- rb_define_method(rb_cEvent, "result", grpc_rb_event_result, 0);
- rb_define_method(rb_cEvent, "tag", grpc_rb_event_tag, 0);
- rb_define_method(rb_cEvent, "type", grpc_rb_event_type, 0);
- rb_define_method(rb_cEvent, "finish", grpc_rb_event_finish, 0);
- rb_define_alias(rb_cEvent, "close", "finish");
-
- /* Constants representing the completion types */
- rb_mCompletionType =
- rb_define_module_under(rb_mGrpcCore, "CompletionType");
- rb_define_const(rb_mCompletionType, "QUEUE_SHUTDOWN",
- INT2NUM(GRPC_QUEUE_SHUTDOWN));
- rb_define_const(rb_mCompletionType, "OP_COMPLETE", INT2NUM(GRPC_OP_COMPLETE));
- rb_define_const(rb_mCompletionType, "READ", INT2NUM(GRPC_READ));
- rb_define_const(rb_mCompletionType, "WRITE_ACCEPTED",
- INT2NUM(GRPC_WRITE_ACCEPTED));
- rb_define_const(rb_mCompletionType, "FINISH_ACCEPTED",
- INT2NUM(GRPC_FINISH_ACCEPTED));
- rb_define_const(rb_mCompletionType, "CLIENT_METADATA_READ",
- INT2NUM(GRPC_CLIENT_METADATA_READ));
- rb_define_const(rb_mCompletionType, "FINISHED", INT2NUM(GRPC_FINISHED));
- rb_define_const(rb_mCompletionType, "SERVER_RPC_NEW",
- INT2NUM(GRPC_SERVER_RPC_NEW));
- rb_define_const(rb_mCompletionType, "SERVER_SHUTDOWN",
- INT2NUM(GRPC_SERVER_SHUTDOWN));
- rb_define_const(rb_mCompletionType, "RESERVED",
- INT2NUM(GRPC_COMPLETION_DO_NOT_USE));
-}
-
-VALUE grpc_rb_new_event(grpc_event *ev) {
- grpc_rb_event *wrapper = ALLOC(grpc_rb_event);
- wrapper->wrapped = ev;
- wrapper->mark = Qnil;
- return Data_Wrap_Struct(rb_cEvent, grpc_rb_event_mark, grpc_rb_event_free,
- wrapper);
-}
diff --git a/src/ruby/ext/grpc/rb_grpc.c b/src/ruby/ext/grpc/rb_grpc.c
index 400efd0dfa..d4335dd1ba 100644
--- a/src/ruby/ext/grpc/rb_grpc.c
+++ b/src/ruby/ext/grpc/rb_grpc.c
@@ -39,12 +39,9 @@
#include <grpc/grpc.h>
#include <grpc/support/time.h>
-#include "rb_byte_buffer.h"
#include "rb_call.h"
#include "rb_channel.h"
#include "rb_completion_queue.h"
-#include "rb_event.h"
-#include "rb_metadata.h"
#include "rb_server.h"
#include "rb_credentials.h"
#include "rb_server_credentials.h"
@@ -195,7 +192,7 @@ static ID id_inspect;
/* id_to_s is the to_s method found on various ruby objects. */
static ID id_to_s;
-/* Converts `a wrapped time constant to a standard time. */
+/* Converts a wrapped time constant to a standard time. */
VALUE grpc_rb_time_val_to_time(VALUE self) {
gpr_timespec *time_const = NULL;
Data_Get_Struct(self, gpr_timespec, time_const);
@@ -257,16 +254,16 @@ void Init_grpc() {
rb_mGRPC = rb_define_module("GRPC");
rb_mGrpcCore = rb_define_module_under(rb_mGRPC, "Core");
rb_sNewServerRpc = rb_struct_define("NewServerRpc", "method", "host",
- "deadline", "metadata", NULL);
+ "deadline", "metadata", "call", NULL);
rb_sStatus = rb_struct_define("Status", "code", "details", "metadata", NULL);
+ sym_code = ID2SYM(rb_intern("code"));
+ sym_details = ID2SYM(rb_intern("details"));
+ sym_metadata = ID2SYM(rb_intern("metadata"));
- Init_grpc_byte_buffer();
- Init_grpc_event();
Init_grpc_channel();
Init_grpc_completion_queue();
Init_grpc_call();
Init_grpc_credentials();
- Init_grpc_metadata();
Init_grpc_server();
Init_grpc_server_credentials();
Init_grpc_status_codes();
diff --git a/src/ruby/ext/grpc/rb_grpc.h b/src/ruby/ext/grpc/rb_grpc.h
index 851f5ee69f..4ff9b7f6e9 100644
--- a/src/ruby/ext/grpc/rb_grpc.h
+++ b/src/ruby/ext/grpc/rb_grpc.h
@@ -50,6 +50,15 @@ extern VALUE rb_sNewServerRpc;
/* rb_sStruct is the struct that holds status details. */
extern VALUE rb_sStatus;
+/* sym_code is the symbol for the code attribute of rb_sStatus. */
+VALUE sym_code;
+
+/* sym_details is the symbol for the details attribute of rb_sStatus. */
+VALUE sym_details;
+
+/* sym_metadata is the symbol for the metadata attribute of rb_sStatus. */
+VALUE sym_metadata;
+
/* GC_NOT_MARKED is used in calls to Data_Wrap_Struct to indicate that the
wrapped struct does not need to participate in ruby gc. */
extern const RUBY_DATA_FUNC GC_NOT_MARKED;
diff --git a/src/ruby/ext/grpc/rb_metadata.c b/src/ruby/ext/grpc/rb_metadata.c
deleted file mode 100644
index 7622a8c57e..0000000000
--- a/src/ruby/ext/grpc/rb_metadata.c
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "rb_metadata.h"
-
-#include <ruby.h>
-#include <string.h>
-
-#include <grpc/grpc.h>
-#include "rb_grpc.h"
-
-/* grpc_rb_metadata wraps a grpc_metadata. It provides a peer ruby object,
- * 'mark' to minimize copying when a metadata is created from ruby. */
-typedef struct grpc_rb_metadata {
- /* Holder of ruby objects involved in constructing the metadata */
- VALUE mark;
- /* The actual metadata */
- grpc_metadata *wrapped;
-} grpc_rb_metadata;
-
-/* Destroys Metadata instances. */
-static void grpc_rb_metadata_free(void *p) {
- if (p == NULL) {
- return;
- };
-
- /* Because metadata is only created during a call to grpc_call_add_metadata,
- * and the call takes ownership of the metadata, this does not free the
- * wrapped struct, only the wrapper */
- xfree(p);
-}
-
-/* Protects the mark object from GC */
-static void grpc_rb_metadata_mark(void *p) {
- grpc_rb_metadata *md = NULL;
- if (p == NULL) {
- return;
- }
-
- md = (grpc_rb_metadata *)p;
- /* If it's not already cleaned up, mark the mark object */
- if (md->mark != Qnil && BUILTIN_TYPE(md->mark) != T_NONE) {
- rb_gc_mark(md->mark);
- }
-}
-
-/* Allocates Metadata instances.
-
- Provides safe default values for the Metadata fields. */
-static VALUE grpc_rb_metadata_alloc(VALUE cls) {
- grpc_rb_metadata *wrapper = ALLOC(grpc_rb_metadata);
- wrapper->wrapped = NULL;
- wrapper->mark = Qnil;
- return Data_Wrap_Struct(cls, grpc_rb_metadata_mark, grpc_rb_metadata_free,
- wrapper);
-}
-
-/* id_key and id_value are the names of the hidden ivars that preserve the
- * original byte_buffer source string */
-static ID id_key;
-static ID id_value;
-
-/* Initializes Metadata instances. */
-static VALUE grpc_rb_metadata_init(VALUE self, VALUE key, VALUE value) {
- grpc_rb_metadata *wrapper = NULL;
- grpc_metadata *md = ALLOC(grpc_metadata);
-
- /* Use direct pointers to the strings wrapped by the ruby object to avoid
- * copying */
- Data_Get_Struct(self, grpc_rb_metadata, wrapper);
- wrapper->wrapped = md;
- if (TYPE(key) == T_SYMBOL) {
- md->key = (char *)rb_id2name(SYM2ID(key));
- } else { /* StringValueCStr does all other type exclusions for us */
- md->key = StringValueCStr(key);
- }
- md->value = RSTRING_PTR(value);
- md->value_length = RSTRING_LEN(value);
-
- /* Save references to the original values on the mark object so that the
- * pointers used there are valid for the lifetime of the object. */
- wrapper->mark = rb_class_new_instance(0, NULL, rb_cObject);
- rb_ivar_set(wrapper->mark, id_key, key);
- rb_ivar_set(wrapper->mark, id_value, value);
-
- return self;
-}
-
-/* Clones Metadata instances.
-
- Gives Metadata a consistent implementation of Ruby's object copy/dup
- protocol. */
-static VALUE grpc_rb_metadata_init_copy(VALUE copy, VALUE orig) {
- grpc_rb_metadata *orig_md = NULL;
- grpc_rb_metadata *copy_md = NULL;
-
- if (copy == orig) {
- return copy;
- }
-
- /* Raise an error if orig is not a metadata object or a subclass. */
- if (TYPE(orig) != T_DATA ||
- RDATA(orig)->dfree != (RUBY_DATA_FUNC)grpc_rb_metadata_free) {
- rb_raise(rb_eTypeError, "not a %s", rb_obj_classname(rb_cMetadata));
- }
-
- Data_Get_Struct(orig, grpc_rb_metadata, orig_md);
- Data_Get_Struct(copy, grpc_rb_metadata, copy_md);
-
- /* use ruby's MEMCPY to make a byte-for-byte copy of the metadata wrapper
- * object. */
- MEMCPY(copy_md, orig_md, grpc_rb_metadata, 1);
- return copy;
-}
-
-/* Gets the key from a metadata instance. */
-static VALUE grpc_rb_metadata_key(VALUE self) {
- VALUE key = Qnil;
- grpc_rb_metadata *wrapper = NULL;
- grpc_metadata *md = NULL;
-
- Data_Get_Struct(self, grpc_rb_metadata, wrapper);
- if (wrapper->mark != Qnil) {
- key = rb_ivar_get(wrapper->mark, id_key);
- if (key != Qnil) {
- return key;
- }
- }
-
- md = wrapper->wrapped;
- if (md == NULL || md->key == NULL) {
- return Qnil;
- }
- return rb_str_new2(md->key);
-}
-
-/* Gets the value from a metadata instance. */
-static VALUE grpc_rb_metadata_value(VALUE self) {
- VALUE val = Qnil;
- grpc_rb_metadata *wrapper = NULL;
- grpc_metadata *md = NULL;
-
- Data_Get_Struct(self, grpc_rb_metadata, wrapper);
- if (wrapper->mark != Qnil) {
- val = rb_ivar_get(wrapper->mark, id_value);
- if (val != Qnil) {
- return val;
- }
- }
-
- md = wrapper->wrapped;
- if (md == NULL || md->value == NULL) {
- return Qnil;
- }
- return rb_str_new2(md->value);
-}
-
-/* rb_cMetadata is the Metadata class whose instances proxy grpc_metadata. */
-VALUE rb_cMetadata = Qnil;
-void Init_grpc_metadata() {
- rb_cMetadata =
- rb_define_class_under(rb_mGrpcCore, "Metadata", rb_cObject);
-
- /* Allocates an object managed by the ruby runtime */
- rb_define_alloc_func(rb_cMetadata, grpc_rb_metadata_alloc);
-
- /* Provides a ruby constructor and support for dup/clone. */
- rb_define_method(rb_cMetadata, "initialize", grpc_rb_metadata_init, 2);
- rb_define_method(rb_cMetadata, "initialize_copy", grpc_rb_metadata_init_copy,
- 1);
-
- /* Provides accessors for the code and details. */
- rb_define_method(rb_cMetadata, "key", grpc_rb_metadata_key, 0);
- rb_define_method(rb_cMetadata, "value", grpc_rb_metadata_value, 0);
-
- id_key = rb_intern("__key");
- id_value = rb_intern("__value");
-}
-
-/* Gets the wrapped metadata from the ruby wrapper */
-grpc_metadata *grpc_rb_get_wrapped_metadata(VALUE v) {
- grpc_rb_metadata *wrapper = NULL;
- Data_Get_Struct(v, grpc_rb_metadata, wrapper);
- return wrapper->wrapped;
-}
diff --git a/src/ruby/ext/grpc/rb_server.c b/src/ruby/ext/grpc/rb_server.c
index c54f02e87a..9a49285db2 100644
--- a/src/ruby/ext/grpc/rb_server.c
+++ b/src/ruby/ext/grpc/rb_server.c
@@ -46,6 +46,9 @@
/* rb_cServer is the ruby class that proxies grpc_server. */
VALUE rb_cServer = Qnil;
+/* id_at is the constructor method of the ruby standard Time class. */
+static ID id_at;
+
/* grpc_rb_server wraps a grpc_server. It provides a peer ruby object,
'mark' to minimize copying when a server is created from ruby. */
typedef struct grpc_rb_server {
@@ -152,18 +155,89 @@ static VALUE grpc_rb_server_init_copy(VALUE copy, VALUE orig) {
return copy;
}
-static VALUE grpc_rb_server_request_call(VALUE self, VALUE tag_new) {
- grpc_call_error err;
+/* request_call_stack holds various values used by the
+ * grpc_rb_server_request_call function */
+typedef struct request_call_stack {
+ grpc_call_details details;
+ grpc_metadata_array md_ary;
+} request_call_stack;
+
+/* grpc_request_call_stack_init ensures the request_call_stack is properly
+ * initialized */
+static void grpc_request_call_stack_init(request_call_stack* st) {
+ MEMZERO(st, request_call_stack, 1);
+ grpc_metadata_array_init(&st->md_ary);
+ grpc_call_details_init(&st->details);
+ st->details.method = NULL;
+ st->details.host = NULL;
+}
+
+/* grpc_request_call_stack_cleanup ensures the request_call_stack is properly
+ * cleaned up */
+static void grpc_request_call_stack_cleanup(request_call_stack* st) {
+ grpc_metadata_array_destroy(&st->md_ary);
+ grpc_call_details_destroy(&st->details);
+}
+
+/* call-seq:
+ cq = CompletionQueue.new
+ tag = Object.new
+ timeout = 10
+ server.request_call(cqueue, tag, timeout)
+
+ Requests notification of a new call on a server. */
+static VALUE grpc_rb_server_request_call(VALUE self, VALUE cqueue,
+ VALUE tag_new, VALUE timeout) {
grpc_rb_server *s = NULL;
+ grpc_call *call = NULL;
+ grpc_event *ev = NULL;
+ grpc_call_error err;
+ request_call_stack st;
+ VALUE result;
Data_Get_Struct(self, grpc_rb_server, s);
if (s->wrapped == NULL) {
rb_raise(rb_eRuntimeError, "closed!");
+ return Qnil;
} else {
- err = grpc_server_request_call_old(s->wrapped, ROBJECT(tag_new));
+ grpc_request_call_stack_init(&st);
+ /* call grpc_server_request_call, then wait for it to complete using
+ * pluck_event */
+ err = grpc_server_request_call(
+ s->wrapped, &call, &st.details, &st.md_ary,
+ grpc_rb_get_wrapped_completion_queue(cqueue),
+ ROBJECT(tag_new));
if (err != GRPC_CALL_OK) {
- rb_raise(rb_eCallError, "server request failed: %s (code=%d)",
+ grpc_request_call_stack_cleanup(&st);
+ rb_raise(rb_eCallError, "grpc_server_request_call failed: %s (code=%d)",
grpc_call_error_detail_of(err), err);
+ return Qnil;
}
+ ev = grpc_rb_completion_queue_pluck_event(cqueue, tag_new, timeout);
+ if (ev == NULL) {
+ grpc_request_call_stack_cleanup(&st);
+ return Qnil;
+ }
+ if (ev->data.op_complete != GRPC_OP_OK) {
+ grpc_request_call_stack_cleanup(&st);
+ grpc_event_finish(ev);
+ rb_raise(rb_eCallError, "request_call completion failed: (code=%d)",
+ ev->data.op_complete);
+ return Qnil;
+ }
+
+ /* build the NewServerRpc struct result */
+ result = rb_struct_new(
+ rb_sNewServerRpc,
+ rb_str_new2(st.details.method),
+ rb_str_new2(st.details.host),
+ rb_funcall(rb_cTime, id_at, 2, INT2NUM(st.details.deadline.tv_sec),
+ INT2NUM(st.details.deadline.tv_nsec)),
+ grpc_rb_md_ary_to_h(&st.md_ary),
+ grpc_rb_wrap_call(call),
+ NULL);
+ grpc_event_finish(ev);
+ grpc_request_call_stack_cleanup(&st);
+ return result;
}
return Qnil;
}
@@ -249,12 +323,13 @@ void Init_grpc_server() {
rb_define_method(rb_cServer, "initialize_copy", grpc_rb_server_init_copy, 1);
/* Add the server methods. */
- rb_define_method(rb_cServer, "request_call", grpc_rb_server_request_call, 1);
+ rb_define_method(rb_cServer, "request_call", grpc_rb_server_request_call, 3);
rb_define_method(rb_cServer, "start", grpc_rb_server_start, 0);
rb_define_method(rb_cServer, "destroy", grpc_rb_server_destroy, 0);
rb_define_alias(rb_cServer, "close", "destroy");
rb_define_method(rb_cServer, "add_http2_port", grpc_rb_server_add_http2_port,
-1);
+ id_at = rb_intern("at");
}
/* Gets the wrapped server from the ruby wrapper */
diff --git a/src/ruby/lib/grpc.rb b/src/ruby/lib/grpc.rb
index dd02ef7666..b0f68035cd 100644
--- a/src/ruby/lib/grpc.rb
+++ b/src/ruby/lib/grpc.rb
@@ -31,7 +31,6 @@ require 'grpc/errors'
require 'grpc/grpc'
require 'grpc/logconfig'
require 'grpc/version'
-require 'grpc/core/event'
require 'grpc/core/time_consts'
require 'grpc/generic/active_call'
require 'grpc/generic/client_stub'
diff --git a/src/ruby/lib/grpc/core/event.rb b/src/ruby/lib/grpc/core/event.rb
deleted file mode 100644
index 194aa8ecac..0000000000
--- a/src/ruby/lib/grpc/core/event.rb
+++ /dev/null
@@ -1,44 +0,0 @@
-# Copyright 2015, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-require 'grpc'
-
-# GRPC contains the General RPC module.
-module GRPC
- module Core
- # Event is a class defined in the c extension
- #
- # Here, we add an inspect method.
- class Event
- def inspect
- "<#{self.class}: type:#{type}, tag:#{tag} result:#{result}>"
- end
- end
- end
-end
diff --git a/src/ruby/lib/grpc/errors.rb b/src/ruby/lib/grpc/errors.rb
index 58944872b5..b23793730f 100644
--- a/src/ruby/lib/grpc/errors.rb
+++ b/src/ruby/lib/grpc/errors.rb
@@ -31,10 +31,6 @@ require 'grpc'
# GRPC contains the General RPC module.
module GRPC
- # OutOfTime is an exception class that indicates that an RPC exceeded its
- # deadline.
- OutOfTime = Class.new(StandardError)
-
# BadStatus is an exception class that indicates that an error occurred at
# either end of a GRPC connection. When raised, it indicates that a status
# error should be returned to the other end of a GRPC connection; when
diff --git a/src/ruby/lib/grpc/generic/active_call.rb b/src/ruby/lib/grpc/generic/active_call.rb
index 6256330e88..489349c2c9 100644
--- a/src/ruby/lib/grpc/generic/active_call.rb
+++ b/src/ruby/lib/grpc/generic/active_call.rb
@@ -30,20 +30,14 @@
require 'forwardable'
require 'grpc/generic/bidi_call'
-def assert_event_type(ev, want)
- fail OutOfTime if ev.nil?
- got = ev.type
- fail "Unexpected rpc event: got #{got}, want #{want}" unless got == want
-end
-
# GRPC contains the General RPC module.
module GRPC
# The ActiveCall class provides simple methods for sending marshallable
# data to a call
class ActiveCall
- include Core::CompletionType
include Core::StatusCodes
include Core::TimeConsts
+ include Core::CallOps
attr_reader(:deadline)
# client_invoke begins a client invocation.
@@ -61,15 +55,14 @@ module GRPC
# @param q [CompletionQueue] the completion queue
# @param deadline [Fixnum,TimeSpec] the deadline
def self.client_invoke(call, q, _deadline, **kw)
- fail(ArgumentError, 'not a call') unless call.is_a? Core::Call
+ fail(TypeError, '!Core::Call') unless call.is_a? Core::Call
unless q.is_a? Core::CompletionQueue
- fail(ArgumentError, 'not a CompletionQueue')
+ fail(TypeError, '!Core::CompletionQueue')
end
- call.add_metadata(kw) if kw.length > 0
- client_metadata_read = Object.new
- finished_tag = Object.new
- call.invoke(q, client_metadata_read, finished_tag)
- [finished_tag, client_metadata_read]
+ metadata_tag = Object.new
+ call.run_batch(q, metadata_tag, INFINITE_FUTURE,
+ SEND_INITIAL_METADATA => kw)
+ metadata_tag
end
# Creates an ActiveCall.
@@ -91,25 +84,21 @@ module GRPC
# @param marshal [Function] f(obj)->string that marshal requests
# @param unmarshal [Function] f(string)->obj that unmarshals responses
# @param deadline [Fixnum] the deadline for the call to complete
- # @param finished_tag [Object] the object used as the call's finish tag,
- # if the call has begun
- # @param read_metadata_tag [Object] the object used as the call's finish
- # tag, if the call has begun
+ # @param metadata_tag [Object] the object use obtain metadata for clients
# @param started [true|false] indicates if the call has begun
- def initialize(call, q, marshal, unmarshal, deadline, finished_tag: nil,
- read_metadata_tag: nil, started: true)
- fail(ArgumentError, 'not a call') unless call.is_a? Core::Call
+ def initialize(call, q, marshal, unmarshal, deadline, started: true,
+ metadata_tag: nil)
+ fail(TypeError, '!Core::Call') unless call.is_a? Core::Call
unless q.is_a? Core::CompletionQueue
- fail(ArgumentError, 'not a CompletionQueue')
+ fail(TypeError, '!Core::CompletionQueue')
end
@call = call
@cq = q
@deadline = deadline
- @finished_tag = finished_tag
- @read_metadata_tag = read_metadata_tag
@marshal = marshal
@started = started
@unmarshal = unmarshal
+ @metadata_tag = metadata_tag
end
# Obtains the status of the call.
@@ -176,51 +165,38 @@ module GRPC
# writes_done indicates that all writes are completed.
#
- # It blocks until the remote endpoint acknowledges by sending a FINISHED
- # event, unless assert_finished is set to false. Any calls to
- # #remote_send after this call will fail.
+ # It blocks until the remote endpoint acknowledges with at status unless
+ # assert_finished is set to false. Any calls to #remote_send after this
+ # call will fail.
#
# @param assert_finished [true, false] when true(default), waits for
# FINISHED.
def writes_done(assert_finished = true)
- @call.writes_done(self)
- ev = @cq.pluck(self, INFINITE_FUTURE)
- begin
- assert_event_type(ev, FINISH_ACCEPTED)
- logger.debug("Writes done: waiting for finish? #{assert_finished}")
- ensure
- ev.close
- end
-
+ ops = {
+ SEND_CLOSE_FROM_CLIENT => nil
+ }
+ ops[RECV_STATUS_ON_CLIENT] = nil if assert_finished
+ @call.run_batch(@cq, self, INFINITE_FUTURE, ops)
return unless assert_finished
- ev = @cq.pluck(@finished_tag, INFINITE_FUTURE)
- fail 'unexpected nil event' if ev.nil?
- ev.close
@call.status
end
- # finished waits until the call is completed.
+ # finished waits until a client call is completed.
#
- # It blocks until the remote endpoint acknowledges by sending a FINISHED
- # event.
+ # It blocks until the remote endpoint acknowledges by sending a status.
def finished
- ev = @cq.pluck(@finished_tag, INFINITE_FUTURE)
- begin
- fail "unexpected event: #{ev.inspect}" unless ev.type == FINISHED
- if @call.metadata.nil?
- @call.metadata = ev.result.metadata
- else
- @call.metadata.merge!(ev.result.metadata)
- end
-
- if ev.result.code != Core::StatusCodes::OK
- fail BadStatus.new(ev.result.code, ev.result.details)
- end
- res = ev.result
- ensure
- ev.close
+ batch_result = @call.run_batch(@cq, self, INFINITE_FUTURE,
+ RECV_STATUS_ON_CLIENT => nil)
+ if @call.metadata.nil?
+ @call.metadata = batch_result.metadata
+ elsif !batch_result.metadata.nil?
+ @call.metadata.merge!(batch_result.metadata)
end
- res
+ if batch_result.status.code != Core::StatusCodes::OK
+ fail BadStatus.new(batch_result.status.code,
+ batch_result.status.details)
+ end
+ batch_result
end
# remote_send sends a request to the remote endpoint.
@@ -232,72 +208,50 @@ module GRPC
# @param marshalled [false, true] indicates if the object is already
# marshalled.
def remote_send(req, marshalled = false)
- assert_queue_is_ready
logger.debug("sending #{req.inspect}, marshalled? #{marshalled}")
if marshalled
payload = req
else
payload = @marshal.call(req)
end
- @call.start_write(Core::ByteBuffer.new(payload), self)
-
- # call queue#pluck, and wait for WRITE_ACCEPTED, so as not to return
- # until the flow control allows another send on this call.
- ev = @cq.pluck(self, INFINITE_FUTURE)
- begin
- assert_event_type(ev, WRITE_ACCEPTED)
- ensure
- ev.close
- end
+ @call.run_batch(@cq, self, INFINITE_FUTURE, SEND_MESSAGE => payload)
end
- # send_status sends a status to the remote endpoint
+ # send_status sends a status to the remote endpoint.
#
# @param code [int] the status code to send
# @param details [String] details
# @param assert_finished [true, false] when true(default), waits for
# FINISHED.
def send_status(code = OK, details = '', assert_finished = false)
- assert_queue_is_ready
- @call.start_write_status(code, details, self)
- ev = @cq.pluck(self, INFINITE_FUTURE)
- begin
- assert_event_type(ev, FINISH_ACCEPTED)
- ensure
- ev.close
- end
- logger.debug("Status sent: #{code}:'#{details}'")
- return finished if assert_finished
+ ops = {
+ SEND_STATUS_FROM_SERVER => Struct::Status.new(code, details)
+ }
+ ops[RECV_CLOSE_ON_SERVER] = nil if assert_finished
+ @call.run_batch(@cq, self, INFINITE_FUTURE, ops)
nil
end
# remote_read reads a response from the remote endpoint.
#
- # It blocks until the remote endpoint sends a READ or FINISHED event. On
- # a READ, it returns the response after unmarshalling it. On
- # FINISHED, it returns nil if the status is OK, otherwise raising
- # BadStatus
+ # It blocks until the remote endpoint replies with a message or status.
+ # On receiving a message, it returns the response after unmarshalling it.
+ # On receiving a status, it returns nil if the status is OK, otherwise
+ # raising BadStatus
def remote_read
- if @call.metadata.nil? && !@read_metadata_tag.nil?
- ev = @cq.pluck(@read_metadata_tag, INFINITE_FUTURE)
- assert_event_type(ev, CLIENT_METADATA_READ)
- @call.metadata = ev.result
- @read_metadata_tag = nil
+ ops = { RECV_MESSAGE => nil }
+ ops[RECV_INITIAL_METADATA] = nil unless @metadata_tag.nil?
+ batch_result = @call.run_batch(@cq, self, INFINITE_FUTURE, ops)
+ unless @metadata_tag.nil?
+ @call.metadata = batch_result.metadata
+ @metadata_tag = nil
end
-
- @call.start_read(self)
- ev = @cq.pluck(self, INFINITE_FUTURE)
- begin
- assert_event_type(ev, READ)
- logger.debug("received req: #{ev.result.inspect}")
- unless ev.result.nil?
- logger.debug("received req.to_s: #{ev.result}")
- res = @unmarshal.call(ev.result.to_s)
- logger.debug("received_req (unmarshalled): #{res.inspect}")
- return res
- end
- ensure
- ev.close
+ logger.debug("received req: #{batch_result}")
+ unless batch_result.nil? || batch_result.message.nil?
+ logger.debug("received req.to_s: #{batch_result.message}")
+ res = @unmarshal.call(batch_result.message)
+ logger.debug("received_req (unmarshalled): #{res.inspect}")
+ return res
end
logger.debug('found nil; the final response has been sent')
nil
@@ -324,7 +278,6 @@ module GRPC
return enum_for(:each_remote_read) unless block_given?
loop do
resp = remote_read
- break if resp.is_a? Struct::Status # is an OK status
break if resp.nil? # the last response was received
yield resp
end
@@ -461,8 +414,7 @@ module GRPC
# @return [Enumerator, nil] a response Enumerator
def bidi_streamer(requests, **kw, &blk)
start_call(**kw) unless @started
- bd = BidiCall.new(@call, @cq, @marshal, @unmarshal, @deadline,
- @finished_tag)
+ bd = BidiCall.new(@call, @cq, @marshal, @unmarshal, @deadline)
bd.run_on_client(requests, &blk)
end
@@ -478,8 +430,7 @@ module GRPC
#
# @param gen_each_reply [Proc] generates the BiDi stream replies
def run_server_bidi(gen_each_reply)
- bd = BidiCall.new(@call, @cq, @marshal, @unmarshal, @deadline,
- @finished_tag)
+ bd = BidiCall.new(@call, @cq, @marshal, @unmarshal, @deadline)
bd.run_on_server(gen_each_reply)
end
@@ -516,21 +467,5 @@ module GRPC
# a Operation on the client.
Operation = view_class(:cancel, :cancelled, :deadline, :execute,
:metadata, :status)
-
- # confirms that no events are enqueued, and that the queue is not
- # shutdown.
- def assert_queue_is_ready
- ev = nil
- begin
- ev = @cq.pluck(self, ZERO)
- fail "unexpected event #{ev.inspect}" unless ev.nil?
- rescue OutOfTime
- logging.debug('timed out waiting for next event')
- # expected, nothing should be on the queue and the deadline was ZERO,
- # except things using another tag
- ensure
- ev.close unless ev.nil?
- end
- end
end
end
diff --git a/src/ruby/lib/grpc/generic/bidi_call.rb b/src/ruby/lib/grpc/generic/bidi_call.rb
index c66deaae60..1c1b3b0db7 100644
--- a/src/ruby/lib/grpc/generic/bidi_call.rb
+++ b/src/ruby/lib/grpc/generic/bidi_call.rb
@@ -30,18 +30,12 @@
require 'forwardable'
require 'grpc/grpc'
-def assert_event_type(ev, want)
- fail OutOfTime if ev.nil?
- got = ev.type
- fail("Unexpected rpc event: got #{got}, want #{want}") unless got == want
-end
-
# GRPC contains the General RPC module.
module GRPC
# The BiDiCall class orchestrates exection of a BiDi stream on a client or
# server.
class BidiCall
- include Core::CompletionType
+ include Core::CallOps
include Core::StatusCodes
include Core::TimeConsts
@@ -63,8 +57,7 @@ module GRPC
# @param marshal [Function] f(obj)->string that marshal requests
# @param unmarshal [Function] f(string)->obj that unmarshals responses
# @param deadline [Fixnum] the deadline for the call to complete
- # @param finished_tag [Object] the object used as the call's finish tag,
- def initialize(call, q, marshal, unmarshal, deadline, finished_tag)
+ def initialize(call, q, marshal, unmarshal, deadline)
fail(ArgumentError, 'not a call') unless call.is_a? Core::Call
unless q.is_a? Core::CompletionQueue
fail(ArgumentError, 'not a CompletionQueue')
@@ -72,7 +65,6 @@ module GRPC
@call = call
@cq = q
@deadline = deadline
- @finished_tag = finished_tag
@marshal = marshal
@readq = Queue.new
@unmarshal = unmarshal
@@ -146,30 +138,14 @@ module GRPC
requests.each do |req|
count += 1
payload = @marshal.call(req)
- @call.start_write(Core::ByteBuffer.new(payload), write_tag)
- ev = @cq.pluck(write_tag, INFINITE_FUTURE)
- begin
- assert_event_type(ev, WRITE_ACCEPTED)
- ensure
- ev.close
- end
+ @call.run_batch(@cq, write_tag, INFINITE_FUTURE,
+ SEND_MESSAGE => payload)
end
if is_client
- @call.writes_done(write_tag)
- ev = @cq.pluck(write_tag, INFINITE_FUTURE)
- begin
- assert_event_type(ev, FINISH_ACCEPTED)
- ensure
- ev.close
- end
logger.debug("bidi-client: sent #{count} reqs, waiting to finish")
- ev = @cq.pluck(@finished_tag, INFINITE_FUTURE)
- begin
- assert_event_type(ev, FINISHED)
- ensure
- ev.close
- end
- logger.debug('bidi-client: finished received')
+ @call.run_batch(@cq, write_tag, INFINITE_FUTURE,
+ SEND_CLOSE_FROM_CLIENT => nil,
+ RECV_STATUS_ON_CLIENT => nil)
end
rescue StandardError => e
logger.warn('bidi: write_loop failed')
@@ -189,25 +165,20 @@ module GRPC
loop do
logger.debug("waiting for read #{count}")
count += 1
- @call.start_read(read_tag)
- ev = @cq.pluck(read_tag, INFINITE_FUTURE)
- begin
- assert_event_type(ev, READ)
-
- # handle the next event.
- if ev.result.nil?
- @readq.push(END_OF_READS)
- logger.debug('done reading!')
- break
- end
-
- # push the latest read onto the queue and continue reading
- logger.debug("received req: #{ev.result}")
- res = @unmarshal.call(ev.result.to_s)
- @readq.push(res)
- ensure
- ev.close
+ # TODO: ensure metadata is read if available, currently it's not
+ batch_result = @call.run_batch(@cq, read_tag, INFINITE_FUTURE,
+ RECV_MESSAGE => nil)
+ # handle the next message
+ if batch_result.message.nil?
+ @readq.push(END_OF_READS)
+ logger.debug('done reading!')
+ break
end
+
+ # push the latest read onto the queue and continue reading
+ logger.debug("received req: #{batch_result.message}")
+ res = @unmarshal.call(batch_result.message)
+ @readq.push(res)
end
rescue StandardError => e
diff --git a/src/ruby/lib/grpc/generic/client_stub.rb b/src/ruby/lib/grpc/generic/client_stub.rb
index 01328d4a5b..6547a1499e 100644
--- a/src/ruby/lib/grpc/generic/client_stub.rb
+++ b/src/ruby/lib/grpc/generic/client_stub.rb
@@ -35,9 +35,10 @@ module GRPC
# ClientStub represents an endpoint used to send requests to GRPC servers.
class ClientStub
include Core::StatusCodes
+ include Core::TimeConsts
- # Default deadline is 5 seconds.
- DEFAULT_DEADLINE = 5
+ # Default timeout is 5 seconds.
+ DEFAULT_TIMEOUT = 5
# setup_channel is used by #initialize to constuct a channel from its
# arguments.
@@ -76,8 +77,8 @@ module GRPC
# present the host and arbitrary keyword arg areignored, and the RPC
# connection uses this channel.
#
- # - :deadline
- # when present, this is the default deadline used for calls
+ # - :timeout
+ # when present, this is the default timeout used for calls
#
# - :update_metadata
# when present, this a func that takes a hash and returns a hash
@@ -87,13 +88,13 @@ module GRPC
# @param host [String] the host the stub connects to
# @param q [Core::CompletionQueue] used to wait for events
# @param channel_override [Core::Channel] a pre-created channel
- # @param deadline [Number] the default deadline to use in requests
+ # @param timeout [Number] the default timeout to use in requests
# @param creds [Core::Credentials] the channel
# @param update_metadata a func that updates metadata as described above
# @param kw [KeywordArgs]the channel arguments
def initialize(host, q,
channel_override: nil,
- deadline: DEFAULT_DEADLINE,
+ timeout: nil,
creds: nil,
update_metadata: nil,
**kw)
@@ -103,7 +104,7 @@ module GRPC
@update_metadata = ClientStub.check_update_metadata(update_metadata)
alt_host = kw[Core::Channel::SSL_TARGET]
@host = alt_host.nil? ? host : alt_host
- @deadline = deadline
+ @timeout = timeout.nil? ? DEFAULT_TIMEOUT : timeout
end
# request_response sends a request to a GRPC server, and returns the
@@ -140,12 +141,12 @@ module GRPC
# @param req [Object] the request sent to the server
# @param marshal [Function] f(obj)->string that marshals requests
# @param unmarshal [Function] f(string)->obj that unmarshals responses
- # @param deadline [Numeric] (optional) the max completion time in seconds
+ # @param timeout [Numeric] (optional) the max completion time in seconds
# @param return_op [true|false] return an Operation if true
# @return [Object] the response received from the server
- def request_response(method, req, marshal, unmarshal, deadline = nil,
+ def request_response(method, req, marshal, unmarshal, timeout = nil,
return_op: false, **kw)
- c = new_active_call(method, marshal, unmarshal, deadline || @deadline)
+ c = new_active_call(method, marshal, unmarshal, timeout)
md = @update_metadata.nil? ? kw : @update_metadata.call(kw.clone)
return c.request_response(req, **md) unless return_op
@@ -197,12 +198,12 @@ module GRPC
# @param requests [Object] an Enumerable of requests to send
# @param marshal [Function] f(obj)->string that marshals requests
# @param unmarshal [Function] f(string)->obj that unmarshals responses
- # @param deadline [Numeric] the max completion time in seconds
+ # @param timeout [Numeric] the max completion time in seconds
# @param return_op [true|false] return an Operation if true
# @return [Object|Operation] the response received from the server
- def client_streamer(method, requests, marshal, unmarshal, deadline = nil,
+ def client_streamer(method, requests, marshal, unmarshal, timeout = nil,
return_op: false, **kw)
- c = new_active_call(method, marshal, unmarshal, deadline || @deadline)
+ c = new_active_call(method, marshal, unmarshal, timeout)
md = @update_metadata.nil? ? kw : @update_metadata.call(kw.clone)
return c.client_streamer(requests, **md) unless return_op
@@ -262,13 +263,13 @@ module GRPC
# @param req [Object] the request sent to the server
# @param marshal [Function] f(obj)->string that marshals requests
# @param unmarshal [Function] f(string)->obj that unmarshals responses
- # @param deadline [Numeric] the max completion time in seconds
+ # @param timeout [Numeric] the max completion time in seconds
# @param return_op [true|false]return an Operation if true
# @param blk [Block] when provided, is executed for each response
# @return [Enumerator|Operation|nil] as discussed above
- def server_streamer(method, req, marshal, unmarshal, deadline = nil,
+ def server_streamer(method, req, marshal, unmarshal, timeout = nil,
return_op: false, **kw, &blk)
- c = new_active_call(method, marshal, unmarshal, deadline || @deadline)
+ c = new_active_call(method, marshal, unmarshal, timeout)
md = @update_metadata.nil? ? kw : @update_metadata.call(kw.clone)
return c.server_streamer(req, **md, &blk) unless return_op
@@ -367,13 +368,13 @@ module GRPC
# @param requests [Object] an Enumerable of requests to send
# @param marshal [Function] f(obj)->string that marshals requests
# @param unmarshal [Function] f(string)->obj that unmarshals responses
- # @param deadline [Numeric] (optional) the max completion time in seconds
+ # @param timeout [Numeric] (optional) the max completion time in seconds
# @param blk [Block] when provided, is executed for each response
# @param return_op [true|false] return an Operation if true
# @return [Enumerator|nil|Operation] as discussed above
- def bidi_streamer(method, requests, marshal, unmarshal, deadline = nil,
+ def bidi_streamer(method, requests, marshal, unmarshal, timeout = nil,
return_op: false, **kw, &blk)
- c = new_active_call(method, marshal, unmarshal, deadline || @deadline)
+ c = new_active_call(method, marshal, unmarshal, timeout)
md = @update_metadata.nil? ? kw : @update_metadata.call(kw.clone)
return c.bidi_streamer(requests, **md, &blk) unless return_op
@@ -390,15 +391,14 @@ module GRPC
# Creates a new active stub
#
- # @param ch [GRPC::Channel] the channel used to create the stub.
+ # @param method [string] the method being called.
# @param marshal [Function] f(obj)->string that marshals requests
# @param unmarshal [Function] f(string)->obj that unmarshals responses
- # @param deadline [TimeConst]
- def new_active_call(ch, marshal, unmarshal, deadline = nil)
- absolute_deadline = Core::TimeConsts.from_relative_time(deadline)
- call = @ch.create_call(ch, @host, absolute_deadline)
- ActiveCall.new(call, @queue, marshal, unmarshal, absolute_deadline,
- started: false)
+ # @param timeout [TimeConst]
+ def new_active_call(method, marshal, unmarshal, timeout = nil)
+ deadline = from_relative_time(timeout.nil? ? @timeout : timeout)
+ call = @ch.create_call(@queue, method, @host, deadline)
+ ActiveCall.new(call, @queue, marshal, unmarshal, deadline, started: false)
end
end
end
diff --git a/src/ruby/lib/grpc/generic/rpc_desc.rb b/src/ruby/lib/grpc/generic/rpc_desc.rb
index 2cb3d2eebf..3e48b8e51d 100644
--- a/src/ruby/lib/grpc/generic/rpc_desc.rb
+++ b/src/ruby/lib/grpc/generic/rpc_desc.rb
@@ -81,7 +81,6 @@ module GRPC
active_call.run_server_bidi(mth)
end
send_status(active_call, OK, 'OK')
- active_call.finished
rescue BadStatus => e
# this is raised by handlers that want GRPC to send an application
# error code and detail message.
@@ -91,15 +90,11 @@ module GRPC
# This is raised by GRPC internals but should rarely, if ever happen.
# Log it, but don't notify the other endpoint..
logger.warn("failed call: #{active_call}\n#{e}")
- rescue OutOfTime
+ rescue Core::OutOfTime
# This is raised when active_call#method.call exceeeds the deadline
# event. Send a status of deadline exceeded
logger.warn("late call: #{active_call}")
send_status(active_call, DEADLINE_EXCEEDED, 'late')
- rescue Core::EventError => e
- # This is raised by GRPC internals but should rarely, if ever happen.
- # Log it, but don't notify the other endpoint..
- logger.warn("failed call: #{active_call}\n#{e}")
rescue StandardError => e
# This will usuaally be an unhandled error in the handling code.
# Send back a UNKNOWN status to the client
@@ -142,7 +137,7 @@ module GRPC
def send_status(active_client, code, details)
details = 'Not sure why' if details.nil?
- active_client.send_status(code, details)
+ active_client.send_status(code, details, code == OK)
rescue StandardError => e
logger.warn("Could not send status #{code}:#{details}")
logger.warn(e)
diff --git a/src/ruby/lib/grpc/generic/rpc_server.rb b/src/ruby/lib/grpc/generic/rpc_server.rb
index 35e84023be..30a4bf1532 100644
--- a/src/ruby/lib/grpc/generic/rpc_server.rb
+++ b/src/ruby/lib/grpc/generic/rpc_server.rb
@@ -38,7 +38,7 @@ module GRPC
# RpcServer hosts a number of services and makes them available on the
# network.
class RpcServer
- include Core::CompletionType
+ include Core::CallOps
include Core::TimeConsts
extend ::Forwardable
@@ -202,20 +202,14 @@ module GRPC
end
@pool.start
@server.start
- server_tag = Object.new
+ request_call_tag = Object.new
until stopped?
- @server.request_call(server_tag)
- ev = @cq.pluck(server_tag, @poll_period)
- next if ev.nil?
- if ev.type != SERVER_RPC_NEW
- logger.warn("bad evt: got:#{ev.type}, want:#{SERVER_RPC_NEW}")
- ev.close
- next
- end
- c = new_active_server_call(ev.call, ev.result)
+ deadline = from_relative_time(@poll_period)
+ an_rpc = @server.request_call(@cq, request_call_tag, deadline)
+ next if an_rpc.nil?
+ c = new_active_server_call(an_rpc)
unless c.nil?
- mth = ev.result.method.to_sym
- ev.close
+ mth = an_rpc.method.to_sym
@pool.schedule(c) do |call|
rpc_descs[mth].run_server_method(call, rpc_handlers[mth])
end
@@ -224,46 +218,49 @@ module GRPC
@running = false
end
- def new_active_server_call(call, new_server_rpc)
- # Accept the call. This is necessary even if a status is to be sent
- # back immediately
- finished_tag = Object.new
- call_queue = Core::CompletionQueue.new
- call.metadata = new_server_rpc.metadata # store the metadata
- call.server_accept(call_queue, finished_tag)
- call.server_end_initial_metadata
-
- # Send UNAVAILABLE if there are too many unprocessed jobs
+ # Sends UNAVAILABLE if there are too many unprocessed jobs
+ def available?(an_rpc)
jobs_count, max = @pool.jobs_waiting, @max_waiting_requests
logger.info("waiting: #{jobs_count}, max: #{max}")
- if @pool.jobs_waiting > @max_waiting_requests
- logger.warn("NOT AVAILABLE: too many jobs_waiting: #{new_server_rpc}")
- noop = proc { |x| x }
- c = ActiveCall.new(call, call_queue, noop, noop,
- new_server_rpc.deadline,
- finished_tag: finished_tag)
- c.send_status(StatusCodes::UNAVAILABLE, '')
- return nil
- end
+ return an_rpc if @pool.jobs_waiting <= @max_waiting_requests
+ logger.warn("NOT AVAILABLE: too many jobs_waiting: #{an_rpc}")
+ noop = proc { |x| x }
+ c = ActiveCall.new(an_rpc.call, @cq, noop, noop, an_rpc.deadline)
+ c.send_status(StatusCodes::UNAVAILABLE, '')
+ nil
+ end
- # Send NOT_FOUND if the method does not exist
- mth = new_server_rpc.method.to_sym
- unless rpc_descs.key?(mth)
- logger.warn("NOT_FOUND: #{new_server_rpc}")
- noop = proc { |x| x }
- c = ActiveCall.new(call, call_queue, noop, noop,
- new_server_rpc.deadline,
- finished_tag: finished_tag)
- c.send_status(StatusCodes::NOT_FOUND, '')
- return nil
- end
+ # Sends NOT_FOUND if the method can't be found
+ def found?(an_rpc)
+ mth = an_rpc.method.to_sym
+ return an_rpc if rpc_descs.key?(mth)
+ logger.warn("NOT_FOUND: #{an_rpc}")
+ noop = proc { |x| x }
+ c = ActiveCall.new(an_rpc.call, @cq, noop, noop, an_rpc.deadline)
+ c.send_status(StatusCodes::NOT_FOUND, '')
+ nil
+ end
+
+ def new_active_server_call(an_rpc)
+ # Accept the call. This is necessary even if a status is to be sent
+ # back immediately
+ return nil if an_rpc.nil? || an_rpc.call.nil?
+
+ # allow the metadata to be accessed from the call
+ handle_call_tag = Object.new
+ an_rpc.call.metadata = an_rpc.metadata
+ # TODO: add a hook to send md
+ an_rpc.call.run_batch(@cq, handle_call_tag, INFINITE_FUTURE,
+ SEND_INITIAL_METADATA => nil)
+ return nil unless available?(an_rpc)
+ return nil unless found?(an_rpc)
# Create the ActiveCall
- rpc_desc = rpc_descs[mth]
- logger.info("deadline is #{new_server_rpc.deadline}; (now=#{Time.now})")
- ActiveCall.new(call, call_queue,
+ logger.info("deadline is #{an_rpc.deadline}; (now=#{Time.now})")
+ rpc_desc = rpc_descs[an_rpc.method.to_sym]
+ ActiveCall.new(an_rpc.call, @cq,
rpc_desc.marshal_proc, rpc_desc.unmarshal_proc(:input),
- new_server_rpc.deadline, finished_tag: finished_tag)
+ an_rpc.deadline)
end
# Pool is a simple thread pool for running server requests.
diff --git a/src/ruby/spec/alloc_spec.rb b/src/ruby/spec/alloc_spec.rb
deleted file mode 100644
index 88e7e2b3e7..0000000000
--- a/src/ruby/spec/alloc_spec.rb
+++ /dev/null
@@ -1,44 +0,0 @@
-# Copyright 2015, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-require 'grpc'
-
-describe 'Wrapped classes where .new cannot create an instance' do
- describe GRPC::Core::Event do
- it 'should fail .new fail with a runtime error' do
- expect { GRPC::Core::Event.new }.to raise_error(TypeError)
- end
- end
-
- describe GRPC::Core::Call do
- it 'should fail .new fail with a runtime error' do
- expect { GRPC::Core::Event.new }.to raise_error(TypeError)
- end
- end
-end
diff --git a/src/ruby/spec/byte_buffer_spec.rb b/src/ruby/spec/byte_buffer_spec.rb
deleted file mode 100644
index e1833ebb3a..0000000000
--- a/src/ruby/spec/byte_buffer_spec.rb
+++ /dev/null
@@ -1,67 +0,0 @@
-# Copyright 2015, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-require 'grpc'
-
-describe GRPC::Core::ByteBuffer do
- describe '#new' do
- it 'is constructed from a string' do
- expect { GRPC::Core::ByteBuffer.new('#new') }.not_to raise_error
- end
-
- it 'can be constructed from the empty string' do
- expect { GRPC::Core::ByteBuffer.new('') }.not_to raise_error
- end
-
- it 'cannot be constructed from nil' do
- expect { GRPC::Core::ByteBuffer.new(nil) }.to raise_error TypeError
- end
-
- it 'cannot be constructed from non-strings' do
- [1, Object.new, :a_symbol].each do |x|
- expect { GRPC::Core::ByteBuffer.new(x) }.to raise_error TypeError
- end
- end
- end
-
- describe '#to_s' do
- it 'is the string value the ByteBuffer was constructed with' do
- expect(GRPC::Core::ByteBuffer.new('#to_s').to_s).to eq('#to_s')
- end
- end
-
- describe '#dup' do
- it 'makes an instance whose #to_s is the original string value' do
- bb = GRPC::Core::ByteBuffer.new('#dup')
- a_copy = bb.dup
- expect(a_copy.to_s).to eq('#dup')
- expect(a_copy.dup.to_s).to eq('#dup')
- end
- end
-end
diff --git a/src/ruby/spec/call_spec.rb b/src/ruby/spec/call_spec.rb
index 2617564571..4977c10a7e 100644
--- a/src/ruby/spec/call_spec.rb
+++ b/src/ruby/spec/call_spec.rb
@@ -66,51 +66,34 @@ describe GRPC::Core::RpcErrors do
end
end
-describe GRPC::Core::Call do
+describe GRPC::Core::CallOps do
before(:each) do
- @tag = Object.new
- @client_queue = GRPC::Core::CompletionQueue.new
- fake_host = 'localhost:10101'
- @ch = GRPC::Core::Channel.new(fake_host, nil)
- end
-
- describe '#start_read' do
- xit 'should fail if called immediately' do
- blk = proc { make_test_call.start_read(@tag) }
- expect(&blk).to raise_error GRPC::Core::CallError
- end
- end
-
- describe '#start_write' do
- xit 'should fail if called immediately' do
- bytes = GRPC::Core::ByteBuffer.new('test string')
- blk = proc { make_test_call.start_write(bytes, @tag) }
- expect(&blk).to raise_error GRPC::Core::CallError
- end
+ @known_types = {
+ SEND_INITIAL_METADATA: 0,
+ SEND_MESSAGE: 1,
+ SEND_CLOSE_FROM_CLIENT: 2,
+ SEND_STATUS_FROM_SERVER: 3,
+ RECV_INITIAL_METADATA: 4,
+ RECV_MESSAGE: 5,
+ RECV_STATUS_ON_CLIENT: 6,
+ RECV_CLOSE_ON_SERVER: 7
+ }
end
- describe '#start_write_status' do
- xit 'should fail if called immediately' do
- blk = proc { make_test_call.start_write_status(153, 'x', @tag) }
- expect(&blk).to raise_error GRPC::Core::CallError
- end
+ it 'should have symbols for all the known operation types' do
+ m = GRPC::Core::CallOps
+ syms_and_codes = m.constants.collect { |c| [c, m.const_get(c)] }
+ expect(Hash[syms_and_codes]).to eq(@known_types)
end
+end
- describe '#writes_done' do
- xit 'should fail if called immediately' do
- blk = proc { make_test_call.writes_done(Object.new) }
- expect(&blk).to raise_error GRPC::Core::CallError
- end
- end
+describe GRPC::Core::Call do
+ let(:client_queue) { GRPC::Core::CompletionQueue.new }
+ let(:test_tag) { Object.new }
+ let(:fake_host) { 'localhost:10101' }
- describe '#add_metadata' do
- it 'adds metadata to a call without fail' do
- call = make_test_call
- n = 37
- one_md = proc { |x| [sprintf('key%d', x), sprintf('value%d', x)] }
- metadata = Hash[n.times.collect { |i| one_md.call i }]
- expect { call.add_metadata(metadata) }.to_not raise_error
- end
+ before(:each) do
+ @ch = GRPC::Core::Channel.new(fake_host, nil)
end
describe '#status' do
@@ -154,7 +137,7 @@ describe GRPC::Core::Call do
end
def make_test_call
- @ch.create_call('dummy_method', 'dummy_host', deadline)
+ @ch.create_call(client_queue, 'dummy_method', 'dummy_host', deadline)
end
def deadline
diff --git a/src/ruby/spec/channel_spec.rb b/src/ruby/spec/channel_spec.rb
index af73294abe..31e38d71b8 100644
--- a/src/ruby/spec/channel_spec.rb
+++ b/src/ruby/spec/channel_spec.rb
@@ -36,16 +36,13 @@ def load_test_certs
end
describe GRPC::Core::Channel do
- FAKE_HOST = 'localhost:0'
+ let(:fake_host) { 'localhost:0' }
+ let(:cq) { GRPC::Core::CompletionQueue.new }
def create_test_cert
GRPC::Core::Credentials.new(load_test_certs[0])
end
- before(:each) do
- @cq = GRPC::Core::CompletionQueue.new
- end
-
shared_examples '#new' do
it 'take a host name without channel args' do
expect { GRPC::Core::Channel.new('dummy_host', nil) }.not_to raise_error
@@ -115,25 +112,23 @@ describe GRPC::Core::Channel do
describe '#create_call' do
it 'creates a call OK' do
- host = FAKE_HOST
- ch = GRPC::Core::Channel.new(host, nil)
+ ch = GRPC::Core::Channel.new(fake_host, nil)
deadline = Time.now + 5
blk = proc do
- ch.create_call('dummy_method', 'dummy_host', deadline)
+ ch.create_call(cq, 'dummy_method', 'dummy_host', deadline)
end
expect(&blk).to_not raise_error
end
it 'raises an error if called on a closed channel' do
- host = FAKE_HOST
- ch = GRPC::Core::Channel.new(host, nil)
+ ch = GRPC::Core::Channel.new(fake_host, nil)
ch.close
deadline = Time.now + 5
blk = proc do
- ch.create_call('dummy_method', 'dummy_host', deadline)
+ ch.create_call(cq, 'dummy_method', 'dummy_host', deadline)
end
expect(&blk).to raise_error(RuntimeError)
end
@@ -141,15 +136,13 @@ describe GRPC::Core::Channel do
describe '#destroy' do
it 'destroys a channel ok' do
- host = FAKE_HOST
- ch = GRPC::Core::Channel.new(host, nil)
+ ch = GRPC::Core::Channel.new(fake_host, nil)
blk = proc { ch.destroy }
expect(&blk).to_not raise_error
end
it 'can be called more than once without error' do
- host = FAKE_HOST
- ch = GRPC::Core::Channel.new(host, nil)
+ ch = GRPC::Core::Channel.new(fake_host, nil)
blk = proc { ch.destroy }
blk.call
expect(&blk).to_not raise_error
@@ -164,15 +157,13 @@ describe GRPC::Core::Channel do
describe '#close' do
it 'closes a channel ok' do
- host = FAKE_HOST
- ch = GRPC::Core::Channel.new(host, nil)
+ ch = GRPC::Core::Channel.new(fake_host, nil)
blk = proc { ch.close }
expect(&blk).to_not raise_error
end
it 'can be called more than once without error' do
- host = FAKE_HOST
- ch = GRPC::Core::Channel.new(host, nil)
+ ch = GRPC::Core::Channel.new(fake_host, nil)
blk = proc { ch.close }
blk.call
expect(&blk).to_not raise_error
diff --git a/src/ruby/spec/client_server_spec.rb b/src/ruby/spec/client_server_spec.rb
index 49a2d3bb4d..1a2afbe1f9 100644
--- a/src/ruby/spec/client_server_spec.rb
+++ b/src/ruby/spec/client_server_spec.rb
@@ -30,7 +30,6 @@
require 'grpc'
require 'spec_helper'
-include GRPC::Core::CompletionType
include GRPC::Core
def load_test_certs
@@ -40,6 +39,8 @@ def load_test_certs
end
shared_context 'setup: tags' do
+ let(:sent_message) { 'sent message' }
+ let(:reply_text) { 'the reply' }
before(:example) do
@server_finished_tag = Object.new
@client_finished_tag = Object.new
@@ -52,153 +53,136 @@ shared_context 'setup: tags' do
Time.now + 2
end
- def expect_next_event_on(queue, type, tag)
- ev = queue.pluck(tag, deadline)
- if type.nil?
- expect(ev).to be_nil
- else
- expect(ev).to_not be_nil
- expect(ev.type).to be(type)
- end
- ev
- end
-
def server_allows_client_to_proceed
- @server.request_call(@server_tag)
- ev = @server_queue.pluck(@server_tag, deadline)
- expect(ev).not_to be_nil
- expect(ev.type).to be(SERVER_RPC_NEW)
- server_call = ev.call
- server_call.server_accept(@server_queue, @server_finished_tag)
- server_call.server_end_initial_metadata
+ recvd_rpc = @server.request_call(@server_queue, @server_tag, deadline)
+ expect(recvd_rpc).to_not eq nil
+ server_call = recvd_rpc.call
+ ops = { CallOps::SEND_INITIAL_METADATA => {} }
+ svr_batch = server_call.run_batch(@server_queue, @server_tag, deadline, ops)
+ expect(svr_batch.send_metadata).to be true
server_call
end
- def server_responds_with(server_call, reply_text)
- reply = ByteBuffer.new(reply_text)
- server_call.start_read(@server_tag)
- ev = @server_queue.pluck(@server_tag, TimeConsts::INFINITE_FUTURE)
- expect(ev.type).to be(READ)
- server_call.start_write(reply, @server_tag)
- ev = @server_queue.pluck(@server_tag, TimeConsts::INFINITE_FUTURE)
- expect(ev).not_to be_nil
- expect(ev.type).to be(WRITE_ACCEPTED)
- end
-
- def client_sends(call, sent = 'a message')
- req = ByteBuffer.new(sent)
- call.start_write(req, @tag)
- ev = @client_queue.pluck(@tag, TimeConsts::INFINITE_FUTURE)
- expect(ev).not_to be_nil
- expect(ev.type).to be(WRITE_ACCEPTED)
- sent
- end
-
def new_client_call
- @ch.create_call('/method', 'foo.test.google.fr', deadline)
+ @ch.create_call(@client_queue, '/method', 'foo.test.google.fr', deadline)
end
end
shared_examples 'basic GRPC message delivery is OK' do
+ include GRPC::Core
include_context 'setup: tags'
- it 'servers receive requests from clients and start responding' do
- reply = ByteBuffer.new('the server payload')
+ it 'servers receive requests from clients and can respond' do
call = new_client_call
- call.invoke(@client_queue, @client_metadata_tag, @client_finished_tag)
-
- # check the server rpc new was received
- # @server.request_call(@server_tag)
- # ev = expect_next_event_on(@server_queue, SERVER_RPC_NEW, @server_tag)
-
- # accept the call
- # server_call = ev.call
- # server_call.server_accept(@server_queue, @server_finished_tag)
- # server_call.server_end_initial_metadata
- server_call = server_allows_client_to_proceed
-
- # client sends a message
- msg = client_sends(call)
+ client_ops = {
+ CallOps::SEND_INITIAL_METADATA => {},
+ CallOps::SEND_MESSAGE => sent_message
+ }
+ batch_result = call.run_batch(@client_queue, @client_tag, deadline,
+ client_ops)
+ expect(batch_result.send_metadata).to be true
+ expect(batch_result.send_message).to be true
# confirm the server can read the inbound message
- server_call.start_read(@server_tag)
- ev = expect_next_event_on(@server_queue, READ, @server_tag)
- expect(ev.result.to_s).to eq(msg)
-
- # the server response
- server_call.start_write(reply, @server_tag)
- expect_next_event_on(@server_queue, WRITE_ACCEPTED, @server_tag)
+ server_call = server_allows_client_to_proceed
+ server_ops = {
+ CallOps::RECV_MESSAGE => nil
+ }
+ svr_batch = server_call.run_batch(@server_queue, @server_tag, deadline,
+ server_ops)
+ expect(svr_batch.message).to eq(sent_message)
end
it 'responses written by servers are received by the client' do
call = new_client_call
- call.invoke(@client_queue, @client_metadata_tag, @client_finished_tag)
- server_call = server_allows_client_to_proceed
- client_sends(call)
- server_responds_with(server_call, 'server_response')
+ client_ops = {
+ CallOps::SEND_INITIAL_METADATA => {},
+ CallOps::SEND_MESSAGE => sent_message
+ }
+ batch_result = call.run_batch(@client_queue, @client_tag, deadline,
+ client_ops)
+ expect(batch_result.send_metadata).to be true
+ expect(batch_result.send_message).to be true
- call.start_read(@tag)
- ev = expect_next_event_on(@client_queue, READ, @tag)
- expect(ev.result.to_s).to eq('server_response')
+ # confirm the server can read the inbound message
+ server_call = server_allows_client_to_proceed
+ server_ops = {
+ CallOps::RECV_MESSAGE => nil,
+ CallOps::SEND_MESSAGE => reply_text
+ }
+ svr_batch = server_call.run_batch(@server_queue, @server_tag, deadline,
+ server_ops)
+ expect(svr_batch.message).to eq(sent_message)
+ expect(svr_batch.send_message).to be true
end
it 'servers can ignore a client write and send a status' do
call = new_client_call
- call.invoke(@client_queue, @client_metadata_tag, @client_finished_tag)
-
- # check the server rpc new was received
- @server.request_call(@server_tag)
- ev = expect_next_event_on(@server_queue, SERVER_RPC_NEW, @server_tag)
- expect(ev.tag).to be(@server_tag)
-
- # accept the call - need to do this to sent status.
- server_call = ev.call
- server_call.server_accept(@server_queue, @server_finished_tag)
- server_call.server_end_initial_metadata
- server_call.start_write_status(StatusCodes::NOT_FOUND, 'not found',
- @server_tag)
-
- # Client sends some data
- client_sends(call)
-
- # client gets an empty response for the read, preceeded by some metadata.
- call.start_read(@tag)
- expect_next_event_on(@client_queue, CLIENT_METADATA_READ,
- @client_metadata_tag)
- ev = expect_next_event_on(@client_queue, READ, @tag)
- expect(ev.tag).to be(@tag)
- expect(ev.result.to_s).to eq('')
-
- # finally, after client sends writes_done, they get the finished.
- call.writes_done(@tag)
- expect_next_event_on(@client_queue, FINISH_ACCEPTED, @tag)
- ev = expect_next_event_on(@client_queue, FINISHED, @client_finished_tag)
- expect(ev.result.code).to eq(StatusCodes::NOT_FOUND)
+ client_ops = {
+ CallOps::SEND_INITIAL_METADATA => {},
+ CallOps::SEND_MESSAGE => sent_message
+ }
+ batch_result = call.run_batch(@client_queue, @client_tag, deadline,
+ client_ops)
+ expect(batch_result.send_metadata).to be true
+ expect(batch_result.send_message).to be true
+
+ # confirm the server can read the inbound message
+ the_status = Struct::Status.new(StatusCodes::OK, 'OK')
+ server_call = server_allows_client_to_proceed
+ server_ops = {
+ CallOps::SEND_STATUS_FROM_SERVER => the_status
+ }
+ svr_batch = server_call.run_batch(@server_queue, @server_tag, deadline,
+ server_ops)
+ expect(svr_batch.message).to eq nil
+ expect(svr_batch.send_status).to be true
end
it 'completes calls by sending status to client and server' do
call = new_client_call
- call.invoke(@client_queue, @client_metadata_tag, @client_finished_tag)
+ client_ops = {
+ CallOps::SEND_INITIAL_METADATA => {},
+ CallOps::SEND_MESSAGE => sent_message
+ }
+ batch_result = call.run_batch(@client_queue, @client_tag, deadline,
+ client_ops)
+ expect(batch_result.send_metadata).to be true
+ expect(batch_result.send_message).to be true
+
+ # confirm the server can read the inbound message and respond
+ the_status = Struct::Status.new(StatusCodes::OK, 'OK', {})
server_call = server_allows_client_to_proceed
- client_sends(call)
- server_responds_with(server_call, 'server_response')
- server_call.start_write_status(10_101, 'status code is 10101', @server_tag)
-
- # first the client says writes are done
- call.start_read(@tag)
- expect_next_event_on(@client_queue, READ, @tag)
- call.writes_done(@tag)
-
- # but nothing happens until the server sends a status
- expect_next_event_on(@server_queue, FINISH_ACCEPTED, @server_tag)
- ev = expect_next_event_on(@server_queue, FINISHED, @server_finished_tag)
- expect(ev.result).to be_a(Struct::Status)
-
- # client gets FINISHED
- expect_next_event_on(@client_queue, FINISH_ACCEPTED, @tag)
- ev = expect_next_event_on(@client_queue, FINISHED, @client_finished_tag)
- expect(ev.result.details).to eq('status code is 10101')
- expect(ev.result.code).to eq(10_101)
+ server_ops = {
+ CallOps::RECV_MESSAGE => nil,
+ CallOps::SEND_MESSAGE => reply_text,
+ CallOps::SEND_STATUS_FROM_SERVER => the_status
+ }
+ svr_batch = server_call.run_batch(@server_queue, @server_tag, deadline,
+ server_ops)
+ expect(svr_batch.message).to eq sent_message
+ expect(svr_batch.send_status).to be true
+ expect(svr_batch.send_message).to be true
+
+ # confirm the client can receive the server response and status.
+ client_ops = {
+ CallOps::SEND_CLOSE_FROM_CLIENT => nil,
+ CallOps::RECV_MESSAGE => nil,
+ CallOps::RECV_STATUS_ON_CLIENT => nil
+ }
+ batch_result = call.run_batch(@client_queue, @client_tag, deadline,
+ client_ops)
+ expect(batch_result.send_close).to be true
+ expect(batch_result.message).to eq reply_text
+ expect(batch_result.status).to eq the_status
+
+ # confirm the server can receive the client close.
+ server_ops = {
+ CallOps::RECV_CLOSE_ON_SERVER => nil
+ }
+ svr_batch = server_call.run_batch(@server_queue, @server_tag, deadline,
+ server_ops)
+ expect(svr_batch.send_close).to be true
end
end
@@ -224,25 +208,33 @@ shared_examples 'GRPC metadata delivery works OK' do
it 'raises an exception if a metadata key is invalid' do
@bad_keys.each do |md|
call = new_client_call
- expect { call.add_metadata(md) }.to raise_error
+ client_ops = {
+ CallOps::SEND_INITIAL_METADATA => md
+ }
+ blk = proc do
+ call.run_batch(@client_queue, @client_tag, deadline,
+ client_ops)
+ end
+ expect(&blk).to raise_error
end
end
it 'sends all the metadata pairs when keys and values are valid' do
@valid_metadata.each do |md|
call = new_client_call
- call.add_metadata(md)
-
- # Client begins a call OK
- call.invoke(@client_queue, @client_metadata_tag, @client_finished_tag)
-
- # ... server has all metadata available even though the client did not
- # send a write
- @server.request_call(@server_tag)
- ev = expect_next_event_on(@server_queue, SERVER_RPC_NEW, @server_tag)
+ client_ops = {
+ CallOps::SEND_INITIAL_METADATA => md
+ }
+ batch_result = call.run_batch(@client_queue, @client_tag, deadline,
+ client_ops)
+ expect(batch_result.send_metadata).to be true
+
+ # confirm the server can receive the client metadata
+ recvd_rpc = @server.request_call(@server_queue, @server_tag, deadline)
+ expect(recvd_rpc).to_not eq nil
+ recvd_md = recvd_rpc.metadata
replace_symbols = Hash[md.each_pair.collect { |x, y| [x.to_s, y] }]
- result = ev.result.metadata
- expect(result.merge(replace_symbols)).to eq(result)
+ expect(recvd_md).to eq(recvd_md.merge(replace_symbols))
end
end
end
@@ -266,55 +258,81 @@ shared_examples 'GRPC metadata delivery works OK' do
it 'raises an exception if a metadata key is invalid' do
@bad_keys.each do |md|
call = new_client_call
- call.invoke(@client_queue, @client_metadata_tag, @client_finished_tag)
+ # client signals that it's done sending metadata to allow server to
+ # respond
+ client_ops = {
+ CallOps::SEND_INITIAL_METADATA => nil
+ }
+ call.run_batch(@client_queue, @client_tag, deadline, client_ops)
# server gets the invocation
- @server.request_call(@server_tag)
- ev = expect_next_event_on(@server_queue, SERVER_RPC_NEW, @server_tag)
- expect { ev.call.add_metadata(md) }.to raise_error
+ recvd_rpc = @server.request_call(@server_queue, @server_tag, deadline)
+ expect(recvd_rpc).to_not eq nil
+ server_ops = {
+ CallOps::SEND_INITIAL_METADATA => md
+ }
+ blk = proc do
+ recvd_rpc.call.run_batch(@server_queue, @server_tag, deadline,
+ server_ops)
+ end
+ expect(&blk).to raise_error
end
end
- it 'sends a hash that contains the status when no metadata is added' do
+ it 'sends an empty hash if no metadata is added' do
call = new_client_call
- call.invoke(@client_queue, @client_metadata_tag, @client_finished_tag)
-
- # server gets the invocation
- @server.request_call(@server_tag)
- ev = expect_next_event_on(@server_queue, SERVER_RPC_NEW, @server_tag)
- server_call = ev.call
-
- # ... server accepts the call without adding metadata
- server_call.server_accept(@server_queue, @server_finished_tag)
- server_call.server_end_initial_metadata
-
- # there is the HTTP status metadata, though there should not be any
- # TODO: update this with the bug number to be resolved
- ev = expect_next_event_on(@client_queue, CLIENT_METADATA_READ,
- @client_metadata_tag)
- expect(ev.result).to eq({})
+ # client signals that it's done sending metadata to allow server to
+ # respond
+ client_ops = {
+ CallOps::SEND_INITIAL_METADATA => nil
+ }
+ call.run_batch(@client_queue, @client_tag, deadline, client_ops)
+
+ # server gets the invocation but sends no metadata back
+ recvd_rpc = @server.request_call(@server_queue, @server_tag, deadline)
+ expect(recvd_rpc).to_not eq nil
+ server_call = recvd_rpc.call
+ server_ops = {
+ CallOps::SEND_INITIAL_METADATA => nil
+ }
+ server_call.run_batch(@server_queue, @server_tag, deadline, server_ops)
+
+ # client receives nothing as expected
+ client_ops = {
+ CallOps::RECV_INITIAL_METADATA => nil
+ }
+ batch_result = call.run_batch(@client_queue, @client_tag, deadline,
+ client_ops)
+ expect(batch_result.metadata).to eq({})
end
it 'sends all the pairs when keys and values are valid' do
@valid_metadata.each do |md|
call = new_client_call
- call.invoke(@client_queue, @client_metadata_tag, @client_finished_tag)
-
- # server gets the invocation
- @server.request_call(@server_tag)
- ev = expect_next_event_on(@server_queue, SERVER_RPC_NEW, @server_tag)
- server_call = ev.call
-
- # ... server adds metadata and accepts the call
- server_call.add_metadata(md)
- server_call.server_accept(@server_queue, @server_finished_tag)
- server_call.server_end_initial_metadata
-
- # Now the client can read the metadata
- ev = expect_next_event_on(@client_queue, CLIENT_METADATA_READ,
- @client_metadata_tag)
+ # client signals that it's done sending metadata to allow server to
+ # respond
+ client_ops = {
+ CallOps::SEND_INITIAL_METADATA => nil
+ }
+ call.run_batch(@client_queue, @client_tag, deadline, client_ops)
+
+ # server gets the invocation but sends no metadata back
+ recvd_rpc = @server.request_call(@server_queue, @server_tag, deadline)
+ expect(recvd_rpc).to_not eq nil
+ server_call = recvd_rpc.call
+ server_ops = {
+ CallOps::SEND_INITIAL_METADATA => md
+ }
+ server_call.run_batch(@server_queue, @server_tag, deadline, server_ops)
+
+ # client receives nothing as expected
+ client_ops = {
+ CallOps::RECV_INITIAL_METADATA => nil
+ }
+ batch_result = call.run_batch(@client_queue, @client_tag, deadline,
+ client_ops)
replace_symbols = Hash[md.each_pair.collect { |x, y| [x.to_s, y] }]
- expect(ev.result).to eq(replace_symbols)
+ expect(batch_result.metadata).to eq(replace_symbols)
end
end
end
diff --git a/src/ruby/spec/event_spec.rb b/src/ruby/spec/event_spec.rb
deleted file mode 100644
index 7d92fcd792..0000000000
--- a/src/ruby/spec/event_spec.rb
+++ /dev/null
@@ -1,53 +0,0 @@
-# Copyright 2015, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-require 'grpc'
-
-describe GRPC::Core::CompletionType do
- before(:each) do
- @known_types = {
- QUEUE_SHUTDOWN: 0,
- OP_COMPLETE: 1,
- READ: 2,
- WRITE_ACCEPTED: 3,
- FINISH_ACCEPTED: 4,
- CLIENT_METADATA_READ: 5,
- FINISHED: 6,
- SERVER_RPC_NEW: 7,
- SERVER_SHUTDOWN: 8,
- RESERVED: 9
- }
- end
-
- it 'should have all the known types' do
- mod = GRPC::Core::CompletionType
- blk = proc { Hash[mod.constants.collect { |c| [c, mod.const_get(c)] }] }
- expect(blk.call).to eq(@known_types)
- end
-end
diff --git a/src/ruby/spec/generic/active_call_spec.rb b/src/ruby/spec/generic/active_call_spec.rb
index 96e07cacb4..575871afb1 100644
--- a/src/ruby/spec/generic/active_call_spec.rb
+++ b/src/ruby/spec/generic/active_call_spec.rb
@@ -34,12 +34,11 @@ include GRPC::Core::StatusCodes
describe GRPC::ActiveCall do
ActiveCall = GRPC::ActiveCall
Call = GRPC::Core::Call
- CompletionType = GRPC::Core::CompletionType
+ CallOps = GRPC::Core::CallOps
before(:each) do
@pass_through = proc { |x| x }
@server_tag = Object.new
- @server_done_tag = Object.new
@tag = Object.new
@client_queue = GRPC::Core::CompletionQueue.new
@@ -48,7 +47,7 @@ describe GRPC::ActiveCall do
@server = GRPC::Core::Server.new(@server_queue, nil)
server_port = @server.add_http2_port(host)
@server.start
- @ch = GRPC::Core::Channel.new("localhost:#{server_port}", nil)
+ @ch = GRPC::Core::Channel.new("0.0.0.0:#{server_port}", nil)
end
after(:each) do
@@ -58,12 +57,10 @@ describe GRPC::ActiveCall do
describe 'restricted view methods' do
before(:each) do
call = make_test_call
- done_tag, meta_tag = ActiveCall.client_invoke(call, @client_queue,
- deadline)
+ md_tag = ActiveCall.client_invoke(call, @client_queue, deadline)
@client_call = ActiveCall.new(call, @client_queue, @pass_through,
@pass_through, deadline,
- finished_tag: done_tag,
- read_metadata_tag: meta_tag)
+ metadata_tag: md_tag)
end
describe '#multi_req_view' do
@@ -90,48 +87,45 @@ describe GRPC::ActiveCall do
describe '#remote_send' do
it 'allows a client to send a payload to the server' do
call = make_test_call
- done_tag, meta_tag = ActiveCall.client_invoke(call, @client_queue,
- deadline)
+ md_tag = ActiveCall.client_invoke(call, @client_queue, deadline)
@client_call = ActiveCall.new(call, @client_queue, @pass_through,
@pass_through, deadline,
- finished_tag: done_tag,
- read_metadata_tag: meta_tag)
+ metadata_tag: md_tag)
msg = 'message is a string'
@client_call.remote_send(msg)
# check that server rpc new was received
- @server.request_call(@server_tag)
- ev = @server_queue.next(deadline)
- expect(ev.type).to be(CompletionType::SERVER_RPC_NEW)
- expect(ev.call).to be_a(Call)
- expect(ev.tag).to be(@server_tag)
+ recvd_rpc = @server.request_call(@server_queue, @server_tag, deadline)
+ expect(recvd_rpc).to_not eq nil
+ recvd_call = recvd_rpc.call
# Accept the call, and verify that the server reads the response ok.
- ev.call.server_accept(@client_queue, @server_tag)
- ev.call.server_end_initial_metadata
- server_call = ActiveCall.new(ev.call, @client_queue, @pass_through,
+ server_ops = {
+ CallOps::SEND_INITIAL_METADATA => {}
+ }
+ recvd_call.run_batch(@server_queue, @server_tag, deadline, server_ops)
+ server_call = ActiveCall.new(recvd_call, @server_queue, @pass_through,
@pass_through, deadline)
expect(server_call.remote_read).to eq(msg)
end
it 'marshals the payload using the marshal func' do
call = make_test_call
- done_tag, meta_tag = ActiveCall.client_invoke(call, @client_queue,
- deadline)
+ ActiveCall.client_invoke(call, @client_queue, deadline)
marshal = proc { |x| 'marshalled:' + x }
client_call = ActiveCall.new(call, @client_queue, marshal,
- @pass_through, deadline,
- finished_tag: done_tag,
- read_metadata_tag: meta_tag)
+ @pass_through, deadline)
msg = 'message is a string'
client_call.remote_send(msg)
# confirm that the message was marshalled
- @server.request_call(@server_tag)
- ev = @server_queue.next(deadline)
- ev.call.server_accept(@client_queue, @server_tag)
- ev.call.server_end_initial_metadata
- server_call = ActiveCall.new(ev.call, @client_queue, @pass_through,
+ recvd_rpc = @server.request_call(@server_queue, @server_tag, deadline)
+ recvd_call = recvd_rpc.call
+ server_ops = {
+ CallOps::SEND_INITIAL_METADATA => nil
+ }
+ recvd_call.run_batch(@server_queue, @server_tag, deadline, server_ops)
+ server_call = ActiveCall.new(recvd_call, @server_queue, @pass_through,
@pass_through, deadline)
expect(server_call.remote_read).to eq('marshalled:' + msg)
end
@@ -142,23 +136,22 @@ describe GRPC::ActiveCall do
call = make_test_call
ActiveCall.client_invoke(call, @client_queue, deadline,
k1: 'v1', k2: 'v2')
- @server.request_call(@server_tag)
- ev = @server_queue.next(deadline)
- expect(ev).to_not be_nil
- expect(ev.result.metadata['k1']).to eq('v1')
- expect(ev.result.metadata['k2']).to eq('v2')
+ recvd_rpc = @server.request_call(@server_queue, @server_tag, deadline)
+ recvd_call = recvd_rpc.call
+ expect(recvd_call).to_not be_nil
+ expect(recvd_rpc.metadata).to_not be_nil
+ expect(recvd_rpc.metadata['k1']).to eq('v1')
+ expect(recvd_rpc.metadata['k2']).to eq('v2')
end
end
describe '#remote_read' do
it 'reads the response sent by a server' do
call = make_test_call
- done_tag, meta_tag = ActiveCall.client_invoke(call, @client_queue,
- deadline)
+ md_tag = ActiveCall.client_invoke(call, @client_queue, deadline)
client_call = ActiveCall.new(call, @client_queue, @pass_through,
@pass_through, deadline,
- finished_tag: done_tag,
- read_metadata_tag: meta_tag)
+ metadata_tag: md_tag)
msg = 'message is a string'
client_call.remote_send(msg)
server_call = expect_server_to_receive(msg)
@@ -168,12 +161,10 @@ describe GRPC::ActiveCall do
it 'saves no metadata when the server adds no metadata' do
call = make_test_call
- done_tag, meta_tag = ActiveCall.client_invoke(call, @client_queue,
- deadline)
+ md_tag = ActiveCall.client_invoke(call, @client_queue, deadline)
client_call = ActiveCall.new(call, @client_queue, @pass_through,
@pass_through, deadline,
- finished_tag: done_tag,
- read_metadata_tag: meta_tag)
+ metadata_tag: md_tag)
msg = 'message is a string'
client_call.remote_send(msg)
server_call = expect_server_to_receive(msg)
@@ -185,12 +176,10 @@ describe GRPC::ActiveCall do
it 'saves metadata add by the server' do
call = make_test_call
- done_tag, meta_tag = ActiveCall.client_invoke(call, @client_queue,
- deadline)
+ md_tag = ActiveCall.client_invoke(call, @client_queue, deadline)
client_call = ActiveCall.new(call, @client_queue, @pass_through,
@pass_through, deadline,
- finished_tag: done_tag,
- read_metadata_tag: meta_tag)
+ metadata_tag: md_tag)
msg = 'message is a string'
client_call.remote_send(msg)
server_call = expect_server_to_receive(msg, k1: 'v1', k2: 'v2')
@@ -203,12 +192,10 @@ describe GRPC::ActiveCall do
it 'get a nil msg before a status when an OK status is sent' do
call = make_test_call
- done_tag, meta_tag = ActiveCall.client_invoke(call, @client_queue,
- deadline)
+ md_tag = ActiveCall.client_invoke(call, @client_queue, deadline)
client_call = ActiveCall.new(call, @client_queue, @pass_through,
@pass_through, deadline,
- finished_tag: done_tag,
- read_metadata_tag: meta_tag)
+ metadata_tag: md_tag)
msg = 'message is a string'
client_call.remote_send(msg)
client_call.writes_done(false)
@@ -222,13 +209,11 @@ describe GRPC::ActiveCall do
it 'unmarshals the response using the unmarshal func' do
call = make_test_call
- done_tag, meta_tag = ActiveCall.client_invoke(call, @client_queue,
- deadline)
+ md_tag = ActiveCall.client_invoke(call, @client_queue, deadline)
unmarshal = proc { |x| 'unmarshalled:' + x }
client_call = ActiveCall.new(call, @client_queue, @pass_through,
unmarshal, deadline,
- finished_tag: done_tag,
- read_metadata_tag: meta_tag)
+ metadata_tag: md_tag)
# confirm the client receives the unmarshalled message
msg = 'message is a string'
@@ -249,13 +234,11 @@ describe GRPC::ActiveCall do
it 'the returns an enumerator that can read n responses' do
call = make_test_call
- done_tag, meta_tag = ActiveCall.client_invoke(call, @client_queue,
- deadline)
+ md_tag = ActiveCall.client_invoke(call, @client_queue, deadline)
client_call = ActiveCall.new(call, @client_queue, @pass_through,
@pass_through, deadline,
- finished_tag: done_tag,
- read_metadata_tag: meta_tag)
- msg = 'message is 4a string'
+ metadata_tag: md_tag)
+ msg = 'message is a string'
reply = 'server_response'
client_call.remote_send(msg)
server_call = expect_server_to_receive(msg)
@@ -269,12 +252,10 @@ describe GRPC::ActiveCall do
it 'the returns an enumerator that stops after an OK Status' do
call = make_test_call
- done_tag, meta_tag = ActiveCall.client_invoke(call, @client_queue,
- deadline)
+ md_tag = ActiveCall.client_invoke(call, @client_queue, deadline)
client_call = ActiveCall.new(call, @client_queue, @pass_through,
@pass_through, deadline,
- read_metadata_tag: meta_tag,
- finished_tag: done_tag)
+ metadata_tag: md_tag)
msg = 'message is a string'
reply = 'server_response'
client_call.remote_send(msg)
@@ -294,12 +275,10 @@ describe GRPC::ActiveCall do
describe '#writes_done' do
it 'finishes ok if the server sends a status response' do
call = make_test_call
- done_tag, meta_tag = ActiveCall.client_invoke(call, @client_queue,
- deadline)
+ md_tag = ActiveCall.client_invoke(call, @client_queue, deadline)
client_call = ActiveCall.new(call, @client_queue, @pass_through,
@pass_through, deadline,
- finished_tag: done_tag,
- read_metadata_tag: meta_tag)
+ metadata_tag: md_tag)
msg = 'message is a string'
client_call.remote_send(msg)
expect { client_call.writes_done(false) }.to_not raise_error
@@ -312,12 +291,10 @@ describe GRPC::ActiveCall do
it 'finishes ok if the server sends an early status response' do
call = make_test_call
- done_tag, meta_tag = ActiveCall.client_invoke(call, @client_queue,
- deadline)
+ md_tag = ActiveCall.client_invoke(call, @client_queue, deadline)
client_call = ActiveCall.new(call, @client_queue, @pass_through,
@pass_through, deadline,
- read_metadata_tag: meta_tag,
- finished_tag: done_tag)
+ metadata_tag: md_tag)
msg = 'message is a string'
client_call.remote_send(msg)
server_call = expect_server_to_receive(msg)
@@ -330,12 +307,10 @@ describe GRPC::ActiveCall do
it 'finishes ok if writes_done is true' do
call = make_test_call
- done_tag, meta_tag = ActiveCall.client_invoke(call, @client_queue,
- deadline)
+ md_tag = ActiveCall.client_invoke(call, @client_queue, deadline)
client_call = ActiveCall.new(call, @client_queue, @pass_through,
@pass_through, deadline,
- read_metadata_tag: meta_tag,
- finished_tag: done_tag)
+ metadata_tag: md_tag)
msg = 'message is a string'
client_call.remote_send(msg)
server_call = expect_server_to_receive(msg)
@@ -353,21 +328,20 @@ describe GRPC::ActiveCall do
end
def expect_server_to_be_invoked(**kw)
- @server.request_call(@server_tag)
- ev = @server_queue.next(deadline)
- ev.call.add_metadata(kw)
- ev.call.server_accept(@client_queue, @server_done_tag)
- ev.call.server_end_initial_metadata
- ActiveCall.new(ev.call, @client_queue, @pass_through,
- @pass_through, deadline,
- finished_tag: @server_done_tag)
+ recvd_rpc = @server.request_call(@server_queue, @server_tag, deadline)
+ expect(recvd_rpc).to_not eq nil
+ recvd_call = recvd_rpc.call
+ recvd_call.run_batch(@server_queue, @server_tag, deadline,
+ CallOps::SEND_INITIAL_METADATA => kw)
+ ActiveCall.new(recvd_call, @server_queue, @pass_through,
+ @pass_through, deadline)
end
def make_test_call
- @ch.create_call('dummy_method', 'dummy_host', deadline)
+ @ch.create_call(@client_queue, '/method', 'a.dummy.host', deadline)
end
def deadline
- Time.now + 1 # in 1 second; arbitrary
+ Time.now + 2 # in 2 seconds; arbitrary
end
end
diff --git a/src/ruby/spec/generic/client_stub_spec.rb b/src/ruby/spec/generic/client_stub_spec.rb
index 0c98fc40d9..193c5f2a03 100644
--- a/src/ruby/spec/generic/client_stub_spec.rb
+++ b/src/ruby/spec/generic/client_stub_spec.rb
@@ -30,15 +30,41 @@
require 'grpc'
require 'xray/thread_dump_signal_handler'
-NOOP = proc { |x| x }
-FAKE_HOST = 'localhost:0'
+# Notifier is useful high-level synchronization primitive.
+class Notifier
+ attr_reader :payload, :notified
+ alias_method :notified?, :notified
+
+ def initialize
+ @mutex = Mutex.new
+ @cvar = ConditionVariable.new
+ @notified = false
+ @payload = nil
+ end
+
+ def wait
+ @mutex.synchronize do
+ @cvar.wait(@mutex) until notified?
+ end
+ end
+
+ def notify(payload)
+ @mutex.synchronize do
+ return Error.new('already notified') if notified?
+ @payload = payload
+ @notified = true
+ @cvar.signal
+ return nil
+ end
+ end
+end
def wakey_thread(&blk)
- awake_mutex, awake_cond = Mutex.new, ConditionVariable.new
+ n = Notifier.new
t = Thread.new do
- blk.call(awake_mutex, awake_cond)
+ blk.call(n)
end
- awake_mutex.synchronize { awake_cond.wait(awake_mutex) }
+ n.wait
t
end
@@ -50,8 +76,11 @@ end
include GRPC::Core::StatusCodes
include GRPC::Core::TimeConsts
+include GRPC::Core::CallOps
describe 'ClientStub' do
+ let(:noop) { proc { |x| x } }
+
before(:each) do
Thread.abort_on_exception = true
@server = nil
@@ -66,61 +95,56 @@ describe 'ClientStub' do
end
describe '#new' do
+ let(:fake_host) { 'localhost:0' }
it 'can be created from a host and args' do
- host = FAKE_HOST
opts = { a_channel_arg: 'an_arg' }
blk = proc do
- GRPC::ClientStub.new(host, @cq, **opts)
+ GRPC::ClientStub.new(fake_host, @cq, **opts)
end
expect(&blk).not_to raise_error
end
it 'can be created with a default deadline' do
- host = FAKE_HOST
opts = { a_channel_arg: 'an_arg', deadline: 5 }
blk = proc do
- GRPC::ClientStub.new(host, @cq, **opts)
+ GRPC::ClientStub.new(fake_host, @cq, **opts)
end
expect(&blk).not_to raise_error
end
it 'can be created with an channel override' do
- host = FAKE_HOST
opts = { a_channel_arg: 'an_arg', channel_override: @ch }
blk = proc do
- GRPC::ClientStub.new(host, @cq, **opts)
+ GRPC::ClientStub.new(fake_host, @cq, **opts)
end
expect(&blk).not_to raise_error
end
it 'cannot be created with a bad channel override' do
- host = FAKE_HOST
blk = proc do
opts = { a_channel_arg: 'an_arg', channel_override: Object.new }
- GRPC::ClientStub.new(host, @cq, **opts)
+ GRPC::ClientStub.new(fake_host, @cq, **opts)
end
expect(&blk).to raise_error
end
it 'cannot be created with bad credentials' do
- host = FAKE_HOST
blk = proc do
opts = { a_channel_arg: 'an_arg', creds: Object.new }
- GRPC::ClientStub.new(host, @cq, **opts)
+ GRPC::ClientStub.new(fake_host, @cq, **opts)
end
expect(&blk).to raise_error
end
it 'can be created with test test credentials' do
certs = load_test_certs
- host = FAKE_HOST
blk = proc do
opts = {
GRPC::Core::Channel::SSL_TARGET => 'foo.test.google.fr',
a_channel_arg: 'an_arg',
creds: GRPC::Core::Credentials.new(certs[0], nil, nil)
}
- GRPC::ClientStub.new(host, @cq, **opts)
+ GRPC::ClientStub.new(fake_host, @cq, **opts)
end
expect(&blk).to_not raise_error
end
@@ -187,7 +211,7 @@ describe 'ClientStub' do
describe 'without a call operation' do
def get_response(stub)
- stub.request_response(@method, @sent_msg, NOOP, NOOP,
+ stub.request_response(@method, @sent_msg, noop, noop,
k1: 'v1', k2: 'v2')
end
@@ -196,7 +220,7 @@ describe 'ClientStub' do
describe 'via a call operation' do
def get_response(stub)
- op = stub.request_response(@method, @sent_msg, NOOP, NOOP,
+ op = stub.request_response(@method, @sent_msg, noop, noop,
return_op: true, k1: 'v1', k2: 'v2')
expect(op).to be_a(GRPC::ActiveCall::Operation)
op.execute
@@ -259,7 +283,7 @@ describe 'ClientStub' do
describe 'without a call operation' do
def get_response(stub)
- stub.client_streamer(@method, @sent_msgs, NOOP, NOOP,
+ stub.client_streamer(@method, @sent_msgs, noop, noop,
k1: 'v1', k2: 'v2')
end
@@ -268,7 +292,7 @@ describe 'ClientStub' do
describe 'via a call operation' do
def get_response(stub)
- op = stub.client_streamer(@method, @sent_msgs, NOOP, NOOP,
+ op = stub.client_streamer(@method, @sent_msgs, noop, noop,
return_op: true, k1: 'v1', k2: 'v2')
expect(op).to be_a(GRPC::ActiveCall::Operation)
op.execute
@@ -333,7 +357,7 @@ describe 'ClientStub' do
describe 'without a call operation' do
def get_responses(stub)
- e = stub.server_streamer(@method, @sent_msg, NOOP, NOOP,
+ e = stub.server_streamer(@method, @sent_msg, noop, noop,
k1: 'v1', k2: 'v2')
expect(e).to be_a(Enumerator)
e
@@ -344,7 +368,7 @@ describe 'ClientStub' do
describe 'via a call operation' do
def get_responses(stub)
- op = stub.server_streamer(@method, @sent_msg, NOOP, NOOP,
+ op = stub.server_streamer(@method, @sent_msg, noop, noop,
return_op: true, k1: 'v1', k2: 'v2')
expect(op).to be_a(GRPC::ActiveCall::Operation)
e = op.execute
@@ -361,34 +385,30 @@ describe 'ClientStub' do
before(:each) do
@sent_msgs = Array.new(3) { |i| 'msg_' + (i + 1).to_s }
@replys = Array.new(3) { |i| 'reply_' + (i + 1).to_s }
+ server_port = create_test_server
+ @host = "localhost:#{server_port}"
end
it 'supports sending all the requests first', bidi: true do
- server_port = create_test_server
- host = "localhost:#{server_port}"
th = run_bidi_streamer_handle_inputs_first(@sent_msgs, @replys,
@pass)
- stub = GRPC::ClientStub.new(host, @cq)
+ stub = GRPC::ClientStub.new(@host, @cq)
e = get_responses(stub)
expect(e.collect { |r| r }).to eq(@replys)
th.join
end
it 'supports client-initiated ping pong', bidi: true do
- server_port = create_test_server
- host = "localhost:#{server_port}"
th = run_bidi_streamer_echo_ping_pong(@sent_msgs, @pass, true)
- stub = GRPC::ClientStub.new(host, @cq)
+ stub = GRPC::ClientStub.new(@host, @cq)
e = get_responses(stub)
expect(e.collect { |r| r }).to eq(@sent_msgs)
th.join
end
it 'supports a server-initiated ping pong', bidi: true do
- server_port = create_test_server
- host = "localhost:#{server_port}"
th = run_bidi_streamer_echo_ping_pong(@sent_msgs, @pass, false)
- stub = GRPC::ClientStub.new(host, @cq)
+ stub = GRPC::ClientStub.new(@host, @cq)
e = get_responses(stub)
expect(e.collect { |r| r }).to eq(@sent_msgs)
th.join
@@ -397,7 +417,7 @@ describe 'ClientStub' do
describe 'without a call operation' do
def get_responses(stub)
- e = stub.bidi_streamer(@method, @sent_msgs, NOOP, NOOP)
+ e = stub.bidi_streamer(@method, @sent_msgs, noop, noop)
expect(e).to be_a(Enumerator)
e
end
@@ -407,7 +427,7 @@ describe 'ClientStub' do
describe 'via a call operation' do
def get_responses(stub)
- op = stub.bidi_streamer(@method, @sent_msgs, NOOP, NOOP,
+ op = stub.bidi_streamer(@method, @sent_msgs, noop, noop,
return_op: true)
expect(op).to be_a(GRPC::ActiveCall::Operation)
e = op.execute
@@ -421,8 +441,8 @@ describe 'ClientStub' do
def run_server_streamer(expected_input, replys, status, **kw)
wanted_metadata = kw.clone
- wakey_thread do |mtx, cnd|
- c = expect_server_to_be_invoked(mtx, cnd)
+ wakey_thread do |notifier|
+ c = expect_server_to_be_invoked(notifier)
wanted_metadata.each do |k, v|
expect(c.metadata[k.to_s]).to eq(v)
end
@@ -434,8 +454,8 @@ describe 'ClientStub' do
def run_bidi_streamer_handle_inputs_first(expected_inputs, replys,
status)
- wakey_thread do |mtx, cnd|
- c = expect_server_to_be_invoked(mtx, cnd)
+ wakey_thread do |notifier|
+ c = expect_server_to_be_invoked(notifier)
expected_inputs.each { |i| expect(c.remote_read).to eq(i) }
replys.each { |r| c.remote_send(r) }
c.send_status(status, status == @pass ? 'OK' : 'NOK', true)
@@ -443,8 +463,8 @@ describe 'ClientStub' do
end
def run_bidi_streamer_echo_ping_pong(expected_inputs, status, client_starts)
- wakey_thread do |mtx, cnd|
- c = expect_server_to_be_invoked(mtx, cnd)
+ wakey_thread do |notifier|
+ c = expect_server_to_be_invoked(notifier)
expected_inputs.each do |i|
if client_starts
expect(c.remote_read).to eq(i)
@@ -460,8 +480,8 @@ describe 'ClientStub' do
def run_client_streamer(expected_inputs, resp, status, **kw)
wanted_metadata = kw.clone
- wakey_thread do |mtx, cnd|
- c = expect_server_to_be_invoked(mtx, cnd)
+ wakey_thread do |notifier|
+ c = expect_server_to_be_invoked(notifier)
expected_inputs.each { |i| expect(c.remote_read).to eq(i) }
wanted_metadata.each do |k, v|
expect(c.metadata[k.to_s]).to eq(v)
@@ -473,8 +493,8 @@ describe 'ClientStub' do
def run_request_response(expected_input, resp, status, **kw)
wanted_metadata = kw.clone
- wakey_thread do |mtx, cnd|
- c = expect_server_to_be_invoked(mtx, cnd)
+ wakey_thread do |notifier|
+ c = expect_server_to_be_invoked(notifier)
expect(c.remote_read).to eq(expected_input)
wanted_metadata.each do |k, v|
expect(c.metadata[k.to_s]).to eq(v)
@@ -490,24 +510,16 @@ describe 'ClientStub' do
@server.add_http2_port('0.0.0.0:0')
end
- def start_test_server(awake_mutex, awake_cond)
+ def expect_server_to_be_invoked(notifier)
@server.start
- @server_tag = Object.new
- @server.request_call(@server_tag)
- awake_mutex.synchronize { awake_cond.signal }
- end
-
- def expect_server_to_be_invoked(awake_mutex, awake_cond)
- start_test_server(awake_mutex, awake_cond)
- ev = @server_queue.pluck(@server_tag, INFINITE_FUTURE)
- fail OutOfTime if ev.nil?
- server_call = ev.call
- server_call.metadata = ev.result.metadata
- finished_tag = Object.new
- server_call.server_accept(@server_queue, finished_tag)
- server_call.server_end_initial_metadata
- GRPC::ActiveCall.new(server_call, @server_queue, NOOP, NOOP,
- INFINITE_FUTURE,
- finished_tag: finished_tag)
+ notifier.notify(nil)
+ server_tag = Object.new
+ recvd_rpc = @server.request_call(@server_queue, server_tag,
+ INFINITE_FUTURE)
+ recvd_call = recvd_rpc.call
+ recvd_call.metadata = recvd_rpc.metadata
+ recvd_call.run_batch(@server_queue, server_tag, Time.now + 2,
+ SEND_INITIAL_METADATA => nil)
+ GRPC::ActiveCall.new(recvd_call, @server_queue, noop, noop, INFINITE_FUTURE)
end
end
diff --git a/src/ruby/spec/generic/rpc_desc_spec.rb b/src/ruby/spec/generic/rpc_desc_spec.rb
index 39d1e83748..a68299465c 100644
--- a/src/ruby/spec/generic/rpc_desc_spec.rb
+++ b/src/ruby/spec/generic/rpc_desc_spec.rb
@@ -37,7 +37,6 @@ describe GRPC::RpcDesc do
INTERNAL = GRPC::Core::StatusCodes::INTERNAL
UNKNOWN = GRPC::Core::StatusCodes::UNKNOWN
CallError = GRPC::Core::CallError
- EventError = GRPC::Core::EventError
before(:each) do
@request_response = RpcDesc.new('rr', Object.new, Object.new, 'encode',
@@ -63,24 +62,17 @@ describe GRPC::RpcDesc do
it 'sends the specified status if BadStatus is raised' do
expect(@call).to receive(:remote_read).once.and_return(Object.new)
- expect(@call).to receive(:send_status).once.with(@bs_code, 'NOK')
+ expect(@call).to receive(:send_status).once.with(@bs_code, 'NOK', false)
@request_response.run_server_method(@call, method(:bad_status))
end
it 'sends status UNKNOWN if other StandardErrors are raised' do
expect(@call).to receive(:remote_read).once.and_return(Object.new)
- expect(@call).to receive(:send_status) .once.with(UNKNOWN, @no_reason)
+ expect(@call).to receive(:send_status) .once.with(UNKNOWN, @no_reason,
+ false)
@request_response.run_server_method(@call, method(:other_error))
end
- it 'absorbs EventError with no further action' do
- expect(@call).to receive(:remote_read).once.and_raise(EventError)
- blk = proc do
- @request_response.run_server_method(@call, method(:fake_reqresp))
- end
- expect(&blk).to_not raise_error
- end
-
it 'absorbs CallError with no further action' do
expect(@call).to receive(:remote_read).once.and_raise(CallError)
blk = proc do
@@ -93,8 +85,7 @@ describe GRPC::RpcDesc do
req = Object.new
expect(@call).to receive(:remote_read).once.and_return(req)
expect(@call).to receive(:remote_send).once.with(@ok_response)
- expect(@call).to receive(:send_status).once.with(OK, 'OK')
- expect(@call).to receive(:finished).once
+ expect(@call).to receive(:send_status).once.with(OK, 'OK', true)
@request_response.run_server_method(@call, method(:fake_reqresp))
end
end
@@ -107,23 +98,16 @@ describe GRPC::RpcDesc do
end
it 'sends the specified status if BadStatus is raised' do
- expect(@call).to receive(:send_status).once.with(@bs_code, 'NOK')
+ expect(@call).to receive(:send_status).once.with(@bs_code, 'NOK', false)
@client_streamer.run_server_method(@call, method(:bad_status_alt))
end
it 'sends status UNKNOWN if other StandardErrors are raised' do
- expect(@call).to receive(:send_status) .once.with(UNKNOWN, @no_reason)
+ expect(@call).to receive(:send_status) .once.with(UNKNOWN, @no_reason,
+ false)
@client_streamer.run_server_method(@call, method(:other_error_alt))
end
- it 'absorbs EventError with no further action' do
- expect(@call).to receive(:remote_send).once.and_raise(EventError)
- blk = proc do
- @client_streamer.run_server_method(@call, method(:fake_clstream))
- end
- expect(&blk).to_not raise_error
- end
-
it 'absorbs CallError with no further action' do
expect(@call).to receive(:remote_send).once.and_raise(CallError)
blk = proc do
@@ -134,8 +118,7 @@ describe GRPC::RpcDesc do
it 'sends a response and closes the stream if there no errors' do
expect(@call).to receive(:remote_send).once.with(@ok_response)
- expect(@call).to receive(:send_status).once.with(OK, 'OK')
- expect(@call).to receive(:finished).once
+ expect(@call).to receive(:send_status).once.with(OK, 'OK', true)
@client_streamer.run_server_method(@call, method(:fake_clstream))
end
end
@@ -149,24 +132,17 @@ describe GRPC::RpcDesc do
it 'sends the specified status if BadStatus is raised' do
expect(@call).to receive(:remote_read).once.and_return(Object.new)
- expect(@call).to receive(:send_status).once.with(@bs_code, 'NOK')
+ expect(@call).to receive(:send_status).once.with(@bs_code, 'NOK', false)
@server_streamer.run_server_method(@call, method(:bad_status))
end
it 'sends status UNKNOWN if other StandardErrors are raised' do
expect(@call).to receive(:remote_read).once.and_return(Object.new)
- expect(@call).to receive(:send_status) .once.with(UNKNOWN, @no_reason)
+ expect(@call).to receive(:send_status) .once.with(UNKNOWN, @no_reason,
+ false)
@server_streamer.run_server_method(@call, method(:other_error))
end
- it 'absorbs EventError with no further action' do
- expect(@call).to receive(:remote_read).once.and_raise(EventError)
- blk = proc do
- @server_streamer.run_server_method(@call, method(:fake_svstream))
- end
- expect(&blk).to_not raise_error
- end
-
it 'absorbs CallError with no further action' do
expect(@call).to receive(:remote_read).once.and_raise(CallError)
blk = proc do
@@ -179,8 +155,7 @@ describe GRPC::RpcDesc do
req = Object.new
expect(@call).to receive(:remote_read).once.and_return(req)
expect(@call).to receive(:remote_send).twice.with(@ok_response)
- expect(@call).to receive(:send_status).once.with(OK, 'OK')
- expect(@call).to receive(:finished).once
+ expect(@call).to receive(:send_status).once.with(OK, 'OK', true)
@server_streamer.run_server_method(@call, method(:fake_svstream))
end
end
@@ -197,20 +172,20 @@ describe GRPC::RpcDesc do
it 'sends the specified status if BadStatus is raised' do
e = GRPC::BadStatus.new(@bs_code, 'NOK')
expect(@call).to receive(:run_server_bidi).and_raise(e)
- expect(@call).to receive(:send_status).once.with(@bs_code, 'NOK')
+ expect(@call).to receive(:send_status).once.with(@bs_code, 'NOK', false)
@bidi_streamer.run_server_method(@call, method(:bad_status_alt))
end
it 'sends status UNKNOWN if other StandardErrors are raised' do
expect(@call).to receive(:run_server_bidi).and_raise(StandardError)
- expect(@call).to receive(:send_status).once.with(UNKNOWN, @no_reason)
+ expect(@call).to receive(:send_status).once.with(UNKNOWN, @no_reason,
+ false)
@bidi_streamer.run_server_method(@call, method(:other_error_alt))
end
it 'closes the stream if there no errors' do
expect(@call).to receive(:run_server_bidi)
- expect(@call).to receive(:send_status).once.with(OK, 'OK')
- expect(@call).to receive(:finished).once
+ expect(@call).to receive(:send_status).once.with(OK, 'OK', true)
@bidi_streamer.run_server_method(@call, method(:fake_bidistream))
end
end
diff --git a/src/ruby/spec/generic/rpc_server_spec.rb b/src/ruby/spec/generic/rpc_server_spec.rb
index 34e5cdcd04..f409d73e2f 100644
--- a/src/ruby/spec/generic/rpc_server_spec.rb
+++ b/src/ruby/spec/generic/rpc_server_spec.rb
@@ -364,7 +364,7 @@ describe GRPC::RpcServer do
@srv.wait_till_running
req = EchoMsg.new
stub = SlowStub.new(@host, **@client_opts)
- deadline = service.delay + 0.5 # wait for long enough
+ deadline = service.delay + 1.0 # wait for long enough
expect(stub.an_rpc(req, deadline, k1: 'v1', k2: 'v2')).to be_a(EchoMsg)
wanted_md = [{ 'k1' => 'v1', 'k2' => 'v2' }]
expect(service.received_md).to eq(wanted_md)
diff --git a/src/ruby/spec/metadata_spec.rb b/src/ruby/spec/metadata_spec.rb
deleted file mode 100644
index 2472866692..0000000000
--- a/src/ruby/spec/metadata_spec.rb
+++ /dev/null
@@ -1,64 +0,0 @@
-# Copyright 2015, Google Inc.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-require 'grpc'
-
-describe GRPC::Core::Metadata do
- describe '#new' do
- it 'should create instances' do
- expect { GRPC::Core::Metadata.new('a key', 'a value') }.to_not raise_error
- end
- end
-
- describe '#key' do
- md = GRPC::Core::Metadata.new('a key', 'a value')
- it 'should be the constructor value' do
- expect(md.key).to eq('a key')
- end
- end
-
- describe '#value' do
- md = GRPC::Core::Metadata.new('a key', 'a value')
- it 'should be the constuctor value' do
- expect(md.value).to eq('a value')
- end
- end
-
- describe '#dup' do
- it 'should create a copy that returns the correct key' do
- md = GRPC::Core::Metadata.new('a key', 'a value')
- expect(md.dup.key).to eq('a key')
- end
-
- it 'should create a copy that returns the correct value' do
- md = GRPC::Core::Metadata.new('a key', 'a value')
- expect(md.dup.value).to eq('a value')
- end
- end
-end
diff --git a/templates/BUILD.template b/templates/BUILD.template
index 997c55b1c8..8303b9f8e9 100644
--- a/templates/BUILD.template
+++ b/templates/BUILD.template
@@ -32,38 +32,79 @@
licenses(["notice"]) # 3-clause BSD
+package(default_visibility = ["//visibility:public"])
+
+<%!
+def get_deps(target_dict):
+ deps = []
+ if target_dict.get('secure', 'no') == 'yes':
+ deps = [
+ "//external:libssl",
+ ]
+ if target_dict.get('build', None) == 'protoc':
+ deps.append("//external:protobuf_compiler")
+ if target_dict['name'] == 'grpc++_unsecure' or target_dict['name'] == 'grpc++':
+ deps.append("//external:protobuf_clib")
+ for d in target_dict.get('deps', []):
+ if d.find('//') == 0 or d[0] == ':':
+ deps.append(d)
+ else:
+ deps.append(':%s' % (d))
+ return deps
+%>
+
% for lib in libs:
-% if lib.build == "all" and lib.language == 'c':
-${makelib(lib)}
+% if lib.build != "private":
+${cc_library(lib)}
% endif
% endfor
-<%def name="makelib(lib)">
+% for tgt in targets:
+% if tgt.build == 'protoc':
+${cc_binary(tgt)}
+% endif
+% endfor
+<%def name="cc_library(lib)">
cc_library(
- name = "${lib.name}",
- srcs = [
+ name = "${lib.name}",
+ srcs = [
% for hdr in lib.get("headers", []):
- "${hdr}",
+ "${hdr}",
% endfor
% for src in lib.src:
- "${src}",
+ "${src}",
% endfor
- ],
- hdrs = [
+ ],
+ hdrs = [
% for hdr in lib.get("public_headers", []):
- "${hdr}",
+ "${hdr}",
% endfor
- ],
- includes = [
- "include",
- ".",
- ],
- deps = [
-% for dep in lib.get("deps", []):
- ":${dep}",
+ ],
+ includes = [
+ "include",
+ ".",
+ ],
+ deps = [
+% for dep in get_deps(lib):
+ "${dep}",
% endfor
- ],
+ ],
)
+</%def>
+<%def name="cc_binary(tgt)">
+cc_binary(
+ name = "${tgt.name}",
+ srcs = [
+% for src in tgt.src:
+ "${src}",
+% endfor
+ ],
+ deps = [
+% for dep in get_deps(tgt):
+ "${dep}",
+% endfor
+ ],
+)
</%def>
diff --git a/templates/Makefile.template b/templates/Makefile.template
index 776ee7a49b..2cfbfa36ec 100644
--- a/templates/Makefile.template
+++ b/templates/Makefile.template
@@ -930,6 +930,7 @@ else
$(Q) $(INSTALL) -d $(prefix)/lib
$(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/lib${lib.name}.$(SHARED_EXT) $(prefix)/lib/lib${lib.name}.$(SHARED_EXT)
ifneq ($(SYSTEM),Darwin)
+ $(Q) ln -sf lib${lib.name}.$(SHARED_EXT) $(prefix)/lib/lib${lib.name}.so.${settings.version.major}
$(Q) ln -sf lib${lib.name}.$(SHARED_EXT) $(prefix)/lib/lib${lib.name}.so
endif
endif
diff --git a/test/core/end2end/tests/cancel_after_invoke.c b/test/core/end2end/tests/cancel_after_invoke.c
index e15fa7fcd9..592dfd415f 100644
--- a/test/core/end2end/tests/cancel_after_invoke.c
+++ b/test/core/end2end/tests/cancel_after_invoke.c
@@ -51,10 +51,11 @@ static void *tag(gpr_intptr t) { return (void *)t; }
static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
const char *test_name,
+ cancellation_mode mode,
grpc_channel_args *client_args,
grpc_channel_args *server_args) {
grpc_end2end_test_fixture f;
- gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
+ gpr_log(GPR_INFO, "%s/%s/%s", test_name, config.name, mode.name);
f = config.create_fixture(client_args, server_args);
config.init_client(&f, client_args);
config.init_server(&f, server_args);
@@ -109,7 +110,8 @@ static void test_cancel_after_invoke(grpc_end2end_test_config config,
grpc_op ops[6];
grpc_op *op;
grpc_call *c;
- grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL);
+ grpc_end2end_test_fixture f =
+ begin_test(config, __FUNCTION__, mode, NULL, NULL);
gpr_timespec deadline = five_seconds_time();
cq_verifier *v_client = cq_verifier_create(f.client_cq);
grpc_metadata_array initial_metadata_recv;
diff --git a/test/core/end2end/tests/cancel_test_helpers.h b/test/core/end2end/tests/cancel_test_helpers.h
index f2581dc32f..0d680fcfe1 100644
--- a/test/core/end2end/tests/cancel_test_helpers.h
+++ b/test/core/end2end/tests/cancel_test_helpers.h
@@ -35,6 +35,7 @@
#define GRPC_TEST_CORE_END2END_TESTS_CANCEL_TEST_HELPERS_H
typedef struct {
+ const char *name;
grpc_call_error (*initiate_cancel)(grpc_call *call);
grpc_status_code expect_status;
const char *expect_details;
@@ -45,7 +46,9 @@ static grpc_call_error wait_for_deadline(grpc_call *call) {
}
static const cancellation_mode cancellation_modes[] = {
- {grpc_call_cancel, GRPC_STATUS_CANCELLED, ""},
- {wait_for_deadline, GRPC_STATUS_DEADLINE_EXCEEDED, "Deadline Exceeded"}, };
+ {"cancel", grpc_call_cancel, GRPC_STATUS_CANCELLED, ""},
+ {"deadline", wait_for_deadline, GRPC_STATUS_DEADLINE_EXCEEDED,
+ "Deadline Exceeded"},
+};
-#endif /* GRPC_TEST_CORE_END2END_TESTS_CANCEL_TEST_HELPERS_H */
+#endif /* GRPC_TEST_CORE_END2END_TESTS_CANCEL_TEST_HELPERS_H */
diff --git a/test/core/iomgr/tcp_server_posix_test.c b/test/core/iomgr/tcp_server_posix_test.c
index 2689c3f38e..6b80ee1ee8 100644
--- a/test/core/iomgr/tcp_server_posix_test.c
+++ b/test/core/iomgr/tcp_server_posix_test.c
@@ -60,14 +60,14 @@ static void on_connect(void *arg, grpc_endpoint *tcp) {
static void test_no_op(void) {
grpc_tcp_server *s = grpc_tcp_server_create();
- grpc_tcp_server_destroy(s);
+ grpc_tcp_server_destroy(s, NULL, NULL);
}
static void test_no_op_with_start(void) {
grpc_tcp_server *s = grpc_tcp_server_create();
LOG_TEST();
grpc_tcp_server_start(s, NULL, 0, on_connect, NULL);
- grpc_tcp_server_destroy(s);
+ grpc_tcp_server_destroy(s, NULL, NULL);
}
static void test_no_op_with_port(void) {
@@ -80,7 +80,7 @@ static void test_no_op_with_port(void) {
GPR_ASSERT(
grpc_tcp_server_add_port(s, (struct sockaddr *)&addr, sizeof(addr)));
- grpc_tcp_server_destroy(s);
+ grpc_tcp_server_destroy(s, NULL, NULL);
}
static void test_no_op_with_port_and_start(void) {
@@ -95,7 +95,7 @@ static void test_no_op_with_port_and_start(void) {
grpc_tcp_server_start(s, NULL, 0, on_connect, NULL);
- grpc_tcp_server_destroy(s);
+ grpc_tcp_server_destroy(s, NULL, NULL);
}
static void test_connect(int n) {
@@ -144,7 +144,7 @@ static void test_connect(int n) {
gpr_mu_unlock(&mu);
- grpc_tcp_server_destroy(s);
+ grpc_tcp_server_destroy(s, NULL, NULL);
}
int main(int argc, char **argv) {
diff --git a/test/cpp/interop/client.cc b/test/cpp/interop/client.cc
index 7c5e1aa715..189cdeb0ee 100644
--- a/test/cpp/interop/client.cc
+++ b/test/cpp/interop/client.cc
@@ -31,29 +31,19 @@
*
*/
-#include <chrono>
-#include <fstream>
#include <memory>
-#include <sstream>
-#include <string>
-#include <thread>
#include <unistd.h>
#include <grpc/grpc.h>
#include <grpc/support/log.h>
#include <gflags/gflags.h>
-#include <grpc++/channel_arguments.h>
#include <grpc++/channel_interface.h>
#include <grpc++/client_context.h>
-#include <grpc++/create_channel.h>
-#include <grpc++/credentials.h>
#include <grpc++/status.h>
#include <grpc++/stream.h>
-#include "test/cpp/util/create_test_channel.h"
-#include "test/cpp/interop/test.grpc.pb.h"
-#include "test/cpp/interop/empty.grpc.pb.h"
-#include "test/cpp/interop/messages.grpc.pb.h"
+#include "test/cpp/interop/client_helper.h"
+#include "test/cpp/interop/interop_client.h"
DEFINE_bool(enable_ssl, false, "Whether to use ssl/tls.");
DEFINE_bool(use_prod_roots, false, "True to use SSL roots for google");
@@ -81,21 +71,8 @@ DEFINE_string(service_account_key_file, "",
"Path to service account json key file.");
DEFINE_string(oauth_scope, "", "Scope for OAuth tokens.");
-using grpc::ChannelInterface;
-using grpc::ClientContext;
-using grpc::ComputeEngineCredentials;
-using grpc::CreateTestChannel;
-using grpc::Credentials;
-using grpc::JWTCredentials;
-using grpc::ServiceAccountCredentials;
-using grpc::testing::ResponseParameters;
-using grpc::testing::SimpleRequest;
-using grpc::testing::SimpleResponse;
-using grpc::testing::StreamingInputCallRequest;
-using grpc::testing::StreamingInputCallResponse;
-using grpc::testing::StreamingOutputCallRequest;
-using grpc::testing::StreamingOutputCallResponse;
-using grpc::testing::TestService;
+using grpc::testing::CreateChannelForTestCase;
+using grpc::testing::GetServiceAccountJsonKey;
// In some distros, gflags is in the namespace google, and in some others,
// in gflags. This hack is enabling us to find both.
@@ -104,362 +81,48 @@ namespace gflags {}
using namespace google;
using namespace gflags;
-namespace {
-// The same value is defined by the Java client.
-const std::vector<int> request_stream_sizes = {27182, 8, 1828, 45904};
-const std::vector<int> response_stream_sizes = {31415, 9, 2653, 58979};
-const int kNumResponseMessages = 2000;
-const int kResponseMessageSize = 1030;
-const int kReceiveDelayMilliSeconds = 20;
-const int kLargeRequestSize = 314159;
-const int kLargeResponseSize = 271812;
-} // namespace
-
-grpc::string GetServiceAccountJsonKey() {
- static grpc::string json_key;
- if (json_key.empty()) {
- std::ifstream json_key_file(FLAGS_service_account_key_file);
- std::stringstream key_stream;
- key_stream << json_key_file.rdbuf();
- json_key = key_stream.str();
- }
- return json_key;
-}
-
-std::shared_ptr<ChannelInterface> CreateChannelForTestCase(
- const grpc::string& test_case) {
- GPR_ASSERT(FLAGS_server_port);
- const int host_port_buf_size = 1024;
- char host_port[host_port_buf_size];
- snprintf(host_port, host_port_buf_size, "%s:%d", FLAGS_server_host.c_str(),
- FLAGS_server_port);
-
- if (test_case == "service_account_creds") {
- std::unique_ptr<Credentials> creds;
- GPR_ASSERT(FLAGS_enable_ssl);
- grpc::string json_key = GetServiceAccountJsonKey();
- creds = ServiceAccountCredentials(json_key, FLAGS_oauth_scope,
- std::chrono::hours(1));
- return CreateTestChannel(host_port, FLAGS_server_host_override,
- FLAGS_enable_ssl, FLAGS_use_prod_roots, creds);
- } else if (test_case == "compute_engine_creds") {
- std::unique_ptr<Credentials> creds;
- GPR_ASSERT(FLAGS_enable_ssl);
- creds = ComputeEngineCredentials();
- return CreateTestChannel(host_port, FLAGS_server_host_override,
- FLAGS_enable_ssl, FLAGS_use_prod_roots, creds);
- } else if (test_case == "jwt_token_creds") {
- std::unique_ptr<Credentials> creds;
- GPR_ASSERT(FLAGS_enable_ssl);
- grpc::string json_key = GetServiceAccountJsonKey();
- creds = JWTCredentials(json_key, std::chrono::hours(1));
- return CreateTestChannel(host_port, FLAGS_server_host_override,
- FLAGS_enable_ssl, FLAGS_use_prod_roots, creds);
- } else {
- return CreateTestChannel(host_port, FLAGS_server_host_override,
- FLAGS_enable_ssl, FLAGS_use_prod_roots);
- }
-}
-
-void AssertOkOrPrintErrorStatus(const grpc::Status& s) {
- if (s.IsOk()) {
- return;
- }
- gpr_log(GPR_INFO, "Error status code: %d, message: %s", s.code(),
- s.details().c_str());
- GPR_ASSERT(0);
-}
-
-void DoEmpty() {
- gpr_log(GPR_INFO, "Sending an empty rpc...");
- std::shared_ptr<ChannelInterface> channel =
- CreateChannelForTestCase("empty_unary");
- std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel));
-
- grpc::testing::Empty request = grpc::testing::Empty::default_instance();
- grpc::testing::Empty response = grpc::testing::Empty::default_instance();
- ClientContext context;
-
- grpc::Status s = stub->EmptyCall(&context, request, &response);
- AssertOkOrPrintErrorStatus(s);
-
- gpr_log(GPR_INFO, "Empty rpc done.");
-}
-
-// Shared code to set large payload, make rpc and check response payload.
-void PerformLargeUnary(std::shared_ptr<ChannelInterface> channel,
- SimpleRequest* request, SimpleResponse* response) {
- std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel));
-
- ClientContext context;
- request->set_response_type(grpc::testing::PayloadType::COMPRESSABLE);
- request->set_response_size(kLargeResponseSize);
- grpc::string payload(kLargeRequestSize, '\0');
- request->mutable_payload()->set_body(payload.c_str(), kLargeRequestSize);
-
- grpc::Status s = stub->UnaryCall(&context, *request, response);
-
- AssertOkOrPrintErrorStatus(s);
- GPR_ASSERT(response->payload().type() ==
- grpc::testing::PayloadType::COMPRESSABLE);
- GPR_ASSERT(response->payload().body() ==
- grpc::string(kLargeResponseSize, '\0'));
-}
-
-void DoComputeEngineCreds() {
- gpr_log(GPR_INFO,
- "Sending a large unary rpc with compute engine credentials ...");
- std::shared_ptr<ChannelInterface> channel =
- CreateChannelForTestCase("compute_engine_creds");
- SimpleRequest request;
- SimpleResponse response;
- request.set_fill_username(true);
- request.set_fill_oauth_scope(true);
- PerformLargeUnary(channel, &request, &response);
- gpr_log(GPR_INFO, "Got username %s", response.username().c_str());
- gpr_log(GPR_INFO, "Got oauth_scope %s", response.oauth_scope().c_str());
- GPR_ASSERT(!response.username().empty());
- GPR_ASSERT(response.username().c_str() == FLAGS_default_service_account);
- GPR_ASSERT(!response.oauth_scope().empty());
- const char* oauth_scope_str = response.oauth_scope().c_str();
- GPR_ASSERT(FLAGS_oauth_scope.find(oauth_scope_str) != grpc::string::npos);
- gpr_log(GPR_INFO, "Large unary with compute engine creds done.");
-}
-
-void DoServiceAccountCreds() {
- gpr_log(GPR_INFO,
- "Sending a large unary rpc with service account credentials ...");
- std::shared_ptr<ChannelInterface> channel =
- CreateChannelForTestCase("service_account_creds");
- SimpleRequest request;
- SimpleResponse response;
- request.set_fill_username(true);
- request.set_fill_oauth_scope(true);
- PerformLargeUnary(channel, &request, &response);
- GPR_ASSERT(!response.username().empty());
- GPR_ASSERT(!response.oauth_scope().empty());
- grpc::string json_key = GetServiceAccountJsonKey();
- GPR_ASSERT(json_key.find(response.username()) != grpc::string::npos);
- const char* oauth_scope_str = response.oauth_scope().c_str();
- GPR_ASSERT(FLAGS_oauth_scope.find(oauth_scope_str) != grpc::string::npos);
- gpr_log(GPR_INFO, "Large unary with service account creds done.");
-}
-
-void DoJwtTokenCreds() {
- gpr_log(GPR_INFO, "Sending a large unary rpc with JWT token credentials ...");
- std::shared_ptr<ChannelInterface> channel =
- CreateChannelForTestCase("jwt_token_creds");
- SimpleRequest request;
- SimpleResponse response;
- request.set_fill_username(true);
- PerformLargeUnary(channel, &request, &response);
- GPR_ASSERT(!response.username().empty());
- grpc::string json_key = GetServiceAccountJsonKey();
- GPR_ASSERT(json_key.find(response.username()) != grpc::string::npos);
- gpr_log(GPR_INFO, "Large unary with JWT token creds done.");
-}
-
-void DoLargeUnary() {
- gpr_log(GPR_INFO, "Sending a large unary rpc...");
- std::shared_ptr<ChannelInterface> channel =
- CreateChannelForTestCase("large_unary");
- SimpleRequest request;
- SimpleResponse response;
- PerformLargeUnary(channel, &request, &response);
- gpr_log(GPR_INFO, "Large unary done.");
-}
-
-void DoRequestStreaming() {
- gpr_log(GPR_INFO, "Sending request steaming rpc ...");
- std::shared_ptr<ChannelInterface> channel =
- CreateChannelForTestCase("client_streaming");
- std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel));
-
- grpc::ClientContext context;
- StreamingInputCallRequest request;
- StreamingInputCallResponse response;
-
- std::unique_ptr<grpc::ClientWriter<StreamingInputCallRequest>> stream(
- stub->StreamingInputCall(&context, &response));
-
- int aggregated_payload_size = 0;
- for (unsigned int i = 0; i < request_stream_sizes.size(); ++i) {
- grpc::testing::Payload* payload = request.mutable_payload();
- payload->set_body(grpc::string(request_stream_sizes[i], '\0'));
- GPR_ASSERT(stream->Write(request));
- aggregated_payload_size += request_stream_sizes[i];
- }
- stream->WritesDone();
- grpc::Status s = stream->Finish();
-
- GPR_ASSERT(response.aggregated_payload_size() == aggregated_payload_size);
- AssertOkOrPrintErrorStatus(s);
- gpr_log(GPR_INFO, "Request streaming done.");
-}
-
-void DoResponseStreaming() {
- gpr_log(GPR_INFO, "Receiving response steaming rpc ...");
- std::shared_ptr<ChannelInterface> channel =
- CreateChannelForTestCase("server_streaming");
- std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel));
-
- grpc::ClientContext context;
- StreamingOutputCallRequest request;
- for (unsigned int i = 0; i < response_stream_sizes.size(); ++i) {
- ResponseParameters* response_parameter = request.add_response_parameters();
- response_parameter->set_size(response_stream_sizes[i]);
- }
- StreamingOutputCallResponse response;
- std::unique_ptr<grpc::ClientReader<StreamingOutputCallResponse>> stream(
- stub->StreamingOutputCall(&context, request));
-
- unsigned int i = 0;
- while (stream->Read(&response)) {
- GPR_ASSERT(response.payload().body() ==
- grpc::string(response_stream_sizes[i], '\0'));
- ++i;
- }
- GPR_ASSERT(response_stream_sizes.size() == i);
- grpc::Status s = stream->Finish();
-
- AssertOkOrPrintErrorStatus(s);
- gpr_log(GPR_INFO, "Response streaming done.");
-}
-
-void DoResponseStreamingWithSlowConsumer() {
- gpr_log(GPR_INFO, "Receiving response steaming rpc with slow consumer ...");
- std::shared_ptr<ChannelInterface> channel =
- CreateChannelForTestCase("slow_consumer");
- std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel));
-
- grpc::ClientContext context;
- StreamingOutputCallRequest request;
-
- for (int i = 0; i < kNumResponseMessages; ++i) {
- ResponseParameters* response_parameter = request.add_response_parameters();
- response_parameter->set_size(kResponseMessageSize);
- }
- StreamingOutputCallResponse response;
- std::unique_ptr<grpc::ClientReader<StreamingOutputCallResponse>> stream(
- stub->StreamingOutputCall(&context, request));
-
- int i = 0;
- while (stream->Read(&response)) {
- GPR_ASSERT(response.payload().body() ==
- grpc::string(kResponseMessageSize, '\0'));
- gpr_log(GPR_INFO, "received message %d", i);
- usleep(kReceiveDelayMilliSeconds * 1000);
- ++i;
- }
- GPR_ASSERT(kNumResponseMessages == i);
- grpc::Status s = stream->Finish();
-
- AssertOkOrPrintErrorStatus(s);
- gpr_log(GPR_INFO, "Response streaming done.");
-}
-
-void DoHalfDuplex() {
- gpr_log(GPR_INFO, "Sending half-duplex streaming rpc ...");
- std::shared_ptr<ChannelInterface> channel =
- CreateChannelForTestCase("half_duplex");
- std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel));
-
- grpc::ClientContext context;
- std::unique_ptr<grpc::ClientReaderWriter<StreamingOutputCallRequest,
- StreamingOutputCallResponse>>
- stream(stub->HalfDuplexCall(&context));
-
- StreamingOutputCallRequest request;
- ResponseParameters* response_parameter = request.add_response_parameters();
- for (unsigned int i = 0; i < response_stream_sizes.size(); ++i) {
- response_parameter->set_size(response_stream_sizes[i]);
- GPR_ASSERT(stream->Write(request));
- }
- stream->WritesDone();
-
- unsigned int i = 0;
- StreamingOutputCallResponse response;
- while (stream->Read(&response)) {
- GPR_ASSERT(response.payload().has_body());
- GPR_ASSERT(response.payload().body() ==
- grpc::string(response_stream_sizes[i], '\0'));
- ++i;
- }
- GPR_ASSERT(response_stream_sizes.size() == i);
- grpc::Status s = stream->Finish();
- AssertOkOrPrintErrorStatus(s);
- gpr_log(GPR_INFO, "Half-duplex streaming rpc done.");
-}
-
-void DoPingPong() {
- gpr_log(GPR_INFO, "Sending Ping Pong streaming rpc ...");
- std::shared_ptr<ChannelInterface> channel =
- CreateChannelForTestCase("ping_pong");
- std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel));
-
- grpc::ClientContext context;
- std::unique_ptr<grpc::ClientReaderWriter<StreamingOutputCallRequest,
- StreamingOutputCallResponse>>
- stream(stub->FullDuplexCall(&context));
-
- StreamingOutputCallRequest request;
- request.set_response_type(grpc::testing::PayloadType::COMPRESSABLE);
- ResponseParameters* response_parameter = request.add_response_parameters();
- grpc::testing::Payload* payload = request.mutable_payload();
- StreamingOutputCallResponse response;
- for (unsigned int i = 0; i < request_stream_sizes.size(); ++i) {
- response_parameter->set_size(response_stream_sizes[i]);
- payload->set_body(grpc::string(request_stream_sizes[i], '\0'));
- GPR_ASSERT(stream->Write(request));
- GPR_ASSERT(stream->Read(&response));
- GPR_ASSERT(response.payload().has_body());
- GPR_ASSERT(response.payload().body() ==
- grpc::string(response_stream_sizes[i], '\0'));
- }
-
- stream->WritesDone();
- GPR_ASSERT(!stream->Read(&response));
- grpc::Status s = stream->Finish();
- AssertOkOrPrintErrorStatus(s);
- gpr_log(GPR_INFO, "Ping pong streaming done.");
-}
-
int main(int argc, char** argv) {
grpc_init();
ParseCommandLineFlags(&argc, &argv, true);
+ grpc::testing::InteropClient client(
+ CreateChannelForTestCase(FLAGS_test_case));
if (FLAGS_test_case == "empty_unary") {
- DoEmpty();
+ client.DoEmpty();
} else if (FLAGS_test_case == "large_unary") {
- DoLargeUnary();
+ client.DoLargeUnary();
} else if (FLAGS_test_case == "client_streaming") {
- DoRequestStreaming();
+ client.DoRequestStreaming();
} else if (FLAGS_test_case == "server_streaming") {
- DoResponseStreaming();
+ client.DoResponseStreaming();
} else if (FLAGS_test_case == "slow_consumer") {
- DoResponseStreamingWithSlowConsumer();
+ client.DoResponseStreamingWithSlowConsumer();
} else if (FLAGS_test_case == "half_duplex") {
- DoHalfDuplex();
+ client.DoHalfDuplex();
} else if (FLAGS_test_case == "ping_pong") {
- DoPingPong();
+ client.DoPingPong();
} else if (FLAGS_test_case == "service_account_creds") {
- DoServiceAccountCreds();
+ grpc::string json_key = GetServiceAccountJsonKey();
+ client.DoServiceAccountCreds(json_key, FLAGS_oauth_scope);
} else if (FLAGS_test_case == "compute_engine_creds") {
- DoComputeEngineCreds();
+ client.DoComputeEngineCreds(FLAGS_default_service_account,
+ FLAGS_oauth_scope);
} else if (FLAGS_test_case == "jwt_token_creds") {
- DoJwtTokenCreds();
+ grpc::string json_key = GetServiceAccountJsonKey();
+ client.DoJwtTokenCreds(json_key);
} else if (FLAGS_test_case == "all") {
- DoEmpty();
- DoLargeUnary();
- DoRequestStreaming();
- DoResponseStreaming();
- DoHalfDuplex();
- DoPingPong();
+ client.DoEmpty();
+ client.DoLargeUnary();
+ client.DoRequestStreaming();
+ client.DoResponseStreaming();
+ client.DoHalfDuplex();
+ client.DoPingPong();
// service_account_creds and jwt_token_creds can only run with ssl.
if (FLAGS_enable_ssl) {
- DoServiceAccountCreds();
- DoJwtTokenCreds();
+ grpc::string json_key = GetServiceAccountJsonKey();
+ client.DoServiceAccountCreds(json_key, FLAGS_oauth_scope);
+ client.DoJwtTokenCreds(json_key);
}
// compute_engine_creds only runs in GCE.
} else {
@@ -470,6 +133,7 @@ int main(int argc, char** argv) {
"service_account_creds|compute_engine_creds|jwt_token_creds",
FLAGS_test_case.c_str());
}
+ client.Reset(nullptr);
grpc_shutdown();
return 0;
diff --git a/test/cpp/interop/client_helper.cc b/test/cpp/interop/client_helper.cc
new file mode 100644
index 0000000000..362e6af353
--- /dev/null
+++ b/test/cpp/interop/client_helper.cc
@@ -0,0 +1,119 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "test/cpp/interop/client_helper.h"
+
+#include <fstream>
+#include <memory>
+#include <sstream>
+
+#include <unistd.h>
+
+#include <grpc/grpc.h>
+#include <grpc/support/log.h>
+#include <gflags/gflags.h>
+#include <grpc++/channel_arguments.h>
+#include <grpc++/channel_interface.h>
+#include <grpc++/create_channel.h>
+#include <grpc++/credentials.h>
+#include <grpc++/stream.h>
+#include "test/cpp/util/create_test_channel.h"
+
+DECLARE_bool(enable_ssl);
+DECLARE_bool(use_prod_roots);
+DECLARE_int32(server_port);
+DECLARE_string(server_host);
+DECLARE_string(server_host_override);
+DECLARE_string(test_case);
+DECLARE_string(default_service_account);
+DECLARE_string(service_account_key_file);
+DECLARE_string(oauth_scope);
+
+// 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 {}
+namespace gflags {}
+using namespace google;
+using namespace gflags;
+
+namespace grpc {
+namespace testing {
+
+grpc::string GetServiceAccountJsonKey() {
+ static grpc::string json_key;
+ if (json_key.empty()) {
+ std::ifstream json_key_file(FLAGS_service_account_key_file);
+ std::stringstream key_stream;
+ key_stream << json_key_file.rdbuf();
+ json_key = key_stream.str();
+ }
+ return json_key;
+}
+
+std::shared_ptr<ChannelInterface> CreateChannelForTestCase(
+ const grpc::string& test_case) {
+ GPR_ASSERT(FLAGS_server_port);
+ const int host_port_buf_size = 1024;
+ char host_port[host_port_buf_size];
+ snprintf(host_port, host_port_buf_size, "%s:%d", FLAGS_server_host.c_str(),
+ FLAGS_server_port);
+
+ if (test_case == "service_account_creds") {
+ std::unique_ptr<Credentials> creds;
+ GPR_ASSERT(FLAGS_enable_ssl);
+ grpc::string json_key = GetServiceAccountJsonKey();
+ creds = ServiceAccountCredentials(json_key, FLAGS_oauth_scope,
+ std::chrono::hours(1));
+ return CreateTestChannel(host_port, FLAGS_server_host_override,
+ FLAGS_enable_ssl, FLAGS_use_prod_roots, creds);
+ } else if (test_case == "compute_engine_creds") {
+ std::unique_ptr<Credentials> creds;
+ GPR_ASSERT(FLAGS_enable_ssl);
+ creds = ComputeEngineCredentials();
+ return CreateTestChannel(host_port, FLAGS_server_host_override,
+ FLAGS_enable_ssl, FLAGS_use_prod_roots, creds);
+ } else if (test_case == "jwt_token_creds") {
+ std::unique_ptr<Credentials> creds;
+ GPR_ASSERT(FLAGS_enable_ssl);
+ grpc::string json_key = GetServiceAccountJsonKey();
+ creds = JWTCredentials(json_key, std::chrono::hours(1));
+ return CreateTestChannel(host_port, FLAGS_server_host_override,
+ FLAGS_enable_ssl, FLAGS_use_prod_roots, creds);
+ } else {
+ return CreateTestChannel(host_port, FLAGS_server_host_override,
+ FLAGS_enable_ssl, FLAGS_use_prod_roots);
+ }
+}
+
+} // namespace testing
+} // namespace grpc
diff --git a/src/ruby/ext/grpc/rb_event.h b/test/cpp/interop/client_helper.h
index 3105934b11..897f974026 100644
--- a/src/ruby/ext/grpc/rb_event.h
+++ b/test/cpp/interop/client_helper.h
@@ -31,23 +31,23 @@
*
*/
-#ifndef GRPC_RB_EVENT_H_
-#define GRPC_RB_EVENT_H_
+#ifndef GRPC_TEST_CPP_INTEROP_CLIENT_HELPER_H
+#define GRPC_TEST_CPP_INTEROP_CLIENT_HELPER_H
-#include <ruby.h>
-#include <grpc/grpc.h>
+#include <memory>
-/* rb_cEvent is the Event class whose instances proxy grpc_event. */
-extern VALUE rb_cEvent;
+#include <grpc++/config.h>
+#include <grpc++/channel_interface.h>
-/* rb_cEventError is the ruby class that acts the exception thrown during rpc
- event processing. */
-extern VALUE rb_eEventError;
+namespace grpc {
+namespace testing {
-/* Used to create new ruby event objects */
-VALUE grpc_rb_new_event(grpc_event *ev);
+grpc::string GetServiceAccountJsonKey();
-/* Initializes the Event and EventError classes. */
-void Init_grpc_event();
+std::shared_ptr<ChannelInterface> CreateChannelForTestCase(
+ const grpc::string& test_case);
-#endif /* GRPC_RB_EVENT_H_ */
+} // namespace testing
+} // namespace grpc
+
+#endif // GRPC_TEST_CPP_INTEROP_CLIENT_HELPER_H
diff --git a/test/cpp/interop/interop_client.cc b/test/cpp/interop/interop_client.cc
new file mode 100644
index 0000000000..fd9c2e024a
--- /dev/null
+++ b/test/cpp/interop/interop_client.cc
@@ -0,0 +1,311 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "test/cpp/interop/interop_client.h"
+
+#include <memory>
+
+#include <unistd.h>
+
+#include <grpc/grpc.h>
+#include <grpc/support/log.h>
+#include <grpc++/channel_interface.h>
+#include <grpc++/client_context.h>
+#include <grpc++/status.h>
+#include <grpc++/stream.h>
+#include "test/cpp/interop/test.grpc.pb.h"
+#include "test/cpp/interop/empty.grpc.pb.h"
+#include "test/cpp/interop/messages.grpc.pb.h"
+
+namespace grpc {
+namespace testing {
+
+namespace {
+// The same value is defined by the Java client.
+const std::vector<int> request_stream_sizes = {27182, 8, 1828, 45904};
+const std::vector<int> response_stream_sizes = {31415, 9, 2653, 58979};
+const int kNumResponseMessages = 2000;
+const int kResponseMessageSize = 1030;
+const int kReceiveDelayMilliSeconds = 20;
+const int kLargeRequestSize = 314159;
+const int kLargeResponseSize = 271812;
+} // namespace
+
+InteropClient::InteropClient(std::shared_ptr<ChannelInterface> channel)
+ : channel_(channel) {}
+
+void InteropClient::AssertOkOrPrintErrorStatus(const Status& s) {
+ if (s.IsOk()) {
+ return;
+ }
+ gpr_log(GPR_INFO, "Error status code: %d, message: %s", s.code(),
+ s.details().c_str());
+ GPR_ASSERT(0);
+}
+
+void InteropClient::DoEmpty() {
+ gpr_log(GPR_INFO, "Sending an empty rpc...");
+ std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_));
+
+ Empty request = Empty::default_instance();
+ Empty response = Empty::default_instance();
+ ClientContext context;
+
+ Status s = stub->EmptyCall(&context, request, &response);
+ AssertOkOrPrintErrorStatus(s);
+
+ gpr_log(GPR_INFO, "Empty rpc done.");
+}
+
+// Shared code to set large payload, make rpc and check response payload.
+void InteropClient::PerformLargeUnary(SimpleRequest* request,
+ SimpleResponse* response) {
+ std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_));
+
+ ClientContext context;
+ request->set_response_type(PayloadType::COMPRESSABLE);
+ request->set_response_size(kLargeResponseSize);
+ grpc::string payload(kLargeRequestSize, '\0');
+ request->mutable_payload()->set_body(payload.c_str(), kLargeRequestSize);
+
+ Status s = stub->UnaryCall(&context, *request, response);
+
+ AssertOkOrPrintErrorStatus(s);
+ GPR_ASSERT(response->payload().type() == PayloadType::COMPRESSABLE);
+ GPR_ASSERT(response->payload().body() ==
+ grpc::string(kLargeResponseSize, '\0'));
+}
+
+void InteropClient::DoComputeEngineCreds(
+ const grpc::string& default_service_account,
+ const grpc::string& oauth_scope) {
+ gpr_log(GPR_INFO,
+ "Sending a large unary rpc with compute engine credentials ...");
+ SimpleRequest request;
+ SimpleResponse response;
+ request.set_fill_username(true);
+ request.set_fill_oauth_scope(true);
+ PerformLargeUnary(&request, &response);
+ gpr_log(GPR_INFO, "Got username %s", response.username().c_str());
+ gpr_log(GPR_INFO, "Got oauth_scope %s", response.oauth_scope().c_str());
+ GPR_ASSERT(!response.username().empty());
+ GPR_ASSERT(response.username().c_str() == default_service_account);
+ GPR_ASSERT(!response.oauth_scope().empty());
+ const char* oauth_scope_str = response.oauth_scope().c_str();
+ GPR_ASSERT(oauth_scope.find(oauth_scope_str) != grpc::string::npos);
+ gpr_log(GPR_INFO, "Large unary with compute engine creds done.");
+}
+
+void InteropClient::DoServiceAccountCreds(const grpc::string& username,
+ const grpc::string& oauth_scope) {
+ gpr_log(GPR_INFO,
+ "Sending a large unary rpc with service account credentials ...");
+ SimpleRequest request;
+ SimpleResponse response;
+ request.set_fill_username(true);
+ request.set_fill_oauth_scope(true);
+ PerformLargeUnary(&request, &response);
+ GPR_ASSERT(!response.username().empty());
+ GPR_ASSERT(!response.oauth_scope().empty());
+ GPR_ASSERT(username.find(response.username()) != grpc::string::npos);
+ const char* oauth_scope_str = response.oauth_scope().c_str();
+ GPR_ASSERT(oauth_scope.find(oauth_scope_str) != grpc::string::npos);
+ gpr_log(GPR_INFO, "Large unary with service account creds done.");
+}
+
+void InteropClient::DoJwtTokenCreds(const grpc::string& username) {
+ gpr_log(GPR_INFO, "Sending a large unary rpc with JWT token credentials ...");
+ SimpleRequest request;
+ SimpleResponse response;
+ request.set_fill_username(true);
+ PerformLargeUnary(&request, &response);
+ GPR_ASSERT(!response.username().empty());
+ GPR_ASSERT(username.find(response.username()) != grpc::string::npos);
+ gpr_log(GPR_INFO, "Large unary with JWT token creds done.");
+}
+
+void InteropClient::DoLargeUnary() {
+ gpr_log(GPR_INFO, "Sending a large unary rpc...");
+ SimpleRequest request;
+ SimpleResponse response;
+ PerformLargeUnary(&request, &response);
+ gpr_log(GPR_INFO, "Large unary done.");
+}
+
+void InteropClient::DoRequestStreaming() {
+ gpr_log(GPR_INFO, "Sending request steaming rpc ...");
+ std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_));
+
+ ClientContext context;
+ StreamingInputCallRequest request;
+ StreamingInputCallResponse response;
+
+ std::unique_ptr<ClientWriter<StreamingInputCallRequest>> stream(
+ stub->StreamingInputCall(&context, &response));
+
+ int aggregated_payload_size = 0;
+ for (unsigned int i = 0; i < request_stream_sizes.size(); ++i) {
+ Payload* payload = request.mutable_payload();
+ payload->set_body(grpc::string(request_stream_sizes[i], '\0'));
+ GPR_ASSERT(stream->Write(request));
+ aggregated_payload_size += request_stream_sizes[i];
+ }
+ stream->WritesDone();
+ Status s = stream->Finish();
+
+ GPR_ASSERT(response.aggregated_payload_size() == aggregated_payload_size);
+ AssertOkOrPrintErrorStatus(s);
+ gpr_log(GPR_INFO, "Request streaming done.");
+}
+
+void InteropClient::DoResponseStreaming() {
+ gpr_log(GPR_INFO, "Receiving response steaming rpc ...");
+ std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_));
+
+ ClientContext context;
+ StreamingOutputCallRequest request;
+ for (unsigned int i = 0; i < response_stream_sizes.size(); ++i) {
+ ResponseParameters* response_parameter = request.add_response_parameters();
+ response_parameter->set_size(response_stream_sizes[i]);
+ }
+ StreamingOutputCallResponse response;
+ std::unique_ptr<ClientReader<StreamingOutputCallResponse>> stream(
+ stub->StreamingOutputCall(&context, request));
+
+ unsigned int i = 0;
+ while (stream->Read(&response)) {
+ GPR_ASSERT(response.payload().body() ==
+ grpc::string(response_stream_sizes[i], '\0'));
+ ++i;
+ }
+ GPR_ASSERT(response_stream_sizes.size() == i);
+ Status s = stream->Finish();
+
+ AssertOkOrPrintErrorStatus(s);
+ gpr_log(GPR_INFO, "Response streaming done.");
+}
+
+void InteropClient::DoResponseStreamingWithSlowConsumer() {
+ gpr_log(GPR_INFO, "Receiving response steaming rpc with slow consumer ...");
+ std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_));
+
+ ClientContext context;
+ StreamingOutputCallRequest request;
+
+ for (int i = 0; i < kNumResponseMessages; ++i) {
+ ResponseParameters* response_parameter = request.add_response_parameters();
+ response_parameter->set_size(kResponseMessageSize);
+ }
+ StreamingOutputCallResponse response;
+ std::unique_ptr<ClientReader<StreamingOutputCallResponse>> stream(
+ stub->StreamingOutputCall(&context, request));
+
+ int i = 0;
+ while (stream->Read(&response)) {
+ GPR_ASSERT(response.payload().body() ==
+ grpc::string(kResponseMessageSize, '\0'));
+ gpr_log(GPR_INFO, "received message %d", i);
+ usleep(kReceiveDelayMilliSeconds * 1000);
+ ++i;
+ }
+ GPR_ASSERT(kNumResponseMessages == i);
+ Status s = stream->Finish();
+
+ AssertOkOrPrintErrorStatus(s);
+ gpr_log(GPR_INFO, "Response streaming done.");
+}
+
+void InteropClient::DoHalfDuplex() {
+ gpr_log(GPR_INFO, "Sending half-duplex streaming rpc ...");
+ std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_));
+
+ ClientContext context;
+ std::unique_ptr<ClientReaderWriter<StreamingOutputCallRequest,
+ StreamingOutputCallResponse>>
+ stream(stub->HalfDuplexCall(&context));
+
+ StreamingOutputCallRequest request;
+ ResponseParameters* response_parameter = request.add_response_parameters();
+ for (unsigned int i = 0; i < response_stream_sizes.size(); ++i) {
+ response_parameter->set_size(response_stream_sizes[i]);
+ GPR_ASSERT(stream->Write(request));
+ }
+ stream->WritesDone();
+
+ unsigned int i = 0;
+ StreamingOutputCallResponse response;
+ while (stream->Read(&response)) {
+ GPR_ASSERT(response.payload().has_body());
+ GPR_ASSERT(response.payload().body() ==
+ grpc::string(response_stream_sizes[i], '\0'));
+ ++i;
+ }
+ GPR_ASSERT(response_stream_sizes.size() == i);
+ Status s = stream->Finish();
+ AssertOkOrPrintErrorStatus(s);
+ gpr_log(GPR_INFO, "Half-duplex streaming rpc done.");
+}
+
+void InteropClient::DoPingPong() {
+ gpr_log(GPR_INFO, "Sending Ping Pong streaming rpc ...");
+ std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_));
+
+ ClientContext context;
+ std::unique_ptr<ClientReaderWriter<StreamingOutputCallRequest,
+ StreamingOutputCallResponse>>
+ stream(stub->FullDuplexCall(&context));
+
+ StreamingOutputCallRequest request;
+ request.set_response_type(PayloadType::COMPRESSABLE);
+ ResponseParameters* response_parameter = request.add_response_parameters();
+ Payload* payload = request.mutable_payload();
+ StreamingOutputCallResponse response;
+ for (unsigned int i = 0; i < request_stream_sizes.size(); ++i) {
+ response_parameter->set_size(response_stream_sizes[i]);
+ payload->set_body(grpc::string(request_stream_sizes[i], '\0'));
+ GPR_ASSERT(stream->Write(request));
+ GPR_ASSERT(stream->Read(&response));
+ GPR_ASSERT(response.payload().has_body());
+ GPR_ASSERT(response.payload().body() ==
+ grpc::string(response_stream_sizes[i], '\0'));
+ }
+
+ stream->WritesDone();
+ GPR_ASSERT(!stream->Read(&response));
+ Status s = stream->Finish();
+ AssertOkOrPrintErrorStatus(s);
+ gpr_log(GPR_INFO, "Ping pong streaming done.");
+}
+
+} // namespace testing
+} // namespace grpc
diff --git a/test/cpp/interop/interop_client.h b/test/cpp/interop/interop_client.h
new file mode 100644
index 0000000000..b0ab320f8d
--- /dev/null
+++ b/test/cpp/interop/interop_client.h
@@ -0,0 +1,79 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_TEST_CPP_INTEROP_INTEROP_CLIENT_H
+#define GRPC_TEST_CPP_INTEROP_INTEROP_CLIENT_H
+#include <memory>
+
+#include <grpc/grpc.h>
+#include <grpc++/channel_interface.h>
+#include <grpc++/status.h>
+#include "test/cpp/interop/messages.grpc.pb.h"
+
+namespace grpc {
+namespace testing {
+
+class InteropClient {
+ public:
+ explicit InteropClient(std::shared_ptr<ChannelInterface> channel);
+ ~InteropClient() {}
+
+ void Reset(std::shared_ptr<ChannelInterface> channel) { channel_ = channel; }
+
+ void DoEmpty();
+ void DoLargeUnary();
+ void DoPingPong();
+ void DoHalfDuplex();
+ void DoRequestStreaming();
+ void DoResponseStreaming();
+ void DoResponseStreamingWithSlowConsumer();
+ // Auth tests.
+ // username is a string containing the user email
+ void DoJwtTokenCreds(const grpc::string& username);
+ void DoComputeEngineCreds(const grpc::string& default_service_account,
+ const grpc::string& oauth_scope);
+ // username is a string containing the user email
+ void DoServiceAccountCreds(const grpc::string& username,
+ const grpc::string& oauth_scope);
+
+ private:
+ void PerformLargeUnary(SimpleRequest* request, SimpleResponse* response);
+ void AssertOkOrPrintErrorStatus(const Status& s);
+
+ std::shared_ptr<ChannelInterface> channel_;
+};
+
+} // namespace testing
+} // namespace grpc
+
+#endif // GRPC_TEST_CPP_INTEROP_INTEROP_CLIENT_H
diff --git a/test/cpp/interop/server.cc b/test/cpp/interop/server.cc
index 87bf48938b..d87493b813 100644
--- a/test/cpp/interop/server.cc
+++ b/test/cpp/interop/server.cc
@@ -41,7 +41,6 @@
#include <gflags/gflags.h>
#include <grpc/grpc.h>
#include <grpc/support/log.h>
-#include "test/core/end2end/data/ssl_test_data.h"
#include <grpc++/config.h>
#include <grpc++/server.h>
#include <grpc++/server_builder.h>
@@ -52,6 +51,7 @@
#include "test/cpp/interop/test.grpc.pb.h"
#include "test/cpp/interop/empty.grpc.pb.h"
#include "test/cpp/interop/messages.grpc.pb.h"
+#include "test/cpp/interop/server_helper.h"
DEFINE_bool(enable_ssl, false, "Whether to use ssl/tls.");
DEFINE_int32(port, 0, "Server port.");
@@ -211,15 +211,8 @@ void RunServer() {
ServerBuilder builder;
builder.RegisterService(&service);
- std::shared_ptr<ServerCredentials> creds = grpc::InsecureServerCredentials();
- if (FLAGS_enable_ssl) {
- 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 = grpc::SslServerCredentials(ssl_opts);
- }
+ std::shared_ptr<ServerCredentials> creds =
+ grpc::testing::CreateInteropServerCredentials();
builder.AddListeningPort(server_address.str(), creds);
std::unique_ptr<Server> server(builder.BuildAndStart());
gpr_log(GPR_INFO, "Server listening on %s", server_address.str().c_str());
diff --git a/test/cpp/interop/server_helper.cc b/test/cpp/interop/server_helper.cc
new file mode 100644
index 0000000000..56597c83c4
--- /dev/null
+++ b/test/cpp/interop/server_helper.cc
@@ -0,0 +1,69 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "test/cpp/interop/server_helper.h"
+
+#include <memory>
+
+#include <gflags/gflags.h>
+#include "test/core/end2end/data/ssl_test_data.h"
+#include <grpc++/config.h>
+#include <grpc++/server_credentials.h>
+
+DECLARE_bool(enable_ssl);
+
+// 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 {}
+namespace gflags {}
+using namespace google;
+using namespace gflags;
+
+namespace grpc {
+namespace testing {
+
+std::shared_ptr<ServerCredentials> CreateInteropServerCredentials() {
+ if (FLAGS_enable_ssl) {
+ 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);
+ return SslServerCredentials(ssl_opts);
+ } else {
+ return InsecureServerCredentials();
+ }
+}
+
+} // namespace testing
+} // namespace grpc
diff --git a/src/ruby/ext/grpc/rb_metadata.h b/test/cpp/interop/server_helper.h
index 251072f658..f98e67bb67 100644
--- a/src/ruby/ext/grpc/rb_metadata.h
+++ b/test/cpp/interop/server_helper.h
@@ -31,23 +31,19 @@
*
*/
-#ifndef GRPC_RB_METADATA_H_
-#define GRPC_RB_METADATA_H_
+#ifndef GRPC_TEST_CPP_INTEROP_SERVER_HELPER_H
+#define GRPC_TEST_CPP_INTEROP_SERVER_HELPER_H
-#include <grpc/grpc.h>
-#include <ruby.h>
+#include <memory>
-/* rb_cMetadata is the Metadata class whose instances proxy grpc_metadata. */
-extern VALUE rb_cMetadata;
+#include <grpc++/server_credentials.h>
-/* grpc_rb_metadata_create_with_mark creates a grpc_rb_metadata with a ruby mark
- * object that will be kept alive while the metadata is alive. */
-extern VALUE grpc_rb_metadata_create_with_mark(VALUE mark, grpc_metadata* md);
+namespace grpc {
+namespace testing {
-/* Gets the wrapped metadata from the ruby wrapper */
-grpc_metadata* grpc_rb_get_wrapped_metadata(VALUE v);
+std::shared_ptr<ServerCredentials> CreateInteropServerCredentials();
-/* Initializes the Metadata class. */
-void Init_grpc_metadata();
+} // namespace testing
+} // namespace grpc
-#endif /* GRPC_RB_METADATA_H_ */
+#endif // GRPC_TEST_CPP_INTEROP_SERVER_HELPER_H
diff --git a/test/cpp/qps/client.h b/test/cpp/qps/client.h
index 08b338c747..2dc5b3860f 100644
--- a/test/cpp/qps/client.h
+++ b/test/cpp/qps/client.h
@@ -104,7 +104,7 @@ class Client {
void EndThreads() { threads_.clear(); }
- virtual void ThreadFunc(Histogram* histogram, size_t thread_idx) = 0;
+ virtual bool ThreadFunc(Histogram* histogram, size_t thread_idx) = 0;
private:
class Thread {
@@ -113,20 +113,24 @@ class Client {
: done_(false),
new_(nullptr),
impl_([this, idx, client]() {
- for (;;) {
- // run the loop body
- client->ThreadFunc(&histogram_, idx);
- // lock, see if we're done
- std::lock_guard<std::mutex> g(mu_);
- if (done_) {return;}
- // check if we're marking, swap out the histogram if so
- if (new_) {
- new_->Swap(&histogram_);
- new_ = nullptr;
- cv_.notify_one();
+ for (;;) {
+ // run the loop body
+ bool thread_still_ok = client->ThreadFunc(&histogram_, idx);
+ // lock, see if we're done
+ std::lock_guard<std::mutex> g(mu_);
+ if (!thread_still_ok) {
+ gpr_log(GPR_ERROR, "Finishing client thread due to RPC error");
+ done_ = true;
+ }
+ if (done_) {return;}
+ // check if we're marking, swap out the histogram if so
+ if (new_) {
+ new_->Swap(&histogram_);
+ new_ = nullptr;
+ cv_.notify_one();
+ }
}
- }
- }) {}
+ }) {}
~Thread() {
{
diff --git a/test/cpp/qps/client_async.cc b/test/cpp/qps/client_async.cc
index c01d840178..0a6d9beeca 100644
--- a/test/cpp/qps/client_async.cc
+++ b/test/cpp/qps/client_async.cc
@@ -137,13 +137,7 @@ class AsyncUnaryClient GRPC_FINAL : public Client {
cli_cqs_.emplace_back(new CompletionQueue);
}
- auto payload_size = config.payload_size();
- auto check_done = [payload_size](grpc::Status s, SimpleResponse* response) {
- GPR_ASSERT(s.IsOk() && (response->payload().type() ==
- grpc::testing::PayloadType::COMPRESSABLE) &&
- (response->payload().body().length() ==
- static_cast<size_t>(payload_size)));
- };
+ auto check_done = [](grpc::Status s, SimpleResponse* response) {};
int t = 0;
for (int i = 0; i < config.outstanding_rpcs_per_channel(); i++) {
@@ -179,10 +173,14 @@ class AsyncUnaryClient GRPC_FINAL : public Client {
}
}
- void ThreadFunc(Histogram* histogram, size_t thread_idx) GRPC_OVERRIDE {
+ bool ThreadFunc(Histogram* histogram, size_t thread_idx) GRPC_OVERRIDE {
void* got_tag;
bool ok;
- cli_cqs_[thread_idx]->Next(&got_tag, &ok);
+ switch (cli_cqs_[thread_idx]->AsyncNext(&got_tag, &ok, std::chrono::system_clock::now() + std::chrono::seconds(1))) {
+ case CompletionQueue::SHUTDOWN: return false;
+ case CompletionQueue::TIMEOUT: return true;
+ case CompletionQueue::GOT_EVENT: break;
+ }
ClientRpcContext* ctx = ClientRpcContext::detag(got_tag);
if (ctx->RunNextState(ok, histogram) == false) {
@@ -191,6 +189,8 @@ class AsyncUnaryClient GRPC_FINAL : public Client {
ctx->StartNewClone();
delete ctx;
}
+
+ return true;
}
std::vector<std::unique_ptr<CompletionQueue>> cli_cqs_;
@@ -270,13 +270,7 @@ class AsyncStreamingClient GRPC_FINAL : public Client {
cli_cqs_.emplace_back(new CompletionQueue);
}
- auto payload_size = config.payload_size();
- auto check_done = [payload_size](grpc::Status s, SimpleResponse *response) {
- GPR_ASSERT(s.IsOk() && (response->payload().type() ==
- grpc::testing::PayloadType::COMPRESSABLE) &&
- (response->payload().body().length() ==
- static_cast<size_t>(payload_size)));
- };
+ auto check_done = [](grpc::Status s, SimpleResponse* response) {};
int t = 0;
for (int i = 0; i < config.outstanding_rpcs_per_channel(); i++) {
@@ -313,10 +307,14 @@ class AsyncStreamingClient GRPC_FINAL : public Client {
}
}
- void ThreadFunc(Histogram *histogram, size_t thread_idx) GRPC_OVERRIDE {
+ bool ThreadFunc(Histogram *histogram, size_t thread_idx) GRPC_OVERRIDE {
void *got_tag;
bool ok;
- cli_cqs_[thread_idx]->Next(&got_tag, &ok);
+ switch (cli_cqs_[thread_idx]->AsyncNext(&got_tag, &ok, std::chrono::system_clock::now() + std::chrono::seconds(1))) {
+ case CompletionQueue::SHUTDOWN: return false;
+ case CompletionQueue::TIMEOUT: return true;
+ case CompletionQueue::GOT_EVENT: break;
+ }
ClientRpcContext *ctx = ClientRpcContext::detag(got_tag);
if (ctx->RunNextState(ok, histogram) == false) {
@@ -325,6 +323,8 @@ class AsyncStreamingClient GRPC_FINAL : public Client {
ctx->StartNewClone();
delete ctx;
}
+
+ return true;
}
std::vector<std::unique_ptr<CompletionQueue>> cli_cqs_;
diff --git a/test/cpp/qps/client_sync.cc b/test/cpp/qps/client_sync.cc
index 947618121b..aea5a0fb27 100644
--- a/test/cpp/qps/client_sync.cc
+++ b/test/cpp/qps/client_sync.cc
@@ -83,13 +83,14 @@ class SynchronousUnaryClient GRPC_FINAL : public SynchronousClient {
SynchronousClient(config) {StartThreads(num_threads_);}
~SynchronousUnaryClient() {}
- void ThreadFunc(Histogram* histogram, size_t thread_idx) GRPC_OVERRIDE {
+ bool ThreadFunc(Histogram* histogram, size_t thread_idx) GRPC_OVERRIDE {
auto* stub = channels_[thread_idx % channels_.size()].get_stub();
double start = Timer::Now();
grpc::ClientContext context;
grpc::Status s =
stub->UnaryCall(&context, request_, &responses_[thread_idx]);
histogram->Add((Timer::Now() - start) * 1e9);
+ return s.IsOk();
}
};
@@ -111,11 +112,13 @@ class SynchronousStreamingClient GRPC_FINAL : public SynchronousClient {
}
}
- void ThreadFunc(Histogram* histogram, size_t thread_idx) GRPC_OVERRIDE {
+ bool ThreadFunc(Histogram* histogram, size_t thread_idx) GRPC_OVERRIDE {
double start = Timer::Now();
- EXPECT_TRUE(stream_->Write(request_));
- EXPECT_TRUE(stream_->Read(&responses_[thread_idx]));
- histogram->Add((Timer::Now() - start) * 1e9);
+ if (stream_->Write(request_) && stream_->Read(&responses_[thread_idx])) {
+ histogram->Add((Timer::Now() - start) * 1e9);
+ return true;
+ }
+ return false;
}
private:
grpc::ClientContext context_;
diff --git a/test/cpp/qps/histogram.h b/test/cpp/qps/histogram.h
index eb17821cdc..0547b7283a 100644
--- a/test/cpp/qps/histogram.h
+++ b/test/cpp/qps/histogram.h
@@ -50,10 +50,10 @@ class Histogram {
void Merge(Histogram* h) { gpr_histogram_merge(impl_, h->impl_); }
void Add(double value) { gpr_histogram_add(impl_, value); }
- double Percentile(double pctile) {
+ double Percentile(double pctile) const {
return gpr_histogram_percentile(impl_, pctile);
}
- double Count() { return gpr_histogram_count(impl_); }
+ double Count() const { return gpr_histogram_count(impl_); }
void Swap(Histogram* other) { std::swap(impl_, other->impl_); }
void FillProto(HistogramData* p) {
size_t n;
diff --git a/test/cpp/qps/qps_driver.cc b/test/cpp/qps/qps_driver.cc
index f42d538b16..220f826118 100644
--- a/test/cpp/qps/qps_driver.cc
+++ b/test/cpp/qps/qps_driver.cc
@@ -35,7 +35,7 @@
#include <grpc/support/log.h>
#include "test/cpp/qps/driver.h"
-#include "test/cpp/qps/stats.h"
+#include "test/cpp/qps/report.h"
DEFINE_int32(num_clients, 1, "Number of client binaries");
DEFINE_int32(num_servers, 1, "Number of server binaries");
@@ -65,7 +65,6 @@ using grpc::testing::ClientType;
using grpc::testing::ServerType;
using grpc::testing::RpcType;
using grpc::testing::ResourceUsage;
-using grpc::testing::sum;
// In some distros, gflags is in the namespace google, and in some others,
// in gflags. This hack is enabling us to find both.
@@ -105,37 +104,9 @@ int main(int argc, char** argv) {
server_config, FLAGS_num_servers,
FLAGS_warmup_seconds, FLAGS_benchmark_seconds);
- gpr_log(GPR_INFO, "QPS: %.1f",
- result.latencies.Count() /
- average(result.client_resources,
- [](ResourceUsage u) { return u.wall_time; }));
-
- gpr_log(GPR_INFO, "Latencies (50/95/99/99.9%%-ile): %.1f/%.1f/%.1f/%.1f us",
- result.latencies.Percentile(50) / 1000,
- result.latencies.Percentile(95) / 1000,
- result.latencies.Percentile(99) / 1000,
- result.latencies.Percentile(99.9) / 1000);
-
- gpr_log(GPR_INFO, "Server system time: %.2f%%",
- 100.0 * sum(result.server_resources,
- [](ResourceUsage u) { return u.system_time; }) /
- sum(result.server_resources,
- [](ResourceUsage u) { return u.wall_time; }));
- gpr_log(GPR_INFO, "Server user time: %.2f%%",
- 100.0 * sum(result.server_resources,
- [](ResourceUsage u) { return u.user_time; }) /
- sum(result.server_resources,
- [](ResourceUsage u) { return u.wall_time; }));
- gpr_log(GPR_INFO, "Client system time: %.2f%%",
- 100.0 * sum(result.client_resources,
- [](ResourceUsage u) { return u.system_time; }) /
- sum(result.client_resources,
- [](ResourceUsage u) { return u.wall_time; }));
- gpr_log(GPR_INFO, "Client user time: %.2f%%",
- 100.0 * sum(result.client_resources,
- [](ResourceUsage u) { return u.user_time; }) /
- sum(result.client_resources,
- [](ResourceUsage u) { return u.wall_time; }));
+ ReportQPSPerCore(result, server_config);
+ ReportLatency(result);
+ ReportTimes(result);
grpc_shutdown();
return 0;
diff --git a/test/cpp/qps/report.cc b/test/cpp/qps/report.cc
new file mode 100644
index 0000000000..29d88da344
--- /dev/null
+++ b/test/cpp/qps/report.cc
@@ -0,0 +1,94 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "test/cpp/qps/report.h"
+
+#include <grpc/support/log.h>
+#include "test/cpp/qps/stats.h"
+
+namespace grpc {
+namespace testing {
+
+// QPS: XXX
+void ReportQPS(const ScenarioResult& result) {
+ gpr_log(GPR_INFO, "QPS: %.1f",
+ result.latencies.Count() /
+ average(result.client_resources,
+ [](ResourceUsage u) { return u.wall_time; }));
+}
+
+// QPS: XXX (YYY/server core)
+void ReportQPSPerCore(const ScenarioResult& result, const ServerConfig& server_config) {
+ auto qps =
+ result.latencies.Count() /
+ average(result.client_resources,
+ [](ResourceUsage u) { return u.wall_time; });
+
+ gpr_log(GPR_INFO, "QPS: %.1f (%.1f/server core)", qps, qps/server_config.threads());
+}
+
+// Latency (50/90/95/99/99.9%-ile): AA/BB/CC/DD/EE us
+void ReportLatency(const ScenarioResult& result) {
+ gpr_log(GPR_INFO, "Latencies (50/90/95/99/99.9%%-ile): %.1f/%.1f/%.1f/%.1f/%.1f us",
+ result.latencies.Percentile(50) / 1000,
+ result.latencies.Percentile(90) / 1000,
+ result.latencies.Percentile(95) / 1000,
+ result.latencies.Percentile(99) / 1000,
+ result.latencies.Percentile(99.9) / 1000);
+}
+
+void ReportTimes(const ScenarioResult& result) {
+ gpr_log(GPR_INFO, "Server system time: %.2f%%",
+ 100.0 * sum(result.server_resources,
+ [](ResourceUsage u) { return u.system_time; }) /
+ sum(result.server_resources,
+ [](ResourceUsage u) { return u.wall_time; }));
+ gpr_log(GPR_INFO, "Server user time: %.2f%%",
+ 100.0 * sum(result.server_resources,
+ [](ResourceUsage u) { return u.user_time; }) /
+ sum(result.server_resources,
+ [](ResourceUsage u) { return u.wall_time; }));
+ gpr_log(GPR_INFO, "Client system time: %.2f%%",
+ 100.0 * sum(result.client_resources,
+ [](ResourceUsage u) { return u.system_time; }) /
+ sum(result.client_resources,
+ [](ResourceUsage u) { return u.wall_time; }));
+ gpr_log(GPR_INFO, "Client user time: %.2f%%",
+ 100.0 * sum(result.client_resources,
+ [](ResourceUsage u) { return u.user_time; }) /
+ sum(result.client_resources,
+ [](ResourceUsage u) { return u.wall_time; }));
+}
+
+} // namespace testing
+} // namespace grpc
diff --git a/test/cpp/qps/report.h b/test/cpp/qps/report.h
new file mode 100644
index 0000000000..343e426ca4
--- /dev/null
+++ b/test/cpp/qps/report.h
@@ -0,0 +1,57 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef TEST_QPS_REPORT_H
+#define TEST_QPS_REPORT_H
+
+#include "test/cpp/qps/driver.h"
+
+namespace grpc {
+namespace testing {
+
+// QPS: XXX
+void ReportQPS(const ScenarioResult& result);
+// QPS: XXX (YYY/server core)
+void ReportQPSPerCore(const ScenarioResult& result, const ServerConfig& config);
+// Latency (50/90/95/99/99.9%-ile): AA/BB/CC/DD/EE us
+void ReportLatency(const ScenarioResult& result);
+// Server system time: XX%
+// Server user time: XX%
+// Client system time: XX%
+// Client user time: XX%
+void ReportTimes(const ScenarioResult& result);
+
+} // namespace testing
+} // namespace grpc
+
+#endif
diff --git a/test/cpp/qps/server_async.cc b/test/cpp/qps/server_async.cc
index 2e366a8d72..b19c443c82 100644
--- a/test/cpp/qps/server_async.cc
+++ b/test/cpp/qps/server_async.cc
@@ -97,15 +97,15 @@ class AsyncQpsServerTest : public Server {
bool ok;
void* got_tag;
while (srv_cq_.Next(&got_tag, &ok)) {
- ServerRpcContext* ctx = detag(got_tag);
- // The tag is a pointer to an RPC context to invoke
- if (ctx->RunNextState(ok) == false) {
- // this RPC context is done, so refresh it
+ ServerRpcContext* ctx = detag(got_tag);
+ // The tag is a pointer to an RPC context to invoke
+ if (ctx->RunNextState(ok) == false) {
+ // this RPC context is done, so refresh it
std::lock_guard<std::mutex> g(shutdown_mutex_);
if (!shutdown_) {
ctx->Reset();
}
- }
+ }
}
return;
}));
@@ -175,8 +175,9 @@ class AsyncQpsServerTest : public Server {
private:
bool finisher(bool) { return false; }
bool invoker(bool ok) {
- if (!ok)
- return false;
+ if (!ok) {
+ return false;
+ }
ResponseType response;
@@ -230,8 +231,9 @@ class AsyncQpsServerTest : public Server {
private:
bool request_done(bool ok) {
- if (!ok)
- return false;
+ if (!ok) {
+ return false;
+ }
stream_.Read(&req_, AsyncQpsServerTest::tag(this));
next_state_ = &ServerRpcContextStreamingImpl::read_done;
return true;
diff --git a/test/cpp/qps/smoke_test.cc b/test/cpp/qps/smoke_test.cc
new file mode 100644
index 0000000000..c9d321f133
--- /dev/null
+++ b/test/cpp/qps/smoke_test.cc
@@ -0,0 +1,149 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <grpc/support/log.h>
+
+#include "test/cpp/qps/driver.h"
+#include "test/cpp/qps/report.h"
+
+namespace grpc {
+namespace testing {
+
+static const int WARMUP = 5;
+static const int BENCHMARK = 10;
+
+static void RunSynchronousUnaryPingPong() {
+ gpr_log(GPR_INFO, "Running Synchronous Unary Ping Pong");
+
+ ClientConfig client_config;
+ client_config.set_client_type(SYNCHRONOUS_CLIENT);
+ client_config.set_enable_ssl(false);
+ client_config.set_outstanding_rpcs_per_channel(1);
+ client_config.set_client_channels(1);
+ client_config.set_payload_size(1);
+ client_config.set_rpc_type(UNARY);
+
+ ServerConfig server_config;
+ server_config.set_server_type(SYNCHRONOUS_SERVER);
+ server_config.set_enable_ssl(false);
+ server_config.set_threads(1);
+
+ auto result = RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK);
+
+ ReportQPS(result);
+ ReportLatency(result);
+}
+
+static void RunSynchronousStreamingPingPong() {
+ gpr_log(GPR_INFO, "Running Synchronous Streaming Ping Pong");
+
+ ClientConfig client_config;
+ client_config.set_client_type(SYNCHRONOUS_CLIENT);
+ client_config.set_enable_ssl(false);
+ client_config.set_outstanding_rpcs_per_channel(1);
+ client_config.set_client_channels(1);
+ client_config.set_payload_size(1);
+ client_config.set_rpc_type(STREAMING);
+
+ ServerConfig server_config;
+ server_config.set_server_type(SYNCHRONOUS_SERVER);
+ server_config.set_enable_ssl(false);
+ server_config.set_threads(1);
+
+ auto result = RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK);
+
+ ReportQPS(result);
+ ReportLatency(result);
+}
+
+static void RunAsyncUnaryPingPong() {
+ gpr_log(GPR_INFO, "Running Async Unary Ping Pong");
+
+ ClientConfig client_config;
+ client_config.set_client_type(ASYNC_CLIENT);
+ client_config.set_enable_ssl(false);
+ client_config.set_outstanding_rpcs_per_channel(1);
+ client_config.set_client_channels(1);
+ client_config.set_payload_size(1);
+ client_config.set_async_client_threads(1);
+ client_config.set_rpc_type(UNARY);
+
+ ServerConfig server_config;
+ server_config.set_server_type(ASYNC_SERVER);
+ server_config.set_enable_ssl(false);
+ server_config.set_threads(1);
+
+ auto result = RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK);
+
+ ReportQPS(result);
+ ReportLatency(result);
+}
+
+static void RunQPS() {
+ gpr_log(GPR_INFO, "Running QPS test");
+
+ ClientConfig client_config;
+ client_config.set_client_type(ASYNC_CLIENT);
+ client_config.set_enable_ssl(false);
+ client_config.set_outstanding_rpcs_per_channel(1000);
+ client_config.set_client_channels(8);
+ client_config.set_payload_size(1);
+ client_config.set_async_client_threads(8);
+ client_config.set_rpc_type(UNARY);
+
+ ServerConfig server_config;
+ server_config.set_server_type(ASYNC_SERVER);
+ server_config.set_enable_ssl(false);
+ server_config.set_threads(4);
+
+ auto result = RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK);
+
+ ReportQPSPerCore(result, server_config);
+ ReportLatency(result);
+}
+
+} // namespace testing
+} // namespace grpc
+
+int main(int argc, char** argv) {
+ grpc_init();
+
+ using namespace grpc::testing;
+ RunSynchronousStreamingPingPong();
+ RunSynchronousUnaryPingPong();
+ RunAsyncUnaryPingPong();
+ RunQPS();
+
+ grpc_shutdown();
+ return 0;
+}
diff --git a/test/cpp/qps/smoke_test.sh b/test/cpp/qps/smoke_test.sh
new file mode 100755
index 0000000000..ba7f0a4f27
--- /dev/null
+++ b/test/cpp/qps/smoke_test.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+
+# performs a single qps run with one client and one server
+
+set -ex
+
+cd $(dirname $0)/../../..
+
+killall qps_worker || true
+
+config=opt
+
+NUMCPUS=`python2.7 -c 'import multiprocessing; print multiprocessing.cpu_count()'`
+
+make CONFIG=$config qps_worker qps_smoke_test -j$NUMCPUS
+
+bins/$config/qps_worker -driver_port 10000 -server_port 10001 &
+PID1=$!
+bins/$config/qps_worker -driver_port 10010 -server_port 10011 &
+PID2=$!
+
+export QPS_WORKERS="localhost:10000,localhost:10010"
+
+bins/$config/qps_smoke_test $*
+
+kill -2 $PID1 $PID2
+wait
+
diff --git a/tools/dockerfile/grpc_python/Dockerfile b/tools/dockerfile/grpc_python/Dockerfile
index 62ef785a31..aa29685bee 100644
--- a/tools/dockerfile/grpc_python/Dockerfile
+++ b/tools/dockerfile/grpc_python/Dockerfile
@@ -66,5 +66,8 @@ RUN cd /var/local/git/grpc \
# Add a cacerts directory containing the Google root pem file, allowing the interop client to access the production test instance
ADD cacerts cacerts
+# Add a service_account directory containing the auth creds file
+ADD service_account service_account
+
# Specify the default command such that the interop server runs on its known testing port
CMD ["/bin/bash", "-l", "-c", "python2.7 -m interop.server --use_tls --port 8050"]
diff --git a/tools/gce_setup/grpc_docker.sh b/tools/gce_setup/grpc_docker.sh
index 40634291cf..c68903b816 100755
--- a/tools/gce_setup/grpc_docker.sh
+++ b/tools/gce_setup/grpc_docker.sh
@@ -1047,7 +1047,7 @@ grpc_interop_gen_python_cmd() {
# flags= .... # generic flags to include the command
# cmd=$($grpc_gen_test_cmd $flags)
grpc_cloud_prod_auth_service_account_creds_gen_python_cmd() {
- local cmd_prefix="sudo docker run grpc/ruby bin/bash -l -c";
+ local cmd_prefix="sudo docker run grpc/python bin/bash -l -c";
local gfe_flags=$(_grpc_prod_gfe_flags)
local added_gfe_flags=$(_grpc_default_creds_test_flags)
local env_prefix="SSL_CERT_FILE=/cacerts/roots.pem"
@@ -1062,7 +1062,7 @@ grpc_cloud_prod_auth_service_account_creds_gen_python_cmd() {
# flags= .... # generic flags to include the command
# cmd=$($grpc_gen_test_cmd $flags)
grpc_cloud_prod_auth_compute_engine_creds_gen_python_cmd() {
- local cmd_prefix="sudo docker run grpc/ruby bin/bash -l -c";
+ local cmd_prefix="sudo docker run grpc/python bin/bash -l -c";
local gfe_flags=$(_grpc_prod_gfe_flags)
local added_gfe_flags=$(_grpc_gce_test_flags)
local env_prefix="SSL_CERT_FILE=/cacerts/roots.pem"
diff --git a/tools/gce_setup/interop_test_runner.sh b/tools/gce_setup/interop_test_runner.sh
index 7f0b5bab1a..1c6122e9ae 100755
--- a/tools/gce_setup/interop_test_runner.sh
+++ b/tools/gce_setup/interop_test_runner.sh
@@ -36,7 +36,7 @@ echo $result_file_name
main() {
source grpc_docker.sh
test_cases=(large_unary empty_unary ping_pong client_streaming server_streaming cancel_after_begin cancel_after_first_response)
- clients=(cxx java go ruby node python csharp_mono)
+ clients=(cxx java go ruby node python csharp_mono php)
servers=(cxx java go ruby node python csharp_mono)
for test_case in "${test_cases[@]}"
do
diff --git a/vsprojects/vs2010/grpc++.vcxproj b/vsprojects/vs2010/grpc++.vcxproj
index 0ee433163c..003355eabf 100644
--- a/vsprojects/vs2010/grpc++.vcxproj
+++ b/vsprojects/vs2010/grpc++.vcxproj
@@ -93,6 +93,12 @@
<ClInclude Include="..\..\include\grpc++\impl\rpc_method.h" />
<ClInclude Include="..\..\include\grpc++\impl\rpc_service_method.h" />
<ClInclude Include="..\..\include\grpc++\impl\service_type.h" />
+ <ClInclude Include="..\..\include\grpc++\impl\sync.h" />
+ <ClInclude Include="..\..\include\grpc++\impl\sync_cxx11.h" />
+ <ClInclude Include="..\..\include\grpc++\impl\sync_no_cxx11.h" />
+ <ClInclude Include="..\..\include\grpc++\impl\thd.h" />
+ <ClInclude Include="..\..\include\grpc++\impl\thd_cxx11.h" />
+ <ClInclude Include="..\..\include\grpc++\impl\thd_no_cxx11.h" />
<ClInclude Include="..\..\include\grpc++\server.h" />
<ClInclude Include="..\..\include\grpc++\server_builder.h" />
<ClInclude Include="..\..\include\grpc++\server_context.h" />
@@ -104,6 +110,8 @@
<ClInclude Include="..\..\include\grpc++\thread_pool_interface.h" />
</ItemGroup>
<ItemGroup>
+ <ClInclude Include="..\..\src\cpp\client\secure_credentials.h" />
+ <ClInclude Include="..\..\src\cpp\server\secure_server_credentials.h" />
<ClInclude Include="..\..\src\cpp\client\channel.h" />
<ClInclude Include="..\..\src\cpp\proto\proto_utils.h" />
<ClInclude Include="..\..\src\cpp\server\thread_pool.h" />
diff --git a/vsprojects/vs2010/grpc++.vcxproj.filters b/vsprojects/vs2010/grpc++.vcxproj.filters
index ed93daee04..6466a0fa26 100644
--- a/vsprojects/vs2010/grpc++.vcxproj.filters
+++ b/vsprojects/vs2010/grpc++.vcxproj.filters
@@ -132,6 +132,24 @@
<ClInclude Include="..\..\include\grpc++\impl\service_type.h">
<Filter>include\grpc++\impl</Filter>
</ClInclude>
+ <ClInclude Include="..\..\include\grpc++\impl\sync.h">
+ <Filter>include\grpc++\impl</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\impl\sync_cxx11.h">
+ <Filter>include\grpc++\impl</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\impl\sync_no_cxx11.h">
+ <Filter>include\grpc++\impl</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\impl\thd.h">
+ <Filter>include\grpc++\impl</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\impl\thd_cxx11.h">
+ <Filter>include\grpc++\impl</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\impl\thd_no_cxx11.h">
+ <Filter>include\grpc++\impl</Filter>
+ </ClInclude>
<ClInclude Include="..\..\include\grpc++\server.h">
<Filter>include\grpc++</Filter>
</ClInclude>
@@ -161,6 +179,12 @@
</ClInclude>
</ItemGroup>
<ItemGroup>
+ <ClInclude Include="..\..\src\cpp\client\secure_credentials.h">
+ <Filter>src\cpp\client</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\cpp\server\secure_server_credentials.h">
+ <Filter>src\cpp\server</Filter>
+ </ClInclude>
<ClInclude Include="..\..\src\cpp\client\channel.h">
<Filter>src\cpp\client</Filter>
</ClInclude>
diff --git a/vsprojects/vs2013/grpc++.vcxproj b/vsprojects/vs2013/grpc++.vcxproj
index d545a949cb..dff588166b 100644
--- a/vsprojects/vs2013/grpc++.vcxproj
+++ b/vsprojects/vs2013/grpc++.vcxproj
@@ -95,6 +95,12 @@
<ClInclude Include="..\..\include\grpc++\impl\rpc_method.h" />
<ClInclude Include="..\..\include\grpc++\impl\rpc_service_method.h" />
<ClInclude Include="..\..\include\grpc++\impl\service_type.h" />
+ <ClInclude Include="..\..\include\grpc++\impl\sync.h" />
+ <ClInclude Include="..\..\include\grpc++\impl\sync_cxx11.h" />
+ <ClInclude Include="..\..\include\grpc++\impl\sync_no_cxx11.h" />
+ <ClInclude Include="..\..\include\grpc++\impl\thd.h" />
+ <ClInclude Include="..\..\include\grpc++\impl\thd_cxx11.h" />
+ <ClInclude Include="..\..\include\grpc++\impl\thd_no_cxx11.h" />
<ClInclude Include="..\..\include\grpc++\server.h" />
<ClInclude Include="..\..\include\grpc++\server_builder.h" />
<ClInclude Include="..\..\include\grpc++\server_context.h" />
@@ -106,6 +112,8 @@
<ClInclude Include="..\..\include\grpc++\thread_pool_interface.h" />
</ItemGroup>
<ItemGroup>
+ <ClInclude Include="..\..\src\cpp\client\secure_credentials.h" />
+ <ClInclude Include="..\..\src\cpp\server\secure_server_credentials.h" />
<ClInclude Include="..\..\src\cpp\client\channel.h" />
<ClInclude Include="..\..\src\cpp\proto\proto_utils.h" />
<ClInclude Include="..\..\src\cpp\server\thread_pool.h" />
diff --git a/vsprojects/vs2013/grpc++.vcxproj.filters b/vsprojects/vs2013/grpc++.vcxproj.filters
index ed93daee04..6466a0fa26 100644
--- a/vsprojects/vs2013/grpc++.vcxproj.filters
+++ b/vsprojects/vs2013/grpc++.vcxproj.filters
@@ -132,6 +132,24 @@
<ClInclude Include="..\..\include\grpc++\impl\service_type.h">
<Filter>include\grpc++\impl</Filter>
</ClInclude>
+ <ClInclude Include="..\..\include\grpc++\impl\sync.h">
+ <Filter>include\grpc++\impl</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\impl\sync_cxx11.h">
+ <Filter>include\grpc++\impl</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\impl\sync_no_cxx11.h">
+ <Filter>include\grpc++\impl</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\impl\thd.h">
+ <Filter>include\grpc++\impl</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\impl\thd_cxx11.h">
+ <Filter>include\grpc++\impl</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\include\grpc++\impl\thd_no_cxx11.h">
+ <Filter>include\grpc++\impl</Filter>
+ </ClInclude>
<ClInclude Include="..\..\include\grpc++\server.h">
<Filter>include\grpc++</Filter>
</ClInclude>
@@ -161,6 +179,12 @@
</ClInclude>
</ItemGroup>
<ItemGroup>
+ <ClInclude Include="..\..\src\cpp\client\secure_credentials.h">
+ <Filter>src\cpp\client</Filter>
+ </ClInclude>
+ <ClInclude Include="..\..\src\cpp\server\secure_server_credentials.h">
+ <Filter>src\cpp\server</Filter>
+ </ClInclude>
<ClInclude Include="..\..\src\cpp\client\channel.h">
<Filter>src\cpp\client</Filter>
</ClInclude>