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,7 +45,12 @@ inline absl::Status IntoStatus(absl::Status* status) {
45
45
  // can participate in TrySeq as result types that affect control flow.
46
46
  inline bool IsStatusOk(const absl::Status& status) { return status.ok(); }
47
47
 
48
- template <typename To, typename From>
48
+ template <typename T>
49
+ inline bool IsStatusOk(const absl::StatusOr<T>& status) {
50
+ return status.ok();
51
+ }
52
+
53
+ template <typename To, typename From, typename SfinaeVoid = void>
49
54
  struct StatusCastImpl;
50
55
 
51
56
  template <typename To>
@@ -59,20 +64,52 @@ struct StatusCastImpl<To, const To&> {
59
64
  };
60
65
 
61
66
  template <typename T>
62
- struct StatusCastImpl<absl::StatusOr<T>, absl::Status> {
63
- static absl::StatusOr<T> Cast(absl::Status&& t) { return std::move(t); }
67
+ struct StatusCastImpl<absl::Status, absl::StatusOr<T>> {
68
+ static absl::Status Cast(absl::StatusOr<T>&& t) {
69
+ return std::move(t.status());
70
+ }
64
71
  };
65
72
 
66
73
  template <typename T>
67
- struct StatusCastImpl<absl::StatusOr<T>, const absl::Status&> {
68
- static absl::StatusOr<T> Cast(const absl::Status& t) { return t; }
74
+ struct StatusCastImpl<absl::Status, absl::StatusOr<T>&> {
75
+ static absl::Status Cast(const absl::StatusOr<T>& t) { return t.status(); }
69
76
  };
70
77
 
78
+ template <typename T>
79
+ struct StatusCastImpl<absl::Status, const absl::StatusOr<T>&> {
80
+ static absl::Status Cast(const absl::StatusOr<T>& t) { return t.status(); }
81
+ };
82
+
83
+ // StatusCast<> allows casting from one status-bearing type to another,
84
+ // regardless of whether the status indicates success or failure.
85
+ // This means that we can go from StatusOr to Status safely, but not in the
86
+ // opposite direction.
87
+ // For cases where the status is guaranteed to be a failure (and hence not
88
+ // needing to preserve values) see FailureStatusCast<> below.
71
89
  template <typename To, typename From>
72
90
  To StatusCast(From&& from) {
73
91
  return StatusCastImpl<To, From>::Cast(std::forward<From>(from));
74
92
  }
75
93
 
94
+ template <typename To, typename From, typename SfinaeVoid = void>
95
+ struct FailureStatusCastImpl : public StatusCastImpl<To, From> {};
96
+
97
+ template <typename T>
98
+ struct FailureStatusCastImpl<absl::StatusOr<T>, absl::Status> {
99
+ static absl::StatusOr<T> Cast(absl::Status&& t) { return std::move(t); }
100
+ };
101
+
102
+ template <typename T>
103
+ struct FailureStatusCastImpl<absl::StatusOr<T>, const absl::Status&> {
104
+ static absl::StatusOr<T> Cast(const absl::Status& t) { return t; }
105
+ };
106
+
107
+ template <typename To, typename From>
108
+ To FailureStatusCast(From&& from) {
109
+ GPR_DEBUG_ASSERT(!IsStatusOk(from));
110
+ return FailureStatusCastImpl<To, From>::Cast(std::forward<From>(from));
111
+ }
112
+
76
113
  } // namespace grpc_core
77
114
 
78
115
  #endif // GRPC_SRC_CORE_LIB_PROMISE_DETAIL_STATUS_H
@@ -30,7 +30,9 @@
30
30
  #include "src/core/lib/gprpp/construct_destruct.h"
31
31
  #include "src/core/lib/promise/activity.h"
32
32
  #include "src/core/lib/promise/detail/promise_factory.h"
33
+ #include "src/core/lib/promise/detail/status.h"
33
34
  #include "src/core/lib/promise/poll.h"
35
+ #include "src/core/lib/promise/status_flag.h"
34
36
  #include "src/core/lib/promise/trace.h"
35
37
 
36
38
  namespace grpc_core {
@@ -48,6 +50,16 @@ struct Done<absl::Status> {
48
50
  static absl::Status Make() { return absl::OkStatus(); }
49
51
  };
50
52
 
53
+ template <>
54
+ struct Done<StatusFlag> {
55
+ static StatusFlag Make() { return StatusFlag(true); }
56
+ };
57
+
58
+ template <>
59
+ struct Done<Success> {
60
+ static Success Make() { return Success{}; }
61
+ };
62
+
51
63
  template <typename Reader, typename Action>
52
64
  class ForEach {
53
65
  private:
@@ -139,7 +151,7 @@ class ForEach {
139
151
  }
140
152
  auto r = in_action_.promise();
141
153
  if (auto* p = r.value_if_ready()) {
142
- if (p->ok()) {
154
+ if (IsStatusOk(*p)) {
143
155
  Destruct(&in_action_);
144
156
  Construct(&reader_next_, reader_.Next());
145
157
  reading_next_ = true;
@@ -192,6 +192,10 @@ class If<bool, T, F> {
192
192
  // If it returns failure, returns failure for the entire combinator.
193
193
  // If it returns true, evaluates the second promise.
194
194
  // If it returns false, evaluates the third promise.
195
+ // If C is a constant, it's guaranteed that one of the promise factories
196
+ // if_true or if_false will be evaluated before returning from this function.
197
+ // This makes it safe to capture lambda arguments in the promise factory by
198
+ // reference.
195
199
  template <typename C, typename T, typename F>
196
200
  promise_detail::If<C, T, F> If(C condition, T if_true, F if_false) {
197
201
  return promise_detail::If<C, T, F>(std::move(condition), std::move(if_true),
@@ -37,6 +37,7 @@ namespace grpc_core {
37
37
  // Initially the Latch is unset.
38
38
  // It can be waited upon by the Wait method, which produces a Promise that
39
39
  // resolves when the Latch is Set to a value of type T.
40
+ // Latches only work correctly within a single activity.
40
41
  template <typename T>
41
42
  class Latch {
42
43
  public:
@@ -184,6 +185,8 @@ class Latch<void> {
184
185
  waiter_.Wake();
185
186
  }
186
187
 
188
+ bool is_set() const { return is_set_; }
189
+
187
190
  private:
188
191
  std::string DebugTag() {
189
192
  return absl::StrCat(Activity::current()->DebugTag(), " LATCH(void)[0x",
@@ -204,6 +207,9 @@ class Latch<void> {
204
207
  IntraActivityWaiter waiter_;
205
208
  };
206
209
 
210
+ template <typename T>
211
+ using LatchWaitPromise = decltype(std::declval<Latch<T>>().Wait());
212
+
207
213
  // A Latch that can have its value observed by outside threads, but only waited
208
214
  // upon from inside a single activity.
209
215
  template <typename T>
@@ -268,9 +274,6 @@ class ExternallyObservableLatch<void> {
268
274
  IntraActivityWaiter waiter_;
269
275
  };
270
276
 
271
- template <typename T>
272
- using LatchWaitPromise = decltype(std::declval<Latch<T>>().Wait());
273
-
274
277
  } // namespace grpc_core
275
278
 
276
279
  #endif // GRPC_SRC_CORE_LIB_PROMISE_LATCH_H
@@ -227,40 +227,42 @@ void Party::RunLocked() {
227
227
  bool Party::RunParty() {
228
228
  ScopedActivity activity(this);
229
229
  promise_detail::Context<Arena> arena_ctx(arena_);
230
- return sync_.RunParty([this](int i) {
231
- // If the participant is null, skip.
232
- // This allows participants to complete whilst wakers still exist
233
- // somewhere.
234
- auto* participant = participants_[i].load(std::memory_order_acquire);
235
- if (participant == nullptr) {
236
- if (grpc_trace_promise_primitives.enabled()) {
237
- gpr_log(GPR_DEBUG, "%s[party] wakeup %d already complete",
238
- DebugTag().c_str(), i);
239
- }
240
- return false;
241
- }
242
- absl::string_view name;
230
+ return sync_.RunParty([this](int i) { return RunOneParticipant(i); });
231
+ }
232
+
233
+ bool Party::RunOneParticipant(int i) {
234
+ // If the participant is null, skip.
235
+ // This allows participants to complete whilst wakers still exist
236
+ // somewhere.
237
+ auto* participant = participants_[i].load(std::memory_order_acquire);
238
+ if (participant == nullptr) {
243
239
  if (grpc_trace_promise_primitives.enabled()) {
244
- name = participant->name();
245
- gpr_log(GPR_DEBUG, "%s[%s] begin job %d", DebugTag().c_str(),
246
- std::string(name).c_str(), i);
240
+ gpr_log(GPR_DEBUG, "%s[party] wakeup %d already complete",
241
+ DebugTag().c_str(), i);
247
242
  }
248
- // Poll the participant.
249
- currently_polling_ = i;
250
- bool done = participant->Poll();
251
- currently_polling_ = kNotPolling;
252
- if (done) {
253
- if (!name.empty()) {
254
- gpr_log(GPR_DEBUG, "%s[%s] end poll and finish job %d",
255
- DebugTag().c_str(), std::string(name).c_str(), i);
256
- }
257
- participants_[i].store(nullptr, std::memory_order_relaxed);
258
- } else if (!name.empty()) {
259
- gpr_log(GPR_DEBUG, "%s[%s] end poll", DebugTag().c_str(),
260
- std::string(name).c_str());
243
+ return false;
244
+ }
245
+ absl::string_view name;
246
+ if (grpc_trace_promise_primitives.enabled()) {
247
+ name = participant->name();
248
+ gpr_log(GPR_DEBUG, "%s[%s] begin job %d", DebugTag().c_str(),
249
+ std::string(name).c_str(), i);
250
+ }
251
+ // Poll the participant.
252
+ currently_polling_ = i;
253
+ bool done = participant->PollParticipantPromise();
254
+ currently_polling_ = kNotPolling;
255
+ if (done) {
256
+ if (!name.empty()) {
257
+ gpr_log(GPR_DEBUG, "%s[%s] end poll and finish job %d",
258
+ DebugTag().c_str(), std::string(name).c_str(), i);
261
259
  }
262
- return done;
263
- });
260
+ participants_[i].store(nullptr, std::memory_order_relaxed);
261
+ } else if (!name.empty()) {
262
+ gpr_log(GPR_DEBUG, "%s[%s] end poll", DebugTag().c_str(),
263
+ std::string(name).c_str());
264
+ }
265
+ return done;
264
266
  }
265
267
 
266
268
  void Party::AddParticipants(Participant** participants, size_t count) {
@@ -24,6 +24,7 @@
24
24
  #include <string>
25
25
  #include <utility>
26
26
 
27
+ #include "absl/base/attributes.h"
27
28
  #include "absl/base/thread_annotations.h"
28
29
  #include "absl/strings/string_view.h"
29
30
 
@@ -38,6 +39,7 @@
38
39
  #include "src/core/lib/promise/activity.h"
39
40
  #include "src/core/lib/promise/context.h"
40
41
  #include "src/core/lib/promise/detail/promise_factory.h"
42
+ #include "src/core/lib/promise/poll.h"
41
43
  #include "src/core/lib/promise/trace.h"
42
44
  #include "src/core/lib/resource_quota/arena.h"
43
45
 
@@ -100,7 +102,8 @@ class PartySyncUsingAtomics {
100
102
  template <typename F>
101
103
  GRPC_MUST_USE_RESULT bool RunParty(F poll_one_participant) {
102
104
  uint64_t prev_state;
103
- do {
105
+ iteration_.fetch_add(1, std::memory_order_relaxed);
106
+ for (;;) {
104
107
  // Grab the current state, and clear the wakeup bits & add flag.
105
108
  prev_state = state_.fetch_and(kRefMask | kLocked | kAllocatedMask,
106
109
  std::memory_order_acquire);
@@ -131,9 +134,23 @@ class PartySyncUsingAtomics {
131
134
  // TODO(ctiller): consider mitigations for the accidental wakeup on owning
132
135
  // waker creation case -- I currently expect this will be more expensive
133
136
  // than this quick loop.
134
- } while (!state_.compare_exchange_weak(
135
- prev_state, (prev_state & (kRefMask | kAllocatedMask)),
136
- std::memory_order_acq_rel, std::memory_order_acquire));
137
+ if (wake_after_poll_ == 0) {
138
+ if (state_.compare_exchange_weak(
139
+ prev_state, (prev_state & (kRefMask | kAllocatedMask)),
140
+ std::memory_order_acq_rel, std::memory_order_acquire)) {
141
+ return false;
142
+ }
143
+ } else {
144
+ if (state_.compare_exchange_weak(
145
+ prev_state,
146
+ (prev_state & (kRefMask | kAllocatedMask | kLocked)) |
147
+ wake_after_poll_,
148
+ std::memory_order_acq_rel, std::memory_order_acquire)) {
149
+ iteration_.fetch_add(1, std::memory_order_relaxed);
150
+ wake_after_poll_ = 0;
151
+ }
152
+ }
153
+ }
137
154
  return false;
138
155
  }
139
156
 
@@ -184,6 +201,11 @@ class PartySyncUsingAtomics {
184
201
  // Returns true if the caller should run the party.
185
202
  GRPC_MUST_USE_RESULT bool ScheduleWakeup(WakeupMask mask);
186
203
 
204
+ void WakeAfterPoll(WakeupMask mask) { wake_after_poll_ |= mask; }
205
+ uint32_t iteration() const {
206
+ return iteration_.load(std::memory_order_relaxed);
207
+ }
208
+
187
209
  private:
188
210
  bool UnreffedLast();
189
211
 
@@ -223,6 +245,8 @@ class PartySyncUsingAtomics {
223
245
  static constexpr uint64_t kOneRef = 1ull << kRefShift;
224
246
 
225
247
  std::atomic<uint64_t> state_;
248
+ std::atomic<uint32_t> iteration_{0};
249
+ WakeupMask wake_after_poll_ = 0;
226
250
  };
227
251
 
228
252
  class PartySyncUsingMutex {
@@ -298,7 +322,7 @@ class Party : public Activity, private Wakeable {
298
322
  explicit Participant(absl::string_view name) : name_(name) {}
299
323
  // Poll the participant. Return true if complete.
300
324
  // Participant should take care of its own deallocation in this case.
301
- virtual bool Poll() = 0;
325
+ virtual bool PollParticipantPromise() = 0;
302
326
 
303
327
  // Destroy the participant before finishing.
304
328
  virtual void Destroy() = 0;
@@ -330,6 +354,9 @@ class Party : public Activity, private Wakeable {
330
354
  void Spawn(absl::string_view name, Factory promise_factory,
331
355
  OnComplete on_complete);
332
356
 
357
+ template <typename Factory>
358
+ auto SpawnWaitable(absl::string_view name, Factory factory);
359
+
333
360
  void Orphan() final { Crash("unused"); }
334
361
 
335
362
  // Activity implementation: not allowed to be overridden by derived types.
@@ -353,6 +380,20 @@ class Party : public Activity, private Wakeable {
353
380
 
354
381
  Arena* arena() const { return arena_; }
355
382
 
383
+ // Return a promise that resolves to Empty{} when the current party poll is
384
+ // complete.
385
+ // This is useful for implementing batching and the like: we can hold some
386
+ // action until the rest of the party resolves itself.
387
+ auto AfterCurrentPoll() {
388
+ GPR_DEBUG_ASSERT(Activity::current() == this);
389
+ sync_.WakeAfterPoll(CurrentParticipant());
390
+ return [this, iteration = sync_.iteration()]() -> Poll<Empty> {
391
+ GPR_DEBUG_ASSERT(Activity::current() == this);
392
+ if (iteration == sync_.iteration()) return Pending{};
393
+ return Empty{};
394
+ };
395
+ }
396
+
356
397
  class BulkSpawner {
357
398
  public:
358
399
  explicit BulkSpawner(Party* party) : party_(party) {}
@@ -414,7 +455,7 @@ class Party : public Activity, private Wakeable {
414
455
  }
415
456
  }
416
457
 
417
- bool Poll() override {
458
+ bool PollParticipantPromise() override {
418
459
  if (!started_) {
419
460
  auto p = factory_.Make();
420
461
  Destruct(&factory_);
@@ -441,6 +482,89 @@ class Party : public Activity, private Wakeable {
441
482
  bool started_ = false;
442
483
  };
443
484
 
485
+ template <typename SuppliedFactory>
486
+ class PromiseParticipantImpl final
487
+ : public RefCounted<PromiseParticipantImpl<SuppliedFactory>,
488
+ NonPolymorphicRefCount>,
489
+ public Participant {
490
+ using Factory = promise_detail::OncePromiseFactory<void, SuppliedFactory>;
491
+ using Promise = typename Factory::Promise;
492
+ using Result = typename Promise::Result;
493
+
494
+ public:
495
+ PromiseParticipantImpl(absl::string_view name,
496
+ SuppliedFactory promise_factory)
497
+ : Participant(name) {
498
+ Construct(&factory_, std::move(promise_factory));
499
+ }
500
+
501
+ ~PromiseParticipantImpl() {
502
+ switch (state_.load(std::memory_order_acquire)) {
503
+ case State::kFactory:
504
+ Destruct(&factory_);
505
+ break;
506
+ case State::kPromise:
507
+ Destruct(&promise_);
508
+ break;
509
+ case State::kResult:
510
+ Destruct(&result_);
511
+ break;
512
+ }
513
+ }
514
+
515
+ // Inside party poll: drive from factory -> promise -> result
516
+ bool PollParticipantPromise() override {
517
+ switch (state_.load(std::memory_order_relaxed)) {
518
+ case State::kFactory: {
519
+ auto p = factory_.Make();
520
+ Destruct(&factory_);
521
+ Construct(&promise_, std::move(p));
522
+ state_.store(State::kPromise, std::memory_order_relaxed);
523
+ }
524
+ ABSL_FALLTHROUGH_INTENDED;
525
+ case State::kPromise: {
526
+ auto p = promise_();
527
+ if (auto* r = p.value_if_ready()) {
528
+ Destruct(&promise_);
529
+ Construct(&result_, std::move(*r));
530
+ state_.store(State::kResult, std::memory_order_release);
531
+ waiter_.Wakeup();
532
+ this->Unref();
533
+ return true;
534
+ }
535
+ return false;
536
+ }
537
+ case State::kResult:
538
+ Crash(
539
+ "unreachable: promises should not be repolled after completion");
540
+ }
541
+ }
542
+
543
+ // Outside party poll: check whether the spawning party has completed this
544
+ // promise.
545
+ Poll<Result> PollCompletion() {
546
+ switch (state_.load(std::memory_order_acquire)) {
547
+ case State::kFactory:
548
+ case State::kPromise:
549
+ return Pending{};
550
+ case State::kResult:
551
+ return std::move(result_);
552
+ }
553
+ }
554
+
555
+ void Destroy() override { this->Unref(); }
556
+
557
+ private:
558
+ enum class State : uint8_t { kFactory, kPromise, kResult };
559
+ union {
560
+ GPR_NO_UNIQUE_ADDRESS Factory factory_;
561
+ GPR_NO_UNIQUE_ADDRESS Promise promise_;
562
+ GPR_NO_UNIQUE_ADDRESS Result result_;
563
+ };
564
+ Waker waiter_{Activity::current()->MakeOwningWaker()};
565
+ std::atomic<State> state_{State::kFactory};
566
+ };
567
+
444
568
  // Notification that the party has finished and this instance can be deleted.
445
569
  // Derived types should arrange to call CancelRemainingParticipants during
446
570
  // this sequence.
@@ -460,6 +584,7 @@ class Party : public Activity, private Wakeable {
460
584
 
461
585
  // Add a participant (backs Spawn, after type erasure to ParticipantFactory).
462
586
  void AddParticipants(Participant** participant, size_t count);
587
+ bool RunOneParticipant(int i);
463
588
 
464
589
  virtual grpc_event_engine::experimental::EventEngine* event_engine()
465
590
  const = 0;
@@ -502,6 +627,17 @@ void Party::Spawn(absl::string_view name, Factory promise_factory,
502
627
  std::move(on_complete));
503
628
  }
504
629
 
630
+ template <typename Factory>
631
+ auto Party::SpawnWaitable(absl::string_view name, Factory promise_factory) {
632
+ auto participant = MakeRefCounted<PromiseParticipantImpl<Factory>>(
633
+ name, std::move(promise_factory));
634
+ Participant* p = participant->Ref().release();
635
+ AddParticipants(&p, 1);
636
+ return [participant = std::move(participant)]() mutable {
637
+ return participant->PollCompletion();
638
+ };
639
+ }
640
+
505
641
  } // namespace grpc_core
506
642
 
507
643
  #endif // GRPC_SRC_CORE_LIB_PROMISE_PARTY_H
@@ -186,25 +186,13 @@ class Poll<Pending>;
186
186
  template <class T>
187
187
  class Poll<Poll<T>>;
188
188
 
189
- template <typename T>
190
- bool operator==(const Poll<T>& a, const Poll<T>& b) {
191
- if (a.pending() && b.pending()) return true;
192
- if (a.ready() && b.ready()) return a.value() == b.value();
193
- return false;
194
- }
195
-
196
- template <typename T, typename U>
197
- Poll<T> poll_cast(Poll<U> poll) {
198
- if (poll.pending()) return Pending{};
199
- return static_cast<T>(std::move(poll.value()));
200
- }
201
-
202
189
  // PollTraits tells us whether a type is Poll<> or some other type, and is
203
190
  // leveraged in the PromiseLike/PromiseFactory machinery to select the
204
191
  // appropriate implementation of those concepts based upon the return type of a
205
192
  // lambda, for example (via enable_if).
206
193
  template <typename T>
207
194
  struct PollTraits {
195
+ using Type = T;
208
196
  static constexpr bool is_poll() { return false; }
209
197
  };
210
198
 
@@ -214,6 +202,44 @@ struct PollTraits<Poll<T>> {
214
202
  static constexpr bool is_poll() { return true; }
215
203
  };
216
204
 
205
+ template <typename T>
206
+ bool operator==(const Poll<T>& a, const Poll<T>& b) {
207
+ if (a.pending() && b.pending()) return true;
208
+ if (a.ready() && b.ready()) return a.value() == b.value();
209
+ return false;
210
+ }
211
+
212
+ template <typename T, typename U, typename SfinaeVoid = void>
213
+ struct PollCastImpl;
214
+
215
+ template <typename T, typename U>
216
+ struct PollCastImpl<T, Poll<U>> {
217
+ static Poll<T> Cast(Poll<U>&& poll) {
218
+ if (poll.pending()) return Pending{};
219
+ return static_cast<T>(std::move(poll.value()));
220
+ }
221
+ };
222
+
223
+ template <typename T, typename U>
224
+ struct PollCastImpl<T, U, std::enable_if<!PollTraits<U>::is_poll()>> {
225
+ static Poll<T> Cast(U&& poll) { return Poll<T>(T(std::move(poll))); }
226
+ };
227
+
228
+ template <typename T>
229
+ struct PollCastImpl<T, T> {
230
+ static Poll<T> Cast(T&& poll) { return Poll<T>(std::move(poll)); }
231
+ };
232
+
233
+ template <typename T>
234
+ struct PollCastImpl<T, Poll<T>> {
235
+ static Poll<T> Cast(Poll<T>&& poll) { return std::move(poll); }
236
+ };
237
+
238
+ template <typename T, typename U>
239
+ Poll<T> poll_cast(U poll) {
240
+ return PollCastImpl<T, U>::Cast(std::move(poll));
241
+ }
242
+
217
243
  // Convert a poll to a string
218
244
  template <typename T, typename F>
219
245
  std::string PollToString(
@@ -89,6 +89,10 @@ auto WithResult(F f) ->
89
89
  return f;
90
90
  }
91
91
 
92
+ template <typename Promise>
93
+ using PromiseResult = typename PollTraits<
94
+ typename promise_detail::PromiseLike<Promise>::Result>::Type;
95
+
92
96
  } // namespace grpc_core
93
97
 
94
98
  #endif // GRPC_SRC_CORE_LIB_PROMISE_PROMISE_H