Skip to content

Commit

Permalink
[promises] Add some status-like types for TrySeq (#34906)
Browse files Browse the repository at this point in the history
`StatusFlag` acts like a status, but is just a boolean (we don't want to
accidentally treat a boolean as something that indicates failure in case
it's not)

Similarly `ValueOrFailure` looks like `StatusOr` but reduces the failure
space to one value.

---------

Co-authored-by: ctiller <[email protected]>
  • Loading branch information
ctiller and ctiller authored Nov 10, 2023
1 parent b99d63f commit dc41f42
Show file tree
Hide file tree
Showing 7 changed files with 303 additions and 40 deletions.
35 changes: 35 additions & 0 deletions CMakeLists.txt

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions build_autogenerated.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

121 changes: 81 additions & 40 deletions src/core/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -117,10 +117,12 @@ grpc_cc_library(
"lib/experiments/config.h",
"lib/experiments/experiments.h",
],
defines = select({
"//:grpc_experiments_are_final": ["GRPC_EXPERIMENTS_ARE_FINAL"],
"//conditions:default": [],
}),
defines = select(
{
"//:grpc_experiments_are_final": ["GRPC_EXPERIMENTS_ARE_FINAL"],
"//conditions:default": [],
},
),
external_deps = [
"absl/functional:any_invocable",
"absl/strings",
Expand Down Expand Up @@ -420,6 +422,23 @@ grpc_cc_library(
],
)

grpc_cc_library(
name = "status_flag",
external_deps = [
"absl/status",
"absl/status:statusor",
"absl/types:optional",
],
language = "c++",
public_hdrs = [
"lib/promise/status_flag.h",
],
deps = [
"promise_status",
"//:gpr_platform",
],
)

grpc_cc_library(
name = "map_pipe",
external_deps = ["absl/status"],
Expand Down Expand Up @@ -2329,27 +2348,29 @@ grpc_cc_library(
srcs = ["lib/event_engine/default_event_engine_factory.cc"],
hdrs = ["lib/event_engine/default_event_engine_factory.h"],
external_deps = ["absl/memory"],
select_deps = [{
"//:windows": ["windows_event_engine"],
"//:windows_msvc": ["windows_event_engine"],
"//:windows_other": ["windows_event_engine"],
"//:mac": [
"posix_event_engine",
"cf_event_engine",
],
"//:mac_x86_64": [
"posix_event_engine",
"cf_event_engine",
],
"//:mac_arm64": [
"posix_event_engine",
"cf_event_engine",
],
"//:ios": ["cf_event_engine"],
"//:tvos": ["cf_event_engine"],
"//:watchos": ["cf_event_engine"],
"//conditions:default": ["posix_event_engine"],
}],
select_deps = [
{
"//:windows": ["windows_event_engine"],
"//:windows_msvc": ["windows_event_engine"],
"//:windows_other": ["windows_event_engine"],
"//:mac": [
"posix_event_engine",
"cf_event_engine",
],
"//:mac_x86_64": [
"posix_event_engine",
"cf_event_engine",
],
"//:mac_arm64": [
"posix_event_engine",
"cf_event_engine",
],
"//:ios": ["cf_event_engine"],
"//:tvos": ["cf_event_engine"],
"//:watchos": ["cf_event_engine"],
"//conditions:default": ["posix_event_engine"],
},
],
deps = [
"//:event_engine_base_hdrs",
"//:gpr_platform",
Expand Down Expand Up @@ -5447,8 +5468,12 @@ grpc_cc_library(

grpc_cc_library(
name = "service_config_helper",
srcs = ["ext/filters/client_channel/resolver/dns/event_engine/service_config_helper.cc"],
hdrs = ["ext/filters/client_channel/resolver/dns/event_engine/service_config_helper.h"],
srcs = [
"ext/filters/client_channel/resolver/dns/event_engine/service_config_helper.cc",
],
hdrs = [
"ext/filters/client_channel/resolver/dns/event_engine/service_config_helper.h",
],
external_deps = [
"absl/status:statusor",
"absl/strings",
Expand All @@ -5468,8 +5493,12 @@ grpc_cc_library(

grpc_cc_library(
name = "grpc_resolver_dns_event_engine",
srcs = ["ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.cc"],
hdrs = ["ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.h"],
srcs = [
"ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.cc",
],
hdrs = [
"ext/filters/client_channel/resolver/dns/event_engine/event_engine_client_channel_resolver.h",
],
external_deps = [
"absl/base:core_headers",
"absl/cleanup",
Expand Down Expand Up @@ -6411,7 +6440,9 @@ grpc_upb_proto_library(

grpc_upb_proto_library(
name = "envoy_extensions_load_balancing_policies_client_side_weighted_round_robin_upb",
deps = ["@envoy_api//envoy/extensions/load_balancing_policies/client_side_weighted_round_robin/v3:pkg"],
deps = [
"@envoy_api//envoy/extensions/load_balancing_policies/client_side_weighted_round_robin/v3:pkg",
],
)

grpc_upb_proto_library(
Expand All @@ -6431,12 +6462,16 @@ grpc_upb_proto_library(

grpc_upb_proto_library(
name = "envoy_extensions_filters_network_http_connection_manager_upb",
deps = ["@envoy_api//envoy/extensions/filters/network/http_connection_manager/v3:pkg"],
deps = [
"@envoy_api//envoy/extensions/filters/network/http_connection_manager/v3:pkg",
],
)

grpc_upb_proto_reflection_library(
name = "envoy_extensions_filters_network_http_connection_manager_upbdefs",
deps = ["@envoy_api//envoy/extensions/filters/network/http_connection_manager/v3:pkg"],
deps = [
"@envoy_api//envoy/extensions/filters/network/http_connection_manager/v3:pkg",
],
)

grpc_upb_proto_library(
Expand Down Expand Up @@ -6563,14 +6598,20 @@ WELL_KNOWN_PROTO_TARGETS = [
"wrappers",
]

[grpc_upb_proto_library(
name = "protobuf_" + target + "_upb",
deps = ["@com_google_protobuf//:" + target + "_proto"],
) for target in WELL_KNOWN_PROTO_TARGETS]
[
grpc_upb_proto_library(
name = "protobuf_" + target + "_upb",
deps = ["@com_google_protobuf//:" + target + "_proto"],
)
for target in WELL_KNOWN_PROTO_TARGETS
]

[grpc_upb_proto_reflection_library(
name = "protobuf_" + target + "_upbdefs",
deps = ["@com_google_protobuf//:" + target + "_proto"],
) for target in WELL_KNOWN_PROTO_TARGETS]
[
grpc_upb_proto_reflection_library(
name = "protobuf_" + target + "_upbdefs",
deps = ["@com_google_protobuf//:" + target + "_proto"],
)
for target in WELL_KNOWN_PROTO_TARGETS
]

grpc_generate_one_off_internal_targets()
95 changes: 95 additions & 0 deletions src/core/lib/promise/status_flag.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// Copyright 2023 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef GRPC_SRC_CORE_LIB_PROMISE_STATUS_FLAG_H
#define GRPC_SRC_CORE_LIB_PROMISE_STATUS_FLAG_H

#include <grpc/support/port_platform.h>

#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/types/optional.h"

#include "src/core/lib/promise/detail/status.h"

namespace grpc_core {

// A boolean representing whether an operation succeeded (true) or failed
// (false).
class StatusFlag {
public:
explicit StatusFlag(bool value) : value_(value) {}

bool ok() const { return value_; }

private:
bool value_;
};

inline bool IsStatusOk(const StatusFlag& flag) { return flag.ok(); }

template <>
struct StatusCastImpl<absl::Status, StatusFlag> {
static absl::Status Cast(StatusFlag flag) {
return flag.ok() ? absl::OkStatus() : absl::CancelledError();
}
};

struct Failure {};

// A value if an operation was successful, or a failure flag if not.
template <typename T>
class ValueOrFailure {
public:
explicit ValueOrFailure(T value) : value_(std::move(value)) {}
explicit ValueOrFailure(Failure) {}

static ValueOrFailure FromOptional(absl::optional<T> value) {
return ValueOrFailure{std::move(value)};
}

bool ok() const { return value_.has_value(); }

const T& value() const { return value_.value(); }
T& value() { return value_.value(); }
const T& operator*() const { return *value_; }
T& operator*() { return *value_; }

private:
absl::optional<T> value_;
};

template <typename T>
inline bool IsStatusOk(const ValueOrFailure<T>& value) {
return value.ok();
}

template <typename T>
struct StatusCastImpl<absl::Status, ValueOrFailure<T>> {
static absl::Status Cast(const ValueOrFailure<T> flag) {
return flag.ok() ? absl::OkStatus() : absl::CancelledError();
}
};

template <typename T>
struct StatusCastImpl<absl::StatusOr<T>, ValueOrFailure<T>> {
static absl::StatusOr<T> Cast(ValueOrFailure<T> value) {
return value.ok() ? absl::StatusOr<T>(std::move(value.value()))
: absl::CancelledError();
}
};

} // namespace grpc_core

#endif // GRPC_SRC_CORE_LIB_PROMISE_STATUS_FLAG_H
11 changes: 11 additions & 0 deletions test/core/promise/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,17 @@ grpc_cc_test(
],
)

grpc_cc_test(
name = "status_flag_test",
srcs = ["status_flag_test.cc"],
external_deps = ["gtest"],
language = "c++",
tags = ["promise_test"],
uses_event_engine = False,
uses_polling = False,
deps = ["//src/core:status_flag"],
)

grpc_cc_test(
name = "promise_mutex_test",
srcs = ["promise_mutex_test.cc"],
Expand Down
Loading

0 comments on commit dc41f42

Please sign in to comment.