[promises] Make Poll<T> its own type, not a variant<> (#32515)

Avoids some compilation problems on older MSVC's, opens the door for
some future optimizations.

---------

Co-authored-by: ctiller <ctiller@users.noreply.github.com>
pull/32552/head
Craig Tiller 2 years ago committed by GitHub
parent 73bf7a364d
commit 0d7b34451a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      BUILD
  2. 35
      CMakeLists.txt
  3. 43
      build_autogenerated.yaml
  4. 29
      src/core/BUILD
  5. 5
      src/core/ext/transport/chttp2/transport/chttp2_transport.cc
  6. 10
      src/core/lib/channel/connected_channel.cc
  7. 32
      src/core/lib/channel/promise_based_filter.cc
  8. 4
      src/core/lib/promise/activity.h
  9. 5
      src/core/lib/promise/cancel_callback.h
  10. 3
      src/core/lib/promise/detail/basic_join.h
  11. 20
      src/core/lib/promise/detail/basic_seq.h
  12. 5
      src/core/lib/promise/for_each.h
  13. 4
      src/core/lib/promise/if.h
  14. 3
      src/core/lib/promise/interceptor_list.h
  15. 2
      src/core/lib/promise/loop.h
  16. 4
      src/core/lib/promise/map.h
  17. 3
      src/core/lib/promise/observable.h
  18. 4
      src/core/lib/promise/party.h
  19. 2
      src/core/lib/promise/pipe.h
  20. 121
      src/core/lib/promise/poll.h
  21. 3
      src/core/lib/promise/promise.h
  22. 9
      src/core/lib/promise/race.h
  23. 15
      src/core/lib/surface/call.cc
  24. 4
      src/core/lib/surface/call_trace.cc
  25. 7
      test/core/filters/client_auth_filter_test.cc
  26. 5
      test/core/filters/client_authority_filter_test.cc
  27. 5
      test/core/filters/filter_fuzzer.cc
  28. 27
      test/core/promise/BUILD
  29. 1
      test/core/promise/activity_test.cc
  30. 3
      test/core/promise/arena_promise_test.cc
  31. 2
      test/core/promise/cancel_callback_test.cc
  32. 6
      test/core/promise/for_each_test.cc
  33. 12
      test/core/promise/interceptor_list_test.cc
  34. 1
      test/core/promise/party_test.cc
  35. 5
      test/core/promise/poll_test.cc
  36. 4
      test/core/promise/race_test.cc
  37. 3
      test/core/promise/seq_test.cc
  38. 4
      test/core/promise/try_seq_metadata_test.cc

@ -2346,7 +2346,6 @@ grpc_cc_library(
external_deps = [
"absl/status",
"absl/types:optional",
"absl/types:variant",
],
language = "c++",
public_hdrs = [
@ -3660,7 +3659,6 @@ grpc_cc_library(
"absl/strings:cord",
"absl/strings:str_format",
"absl/types:optional",
"absl/types:variant",
],
language = "c++",
visibility = ["@grpc:grpclb"],

35
CMakeLists.txt generated

@ -7476,7 +7476,7 @@ target_link_libraries(cancel_callback_test
${_gRPC_ZLIB_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
absl::type_traits
absl::variant
gpr
)
@ -13871,7 +13871,7 @@ target_link_libraries(if_test
${_gRPC_ALLTARGETS_LIBRARIES}
absl::type_traits
absl::statusor
absl::variant
gpr
)
@ -14294,9 +14294,8 @@ target_link_libraries(join_test
${_gRPC_ZLIB_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
absl::type_traits
absl::strings
absl::variant
absl::utility
gpr
)
@ -14744,10 +14743,9 @@ target_link_libraries(loop_test
${_gRPC_ZLIB_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
absl::type_traits
absl::status
absl::statusor
absl::variant
absl::utility
gpr
)
@ -16377,7 +16375,7 @@ target_link_libraries(poll_test
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ZLIB_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
absl::variant
gpr
)
@ -16642,9 +16640,7 @@ target_link_libraries(promise_factory_test
${_gRPC_ALLTARGETS_LIBRARIES}
absl::bind_front
absl::type_traits
absl::status
absl::optional
absl::variant
gpr
)
@ -16682,9 +16678,7 @@ target_link_libraries(promise_map_test
${_gRPC_ZLIB_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
absl::type_traits
absl::status
absl::optional
absl::variant
gpr
)
@ -16722,9 +16716,7 @@ target_link_libraries(promise_test
${_gRPC_ZLIB_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
absl::type_traits
absl::status
absl::optional
absl::variant
gpr
)
@ -17009,7 +17001,7 @@ target_link_libraries(race_test
${_gRPC_PROTOBUF_LIBRARIES}
${_gRPC_ZLIB_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
absl::variant
gpr
)
@ -17974,8 +17966,8 @@ target_link_libraries(seq_test
${_gRPC_ZLIB_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
absl::type_traits
absl::variant
absl::utility
gpr
)
@ -21705,11 +21697,9 @@ target_link_libraries(try_join_test
${_gRPC_ZLIB_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
absl::type_traits
absl::status
absl::statusor
absl::strings
absl::variant
absl::utility
gpr
)
@ -21784,10 +21774,9 @@ target_link_libraries(try_seq_test
${_gRPC_ZLIB_LIBRARIES}
${_gRPC_ALLTARGETS_LIBRARIES}
absl::type_traits
absl::status
absl::statusor
absl::variant
absl::utility
gpr
)

@ -5290,7 +5290,7 @@ targets:
- test/core/promise/cancel_callback_test.cc
deps:
- absl/meta:type_traits
- absl/types:variant
- gpr
uses_polling: false
- name: cel_authorization_engine_test
gtest: true
@ -8773,7 +8773,6 @@ targets:
build: test
language: c++
headers:
- src/core/lib/gprpp/construct_destruct.h
- src/core/lib/promise/detail/promise_factory.h
- src/core/lib/promise/detail/promise_like.h
- src/core/lib/promise/if.h
@ -8783,7 +8782,7 @@ targets:
deps:
- absl/meta:type_traits
- absl/status:statusor
- absl/types:variant
- gpr
uses_polling: false
- name: init_test
gtest: true
@ -9004,9 +9003,7 @@ targets:
build: test
language: c++
headers:
- src/core/lib/gpr/useful.h
- src/core/lib/gprpp/bitset.h
- src/core/lib/gprpp/construct_destruct.h
- src/core/lib/promise/detail/basic_join.h
- src/core/lib/promise/detail/promise_like.h
- src/core/lib/promise/join.h
@ -9015,9 +9012,8 @@ targets:
- test/core/promise/join_test.cc
deps:
- absl/meta:type_traits
- absl/strings:strings
- absl/types:variant
- absl/utility:utility
- gpr
uses_polling: false
- name: json_object_loader_test
gtest: true
@ -9215,7 +9211,6 @@ targets:
build: test
language: c++
headers:
- src/core/lib/gprpp/construct_destruct.h
- src/core/lib/promise/detail/basic_seq.h
- src/core/lib/promise/detail/promise_factory.h
- src/core/lib/promise/detail/promise_like.h
@ -9227,10 +9222,9 @@ targets:
- test/core/promise/loop_test.cc
deps:
- absl/meta:type_traits
- absl/status:status
- absl/status:statusor
- absl/types:variant
- absl/utility:utility
- gpr
uses_polling: false
- name: map_pipe_test
gtest: true
@ -9964,7 +9958,7 @@ targets:
src:
- test/core/promise/poll_test.cc
deps:
- absl/types:variant
- gpr
uses_polling: false
- name: port_sharing_end2end_test
gtest: true
@ -10076,9 +10070,7 @@ targets:
deps:
- absl/functional:bind_front
- absl/meta:type_traits
- absl/status:status
- absl/types:optional
- absl/types:variant
- gpr
uses_polling: false
- name: promise_map_test
gtest: true
@ -10093,9 +10085,7 @@ targets:
- test/core/promise/map_test.cc
deps:
- absl/meta:type_traits
- absl/status:status
- absl/types:optional
- absl/types:variant
- gpr
uses_polling: false
- name: promise_test
gtest: true
@ -10109,9 +10099,7 @@ targets:
- test/core/promise/promise_test.cc
deps:
- absl/meta:type_traits
- absl/status:status
- absl/types:optional
- absl/types:variant
- gpr
uses_polling: false
- name: proto_server_reflection_test
gtest: true
@ -10228,7 +10216,7 @@ targets:
src:
- test/core/promise/race_test.cc
deps:
- absl/types:variant
- gpr
uses_polling: false
- name: random_early_detection_test
gtest: true
@ -10660,7 +10648,6 @@ targets:
build: test
language: c++
headers:
- src/core/lib/gprpp/construct_destruct.h
- src/core/lib/promise/detail/basic_seq.h
- src/core/lib/promise/detail/promise_factory.h
- src/core/lib/promise/detail/promise_like.h
@ -10671,8 +10658,8 @@ targets:
- test/core/promise/seq_test.cc
deps:
- absl/meta:type_traits
- absl/types:variant
- absl/utility:utility
- gpr
uses_polling: false
- name: sequential_connectivity_test
gtest: true
@ -12268,9 +12255,7 @@ targets:
build: test
language: c++
headers:
- src/core/lib/gpr/useful.h
- src/core/lib/gprpp/bitset.h
- src/core/lib/gprpp/construct_destruct.h
- src/core/lib/promise/detail/basic_join.h
- src/core/lib/promise/detail/promise_like.h
- src/core/lib/promise/detail/status.h
@ -12280,11 +12265,9 @@ targets:
- test/core/promise/try_join_test.cc
deps:
- absl/meta:type_traits
- absl/status:status
- absl/status:statusor
- absl/strings:strings
- absl/types:variant
- absl/utility:utility
- gpr
uses_polling: false
- name: try_seq_metadata_test
gtest: true
@ -12301,7 +12284,6 @@ targets:
build: test
language: c++
headers:
- src/core/lib/gprpp/construct_destruct.h
- src/core/lib/promise/detail/basic_seq.h
- src/core/lib/promise/detail/promise_factory.h
- src/core/lib/promise/detail/promise_like.h
@ -12313,10 +12295,9 @@ targets:
- test/core/promise/try_seq_test.cc
deps:
- absl/meta:type_traits
- absl/status:status
- absl/status:statusor
- absl/types:variant
- absl/utility:utility
- gpr
uses_polling: false
- name: unique_type_name_test
gtest: true

@ -371,12 +371,15 @@ grpc_cc_library(
grpc_cc_library(
name = "poll",
external_deps = ["absl/types:variant"],
language = "c++",
public_hdrs = [
"lib/promise/poll.h",
],
deps = ["//:gpr_platform"],
deps = [
"construct_destruct",
"//:gpr",
"//:gpr_platform",
],
)
grpc_cc_library(
@ -413,13 +416,11 @@ grpc_cc_library(
"absl/container:inlined_vector",
"absl/strings",
"absl/strings:str_format",
"absl/types:variant",
],
language = "c++",
deps = [
"activity",
"arena",
"poll",
"promise_trace",
"//:gpr",
"//:grpc_trace",
@ -437,7 +438,6 @@ grpc_cc_library(
grpc_cc_library(
name = "map",
external_deps = ["absl/types:variant"],
language = "c++",
public_hdrs = ["lib/promise/map.h"],
deps = [
@ -499,13 +499,11 @@ grpc_cc_library(
grpc_cc_library(
name = "cancel_callback",
external_deps = ["absl/types:variant"],
language = "c++",
public_hdrs = [
"lib/promise/cancel_callback.h",
],
deps = [
"poll",
"promise_like",
"//:gpr_platform",
],
@ -556,13 +554,9 @@ grpc_cc_library(
grpc_cc_library(
name = "race",
external_deps = ["absl/types:variant"],
language = "c++",
public_hdrs = ["lib/promise/race.h"],
deps = [
"poll",
"//:gpr_platform",
],
deps = ["//:gpr_platform"],
)
grpc_cc_library(
@ -585,10 +579,7 @@ grpc_cc_library(
grpc_cc_library(
name = "basic_join",
external_deps = [
"absl/types:variant",
"absl/utility",
],
external_deps = ["absl/utility"],
language = "c++",
public_hdrs = [
"lib/promise/detail/basic_join.h",
@ -647,7 +638,6 @@ grpc_cc_library(
name = "basic_seq",
external_deps = [
"absl/meta:type_traits",
"absl/types:variant",
"absl/utility",
],
language = "c++",
@ -708,7 +698,6 @@ grpc_cc_library(
"absl/status",
"absl/strings:str_format",
"absl/types:optional",
"absl/types:variant",
],
language = "c++",
public_hdrs = [
@ -719,7 +708,6 @@ grpc_cc_library(
"construct_destruct",
"context",
"no_destruct",
"poll",
"promise_factory",
"promise_status",
"//:gpr",
@ -808,7 +796,6 @@ grpc_cc_library(
external_deps = [
"absl/base:core_headers",
"absl/types:optional",
"absl/types:variant",
],
language = "c++",
public_hdrs = [
@ -832,7 +819,6 @@ grpc_cc_library(
"absl/strings",
"absl/strings:str_format",
"absl/types:optional",
"absl/types:variant",
],
deps = [
"arena",
@ -914,7 +900,6 @@ grpc_cc_library(
external_deps = [
"absl/status",
"absl/strings",
"absl/types:variant",
],
language = "c++",
public_hdrs = ["lib/promise/for_each.h"],

@ -37,7 +37,6 @@
#include "absl/strings/str_format.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "absl/types/variant.h"
#include <grpc/event_engine/event_engine.h>
#include <grpc/grpc.h>
@ -1936,7 +1935,7 @@ void grpc_chttp2_maybe_complete_recv_message(grpc_chttp2_transport* t,
return r.ToString();
}).c_str());
}
if (absl::holds_alternative<grpc_core::Pending>(r)) {
if (r.pending()) {
if (s->read_closed) {
grpc_slice_buffer_reset_and_unref(&s->frame_storage);
s->recv_message->reset();
@ -1946,7 +1945,7 @@ void grpc_chttp2_maybe_complete_recv_message(grpc_chttp2_transport* t,
return; // Out of lambda to enclosing function
}
} else {
error = absl::get<grpc_error_handle>(r);
error = std::move(r.value());
if (!error.ok()) {
s->seen_error = true;
grpc_slice_buffer_reset_and_unref(&s->frame_storage);

@ -353,7 +353,7 @@ class ConnectedChannelStream : public Orphanable {
if (auto* next = absl::get_if<PipeReceiverNextType<MessageHandle>>(
&send_message_state_)) {
auto r = (*next)();
if (auto* p = absl::get_if<NextResult<MessageHandle>>(&r)) {
if (auto* p = r.value_if_ready()) {
memset(&send_message_, 0, sizeof(send_message_));
send_message_.payload = batch_payload();
send_message_.on_complete = &send_message_batch_done_;
@ -428,7 +428,7 @@ class ConnectedChannelStream : public Orphanable {
if (auto* push = absl::get_if<PipeSender<MessageHandle>::PushType>(
&recv_message_state_)) {
auto r = (*push)();
if (bool* result = absl::get_if<bool>(&r)) {
if (bool* result = r.value_if_ready()) {
if (*result) {
if (!finished_) {
if (grpc_call_trace.enabled()) {
@ -745,7 +745,7 @@ class ClientStream : public ConnectedChannelStream {
if (server_initial_metadata_state_ ==
ServerInitialMetadataState::kPushing) {
auto r = (*server_initial_metadata_push_promise_)();
if (absl::holds_alternative<bool>(r)) {
if (r.ready()) {
server_initial_metadata_state_ = ServerInitialMetadataState::kPushed;
server_initial_metadata_push_promise_.reset();
}
@ -975,7 +975,7 @@ class ServerStream final : public ConnectedChannelStream {
absl::get_if<PipeReceiverNextType<ServerMetadataHandle>>(
&server_initial_metadata_)) {
auto r = (*promise)();
if (auto* md = absl::get_if<NextResult<ServerMetadataHandle>>(&r)) {
if (auto* md = r.value_if_ready()) {
if (grpc_call_trace.enabled()) {
gpr_log(
GPR_INFO, "%s[connected] got initial metadata %s",
@ -1052,7 +1052,7 @@ class ServerStream final : public ConnectedChannelStream {
PollSendMessage(p->outgoing_messages, nullptr);
}
auto poll = p->promise();
if (auto* r = absl::get_if<ServerMetadataHandle>(&poll)) {
if (auto* r = poll.value_if_ready()) {
if (grpc_call_trace.enabled()) {
gpr_log(GPR_INFO, "%s[connected] got trailing metadata %s; %s",
Activity::current()->DebugTag().c_str(),

@ -29,7 +29,6 @@
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include "absl/strings/str_join.h"
#include "absl/types/variant.h"
#include <grpc/status.h>
@ -504,7 +503,7 @@ void BaseCallData::SendMessage::WakeInsideCombiner(Flusher* flusher,
case State::kPushedToPipe: {
GPR_ASSERT(push_.has_value());
auto r_push = (*push_)();
if (auto* p = absl::get_if<bool>(&r_push)) {
if (auto* p = r_push.value_if_ready()) {
if (grpc_trace_channel.enabled()) {
gpr_log(GPR_INFO,
"%s SendMessage.WakeInsideCombiner push complete, result=%s",
@ -518,7 +517,7 @@ void BaseCallData::SendMessage::WakeInsideCombiner(Flusher* flusher,
}
GPR_ASSERT(next_.has_value());
auto r_next = (*next_)();
if (auto* p = absl::get_if<NextResult<MessageHandle>>(&r_next)) {
if (auto* p = r_next.value_if_ready()) {
if (grpc_trace_channel.enabled()) {
gpr_log(GPR_INFO,
"%s SendMessage.WakeInsideCombiner next complete, "
@ -531,16 +530,16 @@ void BaseCallData::SendMessage::WakeInsideCombiner(Flusher* flusher,
state_ = State::kForwardedBatch;
batch_.ResumeWith(flusher);
next_.reset();
if (!absl::holds_alternative<Pending>((*push_)())) push_.reset();
if ((*push_)().ready()) push_.reset();
}
} break;
case State::kForwardedBatch:
if (push_.has_value() && !absl::holds_alternative<Pending>((*push_)())) {
if (push_.has_value() && (*push_)().ready()) {
push_.reset();
}
break;
case State::kBatchCompleted:
if (push_.has_value() && absl::holds_alternative<Pending>((*push_)())) {
if (push_.has_value() && (*push_)().pending()) {
break;
}
if (completed_status_.ok()) {
@ -835,7 +834,7 @@ void BaseCallData::ReceiveMessage::WakeInsideCombiner(Flusher* flusher,
case State::kPushedToPipe: {
GPR_ASSERT(push_.has_value());
auto r_push = (*push_)();
if (auto* p = absl::get_if<bool>(&r_push)) {
if (auto* p = r_push.value_if_ready()) {
if (grpc_trace_channel.enabled()) {
gpr_log(GPR_INFO,
"%s ReceiveMessage.WakeInsideCombiner push complete: %s",
@ -848,7 +847,7 @@ void BaseCallData::ReceiveMessage::WakeInsideCombiner(Flusher* flusher,
}
GPR_ASSERT(next_.has_value());
auto r_next = (*next_)();
if (auto* p = absl::get_if<NextResult<MessageHandle>>(&r_next)) {
if (auto* p = r_next.value_if_ready()) {
next_.reset();
if (p->has_value()) {
*intercepted_slice_buffer_ = std::move(*(**p)->payload());
@ -885,7 +884,7 @@ void BaseCallData::ReceiveMessage::WakeInsideCombiner(Flusher* flusher,
case State::kCompletedWhilePulledFromPipe:
case State::kPulledFromPipe: {
GPR_ASSERT(push_.has_value());
if (!absl::holds_alternative<Pending>((*push_)())) {
if ((*push_)().ready()) {
if (grpc_trace_channel.enabled()) {
gpr_log(GPR_INFO,
"%s ReceiveMessage.WakeInsideCombiner push complete",
@ -1019,8 +1018,7 @@ class ClientCallData::PollContext {
}
if (self_->server_initial_metadata_pipe() != nullptr) {
if (self_->recv_initial_metadata_->metadata_push_.has_value()) {
if (!absl::holds_alternative<Pending>(
(*self_->recv_initial_metadata_->metadata_push_)())) {
if ((*self_->recv_initial_metadata_->metadata_push_)().ready()) {
self_->recv_initial_metadata_->metadata_push_.reset();
}
}
@ -1059,8 +1057,7 @@ class ClientCallData::PollContext {
GPR_ASSERT(self_->recv_initial_metadata_->metadata_next_.has_value());
Poll<NextResult<ServerMetadataHandle>> p =
(*self_->recv_initial_metadata_->metadata_next_)();
if (NextResult<ServerMetadataHandle>* nr =
absl::get_if<kPollReadyIdx>(&p)) {
if (NextResult<ServerMetadataHandle>* nr = p.value_if_ready()) {
if (nr->has_value()) {
ServerMetadataHandle md = std::move(nr->value());
if (self_->recv_initial_metadata_->metadata != md.get()) {
@ -1097,7 +1094,7 @@ class ClientCallData::PollContext {
return h->DebugString();
}).c_str());
}
if (auto* r = absl::get_if<ServerMetadataHandle>(&poll)) {
if (auto* r = poll.value_if_ready()) {
auto md = std::move(*r);
if (self_->send_message() != nullptr) {
self_->send_message()->Done(*md, flusher_);
@ -2376,8 +2373,7 @@ void ServerCallData::WakeInsideCombiner(Flusher* flusher) {
server_initial_metadata_pipe()->receiver.Next());
}
if (send_initial_metadata_->metadata_push_.has_value()) {
if (!absl::holds_alternative<Pending>(
(*send_initial_metadata_->metadata_push_)())) {
if ((*send_initial_metadata_->metadata_push_)().ready()) {
if (grpc_trace_channel.enabled()) {
gpr_log(GPR_INFO, "%s: WakeInsideCombiner: metadata_push done",
LogTag().c_str());
@ -2453,7 +2449,7 @@ void ServerCallData::WakeInsideCombiner(Flusher* flusher) {
return (*h)->DebugString();
}).c_str());
}
if (auto* nr = absl::get_if<NextResult<ServerMetadataHandle>>(&p)) {
if (auto* nr = p.value_if_ready()) {
ServerMetadataHandle md = std::move(nr->value());
if (send_initial_metadata_->batch->payload->send_initial_metadata
.send_initial_metadata != md.get()) {
@ -2465,7 +2461,7 @@ void ServerCallData::WakeInsideCombiner(Flusher* flusher) {
send_initial_metadata_->batch.ResumeWith(flusher);
}
}
if (auto* r = absl::get_if<ServerMetadataHandle>(&poll)) {
if (auto* r = poll.value_if_ready()) {
promise_ = ArenaPromise<ServerMetadataHandle>();
auto* md = UnwrapMetadata(std::move(*r));
bool destroy_md = true;

@ -28,7 +28,6 @@
#include "absl/base/thread_annotations.h"
#include "absl/status/status.h"
#include "absl/types/optional.h"
#include "absl/types/variant.h"
#include <grpc/support/log.h>
@ -39,7 +38,6 @@
#include "src/core/lib/promise/context.h"
#include "src/core/lib/promise/detail/promise_factory.h"
#include "src/core/lib/promise/detail/status.h"
#include "src/core/lib/promise/poll.h"
namespace grpc_core {
@ -543,7 +541,7 @@ class PromiseActivity final
// Run the promise.
GPR_ASSERT(!done_);
auto r = promise_holder_.promise();
if (auto* status = absl::get_if<kPollReadyIdx>(&r)) {
if (auto* status = r.value_if_ready()) {
// If complete, destroy the promise, flag done, and exit this loop.
MarkDone();
return IntoStatus(status);

@ -19,10 +19,7 @@
#include <utility>
#include "absl/types/variant.h"
#include "src/core/lib/promise/detail/promise_like.h"
#include "src/core/lib/promise/poll.h"
namespace grpc_core {
@ -68,7 +65,7 @@ auto OnCancel(MainFn main_fn, CancelFn cancel_fn) {
main_fn = promise_detail::PromiseLike<MainFn>(
std::move(main_fn))]() mutable {
auto r = main_fn();
if (!absl::holds_alternative<Pending>(r)) {
if (r.ready()) {
on_cancel.Done();
}
return r;

@ -25,7 +25,6 @@
#include <type_traits>
#include <utility>
#include "absl/types/variant.h"
#include "absl/utility/utility.h"
#include "src/core/lib/gprpp/bitset.h"
@ -97,7 +96,7 @@ struct Joint : public Joint<Traits, kRemaining - 1, Fs...> {
if (!bits->is_set(kIdx)) {
// Poll the promise
auto r = fused.f();
if (auto* p = absl::get_if<kPollReadyIdx>(&r)) {
if (auto* p = r.value_if_ready()) {
// If it's done, then ask the trait to unwrap it and store that result
// in the Fused, and continue the iteration. Note that OnResult could
// instead choose to return a value instead of recursing through the

@ -24,7 +24,6 @@
#include <utility>
#include "absl/meta/type_traits.h"
#include "absl/types/variant.h"
#include "absl/utility/utility.h"
#include "src/core/lib/gprpp/construct_destruct.h"
@ -276,18 +275,15 @@ class BasicSeq {
// Poll the current promise in this state.
auto r = s->current_promise();
// If we are still pending, say so by returning.
if (absl::holds_alternative<Pending>(r)) {
return Pending();
}
if (r.pending()) return Pending();
// Current promise is ready, as the traits to do the next thing.
// That may be returning - eg if TrySeq sees an error.
// Or it may be by calling the callable we hand down - RunNext - which
// will advance the state and call the next promise.
return Traits<
typename absl::remove_reference_t<decltype(*s)>::Types::PromiseResult>::
template CheckResultAndRunNext<Result>(
std::move(absl::get<kPollReadyIdx>(std::move(r))),
RunNext<I>{this});
template CheckResultAndRunNext<Result>(std::move(r.value()),
RunNext<I>{this});
}
// Specialization of RunState to run the final state.
@ -296,11 +292,9 @@ class BasicSeq {
// Poll the final promise.
auto r = final_promise_();
// If we are still pending, say so by returning.
if (absl::holds_alternative<Pending>(r)) {
return Pending();
}
if (r.pending()) return Pending();
// We are complete, return the (wrapped) result.
return Result(std::move(absl::get<kPollReadyIdx>(std::move(r))));
return Result(std::move(r.value()));
}
// For state numbered I, destruct the current promise and the next promise
@ -466,9 +460,9 @@ class BasicSeqIter {
private:
Poll<Wrapped> PollNonEmpty() {
Poll<Wrapped> r = state_();
if (absl::holds_alternative<Pending>(r)) return r;
if (r.pending()) return r;
return Traits::template CheckResultAndRunNext<Wrapped>(
std::move(absl::get<Wrapped>(r)), [this](Wrapped arg) -> Poll<Wrapped> {
std::move(r.value()), [this](Wrapped arg) -> Poll<Wrapped> {
auto next = cur_;
++next;
if (next == end_) {

@ -25,7 +25,6 @@
#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
#include "absl/types/variant.h"
#include <grpc/support/log.h>
@ -118,7 +117,7 @@ class ForEach {
gpr_log(GPR_DEBUG, "%s PollReaderNext", DebugTag().c_str());
}
auto r = reader_next_();
if (auto* p = absl::get_if<kPollReadyIdx>(&r)) {
if (auto* p = r.value_if_ready()) {
if (grpc_trace_promise_primitives.enabled()) {
gpr_log(GPR_DEBUG, "%s PollReaderNext: got has_value=%s",
DebugTag().c_str(), p->has_value() ? "true" : "false");
@ -141,7 +140,7 @@ class ForEach {
gpr_log(GPR_DEBUG, "%s PollAction", DebugTag().c_str());
}
auto r = in_action_.promise();
if (auto* p = absl::get_if<kPollReadyIdx>(&r)) {
if (auto* p = r.value_if_ready()) {
if (p->ok()) {
Destruct(&in_action_);
Construct(&reader_next_, reader_.Next());

@ -99,7 +99,7 @@ class If {
!kSetState,
"shouldn't need to set state coming through the initial branch");
auto r = evaluating.condition();
if (auto* p = absl::get_if<kPollReadyIdx>(&r)) {
if (auto* p = r.value_if_ready()) {
return ChooseIf(CallPoll<true>{self}, std::move(*p),
&evaluating.if_true, &evaluating.if_false);
}
@ -109,7 +109,7 @@ class If {
template <class Promise>
PollResult operator()(Promise& promise) const {
auto r = promise();
if (kSetState && absl::holds_alternative<Pending>(r)) {
if (kSetState && r.pending()) {
self->state_.template emplace<Promise>(std::move(promise));
}
return r;

@ -27,7 +27,6 @@
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include "absl/types/optional.h"
#include "absl/types/variant.h"
#include <grpc/support/log.h>
@ -135,7 +134,7 @@ class InterceptorList {
while (true) {
auto r = async_resolution_.current_factory->PollOnce(
async_resolution_.space.get());
if (auto* p = absl::get_if<kPollReadyIdx>(&r)) {
if (auto* p = r.value_if_ready()) {
async_resolution_.current_factory->Destroy(
async_resolution_.space.get());
async_resolution_.current_factory =

@ -98,7 +98,7 @@ class Loop {
// Poll the inner promise.
auto promise_result = promise_();
// If it returns a value:
if (auto* p = absl::get_if<kPollReadyIdx>(&promise_result)) {
if (auto* p = promise_result.value_if_ready()) {
// - then if it's Continue, destroy the promise and recreate a new one
// from our factory.
auto lc = LoopTraits<PromiseResult>::ToLoopCtl(*p);

@ -23,8 +23,6 @@
#include <type_traits>
#include <utility>
#include "absl/types/variant.h"
#include "src/core/lib/promise/detail/promise_like.h"
#include "src/core/lib/promise/poll.h"
@ -47,7 +45,7 @@ class Map {
Poll<Result> operator()() {
Poll<PromiseResult> r = promise_();
if (auto* p = absl::get_if<kPollReadyIdx>(&r)) {
if (auto* p = r.value_if_ready()) {
return fn_(std::move(*p));
}
return Pending();

@ -26,7 +26,6 @@
#include "absl/base/thread_annotations.h"
#include "absl/types/optional.h"
#include "absl/types/variant.h"
#include "src/core/lib/gprpp/sync.h"
#include "src/core/lib/promise/activity.h"
@ -190,7 +189,7 @@ class ObservableWatch final : private WatchCommitter {
Poll<Result> operator()() {
auto r = state_->PollWatch(&version_seen_);
if (auto* p = absl::get_if<kPollReadyIdx>(&r)) {
if (auto* p = r.value_if_ready()) {
if (p->has_value()) {
promise_ = Promise(factory_(std::move(**p), this));
} else {

@ -25,10 +25,8 @@
#include <utility>
#include "absl/container/inlined_vector.h"
#include "absl/types/variant.h"
#include "src/core/lib/promise/activity.h"
#include "src/core/lib/promise/poll.h"
#include "src/core/lib/resource_quota/arena.h"
namespace grpc_core {
@ -98,7 +96,7 @@ class Party : public Activity, private Wakeable {
bool Poll() override {
auto p = promise_();
if (auto* r = absl::get_if<kPollReadyIdx>(&p)) {
if (auto* r = p.value_if_ready()) {
on_complete_(std::move(*r));
return true;
}

@ -467,7 +467,7 @@ class Push {
if (center_ == nullptr) return false;
if (auto* p = absl::get_if<T>(&state_)) {
auto r = center_->Push(p);
if (auto* ok = absl::get_if<bool>(&r)) {
if (auto* ok = r.value_if_ready()) {
state_.template emplace<AwaitingAck>();
if (!*ok) return false;
} else {

@ -17,11 +17,12 @@
#include <grpc/support/port_platform.h>
#include <stddef.h>
#include <string>
#include <utility>
#include <grpc/support/log.h>
#include "absl/types/variant.h"
#include "src/core/lib/gprpp/construct_destruct.h"
namespace grpc_core {
@ -43,17 +44,115 @@ struct Empty {
// Can be either pending - the Promise has not yet completed, or ready -
// indicating that the Promise has completed AND should not be polled again.
template <typename T>
using Poll = absl::variant<Pending, T>;
class Poll {
public:
// NOLINTNEXTLINE(google-explicit-constructor)
Poll(Pending) : ready_(false) {}
Poll() : ready_(false) {}
Poll(const Poll& other) : ready_(other.ready_) {
if (ready_) Construct(&value_, other.value_);
}
Poll(Poll&& other) noexcept : ready_(other.ready_) {
if (ready_) Construct(&value_, std::move(other.value_));
}
Poll& operator=(const Poll& other) {
if (ready_) {
if (other.ready_) {
value_ = other.value_;
} else {
Destruct(&value_);
ready_ = false;
}
} else if (other.ready_) {
Construct(&value_, other.value_);
ready_ = true;
}
return *this;
}
Poll& operator=(Poll&& other) noexcept {
if (ready_) {
if (other.ready_) {
value_ = std::move(other.value_);
} else {
Destruct(&value_);
ready_ = false;
}
} else if (other.ready_) {
Construct(&value_, std::move(other.value_));
ready_ = true;
}
return *this;
}
template <typename U>
// NOLINTNEXTLINE(google-explicit-constructor)
Poll(U value) : ready_(true) {
Construct(&value_, std::move(value));
}
~Poll() {
if (ready_) Destruct(&value_);
}
bool pending() const { return !ready_; }
bool ready() const { return ready_; }
T& value() {
GPR_DEBUG_ASSERT(ready());
return value_;
}
const T& value() const {
GPR_DEBUG_ASSERT(ready());
return value_;
}
T* value_if_ready() {
if (ready()) return &value_;
return nullptr;
}
const T* value_if_ready() const {
if (ready()) return &value_;
return nullptr;
}
private:
// Flag indicating readiness, followed by an optional value.
//
// Why not optional<T>?
//
// We have cases where we want to return absl::nullopt{} from a promise, and
// have that upgraded to a Poll<absl::nullopt_t> prior to a cast to some
// Poll<optional<T>>.
//
// Since optional<nullopt_t> is not allowed, we'd not be allowed to make
// Poll<nullopt_t> and so we'd need to pollute all poll handling code with
// some edge case handling template magic - the complexity would explode and
// grow over time - versus hand coding the pieces we need here and containing
// that quirk to one place.
bool ready_;
// We do a single element union so we can choose when to construct/destruct
// this value.
union {
T value_;
};
};
template <>
class Poll<Pending>;
template <typename T>
bool operator==(const Poll<T>& a, const Poll<T>& b) {
if (a.pending() && b.pending()) return true;
if (a.ready() && b.ready()) return a.value() == b.value();
return false;
}
template <typename T, typename U>
Poll<T> poll_cast(Poll<U> poll) {
if (absl::holds_alternative<Pending>(poll)) return Pending{};
return std::move(absl::get<U>(poll));
if (poll.pending()) return Pending{};
return static_cast<T>(std::move(poll.value()));
}
// Variant of Poll that serves as a ready value
static constexpr size_t kPollReadyIdx = 1;
// PollTraits tells us whether a type is Poll<> or some other type, and is
// leveraged in the PromiseLike/PromiseFactory machinery to select the
// appropriate implementation of those concepts based upon the return type of a
@ -74,10 +173,10 @@ template <typename T, typename F>
std::string PollToString(
const Poll<T>& poll,
F t_to_string = [](const T& t) { return t.ToString(); }) {
if (absl::holds_alternative<Pending>(poll)) {
if (poll.pending()) {
return "<<pending>>";
}
return t_to_string(absl::get<T>(poll));
return t_to_string(poll.value());
}
} // namespace grpc_core

@ -23,7 +23,6 @@
#include "absl/status/status.h"
#include "absl/types/optional.h"
#include "absl/types/variant.h"
#include "src/core/lib/promise/detail/promise_like.h"
#include "src/core/lib/promise/poll.h"
@ -42,7 +41,7 @@ template <typename Promise>
auto NowOrNever(Promise promise)
-> absl::optional<typename promise_detail::PromiseLike<Promise>::Result> {
auto r = promise_detail::PromiseLike<Promise>(std::move(promise))();
if (auto* p = absl::get_if<kPollReadyIdx>(&r)) {
if (auto* p = r.value_if_ready()) {
return std::move(*p);
}
return {};

@ -18,10 +18,7 @@
#include <grpc/support/port_platform.h>
#include <type_traits>
#include "absl/types/variant.h"
#include "src/core/lib/promise/poll.h"
#include <utility>
namespace grpc_core {
@ -42,12 +39,12 @@ class Race<Promise, Promises...> {
Result operator()() {
// Check our own promise.
auto r = promise_();
if (absl::holds_alternative<Pending>(r)) {
if (r.pending()) {
// Check the rest of them.
return next_();
}
// Return the first ready result.
return std::move(absl::get<kPollReadyIdx>(std::move(r)));
return std::move(r.value());
}
private:

@ -2629,7 +2629,7 @@ void PromiseBasedCall::StartSendMessage(const grpc_op& op,
bool PromiseBasedCall::PollSendMessage() {
if (!outstanding_send_.has_value()) return true;
Poll<bool> r = (*outstanding_send_)();
if (const bool* result = absl::get_if<bool>(&r)) {
if (const bool* result = r.value_if_ready()) {
if (grpc_call_trace.enabled()) {
gpr_log(GPR_DEBUG, "%sPollSendMessage completes %s", DebugTag().c_str(),
*result ? "successfully" : "with failure");
@ -2664,7 +2664,7 @@ void PromiseBasedCall::PollRecvMessage(
grpc_compression_algorithm incoming_compression_algorithm) {
if (!outstanding_recv_.has_value()) return;
Poll<NextResult<MessageHandle>> r = (*outstanding_recv_)();
if (auto* result = absl::get_if<NextResult<MessageHandle>>(&r)) {
if (auto* result = r.value_if_ready()) {
outstanding_recv_.reset();
if (result->has_value()) {
MessageHandle& message = **result;
@ -3015,8 +3015,7 @@ void ClientPromiseBasedCall::UpdateOnce() {
if (server_initial_metadata_ready_.has_value()) {
Poll<NextResult<ServerMetadataHandle>> r =
(*server_initial_metadata_ready_)();
if (auto* server_initial_metadata =
absl::get_if<NextResult<ServerMetadataHandle>>(&r)) {
if (auto* server_initial_metadata = r.value_if_ready()) {
PublishInitialMetadata(server_initial_metadata->value().get());
} else if (completed()) {
ServerMetadata no_metadata{GetContext<Arena>()};
@ -3041,7 +3040,7 @@ void ClientPromiseBasedCall::UpdateOnce() {
return h->DebugString();
}).c_str());
}
if (auto* result = absl::get_if<ServerMetadataHandle>(&r)) {
if (auto* result = r.value_if_ready()) {
AcceptTransportStatsFromContext();
Finish(std::move(*result));
}
@ -3071,7 +3070,7 @@ void ClientPromiseBasedCall::Finish(ServerMetadataHandle trailing_metadata) {
Poll<NextResult<ServerMetadataHandle>> r =
(*server_initial_metadata_ready_)();
server_initial_metadata_ready_.reset();
if (auto* result = absl::get_if<NextResult<ServerMetadataHandle>>(&r)) {
if (auto* result = r.value_if_ready()) {
if (pending_initial_metadata) PublishInitialMetadata(result->value().get());
is_trailers_only_ = false;
} else {
@ -3356,7 +3355,7 @@ void ServerPromiseBasedCall::UpdateOnce() {
if (auto* p =
absl::get_if<typename PipeSender<ServerMetadataHandle>::PushType>(
&send_initial_metadata_state_)) {
if (!absl::holds_alternative<Pending>((*p)())) {
if ((*p)().ready()) {
send_initial_metadata_state_ = absl::monostate{};
}
}
@ -3369,7 +3368,7 @@ void ServerPromiseBasedCall::UpdateOnce() {
return h->DebugString();
}).c_str());
}
if (auto* result = absl::get_if<ServerMetadataHandle>(&r)) {
if (auto* result = r.value_if_ready()) {
if (grpc_call_trace.enabled()) {
gpr_log(GPR_INFO, "%s[call] UpdateOnce: GotResult %s result:%s",
DebugTag().c_str(),

@ -26,7 +26,6 @@
#include "absl/meta/type_traits.h"
#include "absl/status/status.h"
#include "absl/strings/str_cat.h"
#include "absl/types/variant.h"
#include <grpc/support/log.h>
@ -36,6 +35,7 @@
#include "src/core/lib/iomgr/closure.h"
#include "src/core/lib/promise/activity.h"
#include "src/core/lib/promise/arena_promise.h"
#include "src/core/lib/promise/poll.h"
#include "src/core/lib/transport/metadata_batch.h"
#include "src/core/lib/transport/transport.h"
@ -66,7 +66,7 @@ const grpc_channel_filter* PromiseTracingFilterFor(
Activity::current()->DebugTag().c_str(),
source_filter->name);
auto r = child();
if (auto* p = absl::get_if<ServerMetadataHandle>(&r)) {
if (auto* p = r.value_if_ready()) {
gpr_log(GPR_DEBUG, "%s[%s] PollCallPromise: done: %s",
Activity::current()->DebugTag().c_str(),
source_filter->name, (*p)->DebugString().c_str());

@ -22,7 +22,6 @@
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "absl/types/variant.h"
#include "gtest/gtest.h"
#include <grpc/event_engine/memory_allocator.h>
@ -164,8 +163,7 @@ TEST_F(ClientAuthFilterTest, CallCredsFails) {
});
});
auto result = promise();
ServerMetadataHandle* server_metadata =
absl::get_if<ServerMetadataHandle>(&result);
ServerMetadataHandle* server_metadata = result.value_if_ready();
ASSERT_TRUE(server_metadata != nullptr);
auto status_md = (*server_metadata)->get(GrpcStatusMetadata());
ASSERT_TRUE(status_md.has_value());
@ -194,8 +192,7 @@ TEST_F(ClientAuthFilterTest, RewritesInvalidStatusFromCallCreds) {
});
});
auto result = promise();
ServerMetadataHandle* server_metadata =
absl::get_if<ServerMetadataHandle>(&result);
ServerMetadataHandle* server_metadata = result.value_if_ready();
ASSERT_TRUE(server_metadata != nullptr);
auto status_md = (*server_metadata)->get(GrpcStatusMetadata());
ASSERT_TRUE(status_md.has_value());

@ -18,7 +18,6 @@
#include "absl/status/status.h"
#include "absl/strings/string_view.h"
#include "absl/types/variant.h"
#include "gtest/gtest.h"
#include <grpc/event_engine/memory_allocator.h>
@ -86,7 +85,7 @@ TEST(ClientAuthorityFilterTest, PromiseCompletesImmediatelyAndSetsAuthority) {
});
});
auto result = promise();
EXPECT_TRUE(absl::get_if<ServerMetadataHandle>(&result) != nullptr);
EXPECT_TRUE(result.ready());
EXPECT_TRUE(seen);
}
@ -121,7 +120,7 @@ TEST(ClientAuthorityFilterTest,
});
});
auto result = promise();
EXPECT_TRUE(absl::get_if<ServerMetadataHandle>(&result) != nullptr);
EXPECT_TRUE(result.ready());
EXPECT_TRUE(seen);
}

@ -28,7 +28,6 @@
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "absl/types/variant.h"
#include <grpc/event_engine/memory_allocator.h>
#include <grpc/grpc.h>
@ -608,8 +607,8 @@ class MainLoop {
void Step() {
if (!promise_.has_value()) return;
auto r = (*promise_)();
if (absl::holds_alternative<Pending>(r)) return;
ServerMetadataHandle md = std::move(absl::get<ServerMetadataHandle>(r));
if (r.pending()) return;
ServerMetadataHandle md = std::move(r.value());
if (md.get() != server_trailing_metadata_.get()) md->~ServerMetadata();
promise_.reset();
}

@ -80,7 +80,10 @@ grpc_cc_test(
language = "c++",
uses_event_engine = False,
uses_polling = False,
deps = ["//src/core:cancel_callback"],
deps = [
"//src/core:cancel_callback",
"//src/core:poll",
],
)
grpc_cc_test(
@ -96,10 +99,7 @@ grpc_cc_test(
grpc_cc_test(
name = "arena_promise_test",
srcs = ["arena_promise_test.cc"],
external_deps = [
"absl/types:variant",
"gtest",
],
external_deps = ["gtest"],
language = "c++",
tags = [
"promise_test",
@ -146,7 +146,10 @@ grpc_cc_test(
tags = ["promise_test"],
uses_event_engine = False,
uses_polling = False,
deps = ["//src/core:race"],
deps = [
"//src/core:poll",
"//src/core:race",
],
)
grpc_cc_test(
@ -224,10 +227,7 @@ grpc_cc_test(
grpc_cc_test(
name = "seq_test",
srcs = ["seq_test.cc"],
external_deps = [
"absl/types:variant",
"gtest",
],
external_deps = ["gtest"],
language = "c++",
tags = ["promise_test"],
uses_event_engine = False,
@ -249,10 +249,7 @@ grpc_cc_test(
grpc_cc_test(
name = "try_seq_metadata_test",
srcs = ["try_seq_metadata_test.cc"],
external_deps = [
"absl/types:variant",
"gtest",
],
external_deps = ["gtest"],
language = "c++",
tags = ["promise_test"],
uses_event_engine = False,
@ -283,6 +280,7 @@ grpc_cc_test(
"//:promise",
"//src/core:activity",
"//src/core:join",
"//src/core:poll",
"//src/core:seq",
"//src/core:wait_set",
],
@ -536,6 +534,7 @@ grpc_cc_test(
"//src/core:event_engine_memory_allocator",
"//src/core:memory_quota",
"//src/core:notification",
"//src/core:poll",
"//src/core:resource_quota",
"//src/core:seq",
"//src/core:sleep",

@ -23,6 +23,7 @@
#include "gtest/gtest.h"
#include "src/core/lib/promise/join.h"
#include "src/core/lib/promise/poll.h"
#include "src/core/lib/promise/promise.h"
#include "src/core/lib/promise/seq.h"
#include "src/core/lib/promise/wait_set.h"

@ -17,7 +17,6 @@
#include <array>
#include <memory>
#include "absl/types/variant.h"
#include "gtest/gtest.h"
#include <grpc/event_engine/memory_allocator.h>
@ -94,7 +93,7 @@ TEST_F(ArenaPromiseTest, AllocatedUniquePtrWorks) {
ArenaPromise<Ptr> initial_promise(
[x = std::move(x)]() mutable { return Poll<Ptr>(std::move(x)); });
ArenaPromise<Ptr> p(std::move(initial_promise));
EXPECT_EQ(*absl::get<Ptr>(p()), 42);
EXPECT_EQ(*p().value(), 42);
}
} // namespace grpc_core

@ -16,6 +16,8 @@
#include "gtest/gtest.h"
#include "src/core/lib/promise/poll.h"
namespace grpc_core {
TEST(CancelCallback, DoesntCallCancelIfCompleted) {

@ -178,8 +178,7 @@ TEST_F(ForEachTest, NextResultHeldThroughCallback) {
// sender->reset() line above yet either, as
// the Push() should block until this code
// completes.
EXPECT_TRUE(absl::holds_alternative<Pending>(
(*sender)->Push(2)()));
EXPECT_TRUE((*sender)->Push(2)().pending());
num_received++;
EXPECT_EQ(num_received, i);
return TrySeq(
@ -189,8 +188,7 @@ TEST_F(ForEachTest, NextResultHeldThroughCallback) {
// Perform the same test verifying the same
// properties for NextResult holding: all should
// still be true.
EXPECT_TRUE(absl::holds_alternative<Pending>(
(*sender)->Push(2)()));
EXPECT_TRUE((*sender)->Push(2)().pending());
return absl::OkStatus();
});
})),

@ -57,9 +57,9 @@ TEST_F(InterceptorListTest, CanRunTwoTwice) {
InterceptorList<std::string> list;
list.AppendMap([](std::string s) { return s + s; }, DEBUG_LOCATION);
list.AppendMap([](std::string s) { return s + s + s; }, DEBUG_LOCATION);
EXPECT_EQ(absl::get<kPollReadyIdx>(list.Run(std::string(10, 'a'))()).value(),
EXPECT_EQ(list.Run(std::string(10, 'a'))().value().value(),
std::string(60, 'a'));
EXPECT_EQ(absl::get<kPollReadyIdx>(list.Run(std::string(100, 'b'))()).value(),
EXPECT_EQ(list.Run(std::string(100, 'b'))().value().value(),
std::string(600, 'b'));
}
@ -76,7 +76,7 @@ TEST_F(InterceptorListTest, CanRunManyWithCaptures) {
for (size_t i = 0; i < 1000; i++) {
expected += "abcdefghijklmnopqrstuvwxyz";
}
EXPECT_EQ(absl::get<kPollReadyIdx>(list.Run("")()).value(), expected);
EXPECT_EQ(list.Run("")().value().value(), expected);
}
TEST_F(InterceptorListTest, CanRunOnePrepended) {
@ -105,7 +105,7 @@ TEST_F(InterceptorListTest, CanRunManyWithCapturesPrepended) {
for (size_t i = 0; i < 1000; i++) {
expected += "zyxwvutsrqponmlkjihgfedcba";
}
EXPECT_EQ(absl::get<kPollReadyIdx>(list.Run("")()).value(), expected);
EXPECT_EQ(list.Run("")().value().value(), expected);
}
TEST_F(InterceptorListTest, CanRunManyWithCapturesThatDelay) {
@ -126,13 +126,13 @@ TEST_F(InterceptorListTest, CanRunManyWithCapturesThatDelay) {
}
auto promise = list.Run("");
for (size_t i = 0; i < 26 * 1000; i++) {
EXPECT_TRUE(absl::holds_alternative<Pending>(promise())) << i;
EXPECT_TRUE(promise().pending()) << i;
}
std::string expected;
for (size_t i = 0; i < 1000; i++) {
expected += "abcdefghijklmnopqrstuvwxyz";
}
EXPECT_EQ(absl::get<kPollReadyIdx>(promise()).value(), expected);
EXPECT_EQ(promise().value().value(), expected);
}
} // namespace

@ -34,6 +34,7 @@
#include "src/core/lib/gprpp/time.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/promise/context.h"
#include "src/core/lib/promise/poll.h"
#include "src/core/lib/promise/seq.h"
#include "src/core/lib/promise/sleep.h"
#include "src/core/lib/resource_quota/memory_quota.h"

@ -31,12 +31,13 @@ TEST(PollTest, IsItPoll) {
TEST(PollTest, Pending) {
Poll<int> i = Pending();
EXPECT_TRUE(absl::holds_alternative<Pending>(i));
EXPECT_TRUE(i.pending());
}
TEST(PollTest, Ready) {
Poll<int> i = 1;
EXPECT_TRUE(absl::holds_alternative<int>(i));
EXPECT_TRUE(i.ready());
EXPECT_EQ(i.value(), 1);
}
} // namespace grpc_core

@ -14,10 +14,10 @@
#include "src/core/lib/promise/race.h"
#include <utility>
#include "gtest/gtest.h"
#include "src/core/lib/promise/poll.h"
namespace grpc_core {
Poll<int> instant() { return 1; }

@ -18,7 +18,6 @@
#include <string>
#include <vector>
#include "absl/types/variant.h"
#include "gtest/gtest.h"
namespace grpc_core {
@ -52,7 +51,7 @@ TEST(SeqTest, TwoTypedThens) {
auto initial = [] { return A{}; };
auto next1 = [](A) { return []() { return B{}; }; };
auto next2 = [](B) { return []() { return C{}; }; };
EXPECT_FALSE(absl::holds_alternative<Pending>(Seq(initial, next1, next2)()));
EXPECT_FALSE(Seq(initial, next1, next2)().pending());
}
// This does not compile, but is useful for testing error messages generated

@ -14,7 +14,6 @@
#include <memory>
#include "absl/types/variant.h"
#include "gtest/gtest.h"
#include <grpc/event_engine/memory_allocator.h>
@ -49,8 +48,7 @@ TEST(PromiseTest, SucceedAndThenFail) {
m.Set(GrpcStatusMetadata(), GRPC_STATUS_UNAVAILABLE);
return m;
})();
EXPECT_EQ(absl::get<TestMap>(r).get(GrpcStatusMetadata()),
GRPC_STATUS_UNAVAILABLE);
EXPECT_EQ(r.value().get(GrpcStatusMetadata()), GRPC_STATUS_UNAVAILABLE);
}
} // namespace grpc_core

Loading…
Cancel
Save