grpc 1.60.0 → 1.61.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (277) 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 +67 -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/http2_settings.cc +122 -32
  93. data/src/core/ext/transport/chttp2/transport/http2_settings.h +142 -37
  94. data/src/core/ext/transport/chttp2/transport/internal.h +1 -22
  95. data/src/core/ext/transport/chttp2/transport/parsing.cc +23 -37
  96. data/src/core/ext/transport/chttp2/transport/writing.cc +26 -58
  97. data/src/core/ext/transport/inproc/inproc_transport.cc +172 -13
  98. data/src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb.h +712 -0
  99. data/src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.c +151 -0
  100. data/src/core/ext/upb-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upb_minitable.h +33 -0
  101. data/src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.c +133 -0
  102. data/src/core/ext/upbdefs-gen/envoy/extensions/upstreams/http/v3/http_protocol_options.upbdefs.h +50 -0
  103. data/src/core/ext/xds/certificate_provider_store.cc +2 -1
  104. data/src/core/ext/xds/certificate_provider_store.h +0 -5
  105. data/src/core/ext/xds/xds_api.cc +31 -18
  106. data/src/core/ext/xds/xds_api.h +2 -2
  107. data/src/core/ext/xds/xds_bootstrap.h +3 -0
  108. data/src/core/ext/xds/xds_certificate_provider.cc +88 -287
  109. data/src/core/ext/xds/xds_certificate_provider.h +44 -111
  110. data/src/core/ext/xds/xds_client.cc +420 -414
  111. data/src/core/ext/xds/xds_client.h +31 -22
  112. data/src/core/ext/xds/xds_client_grpc.cc +3 -1
  113. data/src/core/ext/xds/xds_cluster.cc +104 -11
  114. data/src/core/ext/xds/xds_cluster.h +9 -1
  115. data/src/core/ext/xds/xds_cluster_specifier_plugin.cc +9 -5
  116. data/src/core/ext/xds/xds_common_types.cc +14 -10
  117. data/src/core/ext/xds/xds_endpoint.cc +9 -4
  118. data/src/core/ext/xds/xds_endpoint.h +5 -1
  119. data/src/core/ext/xds/xds_health_status.cc +12 -2
  120. data/src/core/ext/xds/xds_health_status.h +4 -2
  121. data/src/core/ext/xds/xds_http_rbac_filter.cc +5 -3
  122. data/src/core/ext/xds/xds_listener.cc +14 -8
  123. data/src/core/ext/xds/xds_resource_type_impl.h +6 -4
  124. data/src/core/ext/xds/xds_route_config.cc +34 -22
  125. data/src/core/ext/xds/xds_route_config.h +1 -0
  126. data/src/core/ext/xds/xds_server_config_fetcher.cc +61 -57
  127. data/src/core/ext/xds/xds_transport.h +3 -0
  128. data/src/core/ext/xds/xds_transport_grpc.cc +47 -50
  129. data/src/core/ext/xds/xds_transport_grpc.h +4 -0
  130. data/src/core/lib/channel/call_tracer.cc +12 -0
  131. data/src/core/lib/channel/call_tracer.h +17 -3
  132. data/src/core/lib/channel/channel_args.cc +24 -14
  133. data/src/core/lib/channel/channel_args.h +74 -13
  134. data/src/core/lib/channel/channel_stack.cc +27 -0
  135. data/src/core/lib/channel/channel_stack.h +10 -10
  136. data/src/core/lib/channel/connected_channel.cc +64 -18
  137. data/src/core/lib/channel/promise_based_filter.h +1041 -1
  138. data/src/core/lib/channel/server_call_tracer_filter.cc +43 -35
  139. data/src/core/lib/compression/compression_internal.cc +0 -3
  140. data/src/core/lib/event_engine/ares_resolver.cc +35 -14
  141. data/src/core/lib/event_engine/ares_resolver.h +9 -10
  142. data/src/core/lib/event_engine/cf_engine/dns_service_resolver.cc +8 -1
  143. data/src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.cc +132 -0
  144. data/src/core/lib/event_engine/posix_engine/native_posix_dns_resolver.h +61 -0
  145. data/src/core/lib/event_engine/posix_engine/posix_engine.cc +52 -36
  146. data/src/core/lib/event_engine/posix_engine/posix_engine.h +4 -9
  147. data/src/core/lib/event_engine/posix_engine/posix_engine_listener_utils.cc +11 -3
  148. data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.cc +9 -2
  149. data/src/core/lib/event_engine/posix_engine/tcp_socket_utils.h +7 -0
  150. data/src/core/lib/event_engine/posix_engine/timer_manager.cc +17 -27
  151. data/src/core/lib/event_engine/posix_engine/timer_manager.h +0 -3
  152. data/src/core/lib/event_engine/ref_counted_dns_resolver_interface.h +55 -0
  153. data/src/core/lib/event_engine/windows/native_windows_dns_resolver.cc +114 -0
  154. data/src/core/lib/event_engine/windows/native_windows_dns_resolver.h +51 -0
  155. data/src/core/lib/event_engine/windows/windows_engine.cc +7 -7
  156. data/src/core/lib/experiments/config.cc +13 -0
  157. data/src/core/lib/experiments/config.h +3 -0
  158. data/src/core/lib/experiments/experiments.cc +245 -366
  159. data/src/core/lib/experiments/experiments.h +50 -156
  160. data/src/core/lib/gprpp/debug_location.h +13 -0
  161. data/src/core/lib/gprpp/dual_ref_counted.h +36 -7
  162. data/src/core/lib/gprpp/orphanable.h +27 -0
  163. data/src/core/lib/gprpp/ref_counted.h +63 -22
  164. data/src/core/lib/gprpp/ref_counted_ptr.h +70 -27
  165. data/src/core/lib/gprpp/ref_counted_string.h +13 -0
  166. data/src/core/lib/gprpp/status_helper.cc +1 -2
  167. data/src/core/lib/iomgr/combiner.cc +15 -51
  168. data/src/core/lib/iomgr/event_engine_shims/endpoint.cc +31 -0
  169. data/src/core/lib/iomgr/event_engine_shims/endpoint.h +16 -0
  170. data/src/core/lib/iomgr/tcp_client_posix.cc +4 -3
  171. data/src/core/lib/load_balancing/lb_policy.h +1 -1
  172. data/src/core/lib/promise/activity.cc +17 -2
  173. data/src/core/lib/promise/activity.h +5 -4
  174. data/src/core/lib/promise/all_ok.h +80 -0
  175. data/src/core/lib/promise/detail/join_state.h +2077 -0
  176. data/src/core/lib/promise/detail/promise_factory.h +1 -0
  177. data/src/core/lib/promise/detail/promise_like.h +8 -1
  178. data/src/core/lib/promise/detail/seq_state.h +3458 -150
  179. data/src/core/lib/promise/detail/status.h +42 -5
  180. data/src/core/lib/promise/for_each.h +13 -1
  181. data/src/core/lib/promise/if.h +4 -0
  182. data/src/core/lib/promise/latch.h +6 -3
  183. data/src/core/lib/promise/party.cc +33 -31
  184. data/src/core/lib/promise/party.h +142 -6
  185. data/src/core/lib/promise/poll.h +39 -13
  186. data/src/core/lib/promise/promise.h +4 -0
  187. data/src/core/lib/promise/seq.h +107 -7
  188. data/src/core/lib/promise/status_flag.h +196 -0
  189. data/src/core/lib/promise/try_join.h +132 -0
  190. data/src/core/lib/promise/try_seq.h +132 -10
  191. data/src/core/lib/resolver/endpoint_addresses.cc +0 -1
  192. data/src/core/lib/resolver/endpoint_addresses.h +48 -0
  193. data/src/core/lib/resource_quota/arena.h +2 -2
  194. data/src/core/lib/resource_quota/memory_quota.cc +57 -8
  195. data/src/core/lib/resource_quota/memory_quota.h +6 -0
  196. data/src/core/lib/security/authorization/grpc_server_authz_filter.cc +14 -11
  197. data/src/core/lib/security/authorization/grpc_server_authz_filter.h +14 -5
  198. data/src/core/lib/security/credentials/external/aws_external_account_credentials.cc +4 -0
  199. data/src/core/lib/security/credentials/external/aws_external_account_credentials.h +4 -0
  200. data/src/core/lib/security/credentials/external/external_account_credentials.cc +28 -20
  201. data/src/core/lib/security/credentials/external/external_account_credentials.h +4 -0
  202. data/src/core/lib/security/credentials/external/file_external_account_credentials.cc +4 -0
  203. data/src/core/lib/security/credentials/external/file_external_account_credentials.h +4 -0
  204. data/src/core/lib/security/credentials/external/url_external_account_credentials.cc +4 -0
  205. data/src/core/lib/security/credentials/external/url_external_account_credentials.h +4 -0
  206. data/src/core/lib/security/credentials/plugin/plugin_credentials.cc +2 -1
  207. data/src/core/lib/security/credentials/tls/grpc_tls_certificate_provider.h +0 -3
  208. data/src/core/lib/security/credentials/tls/grpc_tls_credentials_options.cc +12 -0
  209. data/src/core/lib/security/credentials/tls/grpc_tls_crl_provider.cc +22 -5
  210. data/src/core/lib/security/credentials/tls/grpc_tls_crl_provider.h +1 -5
  211. data/src/core/lib/security/credentials/tls/tls_credentials.cc +16 -0
  212. data/src/core/lib/security/credentials/xds/xds_credentials.cc +21 -28
  213. data/src/core/lib/security/credentials/xds/xds_credentials.h +2 -4
  214. data/src/core/lib/security/security_connector/tls/tls_security_connector.cc +4 -3
  215. data/src/core/lib/security/transport/auth_filters.h +71 -4
  216. data/src/core/lib/security/transport/client_auth_filter.cc +2 -4
  217. data/src/core/lib/security/transport/legacy_server_auth_filter.cc +244 -0
  218. data/src/core/lib/security/transport/server_auth_filter.cc +70 -90
  219. data/src/core/lib/slice/slice_buffer.h +3 -0
  220. data/src/core/lib/surface/builtins.cc +1 -1
  221. data/src/core/lib/surface/call.cc +683 -196
  222. data/src/core/lib/surface/call.h +26 -13
  223. data/src/core/lib/surface/call_trace.cc +42 -1
  224. data/src/core/lib/surface/channel.cc +0 -1
  225. data/src/core/lib/surface/channel.h +0 -6
  226. data/src/core/lib/surface/channel_init.h +26 -0
  227. data/src/core/lib/surface/init.cc +14 -8
  228. data/src/core/lib/surface/server.cc +256 -237
  229. data/src/core/lib/surface/server.h +26 -54
  230. data/src/core/lib/surface/version.cc +2 -2
  231. data/src/core/lib/surface/wait_for_cq_end_op.h +94 -0
  232. data/src/core/lib/transport/call_final_info.cc +38 -0
  233. data/src/core/lib/transport/call_final_info.h +54 -0
  234. data/src/core/lib/transport/connectivity_state.cc +3 -2
  235. data/src/core/lib/transport/connectivity_state.h +4 -0
  236. data/src/core/lib/transport/metadata_batch.h +4 -4
  237. data/src/core/lib/transport/transport.cc +70 -19
  238. data/src/core/lib/transport/transport.h +395 -25
  239. data/src/core/plugin_registry/grpc_plugin_registry.cc +3 -0
  240. data/src/core/plugin_registry/grpc_plugin_registry_extra.cc +0 -3
  241. data/src/core/tsi/alts/handshaker/alts_handshaker_client.cc +1 -1
  242. data/src/core/tsi/alts/handshaker/alts_tsi_handshaker.cc +1 -1
  243. data/src/core/tsi/alts/handshaker/transport_security_common_api.cc +1 -1
  244. data/src/core/tsi/ssl_transport_security.cc +65 -43
  245. data/src/ruby/ext/grpc/rb_channel_args.c +3 -1
  246. data/src/ruby/ext/grpc/rb_grpc.c +0 -1
  247. data/src/ruby/ext/grpc/rb_grpc.h +0 -2
  248. data/src/ruby/ext/grpc/rb_grpc_imports.generated.c +4 -0
  249. data/src/ruby/ext/grpc/rb_grpc_imports.generated.h +6 -0
  250. data/src/ruby/lib/grpc/version.rb +1 -1
  251. data/third_party/upb/upb/reflection/def_pool.h +2 -2
  252. data/third_party/zlib/adler32.c +5 -27
  253. data/third_party/zlib/compress.c +5 -16
  254. data/third_party/zlib/crc32.c +86 -162
  255. data/third_party/zlib/deflate.c +233 -336
  256. data/third_party/zlib/deflate.h +8 -8
  257. data/third_party/zlib/gzguts.h +11 -12
  258. data/third_party/zlib/infback.c +7 -23
  259. data/third_party/zlib/inffast.c +1 -4
  260. data/third_party/zlib/inffast.h +1 -1
  261. data/third_party/zlib/inflate.c +30 -99
  262. data/third_party/zlib/inftrees.c +6 -11
  263. data/third_party/zlib/inftrees.h +3 -3
  264. data/third_party/zlib/trees.c +224 -302
  265. data/third_party/zlib/uncompr.c +4 -12
  266. data/third_party/zlib/zconf.h +6 -2
  267. data/third_party/zlib/zlib.h +191 -188
  268. data/third_party/zlib/zutil.c +16 -44
  269. data/third_party/zlib/zutil.h +10 -10
  270. metadata +35 -13
  271. data/src/core/ext/filters/client_channel/lb_policy/xds/xds_cluster_resolver.cc +0 -1173
  272. data/src/core/lib/event_engine/memory_allocator.cc +0 -74
  273. data/src/core/lib/transport/pid_controller.cc +0 -51
  274. data/src/core/lib/transport/pid_controller.h +0 -116
  275. data/third_party/upb/upb/collections/array.h +0 -17
  276. data/third_party/upb/upb/collections/map.h +0 -17
  277. 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
+ }