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
@@ -21,6 +21,7 @@
21
21
 
22
22
  #include <utility>
23
23
 
24
+ #include "src/core/lib/gprpp/debug_location.h"
24
25
  #include "src/core/lib/promise/detail/basic_seq.h"
25
26
  #include "src/core/lib/promise/detail/promise_like.h"
26
27
  #include "src/core/lib/promise/detail/seq_state.h"
@@ -39,6 +40,7 @@ struct SeqTraits {
39
40
  return next->Make(std::forward<T>(value));
40
41
  }
41
42
  static bool IsOk(const T&) { return true; }
43
+ static const char* ErrorString(const T&) { abort(); }
42
44
  template <typename R>
43
45
  static R ReturnValue(T&&) {
44
46
  abort();
@@ -57,8 +59,9 @@ struct SeqTraits {
57
59
  template <typename P, typename... Fs>
58
60
  class Seq {
59
61
  public:
60
- explicit Seq(P&& promise, Fs&&... factories)
61
- : state_(std::forward<P>(promise), std::forward<Fs>(factories)...) {}
62
+ explicit Seq(P&& promise, Fs&&... factories, DebugLocation whence)
63
+ : state_(std::forward<P>(promise), std::forward<Fs>(factories)...,
64
+ whence) {}
62
65
 
63
66
  auto operator()() { return state_.PollOnce(); }
64
67
 
@@ -94,16 +97,113 @@ struct SeqIterResultTraits {
94
97
  // Pass its result to the third, and run the returned promise.
95
98
  // etc
96
99
  // Return the final value.
97
- template <typename... Functors>
98
- promise_detail::Seq<Functors...> Seq(Functors... functors) {
99
- return promise_detail::Seq<Functors...>(std::move(functors)...);
100
- }
101
-
102
100
  template <typename F>
103
101
  F Seq(F functor) {
104
102
  return functor;
105
103
  }
106
104
 
105
+ template <typename F0, typename F1>
106
+ promise_detail::Seq<F0, F1> Seq(F0 f0, F1 f1, DebugLocation whence = {}) {
107
+ return promise_detail::Seq<F0, F1>(std::move(f0), std::move(f1), whence);
108
+ }
109
+
110
+ template <typename F0, typename F1, typename F2>
111
+ promise_detail::Seq<F0, F1, F2> Seq(F0 f0, F1 f1, F2 f2,
112
+ DebugLocation whence = {}) {
113
+ return promise_detail::Seq<F0, F1, F2>(std::move(f0), std::move(f1),
114
+ std::move(f2), whence);
115
+ }
116
+
117
+ template <typename F0, typename F1, typename F2, typename F3>
118
+ promise_detail::Seq<F0, F1, F2, F3> Seq(F0 f0, F1 f1, F2 f2, F3 f3,
119
+ DebugLocation whence = {}) {
120
+ return promise_detail::Seq<F0, F1, F2, F3>(
121
+ std::move(f0), std::move(f1), std::move(f2), std::move(f3), whence);
122
+ }
123
+
124
+ template <typename F0, typename F1, typename F2, typename F3, typename F4>
125
+ promise_detail::Seq<F0, F1, F2, F3, F4> Seq(F0 f0, F1 f1, F2 f2, F3 f3, F4 f4,
126
+ DebugLocation whence = {}) {
127
+ return promise_detail::Seq<F0, F1, F2, F3, F4>(std::move(f0), std::move(f1),
128
+ std::move(f2), std::move(f3),
129
+ std::move(f4), whence);
130
+ }
131
+
132
+ template <typename F0, typename F1, typename F2, typename F3, typename F4,
133
+ typename F5>
134
+ promise_detail::Seq<F0, F1, F2, F3, F4, F5> Seq(F0 f0, F1 f1, F2 f2, F3 f3,
135
+ F4 f4, F5 f5,
136
+ DebugLocation whence = {}) {
137
+ return promise_detail::Seq<F0, F1, F2, F3, F4, F5>(
138
+ std::move(f0), std::move(f1), std::move(f2), std::move(f3), std::move(f4),
139
+ std::move(f5), whence);
140
+ }
141
+
142
+ template <typename F0, typename F1, typename F2, typename F3, typename F4,
143
+ typename F5, typename F6>
144
+ promise_detail::Seq<F0, F1, F2, F3, F4, F5, F6> Seq(F0 f0, F1 f1, F2 f2, F3 f3,
145
+ F4 f4, F5 f5, F6 f6,
146
+ DebugLocation whence = {}) {
147
+ return promise_detail::Seq<F0, F1, F2, F3, F4, F5, F6>(
148
+ std::move(f0), std::move(f1), std::move(f2), std::move(f3), std::move(f4),
149
+ std::move(f5), std::move(f6), whence);
150
+ }
151
+
152
+ template <typename F0, typename F1, typename F2, typename F3, typename F4,
153
+ typename F5, typename F6, typename F7>
154
+ promise_detail::Seq<F0, F1, F2, F3, F4, F5, F6, F7> Seq(
155
+ F0 f0, F1 f1, F2 f2, F3 f3, F4 f4, F5 f5, F6 f6, F7 f7,
156
+ DebugLocation whence = {}) {
157
+ return promise_detail::Seq<F0, F1, F2, F3, F4, F5, F6, F7>(
158
+ std::move(f0), std::move(f1), std::move(f2), std::move(f3), std::move(f4),
159
+ std::move(f5), std::move(f6), std::move(f7), whence);
160
+ }
161
+
162
+ template <typename F0, typename F1, typename F2, typename F3, typename F4,
163
+ typename F5, typename F6, typename F7, typename F8>
164
+ promise_detail::Seq<F0, F1, F2, F3, F4, F5, F6, F7, F8> Seq(
165
+ F0 f0, F1 f1, F2 f2, F3 f3, F4 f4, F5 f5, F6 f6, F7 f7, F8 f8,
166
+ DebugLocation whence = {}) {
167
+ return promise_detail::Seq<F0, F1, F2, F3, F4, F5, F6, F7, F8>(
168
+ std::move(f0), std::move(f1), std::move(f2), std::move(f3), std::move(f4),
169
+ std::move(f5), std::move(f6), std::move(f7), std::move(f8), whence);
170
+ }
171
+
172
+ template <typename F0, typename F1, typename F2, typename F3, typename F4,
173
+ typename F5, typename F6, typename F7, typename F8, typename F9>
174
+ promise_detail::Seq<F0, F1, F2, F3, F4, F5, F6, F7, F8, F9> Seq(
175
+ F0 f0, F1 f1, F2 f2, F3 f3, F4 f4, F5 f5, F6 f6, F7 f7, F8 f8, F9 f9,
176
+ DebugLocation whence = {}) {
177
+ return promise_detail::Seq<F0, F1, F2, F3, F4, F5, F6, F7, F8, F9>(
178
+ std::move(f0), std::move(f1), std::move(f2), std::move(f3), std::move(f4),
179
+ std::move(f5), std::move(f6), std::move(f7), std::move(f8), std::move(f9),
180
+ whence);
181
+ }
182
+
183
+ template <typename F0, typename F1, typename F2, typename F3, typename F4,
184
+ typename F5, typename F6, typename F7, typename F8, typename F9,
185
+ typename F10>
186
+ promise_detail::Seq<F0, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10> Seq(
187
+ F0 f0, F1 f1, F2 f2, F3 f3, F4 f4, F5 f5, F6 f6, F7 f7, F8 f8, F9 f9,
188
+ F10 f10, DebugLocation whence = {}) {
189
+ return promise_detail::Seq<F0, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10>(
190
+ std::move(f0), std::move(f1), std::move(f2), std::move(f3), std::move(f4),
191
+ std::move(f5), std::move(f6), std::move(f7), std::move(f8), std::move(f9),
192
+ std::move(f10), whence);
193
+ }
194
+
195
+ template <typename F0, typename F1, typename F2, typename F3, typename F4,
196
+ typename F5, typename F6, typename F7, typename F8, typename F9,
197
+ typename F10, typename F11>
198
+ promise_detail::Seq<F0, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11> Seq(
199
+ F0 f0, F1 f1, F2 f2, F3 f3, F4 f4, F5 f5, F6 f6, F7 f7, F8 f8, F9 f9,
200
+ F10 f10, F11 f11, DebugLocation whence = {}) {
201
+ return promise_detail::Seq<F0, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11>(
202
+ std::move(f0), std::move(f1), std::move(f2), std::move(f3), std::move(f4),
203
+ std::move(f5), std::move(f6), std::move(f7), std::move(f8), std::move(f9),
204
+ std::move(f10), std::move(f11), whence);
205
+ }
206
+
107
207
  // Execute a sequence of operations of unknown length.
108
208
  // Asynchronously:
109
209
  // for (element in (begin, end)) {
@@ -0,0 +1,196 @@
1
+ // Copyright 2023 gRPC authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #ifndef GRPC_SRC_CORE_LIB_PROMISE_STATUS_FLAG_H
16
+ #define GRPC_SRC_CORE_LIB_PROMISE_STATUS_FLAG_H
17
+
18
+ #include <grpc/support/port_platform.h>
19
+
20
+ #include "absl/status/status.h"
21
+ #include "absl/status/statusor.h"
22
+ #include "absl/types/optional.h"
23
+
24
+ #include <grpc/support/log.h>
25
+
26
+ #include "src/core/lib/promise/detail/status.h"
27
+
28
+ namespace grpc_core {
29
+
30
+ struct Failure {};
31
+ struct Success {};
32
+
33
+ inline bool IsStatusOk(Failure) { return false; }
34
+ inline bool IsStatusOk(Success) { return true; }
35
+
36
+ template <>
37
+ struct StatusCastImpl<absl::Status, Success> {
38
+ static absl::Status Cast(Success) { return absl::OkStatus(); }
39
+ };
40
+
41
+ template <>
42
+ struct StatusCastImpl<absl::Status, const Success&> {
43
+ static absl::Status Cast(Success) { return absl::OkStatus(); }
44
+ };
45
+
46
+ template <>
47
+ struct StatusCastImpl<absl::Status, Failure> {
48
+ static absl::Status Cast(Failure) { return absl::CancelledError(); }
49
+ };
50
+
51
+ template <typename T>
52
+ struct StatusCastImpl<absl::StatusOr<T>, Failure> {
53
+ static absl::StatusOr<T> Cast(Failure) { return absl::CancelledError(); }
54
+ };
55
+
56
+ // A boolean representing whether an operation succeeded (true) or failed
57
+ // (false).
58
+ class StatusFlag {
59
+ public:
60
+ StatusFlag() : value_(true) {}
61
+ explicit StatusFlag(bool value) : value_(value) {}
62
+ // NOLINTNEXTLINE(google-explicit-constructor)
63
+ StatusFlag(Failure) : value_(false) {}
64
+ // NOLINTNEXTLINE(google-explicit-constructor)
65
+ StatusFlag(Success) : value_(true) {}
66
+
67
+ bool ok() const { return value_; }
68
+
69
+ bool operator==(StatusFlag other) const { return value_ == other.value_; }
70
+
71
+ private:
72
+ bool value_;
73
+ };
74
+
75
+ inline bool IsStatusOk(const StatusFlag& flag) { return flag.ok(); }
76
+
77
+ template <>
78
+ struct StatusCastImpl<absl::Status, StatusFlag> {
79
+ static absl::Status Cast(StatusFlag flag) {
80
+ return flag.ok() ? absl::OkStatus() : absl::CancelledError();
81
+ }
82
+ };
83
+
84
+ template <>
85
+ struct StatusCastImpl<absl::Status, StatusFlag&> {
86
+ static absl::Status Cast(StatusFlag flag) {
87
+ return flag.ok() ? absl::OkStatus() : absl::CancelledError();
88
+ }
89
+ };
90
+
91
+ template <>
92
+ struct StatusCastImpl<absl::Status, const StatusFlag&> {
93
+ static absl::Status Cast(StatusFlag flag) {
94
+ return flag.ok() ? absl::OkStatus() : absl::CancelledError();
95
+ }
96
+ };
97
+
98
+ template <typename T>
99
+ struct FailureStatusCastImpl<absl::StatusOr<T>, StatusFlag> {
100
+ static absl::StatusOr<T> Cast(StatusFlag flag) {
101
+ GPR_DEBUG_ASSERT(!flag.ok());
102
+ return absl::CancelledError();
103
+ }
104
+ };
105
+
106
+ template <typename T>
107
+ struct FailureStatusCastImpl<absl::StatusOr<T>, StatusFlag&> {
108
+ static absl::StatusOr<T> Cast(StatusFlag flag) {
109
+ GPR_DEBUG_ASSERT(!flag.ok());
110
+ return absl::CancelledError();
111
+ }
112
+ };
113
+
114
+ template <typename T>
115
+ struct FailureStatusCastImpl<absl::StatusOr<T>, const StatusFlag&> {
116
+ static absl::StatusOr<T> Cast(StatusFlag flag) {
117
+ GPR_DEBUG_ASSERT(!flag.ok());
118
+ return absl::CancelledError();
119
+ }
120
+ };
121
+
122
+ // A value if an operation was successful, or a failure flag if not.
123
+ template <typename T>
124
+ class ValueOrFailure {
125
+ public:
126
+ // NOLINTNEXTLINE(google-explicit-constructor)
127
+ ValueOrFailure(T value) : value_(std::move(value)) {}
128
+ // NOLINTNEXTLINE(google-explicit-constructor)
129
+ ValueOrFailure(Failure) {}
130
+ // NOLINTNEXTLINE(google-explicit-constructor)
131
+ ValueOrFailure(StatusFlag status) { GPR_ASSERT(!status.ok()); }
132
+
133
+ static ValueOrFailure FromOptional(absl::optional<T> value) {
134
+ return ValueOrFailure{std::move(value)};
135
+ }
136
+
137
+ bool ok() const { return value_.has_value(); }
138
+ StatusFlag status() const { return StatusFlag(ok()); }
139
+
140
+ const T& value() const { return value_.value(); }
141
+ T& value() { return value_.value(); }
142
+ const T& operator*() const { return *value_; }
143
+ T& operator*() { return *value_; }
144
+
145
+ bool operator==(const ValueOrFailure& other) const {
146
+ return value_ == other.value_;
147
+ }
148
+
149
+ private:
150
+ absl::optional<T> value_;
151
+ };
152
+
153
+ template <typename T>
154
+ inline bool IsStatusOk(const ValueOrFailure<T>& value) {
155
+ return value.ok();
156
+ }
157
+
158
+ template <typename T>
159
+ inline T TakeValue(ValueOrFailure<T>&& value) {
160
+ return std::move(value.value());
161
+ }
162
+
163
+ template <typename T>
164
+ struct StatusCastImpl<absl::StatusOr<T>, ValueOrFailure<T>> {
165
+ static absl::StatusOr<T> Cast(ValueOrFailure<T> value) {
166
+ return value.ok() ? absl::StatusOr<T>(std::move(value.value()))
167
+ : absl::CancelledError();
168
+ }
169
+ };
170
+
171
+ template <typename T>
172
+ struct StatusCastImpl<ValueOrFailure<T>, Failure> {
173
+ static ValueOrFailure<T> Cast(Failure) {
174
+ return ValueOrFailure<T>(Failure{});
175
+ }
176
+ };
177
+
178
+ template <typename T>
179
+ struct StatusCastImpl<ValueOrFailure<T>, StatusFlag&> {
180
+ static ValueOrFailure<T> Cast(StatusFlag f) {
181
+ GPR_ASSERT(!f.ok());
182
+ return ValueOrFailure<T>(Failure{});
183
+ }
184
+ };
185
+
186
+ template <typename T>
187
+ struct StatusCastImpl<ValueOrFailure<T>, StatusFlag> {
188
+ static ValueOrFailure<T> Cast(StatusFlag f) {
189
+ GPR_ASSERT(!f.ok());
190
+ return ValueOrFailure<T>(Failure{});
191
+ }
192
+ };
193
+
194
+ } // namespace grpc_core
195
+
196
+ #endif // GRPC_SRC_CORE_LIB_PROMISE_STATUS_FLAG_H
@@ -0,0 +1,132 @@
1
+ // Copyright 2021 gRPC authors.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ #ifndef GRPC_SRC_CORE_LIB_PROMISE_TRY_JOIN_H
16
+ #define GRPC_SRC_CORE_LIB_PROMISE_TRY_JOIN_H
17
+
18
+ #include <grpc/support/port_platform.h>
19
+
20
+ #include <tuple>
21
+ #include <variant>
22
+
23
+ #include "absl/meta/type_traits.h"
24
+ #include "absl/status/status.h"
25
+ #include "absl/status/statusor.h"
26
+
27
+ #include "src/core/lib/promise/detail/join_state.h"
28
+ #include "src/core/lib/promise/map.h"
29
+ #include "src/core/lib/promise/poll.h"
30
+ #include "src/core/lib/promise/status_flag.h"
31
+
32
+ namespace grpc_core {
33
+
34
+ namespace promise_detail {
35
+
36
+ // Extract the T from a StatusOr<T>
37
+ template <typename T>
38
+ T IntoResult(absl::StatusOr<T>* status) {
39
+ return std::move(**status);
40
+ }
41
+
42
+ // TryJoin returns a StatusOr<tuple<A,B,C>> for f()->Poll<StatusOr<A>>,
43
+ // g()->Poll<StatusOr<B>>, h()->Poll<StatusOr<C>>. If one of those should be a
44
+ // Status instead, we need a placeholder type to return, and this is it.
45
+ inline Empty IntoResult(absl::Status*) { return Empty{}; }
46
+
47
+ // Traits object to pass to BasicJoin
48
+ template <template <typename> class Result>
49
+ struct TryJoinTraits {
50
+ template <typename T>
51
+ using ResultType = Result<absl::remove_reference_t<T>>;
52
+ template <typename T>
53
+ static bool IsOk(const absl::StatusOr<T>& x) {
54
+ return x.ok();
55
+ }
56
+ static bool IsOk(const absl::Status& x) { return x.ok(); }
57
+ static bool IsOk(StatusFlag x) { return x.ok(); }
58
+ template <typename T>
59
+ static bool IsOk(const ValueOrFailure<T>& x) {
60
+ return x.ok();
61
+ }
62
+ template <typename T>
63
+ static T Unwrapped(absl::StatusOr<T> x) {
64
+ return std::move(*x);
65
+ }
66
+ template <typename T>
67
+ static T Unwrapped(ValueOrFailure<T> x) {
68
+ return std::move(*x);
69
+ }
70
+ static Empty Unwrapped(absl::Status) { return Empty{}; }
71
+ static Empty Unwrapped(StatusFlag) { return Empty{}; }
72
+ template <typename R, typename T>
73
+ static R EarlyReturn(absl::StatusOr<T> x) {
74
+ return x.status();
75
+ }
76
+ template <typename R>
77
+ static R EarlyReturn(absl::Status x) {
78
+ return FailureStatusCast<R>(std::move(x));
79
+ }
80
+ template <typename R>
81
+ static R EarlyReturn(StatusFlag x) {
82
+ return FailureStatusCast<R>(x);
83
+ }
84
+ template <typename R, typename T>
85
+ static R EarlyReturn(const ValueOrFailure<T>& x) {
86
+ GPR_ASSERT(!x.ok());
87
+ return FailureStatusCast<R>(Failure{});
88
+ }
89
+ template <typename... A>
90
+ static auto FinalReturn(A&&... a) {
91
+ return Result<std::tuple<A...>>(std::make_tuple(std::forward<A>(a)...));
92
+ }
93
+ };
94
+
95
+ // Implementation of TryJoin combinator.
96
+ template <template <typename> class R, typename... Promises>
97
+ class TryJoin {
98
+ public:
99
+ explicit TryJoin(Promises... promises) : state_(std::move(promises)...) {}
100
+ auto operator()() { return state_.PollOnce(); }
101
+
102
+ private:
103
+ JoinState<TryJoinTraits<R>, Promises...> state_;
104
+ };
105
+
106
+ template <template <typename> class R>
107
+ struct WrapInStatusOrTuple {
108
+ template <typename T>
109
+ R<std::tuple<T>> operator()(R<T> x) {
110
+ if (!x.ok()) return x.status();
111
+ return std::make_tuple(std::move(*x));
112
+ }
113
+ };
114
+
115
+ } // namespace promise_detail
116
+
117
+ // Run all promises.
118
+ // If any fail, cancel the rest and return the failure.
119
+ // If all succeed, return Ok(tuple-of-results).
120
+ template <template <typename> class R, typename... Promises>
121
+ promise_detail::TryJoin<R, Promises...> TryJoin(Promises... promises) {
122
+ return promise_detail::TryJoin<R, Promises...>(std::move(promises)...);
123
+ }
124
+
125
+ template <template <typename> class R, typename F>
126
+ auto TryJoin(F promise) {
127
+ return Map(promise, promise_detail::WrapInStatusOrTuple<R>{});
128
+ }
129
+
130
+ } // namespace grpc_core
131
+
132
+ #endif // GRPC_SRC_CORE_LIB_PROMISE_TRY_JOIN_H
@@ -31,6 +31,7 @@
31
31
  #include "src/core/lib/promise/detail/seq_state.h"
32
32
  #include "src/core/lib/promise/detail/status.h"
33
33
  #include "src/core/lib/promise/poll.h"
34
+ #include "src/core/lib/promise/status_flag.h"
34
35
 
35
36
  namespace grpc_core {
36
37
 
@@ -45,6 +46,7 @@ struct TrySeqTraitsWithSfinae {
45
46
  return next->Make(std::forward<T>(value));
46
47
  }
47
48
  static bool IsOk(const T&) { return true; }
49
+ static const char* ErrorString(const T&) { abort(); }
48
50
  template <typename R>
49
51
  static R ReturnValue(T&&) {
50
52
  abort();
@@ -69,9 +71,12 @@ struct TrySeqTraitsWithSfinae<absl::StatusOr<T>> {
69
71
  return next->Make(std::move(*status));
70
72
  }
71
73
  static bool IsOk(const absl::StatusOr<T>& status) { return status.ok(); }
74
+ static std::string ErrorString(const absl::StatusOr<T>& status) {
75
+ return status.status().ToString();
76
+ }
72
77
  template <typename R>
73
78
  static R ReturnValue(absl::StatusOr<T>&& status) {
74
- return StatusCast<R>(status.status());
79
+ return FailureStatusCast<R>(status.status());
75
80
  }
76
81
  template <typename F, typename Elem>
77
82
  static auto CallSeqFactory(F& f, Elem&& elem, absl::StatusOr<T> value)
@@ -81,17 +86,43 @@ struct TrySeqTraitsWithSfinae<absl::StatusOr<T>> {
81
86
  template <typename Result, typename RunNext>
82
87
  static Poll<Result> CheckResultAndRunNext(absl::StatusOr<T> prior,
83
88
  RunNext run_next) {
84
- if (!prior.ok()) return StatusCast<Result>(prior.status());
89
+ if (!prior.ok()) return FailureStatusCast<Result>(prior.status());
85
90
  return run_next(std::move(prior));
86
91
  }
87
92
  };
93
+
94
+ template <typename T>
95
+ struct AllowGenericTrySeqTraits {
96
+ static constexpr bool value = true;
97
+ };
98
+
99
+ template <>
100
+ struct AllowGenericTrySeqTraits<absl::Status> {
101
+ static constexpr bool value = false;
102
+ };
103
+
104
+ template <typename T>
105
+ struct AllowGenericTrySeqTraits<absl::StatusOr<T>> {
106
+ static constexpr bool value = false;
107
+ };
108
+
109
+ template <typename T, typename AnyType = void>
110
+ struct TakeValueExists {
111
+ static constexpr bool value = false;
112
+ };
113
+ template <typename T>
114
+ struct TakeValueExists<T,
115
+ absl::void_t<decltype(TakeValue(std::declval<T>()))>> {
116
+ static constexpr bool value = true;
117
+ };
88
118
  // If there exists a function 'IsStatusOk(const T&) -> bool' then we assume that
89
119
  // T is a status type for the purposes of promise sequences, and a non-OK T
90
120
  // should terminate the sequence and return.
91
121
  template <typename T>
92
122
  struct TrySeqTraitsWithSfinae<
93
123
  T, absl::enable_if_t<
94
- std::is_same<decltype(IsStatusOk(std::declval<T>())), bool>::value,
124
+ std::is_same<decltype(IsStatusOk(std::declval<T>())), bool>::value &&
125
+ !TakeValueExists<T>::value && AllowGenericTrySeqTraits<T>::value,
95
126
  void>> {
96
127
  using UnwrappedType = void;
97
128
  using WrappedType = T;
@@ -100,9 +131,39 @@ struct TrySeqTraitsWithSfinae<
100
131
  return next->Make();
101
132
  }
102
133
  static bool IsOk(const T& status) { return IsStatusOk(status); }
134
+ static std::string ErrorString(const T& status) {
135
+ return IsStatusOk(status) ? "OK" : "FAILED";
136
+ }
137
+ template <typename R>
138
+ static R ReturnValue(T&& status) {
139
+ return FailureStatusCast<R>(std::move(status));
140
+ }
141
+ template <typename Result, typename RunNext>
142
+ static Poll<Result> CheckResultAndRunNext(T prior, RunNext run_next) {
143
+ if (!IsStatusOk(prior)) return Result(std::move(prior));
144
+ return run_next(std::move(prior));
145
+ }
146
+ };
147
+ template <typename T>
148
+ struct TrySeqTraitsWithSfinae<
149
+ T, absl::enable_if_t<
150
+ std::is_same<decltype(IsStatusOk(std::declval<T>())), bool>::value &&
151
+ TakeValueExists<T>::value && AllowGenericTrySeqTraits<T>::value,
152
+ void>> {
153
+ using UnwrappedType = decltype(TakeValue(std::declval<T>()));
154
+ using WrappedType = T;
155
+ template <typename Next>
156
+ static auto CallFactory(Next* next, T&& status) {
157
+ return next->Make(TakeValue(std::forward<T>(status)));
158
+ }
159
+ static bool IsOk(const T& status) { return IsStatusOk(status); }
160
+ static std::string ErrorString(const T& status) {
161
+ return IsStatusOk(status) ? "OK" : "FAILED";
162
+ }
103
163
  template <typename R>
104
164
  static R ReturnValue(T&& status) {
105
- return R(std::move(status));
165
+ GPR_DEBUG_ASSERT(!IsStatusOk(status));
166
+ return FailureStatusCast<R>(status.status());
106
167
  }
107
168
  template <typename Result, typename RunNext>
108
169
  static Poll<Result> CheckResultAndRunNext(T prior, RunNext run_next) {
@@ -119,9 +180,12 @@ struct TrySeqTraitsWithSfinae<absl::Status> {
119
180
  return next->Make();
120
181
  }
121
182
  static bool IsOk(const absl::Status& status) { return status.ok(); }
183
+ static std::string ErrorString(const absl::Status& status) {
184
+ return status.ToString();
185
+ }
122
186
  template <typename R>
123
187
  static R ReturnValue(absl::Status&& status) {
124
- return StatusCast<R>(std::move(status));
188
+ return FailureStatusCast<R>(std::move(status));
125
189
  }
126
190
  template <typename Result, typename RunNext>
127
191
  static Poll<Result> CheckResultAndRunNext(absl::Status prior,
@@ -137,8 +201,9 @@ using TrySeqTraits = TrySeqTraitsWithSfinae<T>;
137
201
  template <typename P, typename... Fs>
138
202
  class TrySeq {
139
203
  public:
140
- explicit TrySeq(P&& promise, Fs&&... factories)
141
- : state_(std::forward<P>(promise), std::forward<Fs>(factories)...) {}
204
+ explicit TrySeq(P&& promise, Fs&&... factories, DebugLocation whence)
205
+ : state_(std::forward<P>(promise), std::forward<Fs>(factories)...,
206
+ whence) {}
142
207
 
143
208
  auto operator()() { return state_.PollOnce(); }
144
209
 
@@ -180,9 +245,66 @@ struct TrySeqIterResultTraits {
180
245
  // Functors can return StatusOr<> to signal that a value is fed forward, or
181
246
  // Status to indicate only success/failure. In the case of returning Status,
182
247
  // the construction functors take no arguments.
183
- template <typename... Functors>
184
- promise_detail::TrySeq<Functors...> TrySeq(Functors... functors) {
185
- return promise_detail::TrySeq<Functors...>(std::move(functors)...);
248
+ template <typename F>
249
+ F TrySeq(F functor) {
250
+ return functor;
251
+ }
252
+
253
+ template <typename F0, typename F1>
254
+ promise_detail::TrySeq<F0, F1> TrySeq(F0 f0, F1 f1, DebugLocation whence = {}) {
255
+ return promise_detail::TrySeq<F0, F1>(std::move(f0), std::move(f1), whence);
256
+ }
257
+
258
+ template <typename F0, typename F1, typename F2>
259
+ promise_detail::TrySeq<F0, F1, F2> TrySeq(F0 f0, F1 f1, F2 f2,
260
+ DebugLocation whence = {}) {
261
+ return promise_detail::TrySeq<F0, F1, F2>(std::move(f0), std::move(f1),
262
+ std::move(f2), whence);
263
+ }
264
+
265
+ template <typename F0, typename F1, typename F2, typename F3>
266
+ promise_detail::TrySeq<F0, F1, F2, F3> TrySeq(F0 f0, F1 f1, F2 f2, F3 f3,
267
+ DebugLocation whence = {}) {
268
+ return promise_detail::TrySeq<F0, F1, F2, F3>(
269
+ std::move(f0), std::move(f1), std::move(f2), std::move(f3), whence);
270
+ }
271
+
272
+ template <typename F0, typename F1, typename F2, typename F3, typename F4>
273
+ promise_detail::TrySeq<F0, F1, F2, F3, F4> TrySeq(F0 f0, F1 f1, F2 f2, F3 f3,
274
+ F4 f4,
275
+ DebugLocation whence = {}) {
276
+ return promise_detail::TrySeq<F0, F1, F2, F3, F4>(
277
+ std::move(f0), std::move(f1), std::move(f2), std::move(f3), std::move(f4),
278
+ whence);
279
+ }
280
+
281
+ template <typename F0, typename F1, typename F2, typename F3, typename F4,
282
+ typename F5>
283
+ promise_detail::TrySeq<F0, F1, F2, F3, F4, F5> TrySeq(
284
+ F0 f0, F1 f1, F2 f2, F3 f3, F4 f4, F5 f5, DebugLocation whence = {}) {
285
+ return promise_detail::TrySeq<F0, F1, F2, F3, F4, F5>(
286
+ std::move(f0), std::move(f1), std::move(f2), std::move(f3), std::move(f4),
287
+ std::move(f5), whence);
288
+ }
289
+
290
+ template <typename F0, typename F1, typename F2, typename F3, typename F4,
291
+ typename F5, typename F6>
292
+ promise_detail::TrySeq<F0, F1, F2, F3, F4, F5, F6> TrySeq(
293
+ F0 f0, F1 f1, F2 f2, F3 f3, F4 f4, F5 f5, F6 f6,
294
+ DebugLocation whence = {}) {
295
+ return promise_detail::TrySeq<F0, F1, F2, F3, F4, F5, F6>(
296
+ std::move(f0), std::move(f1), std::move(f2), std::move(f3), std::move(f4),
297
+ std::move(f5), std::move(f6), whence);
298
+ }
299
+
300
+ template <typename F0, typename F1, typename F2, typename F3, typename F4,
301
+ typename F5, typename F6, typename F7>
302
+ promise_detail::TrySeq<F0, F1, F2, F3, F4, F5, F6, F7> TrySeq(
303
+ F0 f0, F1 f1, F2 f2, F3 f3, F4 f4, F5 f5, F6 f6, F7 f7,
304
+ DebugLocation whence = {}) {
305
+ return promise_detail::TrySeq<F0, F1, F2, F3, F4, F5, F6, F7>(
306
+ std::move(f0), std::move(f1), std::move(f2), std::move(f3), std::move(f4),
307
+ std::move(f5), std::move(f6), std::move(f7), whence);
186
308
  }
187
309
 
188
310
  // Try a sequence of operations of unknown length.
@@ -22,7 +22,6 @@
22
22
 
23
23
  #include <string.h>
24
24
 
25
- #include <algorithm>
26
25
  #include <string>
27
26
  #include <utility>
28
27
  #include <vector>