grpc 1.60.2 → 1.61.0.pre2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (279) hide show
  1. checksums.yaml +4 -4
  2. data/Makefile +208 -165
  3. data/include/grpc/event_engine/event_engine.h +59 -12
  4. data/include/grpc/event_engine/internal/memory_allocator_impl.h +6 -0
  5. data/include/grpc/event_engine/internal/slice_cast.h +12 -0
  6. data/include/grpc/event_engine/memory_allocator.h +3 -1
  7. data/include/grpc/event_engine/slice.h +5 -0
  8. data/include/grpc/grpc_security.h +22 -1
  9. data/include/grpc/impl/call.h +29 -0
  10. data/include/grpc/impl/channel_arg_names.h +12 -1
  11. data/include/grpc/impl/slice_type.h +1 -1
  12. data/include/grpc/module.modulemap +1 -0
  13. data/src/core/ext/filters/backend_metrics/backend_metric_filter.cc +54 -7
  14. data/src/core/ext/filters/backend_metrics/backend_metric_filter.h +20 -6
  15. data/src/core/ext/filters/channel_idle/channel_idle_filter.cc +10 -13
  16. data/src/core/ext/filters/channel_idle/channel_idle_filter.h +18 -10
  17. data/src/core/ext/filters/channel_idle/legacy_channel_idle_filter.cc +326 -0
  18. data/src/core/ext/filters/channel_idle/legacy_channel_idle_filter.h +143 -0
  19. data/src/core/ext/filters/client_channel/backend_metric.cc +2 -2
  20. data/src/core/ext/filters/client_channel/client_channel.cc +32 -6
  21. data/src/core/ext/filters/client_channel/client_channel_internal.h +2 -0
  22. data/src/core/ext/filters/client_channel/global_subchannel_pool.cc +1 -1
  23. data/src/core/ext/filters/client_channel/lb_policy/address_filtering.cc +54 -21
  24. data/src/core/ext/filters/client_channel/lb_policy/address_filtering.h +3 -2
  25. data/src/core/ext/filters/client_channel/lb_policy/child_policy_handler.cc +2 -1
  26. data/src/core/ext/filters/client_channel/lb_policy/endpoint_list.cc +12 -15
  27. data/src/core/ext/filters/client_channel/lb_policy/endpoint_list.h +8 -5
  28. data/src/core/ext/filters/client_channel/lb_policy/grpclb/grpclb.cc +139 -92
  29. data/src/core/ext/filters/client_channel/lb_policy/health_check_client.cc +9 -4
  30. data/src/core/ext/filters/client_channel/lb_policy/oob_backend_metric.cc +9 -4
  31. data/src/core/ext/filters/client_channel/lb_policy/outlier_detection/outlier_detection.cc +10 -11
  32. data/src/core/ext/filters/client_channel/lb_policy/pick_first/pick_first.cc +94 -93
  33. data/src/core/ext/filters/client_channel/lb_policy/priority/priority.cc +5 -3
  34. data/src/core/ext/filters/client_channel/lb_policy/ring_hash/ring_hash.cc +12 -15
  35. data/src/core/ext/filters/client_channel/lb_policy/rls/rls.cc +38 -16
  36. data/src/core/ext/filters/client_channel/lb_policy/round_robin/round_robin.cc +25 -28
  37. data/src/core/ext/filters/client_channel/lb_policy/subchannel_list.h +10 -10
  38. data/src/core/ext/filters/client_channel/lb_policy/weighted_round_robin/weighted_round_robin.cc +37 -35
  39. data/src/core/ext/filters/client_channel/lb_policy/weighted_target/weighted_target.cc +11 -9
  40. data/src/core/ext/filters/client_channel/lb_policy/xds/cds.cc +504 -461
  41. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_impl.cc +232 -122
  42. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_manager.cc +8 -6
  43. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_override_host.cc +642 -251
  44. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_override_host.h +2 -6
  45. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_wrr_locality.cc +7 -8
  46. data/src/core/ext/filters/client_channel/resolver/dns/c_ares/dns_resolver_ares.cc +2 -1
  47. data/src/core/ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.cc +3 -1
  48. data/src/core/ext/filters/client_channel/resolver/fake/fake_resolver.cc +2 -2
  49. data/src/core/ext/filters/client_channel/resolver/google_c2p/google_c2p_resolver.cc +2 -2
  50. data/src/core/ext/filters/client_channel/resolver/polling_resolver.cc +6 -8
  51. data/src/core/ext/filters/client_channel/resolver/xds/xds_dependency_manager.cc +1031 -0
  52. data/src/core/ext/filters/client_channel/resolver/xds/xds_dependency_manager.h +277 -0
  53. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver.cc +128 -270
  54. data/src/core/ext/filters/client_channel/resolver/xds/{xds_resolver.h → xds_resolver_attributes.h} +5 -4
  55. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver_trace.cc +25 -0
  56. data/src/core/ext/filters/client_channel/resolver/xds/xds_resolver_trace.h +30 -0
  57. data/src/core/ext/filters/client_channel/retry_filter.cc +1 -0
  58. data/src/core/ext/filters/client_channel/service_config_channel_arg_filter.cc +35 -17
  59. data/src/core/ext/filters/deadline/deadline_filter.cc +12 -0
  60. data/src/core/ext/filters/fault_injection/fault_injection_filter.cc +17 -13
  61. data/src/core/ext/filters/fault_injection/fault_injection_filter.h +13 -4
  62. data/src/core/ext/filters/http/client/http_client_filter.cc +23 -32
  63. data/src/core/ext/filters/http/client/http_client_filter.h +10 -5
  64. data/src/core/ext/filters/http/client_authority_filter.cc +14 -14
  65. data/src/core/ext/filters/http/client_authority_filter.h +12 -4
  66. data/src/core/ext/filters/http/http_filters_plugin.cc +42 -20
  67. data/src/core/ext/filters/http/message_compress/compression_filter.cc +55 -80
  68. data/src/core/ext/filters/http/message_compress/compression_filter.h +54 -12
  69. data/src/core/ext/filters/http/message_compress/legacy_compression_filter.cc +325 -0
  70. data/src/core/ext/filters/http/message_compress/legacy_compression_filter.h +139 -0
  71. data/src/core/ext/filters/http/server/http_server_filter.cc +41 -41
  72. data/src/core/ext/filters/http/server/http_server_filter.h +11 -4
  73. data/src/core/ext/filters/message_size/message_size_filter.cc +56 -76
  74. data/src/core/ext/filters/message_size/message_size_filter.h +35 -23
  75. data/src/core/ext/filters/rbac/rbac_filter.cc +15 -11
  76. data/src/core/ext/filters/rbac/rbac_filter.h +11 -4
  77. data/src/core/ext/filters/server_config_selector/server_config_selector_filter.cc +25 -13
  78. data/src/core/ext/filters/stateful_session/stateful_session_filter.cc +47 -50
  79. data/src/core/ext/filters/stateful_session/stateful_session_filter.h +21 -4
  80. data/src/core/ext/transport/chttp2/alpn/alpn.cc +1 -1
  81. data/src/core/ext/transport/chttp2/client/chttp2_connector.cc +2 -2
  82. data/src/core/ext/transport/chttp2/server/chttp2_server.cc +11 -2
  83. data/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +68 -145
  84. data/src/core/ext/transport/chttp2/transport/chttp2_transport.h +3 -3
  85. data/src/core/ext/transport/chttp2/transport/flow_control.cc +21 -82
  86. data/src/core/ext/transport/chttp2/transport/flow_control.h +1 -8
  87. data/src/core/ext/transport/chttp2/transport/frame.cc +506 -0
  88. data/src/core/ext/transport/chttp2/transport/frame.h +214 -0
  89. data/src/core/ext/transport/chttp2/transport/frame_rst_stream.cc +1 -1
  90. data/src/core/ext/transport/chttp2/transport/frame_settings.cc +33 -79
  91. data/src/core/ext/transport/chttp2/transport/frame_settings.h +4 -7
  92. data/src/core/ext/transport/chttp2/transport/hpack_parser.cc +27 -36
  93. data/src/core/ext/transport/chttp2/transport/hpack_parser.h +0 -2
  94. data/src/core/ext/transport/chttp2/transport/http2_settings.cc +122 -32
  95. data/src/core/ext/transport/chttp2/transport/http2_settings.h +142 -37
  96. data/src/core/ext/transport/chttp2/transport/internal.h +1 -22
  97. data/src/core/ext/transport/chttp2/transport/parsing.cc +23 -37
  98. data/src/core/ext/transport/chttp2/transport/writing.cc +26 -58
  99. data/src/core/ext/transport/inproc/inproc_transport.cc +172 -13
  100. data/src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb.h +712 -0
  101. data/src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.c +151 -0
  102. data/src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.h +33 -0
  103. data/src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.c +133 -0
  104. data/src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.h +50 -0
  105. data/src/core/ext/xds/certificate_provider_store.cc +2 -1
  106. data/src/core/ext/xds/certificate_provider_store.h +0 -5
  107. data/src/core/ext/xds/xds_api.cc +31 -18
  108. data/src/core/ext/xds/xds_api.h +2 -2
  109. data/src/core/ext/xds/xds_bootstrap.h +3 -0
  110. data/src/core/ext/xds/xds_certificate_provider.cc +88 -287
  111. data/src/core/ext/xds/xds_certificate_provider.h +44 -111
  112. data/src/core/ext/xds/xds_client.cc +420 -414
  113. data/src/core/ext/xds/xds_client.h +31 -22
  114. data/src/core/ext/xds/xds_client_grpc.cc +3 -1
  115. data/src/core/ext/xds/xds_cluster.cc +104 -11
  116. data/src/core/ext/xds/xds_cluster.h +9 -1
  117. data/src/core/ext/xds/xds_cluster_specifier_plugin.cc +9 -5
  118. data/src/core/ext/xds/xds_common_types.cc +14 -10
  119. data/src/core/ext/xds/xds_endpoint.cc +9 -4
  120. data/src/core/ext/xds/xds_endpoint.h +5 -1
  121. data/src/core/ext/xds/xds_health_status.cc +12 -2
  122. data/src/core/ext/xds/xds_health_status.h +4 -2
  123. data/src/core/ext/xds/xds_http_rbac_filter.cc +5 -3
  124. data/src/core/ext/xds/xds_listener.cc +14 -8
  125. data/src/core/ext/xds/xds_resource_type_impl.h +6 -4
  126. data/src/core/ext/xds/xds_route_config.cc +34 -22
  127. data/src/core/ext/xds/xds_route_config.h +1 -0
  128. data/src/core/ext/xds/xds_server_config_fetcher.cc +61 -57
  129. data/src/core/ext/xds/xds_transport.h +3 -0
  130. data/src/core/ext/xds/xds_transport_grpc.cc +47 -50
  131. data/src/core/ext/xds/xds_transport_grpc.h +4 -0
  132. data/src/core/lib/channel/call_tracer.cc +12 -0
  133. data/src/core/lib/channel/call_tracer.h +17 -3
  134. data/src/core/lib/channel/channel_args.cc +24 -14
  135. data/src/core/lib/channel/channel_args.h +74 -13
  136. data/src/core/lib/channel/channel_stack.cc +27 -0
  137. data/src/core/lib/channel/channel_stack.h +10 -10
  138. data/src/core/lib/channel/connected_channel.cc +64 -18
  139. data/src/core/lib/channel/promise_based_filter.h +1041 -1
  140. data/src/core/lib/channel/server_call_tracer_filter.cc +43 -35
  141. data/src/core/lib/compression/compression_internal.cc +0 -3
  142. data/src/core/lib/event_engine/ares_resolver.cc +35 -14
  143. data/src/core/lib/event_engine/ares_resolver.h +9 -10
  144. data/src/core/lib/event_engine/cf_engine/dns_service_resolver.cc +8 -1
  145. data/src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc +132 -0
  146. data/src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.h +61 -0
  147. data/src/core/lib/event_engine/posix_engine/posix_engine.cc +52 -36
  148. data/src/core/lib/event_engine/posix_engine/posix_engine.h +4 -9
  149. data/src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.cc +11 -3
  150. data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.cc +9 -2
  151. data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.h +7 -0
  152. data/src/core/lib/event_engine/posix_engine/timer_manager.cc +17 -27
  153. data/src/core/lib/event_engine/posix_engine/timer_manager.h +0 -3
  154. data/src/core/lib/event_engine/ref_counted_dns_resolver_interface.h +55 -0
  155. data/src/core/lib/event_engine/windows/native_windows_dns_resolver.cc +114 -0
  156. data/src/core/lib/event_engine/windows/native_windows_dns_resolver.h +51 -0
  157. data/src/core/lib/event_engine/windows/windows_engine.cc +7 -7
  158. data/src/core/lib/experiments/config.cc +13 -0
  159. data/src/core/lib/experiments/config.h +3 -0
  160. data/src/core/lib/experiments/experiments.cc +245 -366
  161. data/src/core/lib/experiments/experiments.h +50 -156
  162. data/src/core/lib/gprpp/debug_location.h +13 -0
  163. data/src/core/lib/gprpp/dual_ref_counted.h +36 -7
  164. data/src/core/lib/gprpp/orphanable.h +27 -0
  165. data/src/core/lib/gprpp/ref_counted.h +63 -22
  166. data/src/core/lib/gprpp/ref_counted_ptr.h +70 -27
  167. data/src/core/lib/gprpp/ref_counted_string.h +13 -0
  168. data/src/core/lib/gprpp/status_helper.cc +1 -2
  169. data/src/core/lib/iomgr/combiner.cc +15 -51
  170. data/src/core/lib/iomgr/event_engine_shims/endpoint.cc +31 -0
  171. data/src/core/lib/iomgr/event_engine_shims/endpoint.h +16 -0
  172. data/src/core/lib/iomgr/tcp_client_posix.cc +4 -3
  173. data/src/core/lib/load_balancing/lb_policy.h +1 -1
  174. data/src/core/lib/promise/activity.cc +17 -2
  175. data/src/core/lib/promise/activity.h +5 -4
  176. data/src/core/lib/promise/all_ok.h +80 -0
  177. data/src/core/lib/promise/detail/join_state.h +2077 -0
  178. data/src/core/lib/promise/detail/promise_factory.h +1 -0
  179. data/src/core/lib/promise/detail/promise_like.h +8 -1
  180. data/src/core/lib/promise/detail/seq_state.h +3458 -150
  181. data/src/core/lib/promise/detail/status.h +42 -5
  182. data/src/core/lib/promise/for_each.h +13 -1
  183. data/src/core/lib/promise/if.h +4 -0
  184. data/src/core/lib/promise/latch.h +6 -3
  185. data/src/core/lib/promise/party.cc +33 -31
  186. data/src/core/lib/promise/party.h +142 -6
  187. data/src/core/lib/promise/poll.h +39 -13
  188. data/src/core/lib/promise/promise.h +4 -0
  189. data/src/core/lib/promise/seq.h +107 -7
  190. data/src/core/lib/promise/status_flag.h +196 -0
  191. data/src/core/lib/promise/try_join.h +132 -0
  192. data/src/core/lib/promise/try_seq.h +132 -10
  193. data/src/core/lib/resolver/endpoint_addresses.cc +0 -1
  194. data/src/core/lib/resolver/endpoint_addresses.h +48 -0
  195. data/src/core/lib/resource_quota/arena.h +2 -2
  196. data/src/core/lib/resource_quota/memory_quota.cc +57 -8
  197. data/src/core/lib/resource_quota/memory_quota.h +6 -0
  198. data/src/core/lib/security/authorization/grpc_server_authz_filter.cc +14 -11
  199. data/src/core/lib/security/authorization/grpc_server_authz_filter.h +14 -5
  200. data/src/core/lib/security/credentials/external/aws_external_account_credentials.cc +4 -0
  201. data/src/core/lib/security/credentials/external/aws_external_account_credentials.h +4 -0
  202. data/src/core/lib/security/credentials/external/external_account_credentials.cc +28 -20
  203. data/src/core/lib/security/credentials/external/external_account_credentials.h +4 -0
  204. data/src/core/lib/security/credentials/external/file_external_account_credentials.cc +4 -0
  205. data/src/core/lib/security/credentials/external/file_external_account_credentials.h +4 -0
  206. data/src/core/lib/security/credentials/external/url_external_account_credentials.cc +4 -0
  207. data/src/core/lib/security/credentials/external/url_external_account_credentials.h +4 -0
  208. data/src/core/lib/security/credentials/plugin/plugin_credentials.cc +2 -1
  209. data/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h +0 -3
  210. data/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc +12 -0
  211. data/src/core/lib/security/credentials/tls/grpc_tls_crl_provider.cc +22 -5
  212. data/src/core/lib/security/credentials/tls/grpc_tls_crl_provider.h +1 -5
  213. data/src/core/lib/security/credentials/tls/tls_credentials.cc +16 -0
  214. data/src/core/lib/security/credentials/xds/xds_credentials.cc +21 -28
  215. data/src/core/lib/security/credentials/xds/xds_credentials.h +2 -4
  216. data/src/core/lib/security/security_connector/tls/tls_security_connector.cc +4 -3
  217. data/src/core/lib/security/transport/auth_filters.h +71 -4
  218. data/src/core/lib/security/transport/client_auth_filter.cc +2 -4
  219. data/src/core/lib/security/transport/legacy_server_auth_filter.cc +244 -0
  220. data/src/core/lib/security/transport/server_auth_filter.cc +70 -90
  221. data/src/core/lib/slice/slice_buffer.h +3 -0
  222. data/src/core/lib/surface/builtins.cc +1 -1
  223. data/src/core/lib/surface/call.cc +683 -196
  224. data/src/core/lib/surface/call.h +26 -13
  225. data/src/core/lib/surface/call_trace.cc +42 -1
  226. data/src/core/lib/surface/channel.cc +0 -1
  227. data/src/core/lib/surface/channel.h +0 -6
  228. data/src/core/lib/surface/channel_init.h +26 -0
  229. data/src/core/lib/surface/init.cc +14 -8
  230. data/src/core/lib/surface/server.cc +256 -237
  231. data/src/core/lib/surface/server.h +26 -54
  232. data/src/core/lib/surface/version.cc +2 -2
  233. data/src/core/lib/surface/wait_for_cq_end_op.h +94 -0
  234. data/src/core/lib/transport/call_final_info.cc +38 -0
  235. data/src/core/lib/transport/call_final_info.h +54 -0
  236. data/src/core/lib/transport/connectivity_state.cc +3 -2
  237. data/src/core/lib/transport/connectivity_state.h +4 -0
  238. data/src/core/lib/transport/metadata_batch.h +4 -4
  239. data/src/core/lib/transport/transport.cc +70 -19
  240. data/src/core/lib/transport/transport.h +395 -25
  241. data/src/core/plugin_registry/grpc_plugin_registry.cc +3 -0
  242. data/src/core/plugin_registry/grpc_plugin_registry_extra.cc +0 -3
  243. data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +1 -1
  244. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +1 -1
  245. data/src/core/tsi/alts/handshaker/transport_security_common_api.cc +1 -1
  246. data/src/core/tsi/ssl_transport_security.cc +65 -43
  247. data/src/ruby/ext/grpc/rb_channel_args.c +3 -1
  248. data/src/ruby/ext/grpc/rb_grpc.c +0 -1
  249. data/src/ruby/ext/grpc/rb_grpc.h +0 -2
  250. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +4 -0
  251. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +6 -0
  252. data/src/ruby/lib/grpc/version.rb +1 -1
  253. data/third_party/upb/upb/reflection/def_pool.h +2 -2
  254. data/third_party/zlib/adler32.c +5 -27
  255. data/third_party/zlib/compress.c +5 -16
  256. data/third_party/zlib/crc32.c +86 -162
  257. data/third_party/zlib/deflate.c +233 -336
  258. data/third_party/zlib/deflate.h +8 -8
  259. data/third_party/zlib/gzguts.h +11 -12
  260. data/third_party/zlib/infback.c +7 -23
  261. data/third_party/zlib/inffast.c +1 -4
  262. data/third_party/zlib/inffast.h +1 -1
  263. data/third_party/zlib/inflate.c +30 -99
  264. data/third_party/zlib/inftrees.c +6 -11
  265. data/third_party/zlib/inftrees.h +3 -3
  266. data/third_party/zlib/trees.c +224 -302
  267. data/third_party/zlib/uncompr.c +4 -12
  268. data/third_party/zlib/zconf.h +6 -2
  269. data/third_party/zlib/zlib.h +191 -188
  270. data/third_party/zlib/zutil.c +16 -44
  271. data/third_party/zlib/zutil.h +10 -10
  272. metadata +35 -13
  273. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc +0 -1173
  274. data/src/core/lib/event_engine/memory_allocator.cc +0 -74
  275. data/src/core/lib/transport/pid_controller.cc +0 -51
  276. data/src/core/lib/transport/pid_controller.h +0 -116
  277. data/third_party/upb/upb/collections/array.h +0 -17
  278. data/third_party/upb/upb/collections/map.h +0 -17
  279. data/third_party/upb/upb/upb.hpp +0 -18
@@ -45,6 +45,7 @@
45
45
  #include <grpc/compression.h>
46
46
  #include <grpc/event_engine/event_engine.h>
47
47
  #include <grpc/grpc.h>
48
+ #include <grpc/impl/call.h>
48
49
  #include <grpc/impl/propagation_bits.h>
49
50
  #include <grpc/slice.h>
50
51
  #include <grpc/slice_buffer.h>
@@ -79,6 +80,7 @@
79
80
  #include "src/core/lib/iomgr/exec_ctx.h"
80
81
  #include "src/core/lib/iomgr/polling_entity.h"
81
82
  #include "src/core/lib/promise/activity.h"
83
+ #include "src/core/lib/promise/all_ok.h"
82
84
  #include "src/core/lib/promise/arena_promise.h"
83
85
  #include "src/core/lib/promise/context.h"
84
86
  #include "src/core/lib/promise/latch.h"
@@ -88,6 +90,7 @@
88
90
  #include "src/core/lib/promise/poll.h"
89
91
  #include "src/core/lib/promise/race.h"
90
92
  #include "src/core/lib/promise/seq.h"
93
+ #include "src/core/lib/promise/status_flag.h"
91
94
  #include "src/core/lib/resource_quota/arena.h"
92
95
  #include "src/core/lib/slice/slice_buffer.h"
93
96
  #include "src/core/lib/slice/slice_internal.h"
@@ -97,6 +100,7 @@
97
100
  #include "src/core/lib/surface/completion_queue.h"
98
101
  #include "src/core/lib/surface/server.h"
99
102
  #include "src/core/lib/surface/validate_metadata.h"
103
+ #include "src/core/lib/surface/wait_for_cq_end_op.h"
100
104
  #include "src/core/lib/transport/batch_builder.h"
101
105
  #include "src/core/lib/transport/error_utils.h"
102
106
  #include "src/core/lib/transport/metadata_batch.h"
@@ -148,6 +152,10 @@ class Call : public CppImplOf<Call, grpc_call> {
148
152
  // for that functionality be invented)
149
153
  virtual grpc_call_stack* call_stack() = 0;
150
154
 
155
+ // Return the EventEngine used for this call's async execution.
156
+ virtual grpc_event_engine::experimental::EventEngine* event_engine()
157
+ const = 0;
158
+
151
159
  protected:
152
160
  // The maximum number of concurrent batches possible.
153
161
  // Based upon the maximum number of individually queueable ops in the batch
@@ -529,6 +537,10 @@ class FilterStackCall final : public Call {
529
537
  GPR_ROUND_UP_TO_ALIGNMENT_SIZE(sizeof(*this)));
530
538
  }
531
539
 
540
+ grpc_event_engine::experimental::EventEngine* event_engine() const override {
541
+ return channel()->event_engine();
542
+ }
543
+
532
544
  grpc_call_element* call_elem(size_t idx) {
533
545
  return grpc_call_stack_element(call_stack(), idx);
534
546
  }
@@ -847,7 +859,7 @@ grpc_error_handle FilterStackCall::Create(grpc_call_create_args* args,
847
859
  args->server->server_call_tracer_factory() != nullptr) {
848
860
  auto* server_call_tracer =
849
861
  args->server->server_call_tracer_factory()->CreateNewServerCallTracer(
850
- arena);
862
+ arena, args->server->channel_args());
851
863
  if (server_call_tracer != nullptr) {
852
864
  // Note that we are setting both
853
865
  // GRPC_CONTEXT_CALL_TRACER_ANNOTATION_INTERFACE and
@@ -1978,22 +1990,45 @@ bool ValidateMetadata(size_t count, grpc_metadata* metadata) {
1978
1990
  // PromiseBasedCall
1979
1991
  // Will be folded into Call once the promise conversion is done
1980
1992
 
1981
- class PromiseBasedCall : public Call,
1982
- public Party,
1983
- public grpc_event_engine::experimental::EventEngine::
1984
- Closure /* for deadlines */ {
1993
+ class BasicPromiseBasedCall : public Call,
1994
+ public Party,
1995
+ public grpc_event_engine::experimental::
1996
+ EventEngine::Closure /* for deadlines */ {
1985
1997
  public:
1986
- PromiseBasedCall(Arena* arena, uint32_t initial_external_refs,
1987
- const grpc_call_create_args& args);
1998
+ using Call::arena;
1988
1999
 
1989
- void ContextSet(grpc_context_index elem, void* value,
1990
- void (*destroy)(void* value)) override;
1991
- void* ContextGet(grpc_context_index elem) const override;
1992
- void SetCompletionQueue(grpc_completion_queue* cq) override;
1993
- bool Completed() final { return finished_.IsSet(); }
2000
+ BasicPromiseBasedCall(Arena* arena, uint32_t initial_external_refs,
2001
+ const grpc_call_create_args& args)
2002
+ : Call(arena, args.server_transport_data == nullptr, args.send_deadline,
2003
+ args.channel->Ref()),
2004
+ Party(arena, initial_external_refs != 0 ? 1 : 0),
2005
+ external_refs_(initial_external_refs),
2006
+ cq_(args.cq) {
2007
+ if (args.cq != nullptr) {
2008
+ GRPC_CQ_INTERNAL_REF(args.cq, "bind");
2009
+ }
2010
+ }
2011
+
2012
+ ~BasicPromiseBasedCall() override {
2013
+ if (cq_) GRPC_CQ_INTERNAL_UNREF(cq_, "bind");
2014
+ for (int i = 0; i < GRPC_CONTEXT_COUNT; i++) {
2015
+ if (context_[i].destroy) {
2016
+ context_[i].destroy(context_[i].value);
2017
+ }
2018
+ }
2019
+ }
2020
+
2021
+ // Implementation of EventEngine::Closure, called when deadline expires
2022
+ void Run() final;
1994
2023
 
1995
2024
  virtual void OrphanCall() = 0;
1996
2025
 
2026
+ virtual ServerCallContext* server_call_context() { return nullptr; }
2027
+ void SetCompletionQueue(grpc_completion_queue* cq) final {
2028
+ cq_ = cq;
2029
+ GRPC_CQ_INTERNAL_REF(cq, "bind");
2030
+ }
2031
+
1997
2032
  // Implementation of call refcounting: move this to DualRefCounted once we
1998
2033
  // don't need to maintain FilterStackCall compatibility
1999
2034
  void ExternalRef() final {
@@ -2030,9 +2065,18 @@ class PromiseBasedCall : public Call,
2030
2065
  [](Empty) {});
2031
2066
  }
2032
2067
 
2033
- // This should return nullptr for the promise stack (and alternative means
2034
- // for that functionality be invented)
2035
- grpc_call_stack* call_stack() override { return nullptr; }
2068
+ void ContextSet(grpc_context_index elem, void* value,
2069
+ void (*destroy)(void*)) final {
2070
+ if (context_[elem].destroy != nullptr) {
2071
+ context_[elem].destroy(context_[elem].value);
2072
+ }
2073
+ context_[elem].value = value;
2074
+ context_[elem].destroy = destroy;
2075
+ }
2076
+
2077
+ void* ContextGet(grpc_context_index elem) const final {
2078
+ return context_[elem].value;
2079
+ }
2036
2080
 
2037
2081
  void UpdateDeadline(Timestamp deadline) ABSL_LOCKS_EXCLUDED(deadline_mu_);
2038
2082
  void ResetDeadline() ABSL_LOCKS_EXCLUDED(deadline_mu_);
@@ -2041,40 +2085,149 @@ class PromiseBasedCall : public Call,
2041
2085
  return deadline_;
2042
2086
  }
2043
2087
 
2044
- // Implementation of EventEngine::Closure, called when deadline expires
2045
- void Run() override;
2046
-
2047
- virtual ServerCallContext* server_call_context() { return nullptr; }
2048
- bool failed_before_recv_message() const final {
2049
- return failed_before_recv_message_.load(std::memory_order_relaxed);
2088
+ // Accept the stats from the context (call once we have proof the transport is
2089
+ // done with them).
2090
+ void AcceptTransportStatsFromContext() {
2091
+ final_stats_ = *call_context_.call_stats();
2050
2092
  }
2051
2093
 
2052
- grpc_event_engine::experimental::EventEngine* event_engine() const final {
2053
- return channel()->event_engine();
2054
- }
2094
+ // This should return nullptr for the promise stack (and alternative means
2095
+ // for that functionality be invented)
2096
+ grpc_call_stack* call_stack() final { return nullptr; }
2055
2097
 
2056
- using Call::arena;
2098
+ virtual RefCountedPtr<CallSpineInterface> MakeCallSpine(CallArgs) {
2099
+ Crash("Not implemented");
2100
+ }
2057
2101
 
2058
2102
  protected:
2059
2103
  class ScopedContext
2060
2104
  : public ScopedActivity,
2061
- public BatchBuilder,
2062
- public promise_detail::Context<BatchBuilder>,
2063
2105
  public promise_detail::Context<Arena>,
2064
2106
  public promise_detail::Context<grpc_call_context_element>,
2065
2107
  public promise_detail::Context<CallContext>,
2066
2108
  public promise_detail::Context<CallFinalization> {
2067
2109
  public:
2068
- explicit ScopedContext(PromiseBasedCall* call)
2110
+ explicit ScopedContext(BasicPromiseBasedCall* call)
2069
2111
  : ScopedActivity(call),
2070
- BatchBuilder(&call->batch_payload_),
2071
- promise_detail::Context<BatchBuilder>(this),
2072
2112
  promise_detail::Context<Arena>(call->arena()),
2073
2113
  promise_detail::Context<grpc_call_context_element>(call->context_),
2074
2114
  promise_detail::Context<CallContext>(&call->call_context_),
2075
2115
  promise_detail::Context<CallFinalization>(&call->finalization_) {}
2076
2116
  };
2077
2117
 
2118
+ grpc_call_context_element* context() { return context_; }
2119
+
2120
+ grpc_completion_queue* cq() { return cq_; }
2121
+
2122
+ // At the end of the call run any finalization actions.
2123
+ void SetFinalizationStatus(grpc_status_code status, Slice status_details) {
2124
+ final_message_ = std::move(status_details);
2125
+ final_status_ = status;
2126
+ }
2127
+
2128
+ grpc_event_engine::experimental::EventEngine* event_engine() const override {
2129
+ return channel()->event_engine();
2130
+ }
2131
+
2132
+ private:
2133
+ void PartyOver() final {
2134
+ {
2135
+ ScopedContext ctx(this);
2136
+ std::string message;
2137
+ grpc_call_final_info final_info;
2138
+ final_info.stats = final_stats_;
2139
+ final_info.final_status = final_status_;
2140
+ // TODO(ctiller): change type here so we don't need to copy this string.
2141
+ final_info.error_string = nullptr;
2142
+ if (!final_message_.empty()) {
2143
+ message = std::string(final_message_.begin(), final_message_.end());
2144
+ final_info.error_string = message.c_str();
2145
+ }
2146
+ final_info.stats.latency =
2147
+ gpr_cycle_counter_sub(gpr_get_cycle_counter(), start_time());
2148
+ finalization_.Run(&final_info);
2149
+ CancelRemainingParticipants();
2150
+ arena()->DestroyManagedNewObjects();
2151
+ }
2152
+ DeleteThis();
2153
+ }
2154
+
2155
+ // Double refcounted for now: party owns the internal refcount, we track the
2156
+ // external refcount. Figure out a better scheme post-promise conversion.
2157
+ std::atomic<size_t> external_refs_;
2158
+ CallFinalization finalization_;
2159
+ CallContext call_context_{this};
2160
+ // Contexts for various subsystems (security, tracing, ...).
2161
+ grpc_call_context_element context_[GRPC_CONTEXT_COUNT] = {};
2162
+ grpc_call_stats final_stats_{};
2163
+ // Current deadline.
2164
+ Mutex deadline_mu_;
2165
+ Timestamp deadline_ ABSL_GUARDED_BY(deadline_mu_) = Timestamp::InfFuture();
2166
+ grpc_event_engine::experimental::EventEngine::TaskHandle ABSL_GUARDED_BY(
2167
+ deadline_mu_) deadline_task_;
2168
+ Slice final_message_;
2169
+ grpc_status_code final_status_ = GRPC_STATUS_UNKNOWN;
2170
+ grpc_completion_queue* cq_;
2171
+ };
2172
+
2173
+ void BasicPromiseBasedCall::UpdateDeadline(Timestamp deadline) {
2174
+ MutexLock lock(&deadline_mu_);
2175
+ if (grpc_call_trace.enabled()) {
2176
+ gpr_log(GPR_DEBUG, "%s[call] UpdateDeadline from=%s to=%s",
2177
+ DebugTag().c_str(), deadline_.ToString().c_str(),
2178
+ deadline.ToString().c_str());
2179
+ }
2180
+ if (deadline >= deadline_) return;
2181
+ auto* const event_engine = channel()->event_engine();
2182
+ if (deadline_ != Timestamp::InfFuture()) {
2183
+ if (!event_engine->Cancel(deadline_task_)) return;
2184
+ } else {
2185
+ InternalRef("deadline");
2186
+ }
2187
+ deadline_ = deadline;
2188
+ deadline_task_ = event_engine->RunAfter(deadline - Timestamp::Now(), this);
2189
+ }
2190
+
2191
+ void BasicPromiseBasedCall::ResetDeadline() {
2192
+ MutexLock lock(&deadline_mu_);
2193
+ if (deadline_ == Timestamp::InfFuture()) return;
2194
+ auto* const event_engine = channel()->event_engine();
2195
+ if (!event_engine->Cancel(deadline_task_)) return;
2196
+ deadline_ = Timestamp::InfFuture();
2197
+ InternalUnref("deadline");
2198
+ }
2199
+
2200
+ void BasicPromiseBasedCall::Run() {
2201
+ ApplicationCallbackExecCtx callback_exec_ctx;
2202
+ ExecCtx exec_ctx;
2203
+ CancelWithError(absl::DeadlineExceededError("Deadline exceeded"));
2204
+ InternalUnref("deadline");
2205
+ }
2206
+
2207
+ class PromiseBasedCall : public BasicPromiseBasedCall {
2208
+ public:
2209
+ PromiseBasedCall(Arena* arena, uint32_t initial_external_refs,
2210
+ const grpc_call_create_args& args);
2211
+
2212
+ bool Completed() final { return finished_.IsSet(); }
2213
+
2214
+ bool failed_before_recv_message() const final {
2215
+ return failed_before_recv_message_.load(std::memory_order_relaxed);
2216
+ }
2217
+
2218
+ using Call::arena;
2219
+
2220
+ protected:
2221
+ class ScopedContext : public BasicPromiseBasedCall::ScopedContext,
2222
+ public BatchBuilder,
2223
+ public promise_detail::Context<BatchBuilder> {
2224
+ public:
2225
+ explicit ScopedContext(PromiseBasedCall* call)
2226
+ : BasicPromiseBasedCall::ScopedContext(call),
2227
+ BatchBuilder(&call->batch_payload_),
2228
+ promise_detail::Context<BatchBuilder>(this) {}
2229
+ };
2230
+
2078
2231
  class Completion {
2079
2232
  public:
2080
2233
  Completion() : index_(kNullIndex) {}
@@ -2101,15 +2254,6 @@ class PromiseBasedCall : public Call,
2101
2254
  uint8_t index_;
2102
2255
  };
2103
2256
 
2104
- ~PromiseBasedCall() override {
2105
- if (cq_) GRPC_CQ_INTERNAL_UNREF(cq_, "bind");
2106
- for (int i = 0; i < GRPC_CONTEXT_COUNT; i++) {
2107
- if (context_[i].destroy) {
2108
- context_[i].destroy(context_[i].value);
2109
- }
2110
- }
2111
- }
2112
-
2113
2257
  // Enumerates why a Completion is still pending
2114
2258
  enum class PendingOp {
2115
2259
  // We're in the midst of starting a batch of operations
@@ -2176,26 +2320,6 @@ class PromiseBasedCall : public Call,
2176
2320
  // Mark the completion as infallible. Overrides FailCompletion to report
2177
2321
  // success always.
2178
2322
  void ForceCompletionSuccess(const Completion& completion);
2179
- // Accept the stats from the context (call once we have proof the transport is
2180
- // done with them).
2181
- // Right now this means that promise based calls do not record correct stats
2182
- // with census if they are cancelled.
2183
- // TODO(ctiller): this should be remedied before promise based calls are
2184
- // dexperimentalized.
2185
- void AcceptTransportStatsFromContext() {
2186
- final_stats_ = *call_context_.call_stats();
2187
- }
2188
-
2189
- grpc_completion_queue* cq() { return cq_; }
2190
-
2191
- void CToMetadata(grpc_metadata* metadata, size_t count,
2192
- grpc_metadata_batch* batch);
2193
-
2194
- // At the end of the call run any finalization actions.
2195
- void SetFinalizationStatus(grpc_status_code status, Slice status_details) {
2196
- final_message_ = std::move(status_details);
2197
- final_status_ = status;
2198
- }
2199
2323
 
2200
2324
  std::string PresentAndCompletionText(const char* caption, bool has,
2201
2325
  const Completion& completion) const {
@@ -2346,45 +2470,7 @@ class PromiseBasedCall : public Call,
2346
2470
  grpc_cq_completion completion;
2347
2471
  };
2348
2472
 
2349
- void PartyOver() override {
2350
- {
2351
- ScopedContext ctx(this);
2352
- std::string message;
2353
- grpc_call_final_info final_info;
2354
- final_info.stats = final_stats_;
2355
- final_info.final_status = final_status_;
2356
- // TODO(ctiller): change type here so we don't need to copy this string.
2357
- final_info.error_string = nullptr;
2358
- if (!final_message_.empty()) {
2359
- message = std::string(final_message_.begin(), final_message_.end());
2360
- final_info.error_string = message.c_str();
2361
- }
2362
- final_info.stats.latency =
2363
- gpr_cycle_counter_sub(gpr_get_cycle_counter(), start_time());
2364
- finalization_.Run(&final_info);
2365
- CancelRemainingParticipants();
2366
- arena()->DestroyManagedNewObjects();
2367
- }
2368
- DeleteThis();
2369
- }
2370
-
2371
- CallContext call_context_{this};
2372
- // Double refcounted for now: party owns the internal refcount, we track the
2373
- // external refcount. Figure out a better scheme post-promise conversion.
2374
- std::atomic<size_t> external_refs_;
2375
- // Contexts for various subsystems (security, tracing, ...).
2376
- grpc_call_context_element context_[GRPC_CONTEXT_COUNT] = {};
2377
- grpc_completion_queue* cq_;
2378
2473
  CompletionInfo completion_info_[6];
2379
- grpc_call_stats final_stats_{};
2380
- Slice final_message_;
2381
- grpc_status_code final_status_ = GRPC_STATUS_UNKNOWN;
2382
- CallFinalization finalization_;
2383
- // Current deadline.
2384
- Mutex deadline_mu_;
2385
- Timestamp deadline_ ABSL_GUARDED_BY(deadline_mu_) = Timestamp::InfFuture();
2386
- grpc_event_engine::experimental::EventEngine::TaskHandle ABSL_GUARDED_BY(
2387
- deadline_mu_) deadline_task_;
2388
2474
  ExternallyObservableLatch<void> finished_;
2389
2475
  // Non-zero with an outstanding GRPC_OP_SEND_INITIAL_METADATA or
2390
2476
  // GRPC_OP_SEND_MESSAGE (one count each), and 0 once those payloads have been
@@ -2394,7 +2480,7 @@ class PromiseBasedCall : public Call,
2394
2480
  // Waiter for when sends_queued_ becomes 0.
2395
2481
  IntraActivityWaiter waiting_for_queued_sends_;
2396
2482
  grpc_byte_buffer** recv_message_ = nullptr;
2397
- grpc_transport_stream_op_batch_payload batch_payload_{context_};
2483
+ grpc_transport_stream_op_batch_payload batch_payload_{context()};
2398
2484
  };
2399
2485
 
2400
2486
  template <typename T>
@@ -2414,18 +2500,10 @@ grpc_error_handle MakePromiseBasedCall(grpc_call_create_args* args,
2414
2500
 
2415
2501
  PromiseBasedCall::PromiseBasedCall(Arena* arena, uint32_t initial_external_refs,
2416
2502
  const grpc_call_create_args& args)
2417
- : Call(arena, args.server_transport_data == nullptr, args.send_deadline,
2418
- args.channel->Ref()),
2419
- Party(arena, initial_external_refs != 0 ? 1 : 0),
2420
- external_refs_(initial_external_refs),
2421
- cq_(args.cq) {
2422
- if (args.cq != nullptr) {
2423
- GRPC_CQ_INTERNAL_REF(args.cq, "bind");
2424
- }
2425
- }
2503
+ : BasicPromiseBasedCall(arena, initial_external_refs, args) {}
2426
2504
 
2427
- void PromiseBasedCall::CToMetadata(grpc_metadata* metadata, size_t count,
2428
- grpc_metadata_batch* b) {
2505
+ static void CToMetadata(grpc_metadata* metadata, size_t count,
2506
+ grpc_metadata_batch* b) {
2429
2507
  for (size_t i = 0; i < count; i++) {
2430
2508
  grpc_metadata* md = &metadata[i];
2431
2509
  auto key = StringViewFromSlice(md->key);
@@ -2442,19 +2520,6 @@ void PromiseBasedCall::CToMetadata(grpc_metadata* metadata, size_t count,
2442
2520
  }
2443
2521
  }
2444
2522
 
2445
- void PromiseBasedCall::ContextSet(grpc_context_index elem, void* value,
2446
- void (*destroy)(void*)) {
2447
- if (context_[elem].destroy != nullptr) {
2448
- context_[elem].destroy(context_[elem].value);
2449
- }
2450
- context_[elem].value = value;
2451
- context_[elem].destroy = destroy;
2452
- }
2453
-
2454
- void* PromiseBasedCall::ContextGet(grpc_context_index elem) const {
2455
- return context_[elem].value;
2456
- }
2457
-
2458
2523
  PromiseBasedCall::Completion PromiseBasedCall::StartCompletion(
2459
2524
  void* tag, bool is_closure, const grpc_op* ops) {
2460
2525
  Completion c(BatchSlotForOp(ops[0].op));
@@ -2534,45 +2599,6 @@ void PromiseBasedCall::FinishOpOnCompletion(Completion* completion,
2534
2599
  }
2535
2600
  }
2536
2601
 
2537
- void PromiseBasedCall::SetCompletionQueue(grpc_completion_queue* cq) {
2538
- cq_ = cq;
2539
- GRPC_CQ_INTERNAL_REF(cq, "bind");
2540
- }
2541
-
2542
- void PromiseBasedCall::UpdateDeadline(Timestamp deadline) {
2543
- MutexLock lock(&deadline_mu_);
2544
- if (grpc_call_trace.enabled()) {
2545
- gpr_log(GPR_DEBUG, "%s[call] UpdateDeadline from=%s to=%s",
2546
- DebugTag().c_str(), deadline_.ToString().c_str(),
2547
- deadline.ToString().c_str());
2548
- }
2549
- if (deadline >= deadline_) return;
2550
- auto* const event_engine = channel()->event_engine();
2551
- if (deadline_ != Timestamp::InfFuture()) {
2552
- if (!event_engine->Cancel(deadline_task_)) return;
2553
- } else {
2554
- InternalRef("deadline");
2555
- }
2556
- deadline_ = deadline;
2557
- deadline_task_ = event_engine->RunAfter(deadline - Timestamp::Now(), this);
2558
- }
2559
-
2560
- void PromiseBasedCall::ResetDeadline() {
2561
- MutexLock lock(&deadline_mu_);
2562
- if (deadline_ == Timestamp::InfFuture()) return;
2563
- auto* const event_engine = channel()->event_engine();
2564
- if (!event_engine->Cancel(deadline_task_)) return;
2565
- deadline_ = Timestamp::InfFuture();
2566
- InternalUnref("deadline");
2567
- }
2568
-
2569
- void PromiseBasedCall::Run() {
2570
- ApplicationCallbackExecCtx callback_exec_ctx;
2571
- ExecCtx exec_ctx;
2572
- CancelWithError(absl::DeadlineExceededError("Deadline exceeded"));
2573
- InternalUnref("deadline");
2574
- }
2575
-
2576
2602
  void PromiseBasedCall::StartSendMessage(const grpc_op& op,
2577
2603
  const Completion& completion,
2578
2604
  PipeSender<MessageHandle>* sender,
@@ -2685,6 +2711,13 @@ ServerCallContext* CallContext::server_call_context() {
2685
2711
  return call_->server_call_context();
2686
2712
  }
2687
2713
 
2714
+ RefCountedPtr<CallSpineInterface> CallContext::MakeCallSpine(
2715
+ CallArgs call_args) {
2716
+ return call_->MakeCallSpine(std::move(call_args));
2717
+ }
2718
+
2719
+ grpc_call* CallContext::c_call() { return call_->c_ptr(); }
2720
+
2688
2721
  ///////////////////////////////////////////////////////////////////////////////
2689
2722
  // PublishMetadataArray
2690
2723
 
@@ -2805,6 +2838,81 @@ class ClientPromiseBasedCall final : public PromiseBasedCall {
2805
2838
  return absl::StrFormat("CLIENT_CALL[%p]: ", this);
2806
2839
  }
2807
2840
 
2841
+ RefCountedPtr<CallSpineInterface> MakeCallSpine(CallArgs call_args) final {
2842
+ class WrappingCallSpine final : public CallSpineInterface {
2843
+ public:
2844
+ WrappingCallSpine(ClientPromiseBasedCall* call,
2845
+ ClientMetadataHandle metadata)
2846
+ : call_(call) {
2847
+ call_->InternalRef("call-spine");
2848
+ SpawnInfallible("send_client_initial_metadata",
2849
+ [this, metadata = std::move(metadata)]() mutable {
2850
+ return Map(client_initial_metadata_.sender.Push(
2851
+ std::move(metadata)),
2852
+ [](bool) { return Empty{}; });
2853
+ });
2854
+ SpawnInfallible("monitor_cancellation", [this]() {
2855
+ return Seq(cancel_error_.Wait(),
2856
+ [this](ServerMetadataHandle trailing_metadata) {
2857
+ Crash("here");
2858
+ return Map(server_trailing_metadata_.sender.Push(
2859
+ std::move(trailing_metadata)),
2860
+ [](bool) { return Empty{}; });
2861
+ });
2862
+ });
2863
+ }
2864
+
2865
+ ~WrappingCallSpine() override { call_->InternalUnref("call-spine"); }
2866
+
2867
+ Pipe<ClientMetadataHandle>& client_initial_metadata() override {
2868
+ return client_initial_metadata_;
2869
+ }
2870
+
2871
+ Pipe<MessageHandle>& client_to_server_messages() override {
2872
+ return call_->client_to_server_messages_;
2873
+ }
2874
+
2875
+ Pipe<ServerMetadataHandle>& server_initial_metadata() override {
2876
+ return call_->server_initial_metadata_;
2877
+ }
2878
+
2879
+ Pipe<MessageHandle>& server_to_client_messages() override {
2880
+ return call_->server_to_client_messages_;
2881
+ }
2882
+
2883
+ Pipe<ServerMetadataHandle>& server_trailing_metadata() override {
2884
+ return server_trailing_metadata_;
2885
+ }
2886
+
2887
+ Latch<ServerMetadataHandle>& cancel_latch() override {
2888
+ return cancel_error_;
2889
+ }
2890
+
2891
+ Party& party() override { return *call_; }
2892
+
2893
+ void IncrementRefCount() override { refs_.Ref(); }
2894
+ void Unref() override {
2895
+ if (refs_.Unref()) delete this;
2896
+ }
2897
+
2898
+ private:
2899
+ RefCount refs_;
2900
+ ClientPromiseBasedCall* const call_;
2901
+ std::atomic<bool> sent_trailing_metadata_{false};
2902
+ Pipe<ClientMetadataHandle> client_initial_metadata_{call_->arena()};
2903
+ Pipe<ServerMetadataHandle> server_trailing_metadata_{call_->arena()};
2904
+ Latch<ServerMetadataHandle> cancel_error_;
2905
+ };
2906
+ GPR_ASSERT(call_args.server_initial_metadata ==
2907
+ &server_initial_metadata_.sender);
2908
+ GPR_ASSERT(call_args.client_to_server_messages ==
2909
+ &client_to_server_messages_.receiver);
2910
+ GPR_ASSERT(call_args.server_to_client_messages ==
2911
+ &server_to_client_messages_.sender);
2912
+ return MakeRefCounted<WrappingCallSpine>(
2913
+ this, std::move(call_args.client_initial_metadata));
2914
+ }
2915
+
2808
2916
  private:
2809
2917
  // Finish the call with the given status/trailing metadata.
2810
2918
  void Finish(ServerMetadataHandle trailing_metadata);
@@ -2978,7 +3086,8 @@ void ClientPromiseBasedCall::CommitBatch(const grpc_op* ops, size_t nops,
2978
3086
  StartRecvMessage(
2979
3087
  op, completion,
2980
3088
  [this]() {
2981
- return server_initial_metadata_.receiver.AwaitClosed();
3089
+ return Race(server_initial_metadata_.receiver.AwaitClosed(),
3090
+ server_to_client_messages_.receiver.AwaitClosed());
2982
3091
  },
2983
3092
  &server_to_client_messages_.receiver, false, spawner);
2984
3093
  break;
@@ -3147,7 +3256,8 @@ void ClientPromiseBasedCall::StartRecvStatusOnClient(
3147
3256
 
3148
3257
  #ifdef GRPC_EXPERIMENT_IS_INCLUDED_PROMISE_BASED_SERVER_CALL
3149
3258
 
3150
- class ServerPromiseBasedCall final : public PromiseBasedCall {
3259
+ class ServerPromiseBasedCall final : public PromiseBasedCall,
3260
+ public ServerCallContext {
3151
3261
  public:
3152
3262
  ServerPromiseBasedCall(Arena* arena, grpc_call_create_args* args);
3153
3263
 
@@ -3155,7 +3265,9 @@ class ServerPromiseBasedCall final : public PromiseBasedCall {
3155
3265
  void CancelWithError(grpc_error_handle) override;
3156
3266
  grpc_call_error StartBatch(const grpc_op* ops, size_t nops, void* notify_tag,
3157
3267
  bool is_notify_tag_closure) override;
3158
- bool is_trailers_only() const override { abort(); }
3268
+ bool is_trailers_only() const override {
3269
+ Crash("is_trailers_only not implemented for server calls");
3270
+ }
3159
3271
  absl::string_view GetServerAuthority() const override {
3160
3272
  const Slice* authority_metadata =
3161
3273
  client_initial_metadata_->get_pointer(HttpAuthorityMetadata());
@@ -3188,7 +3300,15 @@ class ServerPromiseBasedCall final : public PromiseBasedCall {
3188
3300
  return absl::StrFormat("SERVER_CALL[%p]: ", this);
3189
3301
  }
3190
3302
 
3191
- ServerCallContext* server_call_context() override { return &call_context_; }
3303
+ ServerCallContext* server_call_context() override { return this; }
3304
+
3305
+ const void* server_stream_data() override { return server_transport_data_; }
3306
+ void PublishInitialMetadata(
3307
+ ClientMetadataHandle metadata,
3308
+ grpc_metadata_array* publish_initial_metadata) override;
3309
+ ArenaPromise<ServerMetadataHandle> MakeTopOfServerCallPromise(
3310
+ CallArgs call_args, grpc_completion_queue* cq,
3311
+ absl::FunctionRef<void(grpc_call* call)> publish) override;
3192
3312
 
3193
3313
  private:
3194
3314
  class RecvCloseOpCancelState {
@@ -3273,14 +3393,12 @@ class ServerPromiseBasedCall final : public PromiseBasedCall {
3273
3393
  std::atomic<uintptr_t> state_{kUnset};
3274
3394
  };
3275
3395
 
3276
- grpc_call_error ValidateBatch(const grpc_op* ops, size_t nops) const;
3277
3396
  void CommitBatch(const grpc_op* ops, size_t nops,
3278
3397
  const Completion& completion);
3279
3398
  void Finish(ServerMetadataHandle result);
3280
3399
 
3281
- friend class ServerCallContext;
3282
- ServerCallContext call_context_;
3283
3400
  Server* const server_;
3401
+ const void* const server_transport_data_;
3284
3402
  PipeSender<ServerMetadataHandle>* server_initial_metadata_ = nullptr;
3285
3403
  PipeSender<MessageHandle>* server_to_client_messages_ = nullptr;
3286
3404
  PipeReceiver<MessageHandle>* client_to_server_messages_ = nullptr;
@@ -3294,8 +3412,8 @@ class ServerPromiseBasedCall final : public PromiseBasedCall {
3294
3412
  ServerPromiseBasedCall::ServerPromiseBasedCall(Arena* arena,
3295
3413
  grpc_call_create_args* args)
3296
3414
  : PromiseBasedCall(arena, 0, *args),
3297
- call_context_(this, args->server_transport_data),
3298
- server_(args->server) {
3415
+ server_(args->server),
3416
+ server_transport_data_(args->server_transport_data) {
3299
3417
  global_stats().IncrementServerCallsCreated();
3300
3418
  channelz::ServerNode* channelz_node = server_->channelz_node();
3301
3419
  if (channelz_node != nullptr) {
@@ -3308,7 +3426,7 @@ ServerPromiseBasedCall::ServerPromiseBasedCall(Arena* arena,
3308
3426
  if (args->server->server_call_tracer_factory() != nullptr) {
3309
3427
  auto* server_call_tracer =
3310
3428
  args->server->server_call_tracer_factory()->CreateNewServerCallTracer(
3311
- arena);
3429
+ arena, args->server->channel_args());
3312
3430
  if (server_call_tracer != nullptr) {
3313
3431
  // Note that we are setting both
3314
3432
  // GRPC_CONTEXT_CALL_TRACER_ANNOTATION_INTERFACE and
@@ -3365,8 +3483,7 @@ void ServerPromiseBasedCall::Finish(ServerMetadataHandle result) {
3365
3483
  PropagateCancellationToChildren();
3366
3484
  }
3367
3485
 
3368
- grpc_call_error ServerPromiseBasedCall::ValidateBatch(const grpc_op* ops,
3369
- size_t nops) const {
3486
+ grpc_call_error ValidateServerBatch(const grpc_op* ops, size_t nops) {
3370
3487
  BitSet<8> got_ops;
3371
3488
  for (size_t op_idx = 0; op_idx < nops; op_idx++) {
3372
3489
  const grpc_op& op = ops[op_idx];
@@ -3526,7 +3643,7 @@ grpc_call_error ServerPromiseBasedCall::StartBatch(const grpc_op* ops,
3526
3643
  EndOpImmediately(cq(), notify_tag, is_notify_tag_closure);
3527
3644
  return GRPC_CALL_OK;
3528
3645
  }
3529
- const grpc_call_error validation_result = ValidateBatch(ops, nops);
3646
+ const grpc_call_error validation_result = ValidateServerBatch(ops, nops);
3530
3647
  if (validation_result != GRPC_CALL_OK) {
3531
3648
  return validation_result;
3532
3649
  }
@@ -3560,35 +3677,400 @@ void ServerPromiseBasedCall::CancelWithError(absl::Status error) {
3560
3677
  #endif
3561
3678
 
3562
3679
  #ifdef GRPC_EXPERIMENT_IS_INCLUDED_PROMISE_BASED_SERVER_CALL
3680
+ void ServerPromiseBasedCall::PublishInitialMetadata(
3681
+ ClientMetadataHandle metadata,
3682
+ grpc_metadata_array* publish_initial_metadata) {
3683
+ if (grpc_call_trace.enabled()) {
3684
+ gpr_log(GPR_INFO, "%s[call] PublishInitialMetadata: %s", DebugTag().c_str(),
3685
+ metadata->DebugString().c_str());
3686
+ }
3687
+ PublishMetadataArray(metadata.get(), publish_initial_metadata, false);
3688
+ client_initial_metadata_ = std::move(metadata);
3689
+ }
3690
+
3563
3691
  ArenaPromise<ServerMetadataHandle>
3564
- ServerCallContext::MakeTopOfServerCallPromise(
3692
+ ServerPromiseBasedCall::MakeTopOfServerCallPromise(
3565
3693
  CallArgs call_args, grpc_completion_queue* cq,
3566
- grpc_metadata_array* publish_initial_metadata,
3567
3694
  absl::FunctionRef<void(grpc_call* call)> publish) {
3568
- call_->SetCompletionQueue(cq);
3695
+ SetCompletionQueue(cq);
3569
3696
  call_args.polling_entity->Set(
3570
3697
  grpc_polling_entity_create_from_pollset(grpc_cq_pollset(cq)));
3571
- call_->server_to_client_messages_ = call_args.server_to_client_messages;
3572
- call_->client_to_server_messages_ = call_args.client_to_server_messages;
3573
- call_->server_initial_metadata_ = call_args.server_initial_metadata;
3574
- call_->client_initial_metadata_ =
3575
- std::move(call_args.client_initial_metadata);
3576
- call_->set_send_deadline(call_->deadline());
3577
- call_->ProcessIncomingInitialMetadata(*call_->client_initial_metadata_);
3578
- PublishMetadataArray(call_->client_initial_metadata_.get(),
3579
- publish_initial_metadata, false);
3580
- call_->ExternalRef();
3581
- publish(call_->c_ptr());
3582
- return Seq(call_->server_to_client_messages_->AwaitClosed(),
3583
- call_->send_trailing_metadata_.Wait());
3698
+ server_to_client_messages_ = call_args.server_to_client_messages;
3699
+ client_to_server_messages_ = call_args.client_to_server_messages;
3700
+ server_initial_metadata_ = call_args.server_initial_metadata;
3701
+ set_send_deadline(deadline());
3702
+ ProcessIncomingInitialMetadata(*client_initial_metadata_);
3703
+ ExternalRef();
3704
+ publish(c_ptr());
3705
+ return Seq(server_to_client_messages_->AwaitClosed(),
3706
+ send_trailing_metadata_.Wait());
3707
+ }
3708
+
3709
+ ///////////////////////////////////////////////////////////////////////////////
3710
+ // CallSpine based Server Call
3711
+
3712
+ class ServerCallSpine final : public CallSpineInterface,
3713
+ public ServerCallContext,
3714
+ public BasicPromiseBasedCall {
3715
+ public:
3716
+ ServerCallSpine(Server* server, Channel* channel, Arena* arena);
3717
+
3718
+ // CallSpineInterface
3719
+ Pipe<ClientMetadataHandle>& client_initial_metadata() override {
3720
+ return client_initial_metadata_;
3721
+ }
3722
+ Pipe<ServerMetadataHandle>& server_initial_metadata() override {
3723
+ return server_initial_metadata_;
3724
+ }
3725
+ Pipe<MessageHandle>& client_to_server_messages() override {
3726
+ return client_to_server_messages_;
3727
+ }
3728
+ Pipe<MessageHandle>& server_to_client_messages() override {
3729
+ return server_to_client_messages_;
3730
+ }
3731
+ Pipe<ServerMetadataHandle>& server_trailing_metadata() override {
3732
+ return server_trailing_metadata_;
3733
+ }
3734
+ Latch<ServerMetadataHandle>& cancel_latch() override { return cancel_latch_; }
3735
+ Party& party() override { return *this; }
3736
+ void IncrementRefCount() override { InternalRef("CallSpine"); }
3737
+ void Unref() override { InternalUnref("CallSpine"); }
3738
+
3739
+ // PromiseBasedCall
3740
+ void OrphanCall() override {}
3741
+ void CancelWithError(grpc_error_handle error) override {
3742
+ SpawnInfallible("CancelWithError", [this, error = std::move(error)] {
3743
+ std::ignore = Cancel(ServerMetadataFromStatus(error));
3744
+ return Empty{};
3745
+ });
3746
+ }
3747
+ bool is_trailers_only() const override {
3748
+ Crash("is_trailers_only not implemented for server calls");
3749
+ }
3750
+ absl::string_view GetServerAuthority() const override {
3751
+ Crash("unimplemented");
3752
+ }
3753
+ grpc_call_error StartBatch(const grpc_op* ops, size_t nops, void* notify_tag,
3754
+ bool is_notify_tag_closure) override;
3755
+
3756
+ bool Completed() final { Crash("unimplemented"); }
3757
+ bool failed_before_recv_message() const final { Crash("unimplemented"); }
3758
+
3759
+ ServerCallContext* server_call_context() override { return this; }
3760
+ const void* server_stream_data() override { Crash("unimplemented"); }
3761
+ void PublishInitialMetadata(
3762
+ ClientMetadataHandle metadata,
3763
+ grpc_metadata_array* publish_initial_metadata) override;
3764
+ ArenaPromise<ServerMetadataHandle> MakeTopOfServerCallPromise(
3765
+ CallArgs, grpc_completion_queue*,
3766
+ absl::FunctionRef<void(grpc_call* call)>) override {
3767
+ Crash("unimplemented");
3768
+ }
3769
+
3770
+ bool RunParty() override {
3771
+ ScopedContext ctx(this);
3772
+ return Party::RunParty();
3773
+ }
3774
+
3775
+ private:
3776
+ void CommitBatch(const grpc_op* ops, size_t nops, void* notify_tag,
3777
+ bool is_notify_tag_closure);
3778
+ StatusFlag FinishRecvMessage(NextResult<MessageHandle> result);
3779
+
3780
+ std::string DebugTag() const override {
3781
+ return absl::StrFormat("SERVER_CALL_SPINE[%p]: ", this);
3782
+ }
3783
+
3784
+ // Initial metadata from client to server
3785
+ Pipe<ClientMetadataHandle> client_initial_metadata_;
3786
+ // Initial metadata from server to client
3787
+ Pipe<ServerMetadataHandle> server_initial_metadata_;
3788
+ // Messages travelling from the application to the transport.
3789
+ Pipe<MessageHandle> client_to_server_messages_;
3790
+ // Messages travelling from the transport to the application.
3791
+ Pipe<MessageHandle> server_to_client_messages_;
3792
+ // Trailing metadata from server to client
3793
+ Pipe<ServerMetadataHandle> server_trailing_metadata_;
3794
+ // Latch that can be set to terminate the call
3795
+ Latch<ServerMetadataHandle> cancel_latch_;
3796
+ grpc_byte_buffer** recv_message_ = nullptr;
3797
+ ClientMetadataHandle client_initial_metadata_stored_;
3798
+ };
3799
+
3800
+ ServerCallSpine::ServerCallSpine(Server* server, Channel* channel, Arena* arena)
3801
+ : BasicPromiseBasedCall(
3802
+ arena, 1, [channel, server]() -> grpc_call_create_args {
3803
+ grpc_call_create_args args;
3804
+ args.channel = channel->Ref();
3805
+ args.server = server;
3806
+ args.parent = nullptr;
3807
+ args.propagation_mask = 0;
3808
+ args.cq = nullptr;
3809
+ args.pollset_set_alternative = nullptr;
3810
+ args.server_transport_data = &args; // Arbitrary non-null pointer
3811
+ args.send_deadline = Timestamp::InfFuture();
3812
+ return args;
3813
+ }()) {
3814
+ global_stats().IncrementServerCallsCreated();
3815
+ channel->channel_stack()->InitServerCallSpine(this);
3816
+ }
3817
+
3818
+ void ServerCallSpine::PublishInitialMetadata(
3819
+ ClientMetadataHandle metadata,
3820
+ grpc_metadata_array* publish_initial_metadata) {
3821
+ if (grpc_call_trace.enabled()) {
3822
+ gpr_log(GPR_INFO, "%s[call] PublishInitialMetadata: %s", DebugTag().c_str(),
3823
+ metadata->DebugString().c_str());
3824
+ }
3825
+ PublishMetadataArray(metadata.get(), publish_initial_metadata, false);
3826
+ client_initial_metadata_stored_ = std::move(metadata);
3827
+ }
3828
+
3829
+ grpc_call_error ServerCallSpine::StartBatch(const grpc_op* ops, size_t nops,
3830
+ void* notify_tag,
3831
+ bool is_notify_tag_closure) {
3832
+ if (nops == 0) {
3833
+ EndOpImmediately(cq(), notify_tag, is_notify_tag_closure);
3834
+ return GRPC_CALL_OK;
3835
+ }
3836
+ const grpc_call_error validation_result = ValidateServerBatch(ops, nops);
3837
+ if (validation_result != GRPC_CALL_OK) {
3838
+ return validation_result;
3839
+ }
3840
+ CommitBatch(ops, nops, notify_tag, is_notify_tag_closure);
3841
+ return GRPC_CALL_OK;
3842
+ }
3843
+
3844
+ namespace {
3845
+ template <typename SetupFn>
3846
+ class MaybeOpImpl {
3847
+ public:
3848
+ using SetupResult = decltype(std::declval<SetupFn>()(grpc_op()));
3849
+ using PromiseFactory = promise_detail::OncePromiseFactory<void, SetupResult>;
3850
+ using Promise = typename PromiseFactory::Promise;
3851
+ struct Dismissed {};
3852
+ using State = absl::variant<Dismissed, PromiseFactory, Promise>;
3853
+
3854
+ MaybeOpImpl() : state_(Dismissed{}) {}
3855
+ explicit MaybeOpImpl(SetupResult result)
3856
+ : state_(PromiseFactory(std::move(result))) {}
3857
+
3858
+ MaybeOpImpl(const MaybeOpImpl&) = delete;
3859
+ MaybeOpImpl& operator=(const MaybeOpImpl&) = delete;
3860
+ MaybeOpImpl(MaybeOpImpl&& other) noexcept : state_(MoveState(other.state_)) {}
3861
+ MaybeOpImpl& operator=(MaybeOpImpl&& other) noexcept {
3862
+ if (absl::holds_alternative<Dismissed>(state_)) {
3863
+ state_.template emplace<Dismissed>();
3864
+ return *this;
3865
+ }
3866
+ // Can't move after first poll => Promise is not an option
3867
+ state_.template emplace<PromiseFactory>(
3868
+ std::move(absl::get<PromiseFactory>(other.state_)));
3869
+ return *this;
3870
+ }
3871
+
3872
+ Poll<StatusFlag> operator()() {
3873
+ if (absl::holds_alternative<Dismissed>(state_)) return Success{};
3874
+ if (absl::holds_alternative<PromiseFactory>(state_)) {
3875
+ auto& factory = absl::get<PromiseFactory>(state_);
3876
+ auto promise = factory.Make();
3877
+ state_.template emplace<Promise>(std::move(promise));
3878
+ }
3879
+ auto& promise = absl::get<Promise>(state_);
3880
+ return poll_cast<StatusFlag>(promise());
3881
+ }
3882
+
3883
+ private:
3884
+ State state_;
3885
+
3886
+ static State MoveState(State& state) {
3887
+ if (absl::holds_alternative<Dismissed>(state)) return Dismissed{};
3888
+ // Can't move after first poll => Promise is not an option
3889
+ return std::move(absl::get<PromiseFactory>(state));
3890
+ }
3891
+ };
3892
+
3893
+ // MaybeOp captures a fairly complicated dance we need to do for the batch API.
3894
+ // We first check if an op is included or not, and if it is, we run the setup
3895
+ // function in the context of the API call (NOT in the call party).
3896
+ // This setup function returns a promise factory which we'll then run *in* the
3897
+ // party to do initial setup, and have it return the promise that we'll
3898
+ // ultimately poll on til completion.
3899
+ // Once we express our surface API in terms of core internal types this whole
3900
+ // dance will go away.
3901
+ template <typename SetupFn>
3902
+ auto MaybeOp(const grpc_op* ops, uint8_t idx, SetupFn setup) {
3903
+ if (idx == 255) {
3904
+ return MaybeOpImpl<SetupFn>();
3905
+ } else {
3906
+ return MaybeOpImpl<SetupFn>(setup(ops[idx]));
3907
+ }
3908
+ }
3909
+ } // namespace
3910
+
3911
+ StatusFlag ServerCallSpine::FinishRecvMessage(
3912
+ NextResult<MessageHandle> result) {
3913
+ if (result.has_value()) {
3914
+ MessageHandle& message = *result;
3915
+ NoteLastMessageFlags(message->flags());
3916
+ if ((message->flags() & GRPC_WRITE_INTERNAL_COMPRESS) &&
3917
+ (incoming_compression_algorithm() != GRPC_COMPRESS_NONE)) {
3918
+ *recv_message_ = grpc_raw_compressed_byte_buffer_create(
3919
+ nullptr, 0, incoming_compression_algorithm());
3920
+ } else {
3921
+ *recv_message_ = grpc_raw_byte_buffer_create(nullptr, 0);
3922
+ }
3923
+ grpc_slice_buffer_move_into(message->payload()->c_slice_buffer(),
3924
+ &(*recv_message_)->data.raw.slice_buffer);
3925
+ if (grpc_call_trace.enabled()) {
3926
+ gpr_log(GPR_INFO,
3927
+ "%s[call] RecvMessage: outstanding_recv "
3928
+ "finishes: received %" PRIdPTR " byte message",
3929
+ DebugTag().c_str(),
3930
+ (*recv_message_)->data.raw.slice_buffer.length);
3931
+ }
3932
+ return Success{};
3933
+ }
3934
+ if (result.cancelled()) {
3935
+ if (grpc_call_trace.enabled()) {
3936
+ gpr_log(GPR_INFO,
3937
+ "%s[call] RecvMessage: outstanding_recv "
3938
+ "finishes: received end-of-stream with error",
3939
+ DebugTag().c_str());
3940
+ }
3941
+ *recv_message_ = nullptr;
3942
+ return Failure{};
3943
+ }
3944
+ if (grpc_call_trace.enabled()) {
3945
+ gpr_log(GPR_INFO,
3946
+ "%s[call] RecvMessage: outstanding_recv "
3947
+ "finishes: received end-of-stream",
3948
+ DebugTag().c_str());
3949
+ }
3950
+ *recv_message_ = nullptr;
3951
+ return Success{};
3952
+ }
3953
+
3954
+ void ServerCallSpine::CommitBatch(const grpc_op* ops, size_t nops,
3955
+ void* notify_tag,
3956
+ bool is_notify_tag_closure) {
3957
+ std::array<uint8_t, 8> got_ops{255, 255, 255, 255, 255, 255, 255, 255};
3958
+ for (size_t op_idx = 0; op_idx < nops; op_idx++) {
3959
+ const grpc_op& op = ops[op_idx];
3960
+ got_ops[op.op] = op_idx;
3961
+ }
3962
+ if (!is_notify_tag_closure) grpc_cq_begin_op(cq(), notify_tag);
3963
+ auto send_initial_metadata = MaybeOp(
3964
+ ops, got_ops[GRPC_OP_SEND_INITIAL_METADATA], [this](const grpc_op& op) {
3965
+ auto metadata = arena()->MakePooled<ServerMetadata>(arena());
3966
+ PrepareOutgoingInitialMetadata(op, *metadata);
3967
+ CToMetadata(op.data.send_initial_metadata.metadata,
3968
+ op.data.send_initial_metadata.count, metadata.get());
3969
+ if (grpc_call_trace.enabled()) {
3970
+ gpr_log(GPR_INFO, "%s[call] Send initial metadata",
3971
+ DebugTag().c_str());
3972
+ }
3973
+ return [this, metadata = std::move(metadata)]() mutable {
3974
+ return Map(server_initial_metadata_.sender.Push(std::move(metadata)),
3975
+ [this](bool r) {
3976
+ server_initial_metadata_.sender.Close();
3977
+ return StatusFlag(r);
3978
+ });
3979
+ };
3980
+ });
3981
+ auto send_message =
3982
+ MaybeOp(ops, got_ops[GRPC_OP_SEND_MESSAGE], [this](const grpc_op& op) {
3983
+ SliceBuffer send;
3984
+ grpc_slice_buffer_swap(
3985
+ &op.data.send_message.send_message->data.raw.slice_buffer,
3986
+ send.c_slice_buffer());
3987
+ auto msg = arena()->MakePooled<Message>(std::move(send), op.flags);
3988
+ return [this, msg = std::move(msg)]() mutable {
3989
+ return Map(server_to_client_messages_.sender.Push(std::move(msg)),
3990
+ [](bool r) { return StatusFlag(r); });
3991
+ };
3992
+ });
3993
+ auto send_trailing_metadata = MaybeOp(
3994
+ ops, got_ops[GRPC_OP_SEND_STATUS_FROM_SERVER], [this](const grpc_op& op) {
3995
+ auto metadata = arena()->MakePooled<ServerMetadata>(arena());
3996
+ CToMetadata(op.data.send_status_from_server.trailing_metadata,
3997
+ op.data.send_status_from_server.trailing_metadata_count,
3998
+ metadata.get());
3999
+ metadata->Set(GrpcStatusMetadata(),
4000
+ op.data.send_status_from_server.status);
4001
+ if (auto* details = op.data.send_status_from_server.status_details) {
4002
+ // TODO(ctiller): this should not be a copy, but we have
4003
+ // callers that allocate and pass in a slice created with
4004
+ // grpc_slice_from_static_string and then delete the string
4005
+ // after passing it in, which shouldn't be a supported API.
4006
+ metadata->Set(GrpcMessageMetadata(),
4007
+ Slice(grpc_slice_copy(*details)));
4008
+ }
4009
+ return [this, metadata = std::move(metadata)]() mutable {
4010
+ server_to_client_messages_.sender.Close();
4011
+ return Map(server_trailing_metadata_.sender.Push(std::move(metadata)),
4012
+ [](bool r) { return StatusFlag(r); });
4013
+ };
4014
+ });
4015
+ auto recv_message =
4016
+ MaybeOp(ops, got_ops[GRPC_OP_RECV_MESSAGE], [this](const grpc_op& op) {
4017
+ GPR_ASSERT(recv_message_ == nullptr);
4018
+ recv_message_ = op.data.recv_message.recv_message;
4019
+ return [this]() mutable {
4020
+ return Map(client_to_server_messages_.receiver.Next(),
4021
+ [this](NextResult<MessageHandle> msg) {
4022
+ return FinishRecvMessage(std::move(msg));
4023
+ });
4024
+ };
4025
+ });
4026
+ auto primary_ops = AllOk<StatusFlag>(
4027
+ std::move(send_initial_metadata), std::move(send_message),
4028
+ std::move(send_trailing_metadata), std::move(recv_message));
4029
+ if (got_ops[GRPC_OP_RECV_CLOSE_ON_SERVER] != 255) {
4030
+ auto recv_trailing_metadata = MaybeOp(
4031
+ ops, got_ops[GRPC_OP_RECV_CLOSE_ON_SERVER], [this](const grpc_op& op) {
4032
+ return [this, cancelled = op.data.recv_close_on_server.cancelled]() {
4033
+ return Map(server_trailing_metadata_.receiver.AwaitClosed(),
4034
+ [cancelled](bool result) -> Success {
4035
+ *cancelled = result ? 1 : 0;
4036
+ Crash("return metadata here");
4037
+ return Success{};
4038
+ });
4039
+ };
4040
+ });
4041
+ SpawnInfallible(
4042
+ "final-batch",
4043
+ [primary_ops = std::move(primary_ops),
4044
+ recv_trailing_metadata = std::move(recv_trailing_metadata),
4045
+ is_notify_tag_closure, notify_tag, this]() mutable {
4046
+ return Seq(std::move(primary_ops), std::move(recv_trailing_metadata),
4047
+ [is_notify_tag_closure, notify_tag, this](StatusFlag) {
4048
+ return WaitForCqEndOp(is_notify_tag_closure, notify_tag,
4049
+ absl::OkStatus(), cq());
4050
+ });
4051
+ });
4052
+ } else {
4053
+ SpawnInfallible(
4054
+ "batch", [primary_ops = std::move(primary_ops), is_notify_tag_closure,
4055
+ notify_tag, this]() mutable {
4056
+ return Seq(std::move(primary_ops), [is_notify_tag_closure, notify_tag,
4057
+ this](StatusFlag r) {
4058
+ return WaitForCqEndOp(is_notify_tag_closure, notify_tag,
4059
+ StatusCast<grpc_error_handle>(r), cq());
4060
+ });
4061
+ });
4062
+ }
4063
+ }
4064
+
4065
+ RefCountedPtr<CallSpineInterface> MakeServerCall(Server* server,
4066
+ Channel* channel,
4067
+ Arena* arena) {
4068
+ return RefCountedPtr<ServerCallSpine>(
4069
+ arena->New<ServerCallSpine>(server, channel, arena));
3584
4070
  }
3585
4071
  #else
3586
- ArenaPromise<ServerMetadataHandle>
3587
- ServerCallContext::MakeTopOfServerCallPromise(
3588
- CallArgs, grpc_completion_queue*, grpc_metadata_array*,
3589
- absl::FunctionRef<void(grpc_call*)>) {
3590
- (void)call_;
3591
- Crash("Promise-based server call is not enabled");
4072
+ RefCountedPtr<CallSpineInterface> MakeServerCall(Server*, Channel*, Arena*) {
4073
+ Crash("not implemented");
3592
4074
  }
3593
4075
  #endif
3594
4076
 
@@ -3794,3 +4276,8 @@ const char* grpc_call_error_to_string(grpc_call_error error) {
3794
4276
  }
3795
4277
  GPR_UNREACHABLE_CODE(return "GRPC_CALL_ERROR_UNKNOW");
3796
4278
  }
4279
+
4280
+ void grpc_call_run_in_event_engine(const grpc_call* call,
4281
+ absl::AnyInvocable<void()> cb) {
4282
+ grpc_core::Call::FromC(call)->event_engine()->Run(std::move(cb));
4283
+ }