grpc 1.6.7 → 1.7.0.pre1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of grpc might be problematic. Click here for more details.

Files changed (277) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +579 -77
  3. data/include/grpc/byte_buffer.h +1 -63
  4. data/include/grpc/compression.h +27 -5
  5. data/include/grpc/fork.h +24 -0
  6. data/include/grpc/grpc.h +12 -6
  7. data/include/grpc/grpc_security.h +28 -7
  8. data/include/grpc/impl/codegen/atm.h +1 -0
  9. data/include/grpc/impl/codegen/byte_buffer.h +86 -0
  10. data/include/grpc/impl/codegen/compression_types.h +63 -5
  11. data/include/grpc/impl/codegen/fork.h +48 -0
  12. data/include/grpc/impl/codegen/grpc_types.h +26 -9
  13. data/include/grpc/impl/codegen/port_platform.h +11 -4
  14. data/include/grpc/impl/codegen/slice.h +6 -1
  15. data/include/grpc/impl/codegen/sync.h +3 -1
  16. data/include/grpc/impl/codegen/sync_custom.h +36 -0
  17. data/include/grpc/module.modulemap +75 -3
  18. data/include/grpc/slice.h +1 -5
  19. data/include/grpc/support/sync_custom.h +24 -0
  20. data/src/core/ext/census/base_resources.c +14 -14
  21. data/src/core/ext/census/context.c +7 -5
  22. data/src/core/ext/census/grpc_filter.c +12 -14
  23. data/src/core/ext/census/mlog.c +2 -1
  24. data/src/core/ext/census/resource.c +13 -9
  25. data/src/core/ext/filters/client_channel/channel_connectivity.c +15 -8
  26. data/src/core/ext/filters/client_channel/client_channel.c +418 -439
  27. data/src/core/ext/filters/client_channel/client_channel_factory.c +4 -5
  28. data/src/core/ext/filters/client_channel/client_channel_plugin.c +2 -2
  29. data/src/core/ext/filters/client_channel/http_connect_handshaker.c +7 -5
  30. data/src/core/ext/filters/client_channel/http_proxy.c +17 -21
  31. data/src/core/ext/filters/client_channel/lb_policy.c +1 -1
  32. data/src/core/ext/filters/client_channel/lb_policy/grpclb/client_load_reporting_filter.c +7 -7
  33. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.c +371 -257
  34. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb_client_stats.c +7 -5
  35. data/src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.c +25 -14
  36. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.c +16 -16
  37. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.c +33 -28
  38. data/src/core/ext/filters/client_channel/lb_policy_factory.c +10 -8
  39. data/src/core/ext/filters/client_channel/lb_policy_factory.h +1 -1
  40. data/src/core/ext/filters/client_channel/proxy_mapper_registry.c +1 -1
  41. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.c +7 -6
  42. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_ev_driver_posix.c +62 -28
  43. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/grpc_ares_wrapper.c +29 -23
  44. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.c +25 -14
  45. data/src/core/ext/filters/client_channel/retry_throttle.c +9 -6
  46. data/src/core/ext/filters/client_channel/subchannel.c +30 -30
  47. data/src/core/ext/filters/client_channel/subchannel.h +1 -4
  48. data/src/core/ext/filters/client_channel/subchannel_index.c +31 -15
  49. data/src/core/ext/filters/client_channel/subchannel_index.h +7 -0
  50. data/src/core/ext/filters/client_channel/uri_parser.c +4 -3
  51. data/src/core/ext/filters/deadline/deadline_filter.c +78 -39
  52. data/src/core/ext/filters/deadline/deadline_filter.h +7 -1
  53. data/src/core/ext/filters/http/client/http_client_filter.c +14 -14
  54. data/src/core/ext/filters/http/http_filters_plugin.c +1 -1
  55. data/src/core/ext/filters/http/message_compress/message_compress_filter.c +240 -175
  56. data/src/core/ext/filters/http/server/http_server_filter.c +48 -36
  57. data/src/core/ext/filters/load_reporting/{load_reporting_filter.c → server_load_reporting_filter.c} +11 -12
  58. data/src/core/ext/filters/load_reporting/{load_reporting_filter.h → server_load_reporting_filter.h} +6 -5
  59. data/src/core/ext/filters/load_reporting/{load_reporting.c → server_load_reporting_plugin.c} +19 -13
  60. data/src/core/ext/filters/load_reporting/{load_reporting.h → server_load_reporting_plugin.h} +4 -3
  61. data/src/core/ext/filters/max_age/max_age_filter.c +2 -3
  62. data/src/core/ext/filters/message_size/message_size_filter.c +4 -2
  63. data/src/core/ext/filters/workarounds/workaround_cronet_compression_filter.c +0 -1
  64. data/src/core/ext/transport/chttp2/client/chttp2_connector.c +5 -5
  65. data/src/core/ext/transport/chttp2/client/insecure/channel_create.c +1 -1
  66. data/src/core/ext/transport/chttp2/client/insecure/channel_create_posix.c +1 -1
  67. data/src/core/ext/transport/chttp2/server/chttp2_server.c +20 -18
  68. data/src/core/ext/transport/chttp2/transport/chttp2_plugin.c +1 -0
  69. data/src/core/ext/transport/chttp2/transport/chttp2_transport.c +493 -210
  70. data/src/core/ext/transport/chttp2/transport/chttp2_transport.h +1 -0
  71. data/src/core/ext/transport/chttp2/transport/flow_control.c +9 -8
  72. data/src/core/ext/transport/chttp2/transport/frame_data.c +2 -2
  73. data/src/core/ext/transport/chttp2/transport/frame_goaway.c +2 -2
  74. data/src/core/ext/transport/chttp2/transport/frame_ping.c +5 -4
  75. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.c +1 -1
  76. data/src/core/ext/transport/chttp2/transport/frame_settings.c +10 -9
  77. data/src/core/ext/transport/chttp2/transport/frame_window_update.c +9 -5
  78. data/src/core/ext/transport/chttp2/transport/hpack_encoder.c +62 -41
  79. data/src/core/ext/transport/chttp2/transport/hpack_parser.c +52 -8
  80. data/src/core/ext/transport/chttp2/transport/hpack_table.c +2 -2
  81. data/src/core/ext/transport/chttp2/transport/incoming_metadata.c +3 -2
  82. data/src/core/ext/transport/chttp2/transport/internal.h +60 -30
  83. data/src/core/ext/transport/chttp2/transport/parsing.c +16 -5
  84. data/src/core/ext/transport/chttp2/transport/stream_lists.c +36 -16
  85. data/src/core/ext/transport/chttp2/transport/stream_map.c +6 -4
  86. data/src/core/ext/transport/chttp2/transport/writing.c +133 -105
  87. data/src/core/ext/transport/inproc/inproc_transport.c +61 -65
  88. data/src/core/lib/channel/channel_args.c +112 -12
  89. data/src/core/lib/channel/channel_args.h +31 -0
  90. data/src/core/lib/channel/channel_stack.c +1 -15
  91. data/src/core/lib/channel/channel_stack.h +3 -10
  92. data/src/core/lib/channel/channel_stack_builder.c +41 -10
  93. data/src/core/lib/channel/channel_stack_builder.h +10 -0
  94. data/src/core/lib/channel/connected_channel.c +94 -23
  95. data/src/core/lib/channel/handshaker.c +8 -6
  96. data/src/core/lib/channel/handshaker_registry.c +1 -1
  97. data/src/core/lib/compression/algorithm_metadata.h +14 -0
  98. data/src/core/lib/compression/compression.c +101 -1
  99. data/src/core/lib/compression/stream_compression.c +32 -146
  100. data/src/core/lib/compression/stream_compression.h +28 -4
  101. data/src/core/lib/compression/stream_compression_gzip.c +228 -0
  102. data/src/core/lib/{iomgr/ev_epoll_thread_pool_linux.h → compression/stream_compression_gzip.h} +5 -7
  103. data/src/core/lib/compression/stream_compression_identity.c +94 -0
  104. data/src/core/lib/{iomgr/ev_epoll_limited_pollers_linux.h → compression/stream_compression_identity.h} +7 -8
  105. data/src/core/lib/debug/stats.c +174 -0
  106. data/src/core/lib/debug/stats.h +61 -0
  107. data/src/core/lib/debug/stats_data.c +687 -0
  108. data/src/core/lib/debug/stats_data.h +470 -0
  109. data/src/core/lib/debug/trace.c +3 -3
  110. data/src/core/lib/debug/trace.h +1 -1
  111. data/src/core/lib/http/format_request.c +1 -1
  112. data/src/core/lib/http/httpcli.c +8 -7
  113. data/src/core/lib/http/httpcli_security_connector.c +2 -1
  114. data/src/core/lib/http/parser.c +4 -3
  115. data/src/core/lib/iomgr/call_combiner.c +202 -0
  116. data/src/core/lib/iomgr/call_combiner.h +121 -0
  117. data/src/core/lib/iomgr/closure.c +18 -4
  118. data/src/core/lib/iomgr/combiner.c +11 -4
  119. data/src/core/lib/iomgr/error.c +26 -24
  120. data/src/core/lib/iomgr/ev_epoll1_linux.c +395 -212
  121. data/src/core/lib/iomgr/ev_epollex_linux.c +141 -128
  122. data/src/core/lib/iomgr/ev_epollsig_linux.c +44 -41
  123. data/src/core/lib/iomgr/ev_poll_posix.c +99 -75
  124. data/src/core/lib/iomgr/ev_posix.c +5 -9
  125. data/src/core/lib/iomgr/ev_posix.h +1 -1
  126. data/src/core/lib/iomgr/exec_ctx.h +6 -1
  127. data/src/core/lib/iomgr/executor.c +142 -36
  128. data/src/core/lib/iomgr/executor.h +6 -1
  129. data/src/core/lib/iomgr/fork_posix.c +88 -0
  130. data/src/core/lib/iomgr/fork_windows.c +39 -0
  131. data/src/core/lib/iomgr/iocp_windows.c +2 -0
  132. data/src/core/lib/iomgr/iomgr.c +2 -8
  133. data/src/core/lib/iomgr/is_epollexclusive_available.c +6 -6
  134. data/src/core/lib/iomgr/load_file.c +2 -1
  135. data/src/core/lib/iomgr/polling_entity.c +9 -9
  136. data/src/core/lib/iomgr/polling_entity.h +7 -1
  137. data/src/core/lib/iomgr/pollset.h +1 -1
  138. data/src/core/lib/iomgr/pollset_uv.c +1 -1
  139. data/src/core/lib/iomgr/pollset_windows.c +3 -3
  140. data/src/core/lib/iomgr/port.h +4 -0
  141. data/src/core/lib/iomgr/resolve_address_posix.c +8 -7
  142. data/src/core/lib/iomgr/resolve_address_windows.c +1 -1
  143. data/src/core/lib/iomgr/resource_quota.c +24 -19
  144. data/src/core/lib/iomgr/socket_factory_posix.c +4 -4
  145. data/src/core/lib/iomgr/socket_mutator.c +4 -4
  146. data/src/core/lib/iomgr/socket_utils_windows.c +0 -4
  147. data/src/core/lib/iomgr/tcp_client_posix.c +5 -4
  148. data/src/core/lib/iomgr/tcp_posix.c +181 -20
  149. data/src/core/lib/iomgr/tcp_server_posix.c +8 -7
  150. data/src/core/lib/iomgr/tcp_server_utils_posix_common.c +1 -1
  151. data/src/core/lib/iomgr/timer.h +4 -0
  152. data/src/core/lib/iomgr/timer_generic.c +138 -3
  153. data/src/core/lib/iomgr/timer_generic.h +3 -0
  154. data/src/core/lib/iomgr/timer_heap.c +4 -4
  155. data/src/core/lib/iomgr/timer_manager.c +2 -2
  156. data/src/core/lib/iomgr/timer_uv.c +2 -0
  157. data/src/core/lib/iomgr/udp_server.c +10 -8
  158. data/src/core/lib/iomgr/unix_sockets_posix.c +4 -2
  159. data/src/core/lib/iomgr/wakeup_fd_cv.c +9 -8
  160. data/src/core/lib/iomgr/wakeup_fd_cv.h +2 -2
  161. data/src/core/lib/json/json.c +1 -1
  162. data/src/core/lib/json/json_string.c +13 -13
  163. data/src/core/lib/profiling/timers.h +18 -8
  164. data/src/core/lib/security/credentials/composite/composite_credentials.c +4 -10
  165. data/src/core/lib/security/credentials/google_default/google_default_credentials.c +2 -1
  166. data/src/core/lib/security/credentials/jwt/jwt_verifier.c +11 -6
  167. data/src/core/lib/security/credentials/oauth2/oauth2_credentials.c +4 -4
  168. data/src/core/lib/security/credentials/plugin/plugin_credentials.c +132 -50
  169. data/src/core/lib/security/credentials/plugin/plugin_credentials.h +2 -0
  170. data/src/core/lib/security/transport/client_auth_filter.c +68 -135
  171. data/src/core/lib/security/transport/secure_endpoint.c +110 -90
  172. data/src/core/lib/security/transport/secure_endpoint.h +8 -3
  173. data/src/core/lib/security/transport/security_connector.c +10 -12
  174. data/src/core/lib/security/transport/security_handshaker.c +45 -24
  175. data/src/core/lib/security/transport/server_auth_filter.c +71 -20
  176. data/src/core/lib/slice/b64.c +2 -2
  177. data/src/core/lib/slice/slice.c +16 -14
  178. data/src/core/lib/slice/slice_buffer.c +5 -4
  179. data/src/core/lib/slice/slice_hash_table.c +3 -2
  180. data/src/core/lib/slice/slice_intern.c +8 -5
  181. data/src/core/lib/support/block_annotate.h +22 -0
  182. data/src/core/lib/support/fork.c +62 -0
  183. data/src/core/lib/support/fork.h +35 -0
  184. data/src/core/lib/support/log_linux.c +1 -1
  185. data/src/core/lib/support/string.c +15 -1
  186. data/src/core/lib/support/string.h +3 -0
  187. data/src/core/lib/support/thd_internal.h +6 -0
  188. data/src/core/lib/support/thd_posix.c +56 -0
  189. data/src/core/lib/support/thd_windows.c +2 -0
  190. data/src/core/lib/surface/alarm.c +22 -15
  191. data/src/core/lib/surface/byte_buffer.c +4 -2
  192. data/src/core/lib/surface/call.c +442 -141
  193. data/src/core/lib/surface/call.h +6 -6
  194. data/src/core/lib/surface/call_log_batch.c +1 -1
  195. data/src/core/lib/surface/call_test_only.h +12 -0
  196. data/src/core/lib/surface/channel.c +39 -4
  197. data/src/core/lib/surface/channel_init.c +6 -6
  198. data/src/core/lib/surface/channel_ping.c +2 -2
  199. data/src/core/lib/surface/completion_queue.c +56 -57
  200. data/src/core/lib/surface/init.c +17 -3
  201. data/src/core/lib/surface/init_secure.c +5 -1
  202. data/src/core/lib/surface/lame_client.cc +9 -10
  203. data/src/core/lib/surface/server.c +81 -72
  204. data/src/core/lib/surface/version.c +2 -2
  205. data/src/core/lib/transport/byte_stream.c +1 -0
  206. data/src/core/lib/transport/byte_stream.h +3 -1
  207. data/src/core/lib/transport/connectivity_state.c +2 -1
  208. data/src/core/lib/transport/metadata.c +7 -4
  209. data/src/core/lib/transport/metadata_batch.c +18 -16
  210. data/src/core/lib/transport/metadata_batch.h +1 -0
  211. data/src/core/lib/transport/service_config.c +5 -3
  212. data/src/core/lib/transport/static_metadata.c +395 -614
  213. data/src/core/lib/transport/static_metadata.h +165 -133
  214. data/src/core/lib/transport/status_conversion.c +1 -1
  215. data/src/core/lib/transport/transport.c +20 -20
  216. data/src/core/lib/transport/transport.h +8 -5
  217. data/src/core/lib/transport/transport_impl.h +0 -3
  218. data/src/core/lib/transport/transport_op_string.c +8 -1
  219. data/src/core/plugin_registry/grpc_plugin_registry.c +4 -4
  220. data/src/core/tsi/fake_transport_security.c +133 -2
  221. data/src/core/tsi/fake_transport_security.h +5 -0
  222. data/src/core/tsi/ssl_transport_security.c +105 -8
  223. data/src/core/tsi/ssl_transport_security.h +30 -7
  224. data/src/core/tsi/transport_security.h +8 -2
  225. data/src/core/tsi/transport_security_grpc.c +20 -13
  226. data/src/core/tsi/transport_security_grpc.h +13 -9
  227. data/src/ruby/ext/grpc/rb_call_credentials.c +6 -2
  228. data/src/ruby/ext/grpc/rb_grpc.c +1 -1
  229. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +30 -20
  230. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +50 -35
  231. data/src/ruby/lib/grpc.rb +1 -0
  232. data/src/ruby/lib/grpc/generic/active_call.rb +34 -9
  233. data/src/ruby/lib/grpc/generic/bidi_call.rb +19 -10
  234. data/src/ruby/lib/grpc/generic/client_stub.rb +95 -38
  235. data/src/ruby/lib/grpc/generic/interceptor_registry.rb +53 -0
  236. data/src/ruby/lib/grpc/generic/interceptors.rb +186 -0
  237. data/src/ruby/lib/grpc/generic/rpc_desc.rb +66 -20
  238. data/src/ruby/lib/grpc/generic/rpc_server.rb +15 -3
  239. data/src/ruby/lib/grpc/google_rpc_status_utils.rb +1 -2
  240. data/src/ruby/lib/grpc/version.rb +1 -1
  241. data/src/ruby/pb/grpc/testing/duplicate/echo_duplicate_services_pb.rb +1 -0
  242. data/src/ruby/spec/channel_connection_spec.rb +1 -34
  243. data/src/ruby/spec/client_server_spec.rb +188 -82
  244. data/src/ruby/spec/generic/active_call_spec.rb +65 -11
  245. data/src/ruby/spec/generic/client_interceptors_spec.rb +153 -0
  246. data/src/ruby/spec/generic/interceptor_registry_spec.rb +65 -0
  247. data/src/ruby/spec/generic/rpc_desc_spec.rb +38 -0
  248. data/src/ruby/spec/generic/rpc_server_spec.rb +1 -34
  249. data/src/ruby/spec/generic/server_interceptors_spec.rb +218 -0
  250. data/src/ruby/spec/spec_helper.rb +4 -0
  251. data/src/ruby/spec/support/helpers.rb +73 -0
  252. data/src/ruby/spec/support/services.rb +147 -0
  253. data/third_party/cares/ares_build.h +21 -62
  254. data/third_party/cares/cares/ares.h +23 -1
  255. data/third_party/cares/cares/ares__close_sockets.c +2 -2
  256. data/third_party/cares/cares/ares_create_query.c +3 -3
  257. data/third_party/cares/cares/ares_expand_name.c +6 -2
  258. data/third_party/cares/cares/ares_expand_string.c +1 -1
  259. data/third_party/cares/cares/ares_getnameinfo.c +27 -7
  260. data/third_party/cares/cares/ares_init.c +407 -39
  261. data/third_party/cares/cares/ares_library_init.c +10 -0
  262. data/third_party/cares/cares/ares_library_init.h +2 -1
  263. data/third_party/cares/cares/ares_nowarn.c +6 -6
  264. data/third_party/cares/cares/ares_nowarn.h +2 -2
  265. data/third_party/cares/cares/ares_parse_naptr_reply.c +6 -1
  266. data/third_party/cares/cares/ares_private.h +11 -0
  267. data/third_party/cares/cares/ares_process.c +126 -37
  268. data/third_party/cares/cares/ares_version.h +2 -2
  269. data/third_party/cares/cares/ares_writev.c +2 -2
  270. data/third_party/cares/cares/config-win32.h +8 -34
  271. data/third_party/cares/cares/inet_net_pton.c +2 -2
  272. data/third_party/cares/cares/setup_once.h +5 -5
  273. data/third_party/cares/config_darwin/ares_config.h +98 -196
  274. data/third_party/cares/config_linux/ares_config.h +103 -203
  275. metadata +47 -20
  276. data/src/core/lib/iomgr/ev_epoll_limited_pollers_linux.c +0 -1957
  277. data/src/core/lib/iomgr/ev_epoll_thread_pool_linux.c +0 -1182
@@ -47,43 +47,85 @@ module GRPC
47
47
  proc { |o| unmarshal_class.method(unmarshal_method).call(o) }
48
48
  end
49
49
 
50
- def handle_request_response(active_call, mth)
50
+ def handle_request_response(active_call, mth, inter_ctx)
51
51
  req = active_call.read_unary_request
52
- resp = mth.call(req, active_call.single_req_view)
53
- active_call.server_unary_response(
54
- resp, trailing_metadata: active_call.output_metadata)
52
+ call = active_call.single_req_view
53
+
54
+ inter_ctx.intercept!(
55
+ :request_response,
56
+ method: mth,
57
+ call: call,
58
+ request: req
59
+ ) do
60
+ resp = mth.call(req, call)
61
+ active_call.server_unary_response(
62
+ resp,
63
+ trailing_metadata: active_call.output_metadata
64
+ )
65
+ end
55
66
  end
56
67
 
57
- def handle_client_streamer(active_call, mth)
58
- resp = mth.call(active_call.multi_req_view)
59
- active_call.server_unary_response(
60
- resp, trailing_metadata: active_call.output_metadata)
68
+ def handle_client_streamer(active_call, mth, inter_ctx)
69
+ call = active_call.multi_req_view
70
+
71
+ inter_ctx.intercept!(
72
+ :client_streamer,
73
+ method: mth,
74
+ call: call
75
+ ) do
76
+ resp = mth.call(call)
77
+ active_call.server_unary_response(
78
+ resp,
79
+ trailing_metadata: active_call.output_metadata
80
+ )
81
+ end
61
82
  end
62
83
 
63
- def handle_server_streamer(active_call, mth)
84
+ def handle_server_streamer(active_call, mth, inter_ctx)
64
85
  req = active_call.read_unary_request
65
- replys = mth.call(req, active_call.single_req_view)
66
- replys.each { |r| active_call.remote_send(r) }
67
- send_status(active_call, OK, 'OK', active_call.output_metadata)
86
+ call = active_call.single_req_view
87
+
88
+ inter_ctx.intercept!(
89
+ :server_streamer,
90
+ method: mth,
91
+ call: call,
92
+ request: req
93
+ ) do
94
+ replies = mth.call(req, call)
95
+ replies.each { |r| active_call.remote_send(r) }
96
+ send_status(active_call, OK, 'OK', active_call.output_metadata)
97
+ end
68
98
  end
69
99
 
70
- def handle_bidi_streamer(active_call, mth)
71
- active_call.run_server_bidi(mth)
100
+ ##
101
+ # @param [GRPC::ActiveCall] active_call
102
+ # @param [Method] mth
103
+ # @param [Array<GRPC::InterceptionContext>] inter_ctx
104
+ #
105
+ def handle_bidi_streamer(active_call, mth, inter_ctx)
106
+ active_call.run_server_bidi(mth, inter_ctx)
72
107
  send_status(active_call, OK, 'OK', active_call.output_metadata)
73
108
  end
74
109
 
75
- def run_server_method(active_call, mth)
110
+ ##
111
+ # @param [GRPC::ActiveCall] active_call The current active call object
112
+ # for the request
113
+ # @param [Method] mth The current RPC method being called
114
+ # @param [GRPC::InterceptionContext] inter_ctx The interception context
115
+ # being executed
116
+ #
117
+ def run_server_method(active_call, mth, inter_ctx = InterceptionContext.new)
76
118
  # While a server method is running, it might be cancelled, its deadline
77
119
  # might be reached, the handler could throw an unknown error, or a
78
120
  # well-behaved handler could throw a StatusError.
79
121
  if request_response?
80
- handle_request_response(active_call, mth)
122
+ handle_request_response(active_call, mth, inter_ctx)
81
123
  elsif client_streamer?
82
- handle_client_streamer(active_call, mth)
124
+ handle_client_streamer(active_call, mth, inter_ctx)
83
125
  elsif server_streamer?
84
- handle_server_streamer(active_call, mth)
126
+ handle_server_streamer(active_call, mth, inter_ctx)
85
127
  else # is a bidi_stream
86
- handle_bidi_streamer(active_call, mth)
128
+ handle_bidi_streamer(active_call, mth, inter_ctx)
87
129
  end
88
130
  rescue BadStatus => e
89
131
  # this is raised by handlers that want GRPC to send an application error
@@ -99,9 +141,13 @@ module GRPC
99
141
  # event. Send a status of deadline exceeded
100
142
  GRPC.logger.warn("late call: #{active_call}")
101
143
  send_status(active_call, DEADLINE_EXCEEDED, 'late')
102
- rescue StandardError => e
144
+ rescue StandardError, NotImplementedError => e
103
145
  # This will usuaally be an unhandled error in the handling code.
104
146
  # Send back a UNKNOWN status to the client
147
+ #
148
+ # Note: this intentionally does not map NotImplementedError to
149
+ # UNIMPLEMENTED because NotImplementedError is intended for low-level
150
+ # OS interaction (e.g. syscalls) not supported by the current OS.
105
151
  GRPC.logger.warn("failed handler: #{active_call}; sending status:UNKNOWN")
106
152
  GRPC.logger.warn(e)
107
153
  send_status(active_call, UNKNOWN, "#{e.class}: #{e.message}")
@@ -196,11 +196,18 @@ module GRPC
196
196
  #
197
197
  # * server_args:
198
198
  # A server arguments hash to be passed down to the underlying core server
199
+ #
200
+ # * interceptors:
201
+ # Am array of GRPC::ServerInterceptor objects that will be used for
202
+ # intercepting server handlers to provide extra functionality.
203
+ # Interceptors are an EXPERIMENTAL API.
204
+ #
199
205
  def initialize(pool_size:DEFAULT_POOL_SIZE,
200
206
  max_waiting_requests:DEFAULT_MAX_WAITING_REQUESTS,
201
207
  poll_period:DEFAULT_POLL_PERIOD,
202
208
  connect_md_proc:nil,
203
- server_args:{})
209
+ server_args:{},
210
+ interceptors:[])
204
211
  @connect_md_proc = RpcServer.setup_connect_md_proc(connect_md_proc)
205
212
  @max_waiting_requests = max_waiting_requests
206
213
  @poll_period = poll_period
@@ -212,6 +219,7 @@ module GRPC
212
219
  # :stopped. State transitions can only proceed in that order.
213
220
  @running_state = :not_started
214
221
  @server = Core::Server.new(server_args)
222
+ @interceptors = InterceptorRegistry.new(interceptors)
215
223
  end
216
224
 
217
225
  # stops a running server
@@ -374,7 +382,11 @@ module GRPC
374
382
  @pool.schedule(active_call) do |ac|
375
383
  c, mth = ac
376
384
  begin
377
- rpc_descs[mth].run_server_method(c, rpc_handlers[mth])
385
+ rpc_descs[mth].run_server_method(
386
+ c,
387
+ rpc_handlers[mth],
388
+ @interceptors.build_context
389
+ )
378
390
  rescue StandardError
379
391
  c.send_status(GRPC::Core::StatusCodes::INTERNAL,
380
392
  'Server handler failed')
@@ -382,7 +394,7 @@ module GRPC
382
394
  end
383
395
  end
384
396
  rescue Core::CallError, RuntimeError => e
385
- # these might happen for various reasonse. The correct behaviour of
397
+ # these might happen for various reasons. The correct behavior of
386
398
  # the server is to log them and continue, if it's not shutting down.
387
399
  if running_state == :running
388
400
  GRPC.logger.warn("server call failed: #{e}")
@@ -29,8 +29,7 @@ module GRPC
29
29
  fail ArgumentError, 'bad type' unless status.is_a? Struct::Status
30
30
  grpc_status_details_bin_trailer = 'grpc-status-details-bin'
31
31
  return nil if status.metadata[grpc_status_details_bin_trailer].nil?
32
- Google::Rpc::Status.decode(
33
- status.metadata[grpc_status_details_bin_trailer])
32
+ Google::Rpc::Status.decode(status.metadata[grpc_status_details_bin_trailer])
34
33
  end
35
34
  end
36
35
  end
@@ -14,5 +14,5 @@
14
14
 
15
15
  # GRPC contains the General RPC module.
16
16
  module GRPC
17
- VERSION = '1.6.7'
17
+ VERSION = '1.7.0.pre1'
18
18
  end
@@ -34,6 +34,7 @@ module Grpc
34
34
  self.service_name = 'grpc.testing.duplicate.EchoTestService'
35
35
 
36
36
  rpc :Echo, Grpc::Testing::EchoRequest, Grpc::Testing::EchoResponse
37
+ rpc :ResponseStream, Grpc::Testing::EchoRequest, stream(Grpc::Testing::EchoResponse)
37
38
  end
38
39
 
39
40
  Stub = Service.rpc_stub_class
@@ -11,45 +11,12 @@
11
11
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
-
15
- require 'grpc'
14
+ require 'spec_helper'
16
15
  require 'timeout'
17
16
 
18
17
  include Timeout
19
18
  include GRPC::Core
20
19
 
21
- # A test message
22
- class EchoMsg
23
- def self.marshal(_o)
24
- ''
25
- end
26
-
27
- def self.unmarshal(_o)
28
- EchoMsg.new
29
- end
30
- end
31
-
32
- # A test service with an echo implementation.
33
- class EchoService
34
- include GRPC::GenericService
35
- rpc :an_rpc, EchoMsg, EchoMsg
36
- attr_reader :received_md
37
-
38
- def initialize(**kw)
39
- @trailing_metadata = kw
40
- @received_md = []
41
- end
42
-
43
- def an_rpc(req, call)
44
- GRPC.logger.info('echo service received a request')
45
- call.output_metadata.update(@trailing_metadata)
46
- @received_md << call.metadata unless call.metadata.nil?
47
- req
48
- end
49
- end
50
-
51
- EchoStub = EchoService.rpc_stub_class
52
-
53
20
  def start_server(port = 0)
54
21
  @srv = GRPC::RpcServer.new(pool_size: 1)
55
22
  server_port = @srv.add_http2_port("localhost:#{port}", :this_port_is_insecure)
@@ -29,14 +29,18 @@ shared_context 'setup: tags' do
29
29
  expect(recvd_rpc).to_not eq nil
30
30
  server_call = recvd_rpc.call
31
31
  ops = { CallOps::SEND_INITIAL_METADATA => metadata }
32
- svr_batch = server_call.run_batch(ops)
33
- expect(svr_batch.send_metadata).to be true
32
+ server_batch = server_call.run_batch(ops)
33
+ expect(server_batch.send_metadata).to be true
34
34
  server_call
35
35
  end
36
36
 
37
37
  def new_client_call
38
38
  @ch.create_call(nil, nil, '/method', nil, deadline)
39
39
  end
40
+
41
+ def ok_status
42
+ Struct::Status.new(StatusCodes::OK, 'OK')
43
+ end
40
44
  end
41
45
 
42
46
  shared_examples 'basic GRPC message delivery is OK' do
@@ -70,19 +74,32 @@ shared_examples 'basic GRPC message delivery is OK' do
70
74
 
71
75
  client_ops = {
72
76
  CallOps::SEND_INITIAL_METADATA => {},
73
- CallOps::SEND_MESSAGE => sent_message
77
+ CallOps::SEND_MESSAGE => sent_message,
78
+ CallOps::SEND_CLOSE_FROM_CLIENT => nil
74
79
  }
75
- batch_result = call.run_batch(client_ops)
76
- expect(batch_result.send_metadata).to be true
77
- expect(batch_result.send_message).to be true
80
+ client_batch = call.run_batch(client_ops)
81
+ expect(client_batch.send_metadata).to be true
82
+ expect(client_batch.send_message).to be true
83
+ expect(client_batch.send_close).to be true
78
84
 
79
85
  # confirm the server can read the inbound message
80
86
  server_thread.join
81
87
  server_ops = {
82
- CallOps::RECV_MESSAGE => nil
88
+ CallOps::RECV_MESSAGE => nil,
89
+ CallOps::RECV_CLOSE_ON_SERVER => nil,
90
+ CallOps::SEND_STATUS_FROM_SERVER => ok_status
83
91
  }
84
- svr_batch = server_call.run_batch(server_ops)
85
- expect(svr_batch.message).to eq(sent_message)
92
+ server_batch = server_call.run_batch(server_ops)
93
+ expect(server_batch.message).to eq(sent_message)
94
+ expect(server_batch.send_close).to be true
95
+ expect(server_batch.send_status).to be true
96
+
97
+ # finish the call
98
+ final_client_batch = call.run_batch(
99
+ CallOps::RECV_INITIAL_METADATA => nil,
100
+ CallOps::RECV_STATUS_ON_CLIENT => nil)
101
+ expect(final_client_batch.metadata).to eq({})
102
+ expect(final_client_batch.status.code).to eq(0)
86
103
  end
87
104
 
88
105
  it 'responses written by servers are received by the client' do
@@ -95,21 +112,36 @@ shared_examples 'basic GRPC message delivery is OK' do
95
112
 
96
113
  client_ops = {
97
114
  CallOps::SEND_INITIAL_METADATA => {},
98
- CallOps::SEND_MESSAGE => sent_message
115
+ CallOps::SEND_MESSAGE => sent_message,
116
+ CallOps::SEND_CLOSE_FROM_CLIENT => nil
99
117
  }
100
- batch_result = call.run_batch(client_ops)
101
- expect(batch_result.send_metadata).to be true
102
- expect(batch_result.send_message).to be true
118
+ client_batch = call.run_batch(client_ops)
119
+ expect(client_batch.send_metadata).to be true
120
+ expect(client_batch.send_message).to be true
121
+ expect(client_batch.send_close).to be true
103
122
 
104
123
  # confirm the server can read the inbound message
105
124
  server_thread.join
106
125
  server_ops = {
107
126
  CallOps::RECV_MESSAGE => nil,
108
- CallOps::SEND_MESSAGE => reply_text
127
+ CallOps::RECV_CLOSE_ON_SERVER => nil,
128
+ CallOps::SEND_MESSAGE => reply_text,
129
+ CallOps::SEND_STATUS_FROM_SERVER => ok_status
109
130
  }
110
- svr_batch = server_call.run_batch(server_ops)
111
- expect(svr_batch.message).to eq(sent_message)
112
- expect(svr_batch.send_message).to be true
131
+ server_batch = server_call.run_batch(server_ops)
132
+ expect(server_batch.message).to eq(sent_message)
133
+ expect(server_batch.send_close).to be true
134
+ expect(server_batch.send_message).to be true
135
+ expect(server_batch.send_status).to be true
136
+
137
+ # finish the call
138
+ final_client_batch = call.run_batch(
139
+ CallOps::RECV_INITIAL_METADATA => nil,
140
+ CallOps::RECV_MESSAGE => nil,
141
+ CallOps::RECV_STATUS_ON_CLIENT => nil)
142
+ expect(final_client_batch.metadata).to eq({})
143
+ expect(final_client_batch.message).to eq(reply_text)
144
+ expect(final_client_batch.status.code).to eq(0)
113
145
  end
114
146
 
115
147
  it 'compressed messages can be sent and received' do
@@ -125,30 +157,37 @@ shared_examples 'basic GRPC message delivery is OK' do
125
157
 
126
158
  client_ops = {
127
159
  CallOps::SEND_INITIAL_METADATA => md,
128
- CallOps::SEND_MESSAGE => long_request_str
160
+ CallOps::SEND_MESSAGE => long_request_str,
161
+ CallOps::SEND_CLOSE_FROM_CLIENT => nil
129
162
  }
130
- batch_result = call.run_batch(client_ops)
131
- expect(batch_result.send_metadata).to be true
132
- expect(batch_result.send_message).to be true
163
+ client_batch = call.run_batch(client_ops)
164
+ expect(client_batch.send_metadata).to be true
165
+ expect(client_batch.send_message).to be true
166
+ expect(client_batch.send_close).to be true
133
167
 
134
168
  # confirm the server can read the inbound message
135
169
  server_thread.join
136
170
  server_ops = {
137
171
  CallOps::RECV_MESSAGE => nil,
138
- CallOps::SEND_MESSAGE => long_response_str
172
+ CallOps::RECV_CLOSE_ON_SERVER => nil,
173
+ CallOps::SEND_MESSAGE => long_response_str,
174
+ CallOps::SEND_STATUS_FROM_SERVER => ok_status
139
175
  }
140
- svr_batch = server_call.run_batch(server_ops)
141
- expect(svr_batch.message).to eq(long_request_str)
142
- expect(svr_batch.send_message).to be true
176
+ server_batch = server_call.run_batch(server_ops)
177
+ expect(server_batch.message).to eq(long_request_str)
178
+ expect(server_batch.send_close).to be true
179
+ expect(server_batch.send_message).to be true
180
+ expect(server_batch.send_status).to be true
143
181
 
144
182
  client_ops = {
145
- CallOps::SEND_CLOSE_FROM_CLIENT => nil,
146
183
  CallOps::RECV_INITIAL_METADATA => nil,
147
- CallOps::RECV_MESSAGE => nil
184
+ CallOps::RECV_MESSAGE => nil,
185
+ CallOps::RECV_STATUS_ON_CLIENT => nil
148
186
  }
149
- batch_result = call.run_batch(client_ops)
150
- expect(batch_result.send_close).to be true
151
- expect(batch_result.message).to eq long_response_str
187
+ final_client_batch = call.run_batch(client_ops)
188
+ expect(final_client_batch.metadata).to eq({})
189
+ expect(final_client_batch.message).to eq long_response_str
190
+ expect(final_client_batch.status.code).to eq(0)
152
191
  end
153
192
 
154
193
  it 'servers can ignore a client write and send a status' do
@@ -161,11 +200,13 @@ shared_examples 'basic GRPC message delivery is OK' do
161
200
 
162
201
  client_ops = {
163
202
  CallOps::SEND_INITIAL_METADATA => {},
164
- CallOps::SEND_MESSAGE => sent_message
203
+ CallOps::SEND_MESSAGE => sent_message,
204
+ CallOps::SEND_CLOSE_FROM_CLIENT => nil
165
205
  }
166
- batch_result = call.run_batch(client_ops)
167
- expect(batch_result.send_metadata).to be true
168
- expect(batch_result.send_message).to be true
206
+ client_batch = call.run_batch(client_ops)
207
+ expect(client_batch.send_metadata).to be true
208
+ expect(client_batch.send_message).to be true
209
+ expect(client_batch.send_close).to be true
169
210
 
170
211
  # confirm the server can read the inbound message
171
212
  the_status = Struct::Status.new(StatusCodes::OK, 'OK')
@@ -173,9 +214,15 @@ shared_examples 'basic GRPC message delivery is OK' do
173
214
  server_ops = {
174
215
  CallOps::SEND_STATUS_FROM_SERVER => the_status
175
216
  }
176
- svr_batch = server_call.run_batch(server_ops)
177
- expect(svr_batch.message).to eq nil
178
- expect(svr_batch.send_status).to be true
217
+ server_batch = server_call.run_batch(server_ops)
218
+ expect(server_batch.message).to eq nil
219
+ expect(server_batch.send_status).to be true
220
+
221
+ final_client_batch = call.run_batch(
222
+ CallOps::RECV_INITIAL_METADATA => nil,
223
+ CallOps::RECV_STATUS_ON_CLIENT => nil)
224
+ expect(final_client_batch.metadata).to eq({})
225
+ expect(final_client_batch.status.code).to eq(0)
179
226
  end
180
227
 
181
228
  it 'completes calls by sending status to client and server' do
@@ -190,9 +237,9 @@ shared_examples 'basic GRPC message delivery is OK' do
190
237
  CallOps::SEND_INITIAL_METADATA => {},
191
238
  CallOps::SEND_MESSAGE => sent_message
192
239
  }
193
- batch_result = call.run_batch(client_ops)
194
- expect(batch_result.send_metadata).to be true
195
- expect(batch_result.send_message).to be true
240
+ client_batch = call.run_batch(client_ops)
241
+ expect(client_batch.send_metadata).to be true
242
+ expect(client_batch.send_message).to be true
196
243
 
197
244
  # confirm the server can read the inbound message and respond
198
245
  the_status = Struct::Status.new(StatusCodes::OK, 'OK', {})
@@ -202,10 +249,10 @@ shared_examples 'basic GRPC message delivery is OK' do
202
249
  CallOps::SEND_MESSAGE => reply_text,
203
250
  CallOps::SEND_STATUS_FROM_SERVER => the_status
204
251
  }
205
- svr_batch = server_call.run_batch(server_ops)
206
- expect(svr_batch.message).to eq sent_message
207
- expect(svr_batch.send_status).to be true
208
- expect(svr_batch.send_message).to be true
252
+ server_batch = server_call.run_batch(server_ops)
253
+ expect(server_batch.message).to eq sent_message
254
+ expect(server_batch.send_status).to be true
255
+ expect(server_batch.send_message).to be true
209
256
 
210
257
  # confirm the client can receive the server response and status.
211
258
  client_ops = {
@@ -214,17 +261,17 @@ shared_examples 'basic GRPC message delivery is OK' do
214
261
  CallOps::RECV_MESSAGE => nil,
215
262
  CallOps::RECV_STATUS_ON_CLIENT => nil
216
263
  }
217
- batch_result = call.run_batch(client_ops)
218
- expect(batch_result.send_close).to be true
219
- expect(batch_result.message).to eq reply_text
220
- expect(batch_result.status).to eq the_status
264
+ final_client_batch = call.run_batch(client_ops)
265
+ expect(final_client_batch.send_close).to be true
266
+ expect(final_client_batch.message).to eq reply_text
267
+ expect(final_client_batch.status).to eq the_status
221
268
 
222
269
  # confirm the server can receive the client close.
223
270
  server_ops = {
224
271
  CallOps::RECV_CLOSE_ON_SERVER => nil
225
272
  }
226
- svr_batch = server_call.run_batch(server_ops)
227
- expect(svr_batch.send_close).to be true
273
+ final_server_batch = server_call.run_batch(server_ops)
274
+ expect(final_server_batch.send_close).to be true
228
275
  end
229
276
 
230
277
  def client_cancel_test(cancel_proc, expected_code,
@@ -240,9 +287,9 @@ shared_examples 'basic GRPC message delivery is OK' do
240
287
  CallOps::SEND_INITIAL_METADATA => {},
241
288
  CallOps::RECV_INITIAL_METADATA => nil
242
289
  }
243
- batch_result = call.run_batch(client_ops)
244
- expect(batch_result.send_metadata).to be true
245
- expect(batch_result.metadata).to eq({})
290
+ client_batch = call.run_batch(client_ops)
291
+ expect(client_batch.send_metadata).to be true
292
+ expect(client_batch.metadata).to eq({})
246
293
 
247
294
  cancel_proc.call(call)
248
295
 
@@ -250,16 +297,16 @@ shared_examples 'basic GRPC message delivery is OK' do
250
297
  server_ops = {
251
298
  CallOps::RECV_CLOSE_ON_SERVER => nil
252
299
  }
253
- svr_batch = server_call.run_batch(server_ops)
254
- expect(svr_batch.send_close).to be true
300
+ server_batch = server_call.run_batch(server_ops)
301
+ expect(server_batch.send_close).to be true
255
302
 
256
303
  client_ops = {
257
304
  CallOps::RECV_STATUS_ON_CLIENT => {}
258
305
  }
259
- batch_result = call.run_batch(client_ops)
306
+ client_batch = call.run_batch(client_ops)
260
307
 
261
- expect(batch_result.status.code).to be expected_code
262
- expect(batch_result.status.details).to eq expected_details
308
+ expect(client_batch.status.code).to be expected_code
309
+ expect(client_batch.status.details).to eq expected_details
263
310
  end
264
311
 
265
312
  it 'clients can cancel a call on the server' do
@@ -325,10 +372,11 @@ shared_examples 'GRPC metadata delivery works OK' do
325
372
 
326
373
  call = new_client_call
327
374
  client_ops = {
328
- CallOps::SEND_INITIAL_METADATA => md
375
+ CallOps::SEND_INITIAL_METADATA => md,
376
+ CallOps::SEND_CLOSE_FROM_CLIENT => nil
329
377
  }
330
- batch_result = call.run_batch(client_ops)
331
- expect(batch_result.send_metadata).to be true
378
+ client_batch = call.run_batch(client_ops)
379
+ expect(client_batch.send_metadata).to be true
332
380
 
333
381
  # confirm the server can receive the client metadata
334
382
  rcv_thread.join
@@ -336,6 +384,21 @@ shared_examples 'GRPC metadata delivery works OK' do
336
384
  recvd_md = recvd_rpc.metadata
337
385
  replace_symbols = Hash[md.each_pair.collect { |x, y| [x.to_s, y] }]
338
386
  expect(recvd_md).to eq(recvd_md.merge(replace_symbols))
387
+
388
+ # finish the call
389
+ final_server_batch = recvd_rpc.call.run_batch(
390
+ CallOps::RECV_CLOSE_ON_SERVER => nil,
391
+ CallOps::SEND_INITIAL_METADATA => nil,
392
+ CallOps::SEND_STATUS_FROM_SERVER => ok_status)
393
+ expect(final_server_batch.send_close).to be(true)
394
+ expect(final_server_batch.send_metadata).to be(true)
395
+ expect(final_server_batch.send_status).to be(true)
396
+
397
+ final_client_batch = call.run_batch(
398
+ CallOps::RECV_INITIAL_METADATA => nil,
399
+ CallOps::RECV_STATUS_ON_CLIENT => nil)
400
+ expect(final_client_batch.metadata).to eq({})
401
+ expect(final_client_batch.status.code).to eq(0)
339
402
  end
340
403
  end
341
404
  end
@@ -381,6 +444,9 @@ shared_examples 'GRPC metadata delivery works OK' do
381
444
  recvd_rpc.call.run_batch(server_ops)
382
445
  end
383
446
  expect(&blk).to raise_error
447
+
448
+ # cancel the call so the server can shut down immediately
449
+ call.cancel
384
450
  end
385
451
  end
386
452
 
@@ -394,25 +460,37 @@ shared_examples 'GRPC metadata delivery works OK' do
394
460
  # client signals that it's done sending metadata to allow server to
395
461
  # respond
396
462
  client_ops = {
397
- CallOps::SEND_INITIAL_METADATA => nil
463
+ CallOps::SEND_INITIAL_METADATA => nil,
464
+ CallOps::SEND_CLOSE_FROM_CLIENT => nil
398
465
  }
399
- call.run_batch(client_ops)
466
+ client_batch = call.run_batch(client_ops)
467
+ expect(client_batch.send_metadata).to be true
468
+ expect(client_batch.send_close).to be true
400
469
 
401
470
  # server gets the invocation but sends no metadata back
402
471
  rcv_thread.join
403
472
  expect(recvd_rpc).to_not eq nil
404
473
  server_call = recvd_rpc.call
405
474
  server_ops = {
406
- CallOps::SEND_INITIAL_METADATA => nil
475
+ # receive close and send status to finish the call
476
+ CallOps::RECV_CLOSE_ON_SERVER => nil,
477
+ CallOps::SEND_INITIAL_METADATA => nil,
478
+ CallOps::SEND_STATUS_FROM_SERVER => ok_status
407
479
  }
408
- server_call.run_batch(server_ops)
480
+ srv_batch = server_call.run_batch(server_ops)
481
+ expect(srv_batch.send_close).to be true
482
+ expect(srv_batch.send_metadata).to be true
483
+ expect(srv_batch.send_status).to be true
409
484
 
410
485
  # client receives nothing as expected
411
486
  client_ops = {
412
- CallOps::RECV_INITIAL_METADATA => nil
487
+ CallOps::RECV_INITIAL_METADATA => nil,
488
+ # receive status to finish the call
489
+ CallOps::RECV_STATUS_ON_CLIENT => nil
413
490
  }
414
- batch_result = call.run_batch(client_ops)
415
- expect(batch_result.metadata).to eq({})
491
+ final_client_batch = call.run_batch(client_ops)
492
+ expect(final_client_batch.metadata).to eq({})
493
+ expect(final_client_batch.status.code).to eq(0)
416
494
  end
417
495
 
418
496
  it 'sends all the pairs when keys and values are valid' do
@@ -426,26 +504,36 @@ shared_examples 'GRPC metadata delivery works OK' do
426
504
  # client signals that it's done sending metadata to allow server to
427
505
  # respond
428
506
  client_ops = {
429
- CallOps::SEND_INITIAL_METADATA => nil
507
+ CallOps::SEND_INITIAL_METADATA => nil,
508
+ CallOps::SEND_CLOSE_FROM_CLIENT => nil
430
509
  }
431
- call.run_batch(client_ops)
510
+ client_batch = call.run_batch(client_ops)
511
+ expect(client_batch.send_metadata).to be true
512
+ expect(client_batch.send_close).to be true
432
513
 
433
514
  # server gets the invocation but sends no metadata back
434
515
  rcv_thread.join
435
516
  expect(recvd_rpc).to_not eq nil
436
517
  server_call = recvd_rpc.call
437
518
  server_ops = {
438
- CallOps::SEND_INITIAL_METADATA => md
519
+ CallOps::RECV_CLOSE_ON_SERVER => nil,
520
+ CallOps::SEND_INITIAL_METADATA => md,
521
+ CallOps::SEND_STATUS_FROM_SERVER => ok_status
439
522
  }
440
- server_call.run_batch(server_ops)
523
+ srv_batch = server_call.run_batch(server_ops)
524
+ expect(srv_batch.send_close).to be true
525
+ expect(srv_batch.send_metadata).to be true
526
+ expect(srv_batch.send_status).to be true
441
527
 
442
528
  # client receives nothing as expected
443
529
  client_ops = {
444
- CallOps::RECV_INITIAL_METADATA => nil
530
+ CallOps::RECV_INITIAL_METADATA => nil,
531
+ CallOps::RECV_STATUS_ON_CLIENT => nil
445
532
  }
446
- batch_result = call.run_batch(client_ops)
533
+ final_client_batch = call.run_batch(client_ops)
447
534
  replace_symbols = Hash[md.each_pair.collect { |x, y| [x.to_s, y] }]
448
- expect(batch_result.metadata).to eq(replace_symbols)
535
+ expect(final_client_batch.metadata).to eq(replace_symbols)
536
+ expect(final_client_batch.status.code).to eq(0)
449
537
  end
450
538
  end
451
539
  end
@@ -510,8 +598,7 @@ describe 'the secure http client/server' do
510
598
 
511
599
  initial_md_key = 'k2'
512
600
  initial_md_val = 'v2'
513
- initial_md = {}
514
- initial_md[initial_md_key] = initial_md_val
601
+ initial_md = { initial_md_key => initial_md_val }
515
602
  expected_md = creds_update_md.clone
516
603
  fail 'bad test param' unless expected_md[initial_md_key].nil?
517
604
  expected_md[initial_md_key] = initial_md_val
@@ -523,11 +610,12 @@ describe 'the secure http client/server' do
523
610
 
524
611
  call = new_client_call
525
612
  call.set_credentials! call_creds
526
- client_ops = {
527
- CallOps::SEND_INITIAL_METADATA => initial_md
528
- }
529
- batch_result = call.run_batch(client_ops)
530
- expect(batch_result.send_metadata).to be true
613
+
614
+ client_batch = call.run_batch(
615
+ CallOps::SEND_INITIAL_METADATA => initial_md,
616
+ CallOps::SEND_CLOSE_FROM_CLIENT => nil)
617
+ expect(client_batch.send_metadata).to be true
618
+ expect(client_batch.send_close).to be true
531
619
 
532
620
  # confirm the server can receive the client metadata
533
621
  rcv_thread.join
@@ -535,6 +623,24 @@ describe 'the secure http client/server' do
535
623
  recvd_md = recvd_rpc.metadata
536
624
  replace_symbols = Hash[expected_md.each_pair.collect { |x, y| [x.to_s, y] }]
537
625
  expect(recvd_md).to eq(recvd_md.merge(replace_symbols))
626
+
627
+ credentials_update_test_finish_call(call, recvd_rpc.call)
628
+ end
629
+
630
+ def credentials_update_test_finish_call(client_call, server_call)
631
+ final_server_batch = server_call.run_batch(
632
+ CallOps::RECV_CLOSE_ON_SERVER => nil,
633
+ CallOps::SEND_INITIAL_METADATA => nil,
634
+ CallOps::SEND_STATUS_FROM_SERVER => ok_status)
635
+ expect(final_server_batch.send_close).to be(true)
636
+ expect(final_server_batch.send_metadata).to be(true)
637
+ expect(final_server_batch.send_status).to be(true)
638
+
639
+ final_client_batch = client_call.run_batch(
640
+ CallOps::RECV_INITIAL_METADATA => nil,
641
+ CallOps::RECV_STATUS_ON_CLIENT => nil)
642
+ expect(final_client_batch.metadata).to eq({})
643
+ expect(final_client_batch.status.code).to eq(0)
538
644
  end
539
645
 
540
646
  it 'modifies metadata with CallCredentials' do