[transport] Move call spine related types into their own file (#35689)
Part of a continued hygiene effort for transport.h
(pure code movement, no refactoring at this time)
Closes #35689
COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/35689 from ctiller:channel-ez 3366310cc3
PiperOrigin-RevId: 602416330
This commit is contained in:
parent
5b444972f3
commit
fb14685fd6
2
BUILD
2
BUILD
|
|
@ -1533,6 +1533,7 @@ grpc_cc_library(
|
||||||
"//src/core:bitset",
|
"//src/core:bitset",
|
||||||
"//src/core:call_filters",
|
"//src/core:call_filters",
|
||||||
"//src/core:call_final_info",
|
"//src/core:call_final_info",
|
||||||
|
"//src/core:call_spine",
|
||||||
"//src/core:cancel_callback",
|
"//src/core:cancel_callback",
|
||||||
"//src/core:channel_args",
|
"//src/core:channel_args",
|
||||||
"//src/core:channel_args_endpoint_config",
|
"//src/core:channel_args_endpoint_config",
|
||||||
|
|
@ -1584,7 +1585,6 @@ grpc_cc_library(
|
||||||
"//src/core:pollset_set",
|
"//src/core:pollset_set",
|
||||||
"//src/core:posix_event_engine_base_hdrs",
|
"//src/core:posix_event_engine_base_hdrs",
|
||||||
"//src/core:posix_event_engine_endpoint",
|
"//src/core:posix_event_engine_endpoint",
|
||||||
"//src/core:prioritized_race",
|
|
||||||
"//src/core:promise_status",
|
"//src/core:promise_status",
|
||||||
"//src/core:race",
|
"//src/core:race",
|
||||||
"//src/core:random_early_detection",
|
"//src/core:random_early_detection",
|
||||||
|
|
|
||||||
|
|
@ -2528,6 +2528,7 @@ add_library(grpc
|
||||||
src/core/lib/transport/bdp_estimator.cc
|
src/core/lib/transport/bdp_estimator.cc
|
||||||
src/core/lib/transport/call_filters.cc
|
src/core/lib/transport/call_filters.cc
|
||||||
src/core/lib/transport/call_final_info.cc
|
src/core/lib/transport/call_final_info.cc
|
||||||
|
src/core/lib/transport/call_spine.cc
|
||||||
src/core/lib/transport/connectivity_state.cc
|
src/core/lib/transport/connectivity_state.cc
|
||||||
src/core/lib/transport/error_utils.cc
|
src/core/lib/transport/error_utils.cc
|
||||||
src/core/lib/transport/handshaker.cc
|
src/core/lib/transport/handshaker.cc
|
||||||
|
|
@ -3243,6 +3244,7 @@ add_library(grpc_unsecure
|
||||||
src/core/lib/transport/bdp_estimator.cc
|
src/core/lib/transport/bdp_estimator.cc
|
||||||
src/core/lib/transport/call_filters.cc
|
src/core/lib/transport/call_filters.cc
|
||||||
src/core/lib/transport/call_final_info.cc
|
src/core/lib/transport/call_final_info.cc
|
||||||
|
src/core/lib/transport/call_spine.cc
|
||||||
src/core/lib/transport/connectivity_state.cc
|
src/core/lib/transport/connectivity_state.cc
|
||||||
src/core/lib/transport/error_utils.cc
|
src/core/lib/transport/error_utils.cc
|
||||||
src/core/lib/transport/handshaker.cc
|
src/core/lib/transport/handshaker.cc
|
||||||
|
|
@ -5330,6 +5332,7 @@ add_library(grpc_authorization_provider
|
||||||
src/core/lib/transport/batch_builder.cc
|
src/core/lib/transport/batch_builder.cc
|
||||||
src/core/lib/transport/call_filters.cc
|
src/core/lib/transport/call_filters.cc
|
||||||
src/core/lib/transport/call_final_info.cc
|
src/core/lib/transport/call_final_info.cc
|
||||||
|
src/core/lib/transport/call_spine.cc
|
||||||
src/core/lib/transport/connectivity_state.cc
|
src/core/lib/transport/connectivity_state.cc
|
||||||
src/core/lib/transport/error_utils.cc
|
src/core/lib/transport/error_utils.cc
|
||||||
src/core/lib/transport/handshaker.cc
|
src/core/lib/transport/handshaker.cc
|
||||||
|
|
|
||||||
|
|
@ -1710,6 +1710,7 @@ LIBGRPC_SRC = \
|
||||||
src/core/lib/transport/bdp_estimator.cc \
|
src/core/lib/transport/bdp_estimator.cc \
|
||||||
src/core/lib/transport/call_filters.cc \
|
src/core/lib/transport/call_filters.cc \
|
||||||
src/core/lib/transport/call_final_info.cc \
|
src/core/lib/transport/call_final_info.cc \
|
||||||
|
src/core/lib/transport/call_spine.cc \
|
||||||
src/core/lib/transport/connectivity_state.cc \
|
src/core/lib/transport/connectivity_state.cc \
|
||||||
src/core/lib/transport/error_utils.cc \
|
src/core/lib/transport/error_utils.cc \
|
||||||
src/core/lib/transport/handshaker.cc \
|
src/core/lib/transport/handshaker.cc \
|
||||||
|
|
@ -2259,6 +2260,7 @@ LIBGRPC_UNSECURE_SRC = \
|
||||||
src/core/lib/transport/bdp_estimator.cc \
|
src/core/lib/transport/bdp_estimator.cc \
|
||||||
src/core/lib/transport/call_filters.cc \
|
src/core/lib/transport/call_filters.cc \
|
||||||
src/core/lib/transport/call_final_info.cc \
|
src/core/lib/transport/call_final_info.cc \
|
||||||
|
src/core/lib/transport/call_spine.cc \
|
||||||
src/core/lib/transport/connectivity_state.cc \
|
src/core/lib/transport/connectivity_state.cc \
|
||||||
src/core/lib/transport/error_utils.cc \
|
src/core/lib/transport/error_utils.cc \
|
||||||
src/core/lib/transport/handshaker.cc \
|
src/core/lib/transport/handshaker.cc \
|
||||||
|
|
|
||||||
|
|
@ -1903,6 +1903,8 @@ let package = Package(
|
||||||
"src/core/lib/transport/call_filters.h",
|
"src/core/lib/transport/call_filters.h",
|
||||||
"src/core/lib/transport/call_final_info.cc",
|
"src/core/lib/transport/call_final_info.cc",
|
||||||
"src/core/lib/transport/call_final_info.h",
|
"src/core/lib/transport/call_final_info.h",
|
||||||
|
"src/core/lib/transport/call_spine.cc",
|
||||||
|
"src/core/lib/transport/call_spine.h",
|
||||||
"src/core/lib/transport/connectivity_state.cc",
|
"src/core/lib/transport/connectivity_state.cc",
|
||||||
"src/core/lib/transport/connectivity_state.h",
|
"src/core/lib/transport/connectivity_state.h",
|
||||||
"src/core/lib/transport/custom_metadata.h",
|
"src/core/lib/transport/custom_metadata.h",
|
||||||
|
|
|
||||||
|
|
@ -1179,6 +1179,7 @@ libs:
|
||||||
- src/core/lib/transport/bdp_estimator.h
|
- src/core/lib/transport/bdp_estimator.h
|
||||||
- src/core/lib/transport/call_filters.h
|
- src/core/lib/transport/call_filters.h
|
||||||
- src/core/lib/transport/call_final_info.h
|
- src/core/lib/transport/call_final_info.h
|
||||||
|
- src/core/lib/transport/call_spine.h
|
||||||
- src/core/lib/transport/connectivity_state.h
|
- src/core/lib/transport/connectivity_state.h
|
||||||
- src/core/lib/transport/custom_metadata.h
|
- src/core/lib/transport/custom_metadata.h
|
||||||
- src/core/lib/transport/error_utils.h
|
- src/core/lib/transport/error_utils.h
|
||||||
|
|
@ -1982,6 +1983,7 @@ libs:
|
||||||
- src/core/lib/transport/bdp_estimator.cc
|
- src/core/lib/transport/bdp_estimator.cc
|
||||||
- src/core/lib/transport/call_filters.cc
|
- src/core/lib/transport/call_filters.cc
|
||||||
- src/core/lib/transport/call_final_info.cc
|
- src/core/lib/transport/call_final_info.cc
|
||||||
|
- src/core/lib/transport/call_spine.cc
|
||||||
- src/core/lib/transport/connectivity_state.cc
|
- src/core/lib/transport/connectivity_state.cc
|
||||||
- src/core/lib/transport/error_utils.cc
|
- src/core/lib/transport/error_utils.cc
|
||||||
- src/core/lib/transport/handshaker.cc
|
- src/core/lib/transport/handshaker.cc
|
||||||
|
|
@ -2628,6 +2630,7 @@ libs:
|
||||||
- src/core/lib/transport/bdp_estimator.h
|
- src/core/lib/transport/bdp_estimator.h
|
||||||
- src/core/lib/transport/call_filters.h
|
- src/core/lib/transport/call_filters.h
|
||||||
- src/core/lib/transport/call_final_info.h
|
- src/core/lib/transport/call_final_info.h
|
||||||
|
- src/core/lib/transport/call_spine.h
|
||||||
- src/core/lib/transport/connectivity_state.h
|
- src/core/lib/transport/connectivity_state.h
|
||||||
- src/core/lib/transport/custom_metadata.h
|
- src/core/lib/transport/custom_metadata.h
|
||||||
- src/core/lib/transport/error_utils.h
|
- src/core/lib/transport/error_utils.h
|
||||||
|
|
@ -3047,6 +3050,7 @@ libs:
|
||||||
- src/core/lib/transport/bdp_estimator.cc
|
- src/core/lib/transport/bdp_estimator.cc
|
||||||
- src/core/lib/transport/call_filters.cc
|
- src/core/lib/transport/call_filters.cc
|
||||||
- src/core/lib/transport/call_final_info.cc
|
- src/core/lib/transport/call_final_info.cc
|
||||||
|
- src/core/lib/transport/call_spine.cc
|
||||||
- src/core/lib/transport/connectivity_state.cc
|
- src/core/lib/transport/connectivity_state.cc
|
||||||
- src/core/lib/transport/error_utils.cc
|
- src/core/lib/transport/error_utils.cc
|
||||||
- src/core/lib/transport/handshaker.cc
|
- src/core/lib/transport/handshaker.cc
|
||||||
|
|
@ -4669,6 +4673,7 @@ libs:
|
||||||
- src/core/lib/transport/batch_builder.h
|
- src/core/lib/transport/batch_builder.h
|
||||||
- src/core/lib/transport/call_filters.h
|
- src/core/lib/transport/call_filters.h
|
||||||
- src/core/lib/transport/call_final_info.h
|
- src/core/lib/transport/call_final_info.h
|
||||||
|
- src/core/lib/transport/call_spine.h
|
||||||
- src/core/lib/transport/connectivity_state.h
|
- src/core/lib/transport/connectivity_state.h
|
||||||
- src/core/lib/transport/custom_metadata.h
|
- src/core/lib/transport/custom_metadata.h
|
||||||
- src/core/lib/transport/error_utils.h
|
- src/core/lib/transport/error_utils.h
|
||||||
|
|
@ -4965,6 +4970,7 @@ libs:
|
||||||
- src/core/lib/transport/batch_builder.cc
|
- src/core/lib/transport/batch_builder.cc
|
||||||
- src/core/lib/transport/call_filters.cc
|
- src/core/lib/transport/call_filters.cc
|
||||||
- src/core/lib/transport/call_final_info.cc
|
- src/core/lib/transport/call_final_info.cc
|
||||||
|
- src/core/lib/transport/call_spine.cc
|
||||||
- src/core/lib/transport/connectivity_state.cc
|
- src/core/lib/transport/connectivity_state.cc
|
||||||
- src/core/lib/transport/error_utils.cc
|
- src/core/lib/transport/error_utils.cc
|
||||||
- src/core/lib/transport/handshaker.cc
|
- src/core/lib/transport/handshaker.cc
|
||||||
|
|
|
||||||
|
|
@ -838,6 +838,7 @@ if test "$PHP_GRPC" != "no"; then
|
||||||
src/core/lib/transport/bdp_estimator.cc \
|
src/core/lib/transport/bdp_estimator.cc \
|
||||||
src/core/lib/transport/call_filters.cc \
|
src/core/lib/transport/call_filters.cc \
|
||||||
src/core/lib/transport/call_final_info.cc \
|
src/core/lib/transport/call_final_info.cc \
|
||||||
|
src/core/lib/transport/call_spine.cc \
|
||||||
src/core/lib/transport/connectivity_state.cc \
|
src/core/lib/transport/connectivity_state.cc \
|
||||||
src/core/lib/transport/error_utils.cc \
|
src/core/lib/transport/error_utils.cc \
|
||||||
src/core/lib/transport/handshaker.cc \
|
src/core/lib/transport/handshaker.cc \
|
||||||
|
|
|
||||||
|
|
@ -803,6 +803,7 @@ if (PHP_GRPC != "no") {
|
||||||
"src\\core\\lib\\transport\\bdp_estimator.cc " +
|
"src\\core\\lib\\transport\\bdp_estimator.cc " +
|
||||||
"src\\core\\lib\\transport\\call_filters.cc " +
|
"src\\core\\lib\\transport\\call_filters.cc " +
|
||||||
"src\\core\\lib\\transport\\call_final_info.cc " +
|
"src\\core\\lib\\transport\\call_final_info.cc " +
|
||||||
|
"src\\core\\lib\\transport\\call_spine.cc " +
|
||||||
"src\\core\\lib\\transport\\connectivity_state.cc " +
|
"src\\core\\lib\\transport\\connectivity_state.cc " +
|
||||||
"src\\core\\lib\\transport\\error_utils.cc " +
|
"src\\core\\lib\\transport\\error_utils.cc " +
|
||||||
"src\\core\\lib\\transport\\handshaker.cc " +
|
"src\\core\\lib\\transport\\handshaker.cc " +
|
||||||
|
|
|
||||||
|
|
@ -1283,6 +1283,7 @@ Pod::Spec.new do |s|
|
||||||
'src/core/lib/transport/bdp_estimator.h',
|
'src/core/lib/transport/bdp_estimator.h',
|
||||||
'src/core/lib/transport/call_filters.h',
|
'src/core/lib/transport/call_filters.h',
|
||||||
'src/core/lib/transport/call_final_info.h',
|
'src/core/lib/transport/call_final_info.h',
|
||||||
|
'src/core/lib/transport/call_spine.h',
|
||||||
'src/core/lib/transport/connectivity_state.h',
|
'src/core/lib/transport/connectivity_state.h',
|
||||||
'src/core/lib/transport/custom_metadata.h',
|
'src/core/lib/transport/custom_metadata.h',
|
||||||
'src/core/lib/transport/error_utils.h',
|
'src/core/lib/transport/error_utils.h',
|
||||||
|
|
@ -2537,6 +2538,7 @@ Pod::Spec.new do |s|
|
||||||
'src/core/lib/transport/bdp_estimator.h',
|
'src/core/lib/transport/bdp_estimator.h',
|
||||||
'src/core/lib/transport/call_filters.h',
|
'src/core/lib/transport/call_filters.h',
|
||||||
'src/core/lib/transport/call_final_info.h',
|
'src/core/lib/transport/call_final_info.h',
|
||||||
|
'src/core/lib/transport/call_spine.h',
|
||||||
'src/core/lib/transport/connectivity_state.h',
|
'src/core/lib/transport/connectivity_state.h',
|
||||||
'src/core/lib/transport/custom_metadata.h',
|
'src/core/lib/transport/custom_metadata.h',
|
||||||
'src/core/lib/transport/error_utils.h',
|
'src/core/lib/transport/error_utils.h',
|
||||||
|
|
|
||||||
|
|
@ -2012,6 +2012,8 @@ Pod::Spec.new do |s|
|
||||||
'src/core/lib/transport/call_filters.h',
|
'src/core/lib/transport/call_filters.h',
|
||||||
'src/core/lib/transport/call_final_info.cc',
|
'src/core/lib/transport/call_final_info.cc',
|
||||||
'src/core/lib/transport/call_final_info.h',
|
'src/core/lib/transport/call_final_info.h',
|
||||||
|
'src/core/lib/transport/call_spine.cc',
|
||||||
|
'src/core/lib/transport/call_spine.h',
|
||||||
'src/core/lib/transport/connectivity_state.cc',
|
'src/core/lib/transport/connectivity_state.cc',
|
||||||
'src/core/lib/transport/connectivity_state.h',
|
'src/core/lib/transport/connectivity_state.h',
|
||||||
'src/core/lib/transport/custom_metadata.h',
|
'src/core/lib/transport/custom_metadata.h',
|
||||||
|
|
@ -3314,6 +3316,7 @@ Pod::Spec.new do |s|
|
||||||
'src/core/lib/transport/bdp_estimator.h',
|
'src/core/lib/transport/bdp_estimator.h',
|
||||||
'src/core/lib/transport/call_filters.h',
|
'src/core/lib/transport/call_filters.h',
|
||||||
'src/core/lib/transport/call_final_info.h',
|
'src/core/lib/transport/call_final_info.h',
|
||||||
|
'src/core/lib/transport/call_spine.h',
|
||||||
'src/core/lib/transport/connectivity_state.h',
|
'src/core/lib/transport/connectivity_state.h',
|
||||||
'src/core/lib/transport/custom_metadata.h',
|
'src/core/lib/transport/custom_metadata.h',
|
||||||
'src/core/lib/transport/error_utils.h',
|
'src/core/lib/transport/error_utils.h',
|
||||||
|
|
|
||||||
|
|
@ -1905,6 +1905,8 @@ Gem::Specification.new do |s|
|
||||||
s.files += %w( src/core/lib/transport/call_filters.h )
|
s.files += %w( src/core/lib/transport/call_filters.h )
|
||||||
s.files += %w( src/core/lib/transport/call_final_info.cc )
|
s.files += %w( src/core/lib/transport/call_final_info.cc )
|
||||||
s.files += %w( src/core/lib/transport/call_final_info.h )
|
s.files += %w( src/core/lib/transport/call_final_info.h )
|
||||||
|
s.files += %w( src/core/lib/transport/call_spine.cc )
|
||||||
|
s.files += %w( src/core/lib/transport/call_spine.h )
|
||||||
s.files += %w( src/core/lib/transport/connectivity_state.cc )
|
s.files += %w( src/core/lib/transport/connectivity_state.cc )
|
||||||
s.files += %w( src/core/lib/transport/connectivity_state.h )
|
s.files += %w( src/core/lib/transport/connectivity_state.h )
|
||||||
s.files += %w( src/core/lib/transport/custom_metadata.h )
|
s.files += %w( src/core/lib/transport/custom_metadata.h )
|
||||||
|
|
|
||||||
|
|
@ -1024,6 +1024,7 @@
|
||||||
'src/core/lib/transport/bdp_estimator.cc',
|
'src/core/lib/transport/bdp_estimator.cc',
|
||||||
'src/core/lib/transport/call_filters.cc',
|
'src/core/lib/transport/call_filters.cc',
|
||||||
'src/core/lib/transport/call_final_info.cc',
|
'src/core/lib/transport/call_final_info.cc',
|
||||||
|
'src/core/lib/transport/call_spine.cc',
|
||||||
'src/core/lib/transport/connectivity_state.cc',
|
'src/core/lib/transport/connectivity_state.cc',
|
||||||
'src/core/lib/transport/error_utils.cc',
|
'src/core/lib/transport/error_utils.cc',
|
||||||
'src/core/lib/transport/handshaker.cc',
|
'src/core/lib/transport/handshaker.cc',
|
||||||
|
|
@ -1513,6 +1514,7 @@
|
||||||
'src/core/lib/transport/bdp_estimator.cc',
|
'src/core/lib/transport/bdp_estimator.cc',
|
||||||
'src/core/lib/transport/call_filters.cc',
|
'src/core/lib/transport/call_filters.cc',
|
||||||
'src/core/lib/transport/call_final_info.cc',
|
'src/core/lib/transport/call_final_info.cc',
|
||||||
|
'src/core/lib/transport/call_spine.cc',
|
||||||
'src/core/lib/transport/connectivity_state.cc',
|
'src/core/lib/transport/connectivity_state.cc',
|
||||||
'src/core/lib/transport/error_utils.cc',
|
'src/core/lib/transport/error_utils.cc',
|
||||||
'src/core/lib/transport/handshaker.cc',
|
'src/core/lib/transport/handshaker.cc',
|
||||||
|
|
@ -2282,6 +2284,7 @@
|
||||||
'src/core/lib/transport/batch_builder.cc',
|
'src/core/lib/transport/batch_builder.cc',
|
||||||
'src/core/lib/transport/call_filters.cc',
|
'src/core/lib/transport/call_filters.cc',
|
||||||
'src/core/lib/transport/call_final_info.cc',
|
'src/core/lib/transport/call_final_info.cc',
|
||||||
|
'src/core/lib/transport/call_spine.cc',
|
||||||
'src/core/lib/transport/connectivity_state.cc',
|
'src/core/lib/transport/connectivity_state.cc',
|
||||||
'src/core/lib/transport/error_utils.cc',
|
'src/core/lib/transport/error_utils.cc',
|
||||||
'src/core/lib/transport/handshaker.cc',
|
'src/core/lib/transport/handshaker.cc',
|
||||||
|
|
|
||||||
|
|
@ -1887,6 +1887,8 @@
|
||||||
<file baseinstalldir="/" name="src/core/lib/transport/call_filters.h" role="src" />
|
<file baseinstalldir="/" name="src/core/lib/transport/call_filters.h" role="src" />
|
||||||
<file baseinstalldir="/" name="src/core/lib/transport/call_final_info.cc" role="src" />
|
<file baseinstalldir="/" name="src/core/lib/transport/call_final_info.cc" role="src" />
|
||||||
<file baseinstalldir="/" name="src/core/lib/transport/call_final_info.h" role="src" />
|
<file baseinstalldir="/" name="src/core/lib/transport/call_final_info.h" role="src" />
|
||||||
|
<file baseinstalldir="/" name="src/core/lib/transport/call_spine.cc" role="src" />
|
||||||
|
<file baseinstalldir="/" name="src/core/lib/transport/call_spine.h" role="src" />
|
||||||
<file baseinstalldir="/" name="src/core/lib/transport/connectivity_state.cc" role="src" />
|
<file baseinstalldir="/" name="src/core/lib/transport/connectivity_state.cc" role="src" />
|
||||||
<file baseinstalldir="/" name="src/core/lib/transport/connectivity_state.h" role="src" />
|
<file baseinstalldir="/" name="src/core/lib/transport/connectivity_state.h" role="src" />
|
||||||
<file baseinstalldir="/" name="src/core/lib/transport/custom_metadata.h" role="src" />
|
<file baseinstalldir="/" name="src/core/lib/transport/custom_metadata.h" role="src" />
|
||||||
|
|
|
||||||
|
|
@ -6788,6 +6788,30 @@ grpc_cc_library(
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
grpc_cc_library(
|
||||||
|
name = "call_spine",
|
||||||
|
srcs = [
|
||||||
|
"lib/transport/call_spine.cc",
|
||||||
|
],
|
||||||
|
hdrs = [
|
||||||
|
"lib/transport/call_spine.h",
|
||||||
|
],
|
||||||
|
deps = [
|
||||||
|
"1999",
|
||||||
|
"for_each",
|
||||||
|
"if",
|
||||||
|
"latch",
|
||||||
|
"message",
|
||||||
|
"metadata",
|
||||||
|
"pipe",
|
||||||
|
"prioritized_race",
|
||||||
|
"promise_status",
|
||||||
|
"status_flag",
|
||||||
|
"try_seq",
|
||||||
|
"//:gpr",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
grpc_cc_library(
|
grpc_cc_library(
|
||||||
name = "metadata_batch",
|
name = "metadata_batch",
|
||||||
srcs = [
|
srcs = [
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,103 @@
|
||||||
|
// Copyright 2024 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.
|
||||||
|
|
||||||
|
#include <grpc/support/port_platform.h>
|
||||||
|
|
||||||
|
#include "src/core/lib/transport/call_spine.h"
|
||||||
|
|
||||||
|
namespace grpc_core {
|
||||||
|
|
||||||
|
void ForwardCall(CallHandler call_handler, CallInitiator call_initiator,
|
||||||
|
ClientMetadataHandle client_initial_metadata) {
|
||||||
|
// Send initial metadata.
|
||||||
|
call_initiator.SpawnGuarded(
|
||||||
|
"send_initial_metadata",
|
||||||
|
[client_initial_metadata = std::move(client_initial_metadata),
|
||||||
|
call_initiator]() mutable {
|
||||||
|
return call_initiator.PushClientInitialMetadata(
|
||||||
|
std::move(client_initial_metadata));
|
||||||
|
});
|
||||||
|
// Read messages from handler into initiator.
|
||||||
|
call_handler.SpawnGuarded("read_messages", [call_handler,
|
||||||
|
call_initiator]() mutable {
|
||||||
|
return Seq(ForEach(OutgoingMessages(call_handler),
|
||||||
|
[call_initiator](MessageHandle msg) mutable {
|
||||||
|
// Need to spawn a job into the initiator's activity to
|
||||||
|
// push the message in.
|
||||||
|
return call_initiator.SpawnWaitable(
|
||||||
|
"send_message",
|
||||||
|
[msg = std::move(msg), call_initiator]() mutable {
|
||||||
|
return call_initiator.CancelIfFails(
|
||||||
|
call_initiator.PushMessage(std::move(msg)));
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
[call_initiator](StatusFlag result) mutable {
|
||||||
|
call_initiator.SpawnInfallible(
|
||||||
|
"finish-downstream", [call_initiator, result]() mutable {
|
||||||
|
if (result.ok()) {
|
||||||
|
call_initiator.FinishSends();
|
||||||
|
} else {
|
||||||
|
call_initiator.Cancel();
|
||||||
|
}
|
||||||
|
return Empty{};
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
call_initiator.SpawnInfallible("read_the_things", [call_initiator,
|
||||||
|
call_handler]() mutable {
|
||||||
|
return Seq(
|
||||||
|
call_initiator.CancelIfFails(TrySeq(
|
||||||
|
call_initiator.PullServerInitialMetadata(),
|
||||||
|
[call_handler,
|
||||||
|
call_initiator](absl::optional<ServerMetadataHandle> md) mutable {
|
||||||
|
const bool has_md = md.has_value();
|
||||||
|
call_handler.SpawnGuarded(
|
||||||
|
"recv_initial_metadata",
|
||||||
|
[md = std::move(md), call_handler]() mutable {
|
||||||
|
return call_handler.PushServerInitialMetadata(
|
||||||
|
std::move(md));
|
||||||
|
});
|
||||||
|
return If(
|
||||||
|
has_md,
|
||||||
|
ForEach(OutgoingMessages(call_initiator),
|
||||||
|
[call_handler](MessageHandle msg) mutable {
|
||||||
|
return call_handler.SpawnWaitable(
|
||||||
|
"recv_message",
|
||||||
|
[msg = std::move(msg), call_handler]() mutable {
|
||||||
|
return call_handler.CancelIfFails(
|
||||||
|
call_handler.PushMessage(std::move(msg)));
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
[]() -> StatusFlag { return Success{}; });
|
||||||
|
})),
|
||||||
|
call_initiator.PullServerTrailingMetadata(),
|
||||||
|
[call_handler](ServerMetadataHandle md) mutable {
|
||||||
|
call_handler.SpawnGuarded(
|
||||||
|
"recv_trailing_metadata",
|
||||||
|
[md = std::move(md), call_handler]() mutable {
|
||||||
|
return call_handler.PushServerTrailingMetadata(std::move(md));
|
||||||
|
});
|
||||||
|
return Empty{};
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
CallInitiatorAndHandler MakeCall(
|
||||||
|
grpc_event_engine::experimental::EventEngine* event_engine, Arena* arena) {
|
||||||
|
auto spine = CallSpine::Create(event_engine, arena);
|
||||||
|
return {CallInitiator(spine), CallHandler(spine)};
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace grpc_core
|
||||||
|
|
@ -0,0 +1,418 @@
|
||||||
|
// Copyright 2024 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_TRANSPORT_CALL_SPINE_H
|
||||||
|
#define GRPC_SRC_CORE_LIB_TRANSPORT_CALL_SPINE_H
|
||||||
|
|
||||||
|
#include <grpc/support/port_platform.h>
|
||||||
|
|
||||||
|
#include <grpc/support/log.h>
|
||||||
|
|
||||||
|
#include "src/core/lib/promise/detail/status.h"
|
||||||
|
#include "src/core/lib/promise/for_each.h"
|
||||||
|
#include "src/core/lib/promise/if.h"
|
||||||
|
#include "src/core/lib/promise/latch.h"
|
||||||
|
#include "src/core/lib/promise/party.h"
|
||||||
|
#include "src/core/lib/promise/pipe.h"
|
||||||
|
#include "src/core/lib/promise/prioritized_race.h"
|
||||||
|
#include "src/core/lib/promise/status_flag.h"
|
||||||
|
#include "src/core/lib/promise/try_seq.h"
|
||||||
|
#include "src/core/lib/transport/message.h"
|
||||||
|
#include "src/core/lib/transport/metadata.h"
|
||||||
|
|
||||||
|
namespace grpc_core {
|
||||||
|
|
||||||
|
// The common middle part of a call - a reference is held by each of
|
||||||
|
// CallInitiator and CallHandler - which provide interfaces that are appropriate
|
||||||
|
// for each side of a call.
|
||||||
|
// The spine will ultimately host the pipes, filters, and context for one part
|
||||||
|
// of a call: ie top-half client channel, sub channel call, server call.
|
||||||
|
// TODO(ctiller): eventually drop this when we don't need to reference into
|
||||||
|
// legacy promise calls anymore
|
||||||
|
class CallSpineInterface {
|
||||||
|
public:
|
||||||
|
virtual ~CallSpineInterface() = default;
|
||||||
|
virtual Pipe<ClientMetadataHandle>& client_initial_metadata() = 0;
|
||||||
|
virtual Pipe<ServerMetadataHandle>& server_initial_metadata() = 0;
|
||||||
|
virtual Pipe<MessageHandle>& client_to_server_messages() = 0;
|
||||||
|
virtual Pipe<MessageHandle>& server_to_client_messages() = 0;
|
||||||
|
virtual Pipe<ServerMetadataHandle>& server_trailing_metadata() = 0;
|
||||||
|
virtual Latch<ServerMetadataHandle>& cancel_latch() = 0;
|
||||||
|
// Add a callback to be called when server trailing metadata is received.
|
||||||
|
void OnDone(absl::AnyInvocable<void()> fn) {
|
||||||
|
if (on_done_ == nullptr) {
|
||||||
|
on_done_ = std::move(fn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
on_done_ = [first = std::move(fn), next = std::move(on_done_)]() mutable {
|
||||||
|
first();
|
||||||
|
next();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
void CallOnDone() {
|
||||||
|
if (on_done_ != nullptr) std::exchange(on_done_, nullptr)();
|
||||||
|
}
|
||||||
|
virtual Party& party() = 0;
|
||||||
|
virtual void IncrementRefCount() = 0;
|
||||||
|
virtual void Unref() = 0;
|
||||||
|
|
||||||
|
// Cancel the call with the given metadata.
|
||||||
|
// Regarding the `MUST_USE_RESULT absl::nullopt_t`:
|
||||||
|
// Most cancellation calls right now happen in pipe interceptors;
|
||||||
|
// there `nullopt` indicates terminate processing of this pipe and close with
|
||||||
|
// error.
|
||||||
|
// It's convenient then to have the Cancel operation (setting the latch to
|
||||||
|
// terminate the call) be the last thing that occurs in a pipe interceptor,
|
||||||
|
// and this construction supports that (and has helped the author not write
|
||||||
|
// some bugs).
|
||||||
|
GRPC_MUST_USE_RESULT absl::nullopt_t Cancel(ServerMetadataHandle metadata) {
|
||||||
|
GPR_DEBUG_ASSERT(GetContext<Activity>() == &party());
|
||||||
|
auto& c = cancel_latch();
|
||||||
|
if (c.is_set()) return absl::nullopt;
|
||||||
|
c.Set(std::move(metadata));
|
||||||
|
CallOnDone();
|
||||||
|
client_initial_metadata().sender.CloseWithError();
|
||||||
|
server_initial_metadata().sender.CloseWithError();
|
||||||
|
client_to_server_messages().sender.CloseWithError();
|
||||||
|
server_to_client_messages().sender.CloseWithError();
|
||||||
|
return absl::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto WaitForCancel() {
|
||||||
|
GPR_DEBUG_ASSERT(GetContext<Activity>() == &party());
|
||||||
|
return cancel_latch().Wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrap a promise so that if it returns failure it automatically cancels
|
||||||
|
// the rest of the call.
|
||||||
|
// The resulting (returned) promise will resolve to Empty.
|
||||||
|
template <typename Promise>
|
||||||
|
auto CancelIfFails(Promise promise) {
|
||||||
|
GPR_DEBUG_ASSERT(GetContext<Activity>() == &party());
|
||||||
|
using P = promise_detail::PromiseLike<Promise>;
|
||||||
|
using ResultType = typename P::Result;
|
||||||
|
return Map(std::move(promise), [this](ResultType r) {
|
||||||
|
if (!IsStatusOk(r)) {
|
||||||
|
std::ignore = Cancel(StatusCast<ServerMetadataHandle>(r));
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Spawn a promise that returns Empty{} and save some boilerplate handling
|
||||||
|
// that detail.
|
||||||
|
template <typename PromiseFactory>
|
||||||
|
void SpawnInfallible(absl::string_view name, PromiseFactory promise_factory) {
|
||||||
|
party().Spawn(name, std::move(promise_factory), [](Empty) {});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Spawn a promise that returns some status-like type; if the status
|
||||||
|
// represents failure automatically cancel the rest of the call.
|
||||||
|
template <typename PromiseFactory>
|
||||||
|
void SpawnGuarded(absl::string_view name, PromiseFactory promise_factory) {
|
||||||
|
using FactoryType =
|
||||||
|
promise_detail::OncePromiseFactory<void, PromiseFactory>;
|
||||||
|
using PromiseType = typename FactoryType::Promise;
|
||||||
|
using ResultType = typename PromiseType::Result;
|
||||||
|
static_assert(
|
||||||
|
std::is_same<bool,
|
||||||
|
decltype(IsStatusOk(std::declval<ResultType>()))>::value,
|
||||||
|
"SpawnGuarded promise must return a status-like object");
|
||||||
|
party().Spawn(name, std::move(promise_factory), [this](ResultType r) {
|
||||||
|
if (!IsStatusOk(r)) {
|
||||||
|
if (grpc_trace_promise_primitives.enabled()) {
|
||||||
|
gpr_log(GPR_DEBUG, "SpawnGuarded sees failure: %s",
|
||||||
|
r.ToString().c_str());
|
||||||
|
}
|
||||||
|
std::ignore = Cancel(StatusCast<ServerMetadataHandle>(std::move(r)));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
absl::AnyInvocable<void()> on_done_{nullptr};
|
||||||
|
};
|
||||||
|
|
||||||
|
class CallSpine final : public CallSpineInterface, public Party {
|
||||||
|
public:
|
||||||
|
static RefCountedPtr<CallSpine> Create(
|
||||||
|
grpc_event_engine::experimental::EventEngine* event_engine,
|
||||||
|
Arena* arena) {
|
||||||
|
return RefCountedPtr<CallSpine>(arena->New<CallSpine>(event_engine, arena));
|
||||||
|
}
|
||||||
|
|
||||||
|
Pipe<ClientMetadataHandle>& client_initial_metadata() override {
|
||||||
|
return client_initial_metadata_;
|
||||||
|
}
|
||||||
|
Pipe<ServerMetadataHandle>& server_initial_metadata() override {
|
||||||
|
return server_initial_metadata_;
|
||||||
|
}
|
||||||
|
Pipe<MessageHandle>& client_to_server_messages() override {
|
||||||
|
return client_to_server_messages_;
|
||||||
|
}
|
||||||
|
Pipe<MessageHandle>& server_to_client_messages() override {
|
||||||
|
return server_to_client_messages_;
|
||||||
|
}
|
||||||
|
Pipe<ServerMetadataHandle>& server_trailing_metadata() override {
|
||||||
|
return server_trailing_metadata_;
|
||||||
|
}
|
||||||
|
Latch<ServerMetadataHandle>& cancel_latch() override { return cancel_latch_; }
|
||||||
|
Party& party() override { return *this; }
|
||||||
|
void IncrementRefCount() override { Party::IncrementRefCount(); }
|
||||||
|
void Unref() override { Party::Unref(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class Arena;
|
||||||
|
CallSpine(grpc_event_engine::experimental::EventEngine* event_engine,
|
||||||
|
Arena* arena)
|
||||||
|
: Party(arena, 1), event_engine_(event_engine) {}
|
||||||
|
|
||||||
|
class ScopedContext : public ScopedActivity,
|
||||||
|
public promise_detail::Context<Arena> {
|
||||||
|
public:
|
||||||
|
explicit ScopedContext(CallSpine* spine)
|
||||||
|
: ScopedActivity(&spine->party()), Context<Arena>(spine->arena()) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
bool RunParty() override {
|
||||||
|
ScopedContext context(this);
|
||||||
|
return Party::RunParty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void PartyOver() override {
|
||||||
|
Arena* a = arena();
|
||||||
|
{
|
||||||
|
ScopedContext context(this);
|
||||||
|
CancelRemainingParticipants();
|
||||||
|
a->DestroyManagedNewObjects();
|
||||||
|
}
|
||||||
|
this->~CallSpine();
|
||||||
|
a->Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
grpc_event_engine::experimental::EventEngine* event_engine() const override {
|
||||||
|
return event_engine_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Initial metadata from client to server
|
||||||
|
Pipe<ClientMetadataHandle> client_initial_metadata_{arena()};
|
||||||
|
// Initial metadata from server to client
|
||||||
|
Pipe<ServerMetadataHandle> server_initial_metadata_{arena()};
|
||||||
|
// Messages travelling from the application to the transport.
|
||||||
|
Pipe<MessageHandle> client_to_server_messages_{arena()};
|
||||||
|
// Messages travelling from the transport to the application.
|
||||||
|
Pipe<MessageHandle> server_to_client_messages_{arena()};
|
||||||
|
// Trailing metadata from server to client
|
||||||
|
Pipe<ServerMetadataHandle> server_trailing_metadata_{arena()};
|
||||||
|
// Latch that can be set to terminate the call
|
||||||
|
Latch<ServerMetadataHandle> cancel_latch_;
|
||||||
|
// Event engine associated with this call
|
||||||
|
grpc_event_engine::experimental::EventEngine* const event_engine_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CallInitiator {
|
||||||
|
public:
|
||||||
|
explicit CallInitiator(RefCountedPtr<CallSpineInterface> spine)
|
||||||
|
: spine_(std::move(spine)) {}
|
||||||
|
|
||||||
|
auto PushClientInitialMetadata(ClientMetadataHandle md) {
|
||||||
|
GPR_DEBUG_ASSERT(GetContext<Activity>() == &spine_->party());
|
||||||
|
return Map(spine_->client_initial_metadata().sender.Push(std::move(md)),
|
||||||
|
[](bool ok) { return StatusFlag(ok); });
|
||||||
|
}
|
||||||
|
|
||||||
|
auto PullServerInitialMetadata() {
|
||||||
|
GPR_DEBUG_ASSERT(GetContext<Activity>() == &spine_->party());
|
||||||
|
return Map(spine_->server_initial_metadata().receiver.Next(),
|
||||||
|
[](NextResult<ServerMetadataHandle> md)
|
||||||
|
-> ValueOrFailure<absl::optional<ServerMetadataHandle>> {
|
||||||
|
if (!md.has_value()) {
|
||||||
|
if (md.cancelled()) return Failure{};
|
||||||
|
return absl::optional<ServerMetadataHandle>();
|
||||||
|
}
|
||||||
|
return absl::optional<ServerMetadataHandle>(std::move(*md));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
auto PullServerTrailingMetadata() {
|
||||||
|
GPR_DEBUG_ASSERT(GetContext<Activity>() == &spine_->party());
|
||||||
|
return PrioritizedRace(
|
||||||
|
Map(spine_->server_trailing_metadata().receiver.Next(),
|
||||||
|
[spine = spine_](
|
||||||
|
NextResult<ServerMetadataHandle> md) -> ServerMetadataHandle {
|
||||||
|
GPR_ASSERT(md.has_value());
|
||||||
|
return std::move(*md);
|
||||||
|
}),
|
||||||
|
spine_->WaitForCancel());
|
||||||
|
}
|
||||||
|
|
||||||
|
auto PullMessage() {
|
||||||
|
GPR_DEBUG_ASSERT(GetContext<Activity>() == &spine_->party());
|
||||||
|
return spine_->server_to_client_messages().receiver.Next();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto PushMessage(MessageHandle message) {
|
||||||
|
GPR_DEBUG_ASSERT(GetContext<Activity>() == &spine_->party());
|
||||||
|
return Map(
|
||||||
|
spine_->client_to_server_messages().sender.Push(std::move(message)),
|
||||||
|
[](bool r) { return StatusFlag(r); });
|
||||||
|
}
|
||||||
|
|
||||||
|
void FinishSends() {
|
||||||
|
GPR_DEBUG_ASSERT(GetContext<Activity>() == &spine_->party());
|
||||||
|
spine_->client_to_server_messages().sender.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Promise>
|
||||||
|
auto CancelIfFails(Promise promise) {
|
||||||
|
return spine_->CancelIfFails(std::move(promise));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cancel() {
|
||||||
|
GPR_DEBUG_ASSERT(GetContext<Activity>() == &spine_->party());
|
||||||
|
std::ignore =
|
||||||
|
spine_->Cancel(ServerMetadataFromStatus(absl::CancelledError()));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename PromiseFactory>
|
||||||
|
void SpawnGuarded(absl::string_view name, PromiseFactory promise_factory) {
|
||||||
|
spine_->SpawnGuarded(name, std::move(promise_factory));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename PromiseFactory>
|
||||||
|
void SpawnInfallible(absl::string_view name, PromiseFactory promise_factory) {
|
||||||
|
spine_->SpawnInfallible(name, std::move(promise_factory));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename PromiseFactory>
|
||||||
|
auto SpawnWaitable(absl::string_view name, PromiseFactory promise_factory) {
|
||||||
|
return spine_->party().SpawnWaitable(name, std::move(promise_factory));
|
||||||
|
}
|
||||||
|
|
||||||
|
Arena* arena() { return spine_->party().arena(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
RefCountedPtr<CallSpineInterface> spine_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CallHandler {
|
||||||
|
public:
|
||||||
|
explicit CallHandler(RefCountedPtr<CallSpineInterface> spine)
|
||||||
|
: spine_(std::move(spine)) {}
|
||||||
|
|
||||||
|
auto PullClientInitialMetadata() {
|
||||||
|
GPR_DEBUG_ASSERT(GetContext<Activity>() == &spine_->party());
|
||||||
|
return Map(spine_->client_initial_metadata().receiver.Next(),
|
||||||
|
[](NextResult<ClientMetadataHandle> md)
|
||||||
|
-> ValueOrFailure<ClientMetadataHandle> {
|
||||||
|
if (!md.has_value()) return Failure{};
|
||||||
|
return std::move(*md);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
auto PushServerInitialMetadata(absl::optional<ServerMetadataHandle> md) {
|
||||||
|
GPR_DEBUG_ASSERT(GetContext<Activity>() == &spine_->party());
|
||||||
|
return If(
|
||||||
|
md.has_value(),
|
||||||
|
[&md, this]() {
|
||||||
|
return Map(
|
||||||
|
spine_->server_initial_metadata().sender.Push(std::move(*md)),
|
||||||
|
[](bool ok) { return StatusFlag(ok); });
|
||||||
|
},
|
||||||
|
[this]() {
|
||||||
|
spine_->server_initial_metadata().sender.Close();
|
||||||
|
return []() -> StatusFlag { return Success{}; };
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
auto PushServerTrailingMetadata(ServerMetadataHandle md) {
|
||||||
|
GPR_DEBUG_ASSERT(GetContext<Activity>() == &spine_->party());
|
||||||
|
spine_->server_initial_metadata().sender.Close();
|
||||||
|
spine_->server_to_client_messages().sender.Close();
|
||||||
|
spine_->client_to_server_messages().receiver.CloseWithError();
|
||||||
|
spine_->CallOnDone();
|
||||||
|
return Map(spine_->server_trailing_metadata().sender.Push(std::move(md)),
|
||||||
|
[](bool ok) { return StatusFlag(ok); });
|
||||||
|
}
|
||||||
|
|
||||||
|
auto PullMessage() {
|
||||||
|
GPR_DEBUG_ASSERT(GetContext<Activity>() == &spine_->party());
|
||||||
|
return spine_->client_to_server_messages().receiver.Next();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto PushMessage(MessageHandle message) {
|
||||||
|
GPR_DEBUG_ASSERT(GetContext<Activity>() == &spine_->party());
|
||||||
|
return Map(
|
||||||
|
spine_->server_to_client_messages().sender.Push(std::move(message)),
|
||||||
|
[](bool ok) { return StatusFlag(ok); });
|
||||||
|
}
|
||||||
|
|
||||||
|
void Cancel(ServerMetadataHandle status) {
|
||||||
|
GPR_DEBUG_ASSERT(GetContext<Activity>() == &spine_->party());
|
||||||
|
std::ignore = spine_->Cancel(std::move(status));
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnDone(absl::AnyInvocable<void()> fn) { spine_->OnDone(std::move(fn)); }
|
||||||
|
|
||||||
|
template <typename Promise>
|
||||||
|
auto CancelIfFails(Promise promise) {
|
||||||
|
return spine_->CancelIfFails(std::move(promise));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename PromiseFactory>
|
||||||
|
void SpawnGuarded(absl::string_view name, PromiseFactory promise_factory) {
|
||||||
|
spine_->SpawnGuarded(name, std::move(promise_factory));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename PromiseFactory>
|
||||||
|
void SpawnInfallible(absl::string_view name, PromiseFactory promise_factory) {
|
||||||
|
spine_->SpawnInfallible(name, std::move(promise_factory));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename PromiseFactory>
|
||||||
|
auto SpawnWaitable(absl::string_view name, PromiseFactory promise_factory) {
|
||||||
|
return spine_->party().SpawnWaitable(name, std::move(promise_factory));
|
||||||
|
}
|
||||||
|
|
||||||
|
Arena* arena() { return spine_->party().arena(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
RefCountedPtr<CallSpineInterface> spine_;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CallInitiatorAndHandler {
|
||||||
|
CallInitiator initiator;
|
||||||
|
CallHandler handler;
|
||||||
|
};
|
||||||
|
|
||||||
|
CallInitiatorAndHandler MakeCall(
|
||||||
|
grpc_event_engine::experimental::EventEngine* event_engine, Arena* arena);
|
||||||
|
|
||||||
|
template <typename CallHalf>
|
||||||
|
auto OutgoingMessages(CallHalf h) {
|
||||||
|
struct Wrapper {
|
||||||
|
CallHalf h;
|
||||||
|
auto Next() { return h.PullMessage(); }
|
||||||
|
};
|
||||||
|
return Wrapper{std::move(h)};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Forward a call from `call_handler` to `call_initiator` (with initial metadata
|
||||||
|
// `client_initial_metadata`)
|
||||||
|
void ForwardCall(CallHandler call_handler, CallInitiator call_initiator,
|
||||||
|
ClientMetadataHandle client_initial_metadata);
|
||||||
|
|
||||||
|
} // namespace grpc_core
|
||||||
|
|
||||||
|
#endif // GRPC_SRC_CORE_LIB_TRANSPORT_CALL_SPINE_H
|
||||||
|
|
@ -215,89 +215,3 @@ grpc_transport_stream_op_batch* grpc_make_transport_stream_op(
|
||||||
op->op.on_complete = &op->outer_on_complete;
|
op->op.on_complete = &op->outer_on_complete;
|
||||||
return &op->op;
|
return &op->op;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace grpc_core {
|
|
||||||
|
|
||||||
void ForwardCall(CallHandler call_handler, CallInitiator call_initiator,
|
|
||||||
ClientMetadataHandle client_initial_metadata) {
|
|
||||||
// Send initial metadata.
|
|
||||||
call_initiator.SpawnGuarded(
|
|
||||||
"send_initial_metadata",
|
|
||||||
[client_initial_metadata = std::move(client_initial_metadata),
|
|
||||||
call_initiator]() mutable {
|
|
||||||
return call_initiator.PushClientInitialMetadata(
|
|
||||||
std::move(client_initial_metadata));
|
|
||||||
});
|
|
||||||
// Read messages from handler into initiator.
|
|
||||||
call_handler.SpawnGuarded("read_messages", [call_handler,
|
|
||||||
call_initiator]() mutable {
|
|
||||||
return Seq(ForEach(OutgoingMessages(call_handler),
|
|
||||||
[call_initiator](MessageHandle msg) mutable {
|
|
||||||
// Need to spawn a job into the initiator's activity to
|
|
||||||
// push the message in.
|
|
||||||
return call_initiator.SpawnWaitable(
|
|
||||||
"send_message",
|
|
||||||
[msg = std::move(msg), call_initiator]() mutable {
|
|
||||||
return call_initiator.CancelIfFails(
|
|
||||||
call_initiator.PushMessage(std::move(msg)));
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
[call_initiator](StatusFlag result) mutable {
|
|
||||||
call_initiator.SpawnInfallible(
|
|
||||||
"finish-downstream", [call_initiator, result]() mutable {
|
|
||||||
if (result.ok()) {
|
|
||||||
call_initiator.FinishSends();
|
|
||||||
} else {
|
|
||||||
call_initiator.Cancel();
|
|
||||||
}
|
|
||||||
return Empty{};
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
call_initiator.SpawnInfallible("read_the_things", [call_initiator,
|
|
||||||
call_handler]() mutable {
|
|
||||||
return Seq(
|
|
||||||
call_initiator.CancelIfFails(TrySeq(
|
|
||||||
call_initiator.PullServerInitialMetadata(),
|
|
||||||
[call_handler,
|
|
||||||
call_initiator](absl::optional<ServerMetadataHandle> md) mutable {
|
|
||||||
const bool has_md = md.has_value();
|
|
||||||
call_handler.SpawnGuarded(
|
|
||||||
"recv_initial_metadata",
|
|
||||||
[md = std::move(md), call_handler]() mutable {
|
|
||||||
return call_handler.PushServerInitialMetadata(
|
|
||||||
std::move(md));
|
|
||||||
});
|
|
||||||
return If(
|
|
||||||
has_md,
|
|
||||||
ForEach(OutgoingMessages(call_initiator),
|
|
||||||
[call_handler](MessageHandle msg) mutable {
|
|
||||||
return call_handler.SpawnWaitable(
|
|
||||||
"recv_message",
|
|
||||||
[msg = std::move(msg), call_handler]() mutable {
|
|
||||||
return call_handler.CancelIfFails(
|
|
||||||
call_handler.PushMessage(std::move(msg)));
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
[]() -> StatusFlag { return Success{}; });
|
|
||||||
})),
|
|
||||||
call_initiator.PullServerTrailingMetadata(),
|
|
||||||
[call_handler](ServerMetadataHandle md) mutable {
|
|
||||||
call_handler.SpawnGuarded(
|
|
||||||
"recv_trailing_metadata",
|
|
||||||
[md = std::move(md), call_handler]() mutable {
|
|
||||||
return call_handler.PushServerTrailingMetadata(std::move(md));
|
|
||||||
});
|
|
||||||
return Empty{};
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
CallInitiatorAndHandler MakeCall(
|
|
||||||
grpc_event_engine::experimental::EventEngine* event_engine, Arena* arena) {
|
|
||||||
auto spine = CallSpine::Create(event_engine, arena);
|
|
||||||
return {CallInitiator(spine), CallHandler(spine)};
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace grpc_core
|
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,6 @@
|
||||||
|
|
||||||
#include "src/core/lib/channel/context.h"
|
#include "src/core/lib/channel/context.h"
|
||||||
#include "src/core/lib/debug/trace.h"
|
#include "src/core/lib/debug/trace.h"
|
||||||
#include "src/core/lib/gprpp/debug_location.h"
|
|
||||||
#include "src/core/lib/gprpp/orphanable.h"
|
#include "src/core/lib/gprpp/orphanable.h"
|
||||||
#include "src/core/lib/gprpp/ref_counted.h"
|
#include "src/core/lib/gprpp/ref_counted.h"
|
||||||
#include "src/core/lib/iomgr/call_combiner.h"
|
#include "src/core/lib/iomgr/call_combiner.h"
|
||||||
|
|
@ -53,16 +52,12 @@
|
||||||
#include "src/core/lib/iomgr/polling_entity.h"
|
#include "src/core/lib/iomgr/polling_entity.h"
|
||||||
#include "src/core/lib/promise/arena_promise.h"
|
#include "src/core/lib/promise/arena_promise.h"
|
||||||
#include "src/core/lib/promise/context.h"
|
#include "src/core/lib/promise/context.h"
|
||||||
#include "src/core/lib/promise/detail/status.h"
|
|
||||||
#include "src/core/lib/promise/if.h"
|
|
||||||
#include "src/core/lib/promise/latch.h"
|
#include "src/core/lib/promise/latch.h"
|
||||||
#include "src/core/lib/promise/party.h"
|
|
||||||
#include "src/core/lib/promise/pipe.h"
|
#include "src/core/lib/promise/pipe.h"
|
||||||
#include "src/core/lib/promise/prioritized_race.h"
|
|
||||||
#include "src/core/lib/promise/status_flag.h"
|
|
||||||
#include "src/core/lib/resource_quota/arena.h"
|
#include "src/core/lib/resource_quota/arena.h"
|
||||||
#include "src/core/lib/slice/slice_buffer.h"
|
#include "src/core/lib/slice/slice_buffer.h"
|
||||||
#include "src/core/lib/transport/call_final_info.h"
|
#include "src/core/lib/transport/call_final_info.h"
|
||||||
|
#include "src/core/lib/transport/call_spine.h"
|
||||||
#include "src/core/lib/transport/connectivity_state.h"
|
#include "src/core/lib/transport/connectivity_state.h"
|
||||||
#include "src/core/lib/transport/message.h"
|
#include "src/core/lib/transport/message.h"
|
||||||
#include "src/core/lib/transport/metadata.h"
|
#include "src/core/lib/transport/metadata.h"
|
||||||
|
|
@ -160,386 +155,6 @@ struct CallArgs {
|
||||||
using NextPromiseFactory =
|
using NextPromiseFactory =
|
||||||
std::function<ArenaPromise<ServerMetadataHandle>(CallArgs)>;
|
std::function<ArenaPromise<ServerMetadataHandle>(CallArgs)>;
|
||||||
|
|
||||||
// The common middle part of a call - a reference is held by each of
|
|
||||||
// CallInitiator and CallHandler - which provide interfaces that are appropriate
|
|
||||||
// for each side of a call.
|
|
||||||
// The spine will ultimately host the pipes, filters, and context for one part
|
|
||||||
// of a call: ie top-half client channel, sub channel call, server call.
|
|
||||||
// TODO(ctiller): eventually drop this when we don't need to reference into
|
|
||||||
// legacy promise calls anymore
|
|
||||||
class CallSpineInterface {
|
|
||||||
public:
|
|
||||||
virtual ~CallSpineInterface() = default;
|
|
||||||
virtual Pipe<ClientMetadataHandle>& client_initial_metadata() = 0;
|
|
||||||
virtual Pipe<ServerMetadataHandle>& server_initial_metadata() = 0;
|
|
||||||
virtual Pipe<MessageHandle>& client_to_server_messages() = 0;
|
|
||||||
virtual Pipe<MessageHandle>& server_to_client_messages() = 0;
|
|
||||||
virtual Pipe<ServerMetadataHandle>& server_trailing_metadata() = 0;
|
|
||||||
virtual Latch<ServerMetadataHandle>& cancel_latch() = 0;
|
|
||||||
// Add a callback to be called when server trailing metadata is received.
|
|
||||||
void OnDone(absl::AnyInvocable<void()> fn) {
|
|
||||||
if (on_done_ == nullptr) {
|
|
||||||
on_done_ = std::move(fn);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
on_done_ = [first = std::move(fn), next = std::move(on_done_)]() mutable {
|
|
||||||
first();
|
|
||||||
next();
|
|
||||||
};
|
|
||||||
}
|
|
||||||
void CallOnDone() {
|
|
||||||
if (on_done_ != nullptr) std::exchange(on_done_, nullptr)();
|
|
||||||
}
|
|
||||||
virtual Party& party() = 0;
|
|
||||||
virtual void IncrementRefCount() = 0;
|
|
||||||
virtual void Unref() = 0;
|
|
||||||
|
|
||||||
// Cancel the call with the given metadata.
|
|
||||||
// Regarding the `MUST_USE_RESULT absl::nullopt_t`:
|
|
||||||
// Most cancellation calls right now happen in pipe interceptors;
|
|
||||||
// there `nullopt` indicates terminate processing of this pipe and close with
|
|
||||||
// error.
|
|
||||||
// It's convenient then to have the Cancel operation (setting the latch to
|
|
||||||
// terminate the call) be the last thing that occurs in a pipe interceptor,
|
|
||||||
// and this construction supports that (and has helped the author not write
|
|
||||||
// some bugs).
|
|
||||||
GRPC_MUST_USE_RESULT absl::nullopt_t Cancel(ServerMetadataHandle metadata) {
|
|
||||||
GPR_DEBUG_ASSERT(GetContext<Activity>() == &party());
|
|
||||||
auto& c = cancel_latch();
|
|
||||||
if (c.is_set()) return absl::nullopt;
|
|
||||||
c.Set(std::move(metadata));
|
|
||||||
CallOnDone();
|
|
||||||
client_initial_metadata().sender.CloseWithError();
|
|
||||||
server_initial_metadata().sender.CloseWithError();
|
|
||||||
client_to_server_messages().sender.CloseWithError();
|
|
||||||
server_to_client_messages().sender.CloseWithError();
|
|
||||||
return absl::nullopt;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto WaitForCancel() {
|
|
||||||
GPR_DEBUG_ASSERT(GetContext<Activity>() == &party());
|
|
||||||
return cancel_latch().Wait();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wrap a promise so that if it returns failure it automatically cancels
|
|
||||||
// the rest of the call.
|
|
||||||
// The resulting (returned) promise will resolve to Empty.
|
|
||||||
template <typename Promise>
|
|
||||||
auto CancelIfFails(Promise promise) {
|
|
||||||
GPR_DEBUG_ASSERT(GetContext<Activity>() == &party());
|
|
||||||
using P = promise_detail::PromiseLike<Promise>;
|
|
||||||
using ResultType = typename P::Result;
|
|
||||||
return Map(std::move(promise), [this](ResultType r) {
|
|
||||||
if (!IsStatusOk(r)) {
|
|
||||||
std::ignore = Cancel(StatusCast<ServerMetadataHandle>(r));
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Spawn a promise that returns Empty{} and save some boilerplate handling
|
|
||||||
// that detail.
|
|
||||||
template <typename PromiseFactory>
|
|
||||||
void SpawnInfallible(absl::string_view name, PromiseFactory promise_factory) {
|
|
||||||
party().Spawn(name, std::move(promise_factory), [](Empty) {});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Spawn a promise that returns some status-like type; if the status
|
|
||||||
// represents failure automatically cancel the rest of the call.
|
|
||||||
template <typename PromiseFactory>
|
|
||||||
void SpawnGuarded(absl::string_view name, PromiseFactory promise_factory) {
|
|
||||||
using FactoryType =
|
|
||||||
promise_detail::OncePromiseFactory<void, PromiseFactory>;
|
|
||||||
using PromiseType = typename FactoryType::Promise;
|
|
||||||
using ResultType = typename PromiseType::Result;
|
|
||||||
static_assert(
|
|
||||||
std::is_same<bool,
|
|
||||||
decltype(IsStatusOk(std::declval<ResultType>()))>::value,
|
|
||||||
"SpawnGuarded promise must return a status-like object");
|
|
||||||
party().Spawn(name, std::move(promise_factory), [this](ResultType r) {
|
|
||||||
if (!IsStatusOk(r)) {
|
|
||||||
if (grpc_trace_promise_primitives.enabled()) {
|
|
||||||
gpr_log(GPR_DEBUG, "SpawnGuarded sees failure: %s",
|
|
||||||
r.ToString().c_str());
|
|
||||||
}
|
|
||||||
std::ignore = Cancel(StatusCast<ServerMetadataHandle>(std::move(r)));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
absl::AnyInvocable<void()> on_done_{nullptr};
|
|
||||||
};
|
|
||||||
|
|
||||||
class CallSpine final : public CallSpineInterface, public Party {
|
|
||||||
public:
|
|
||||||
static RefCountedPtr<CallSpine> Create(
|
|
||||||
grpc_event_engine::experimental::EventEngine* event_engine,
|
|
||||||
Arena* arena) {
|
|
||||||
return RefCountedPtr<CallSpine>(arena->New<CallSpine>(event_engine, arena));
|
|
||||||
}
|
|
||||||
|
|
||||||
Pipe<ClientMetadataHandle>& client_initial_metadata() override {
|
|
||||||
return client_initial_metadata_;
|
|
||||||
}
|
|
||||||
Pipe<ServerMetadataHandle>& server_initial_metadata() override {
|
|
||||||
return server_initial_metadata_;
|
|
||||||
}
|
|
||||||
Pipe<MessageHandle>& client_to_server_messages() override {
|
|
||||||
return client_to_server_messages_;
|
|
||||||
}
|
|
||||||
Pipe<MessageHandle>& server_to_client_messages() override {
|
|
||||||
return server_to_client_messages_;
|
|
||||||
}
|
|
||||||
Pipe<ServerMetadataHandle>& server_trailing_metadata() override {
|
|
||||||
return server_trailing_metadata_;
|
|
||||||
}
|
|
||||||
Latch<ServerMetadataHandle>& cancel_latch() override { return cancel_latch_; }
|
|
||||||
Party& party() override { return *this; }
|
|
||||||
void IncrementRefCount() override { Party::IncrementRefCount(); }
|
|
||||||
void Unref() override { Party::Unref(); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend class Arena;
|
|
||||||
CallSpine(grpc_event_engine::experimental::EventEngine* event_engine,
|
|
||||||
Arena* arena)
|
|
||||||
: Party(arena, 1), event_engine_(event_engine) {}
|
|
||||||
|
|
||||||
class ScopedContext : public ScopedActivity,
|
|
||||||
public promise_detail::Context<Arena> {
|
|
||||||
public:
|
|
||||||
explicit ScopedContext(CallSpine* spine)
|
|
||||||
: ScopedActivity(&spine->party()), Context<Arena>(spine->arena()) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
bool RunParty() override {
|
|
||||||
ScopedContext context(this);
|
|
||||||
return Party::RunParty();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PartyOver() override {
|
|
||||||
Arena* a = arena();
|
|
||||||
{
|
|
||||||
ScopedContext context(this);
|
|
||||||
CancelRemainingParticipants();
|
|
||||||
a->DestroyManagedNewObjects();
|
|
||||||
}
|
|
||||||
this->~CallSpine();
|
|
||||||
a->Destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
grpc_event_engine::experimental::EventEngine* event_engine() const override {
|
|
||||||
return event_engine_;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initial metadata from client to server
|
|
||||||
Pipe<ClientMetadataHandle> client_initial_metadata_{arena()};
|
|
||||||
// Initial metadata from server to client
|
|
||||||
Pipe<ServerMetadataHandle> server_initial_metadata_{arena()};
|
|
||||||
// Messages travelling from the application to the transport.
|
|
||||||
Pipe<MessageHandle> client_to_server_messages_{arena()};
|
|
||||||
// Messages travelling from the transport to the application.
|
|
||||||
Pipe<MessageHandle> server_to_client_messages_{arena()};
|
|
||||||
// Trailing metadata from server to client
|
|
||||||
Pipe<ServerMetadataHandle> server_trailing_metadata_{arena()};
|
|
||||||
// Latch that can be set to terminate the call
|
|
||||||
Latch<ServerMetadataHandle> cancel_latch_;
|
|
||||||
// Event engine associated with this call
|
|
||||||
grpc_event_engine::experimental::EventEngine* const event_engine_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class CallInitiator {
|
|
||||||
public:
|
|
||||||
explicit CallInitiator(RefCountedPtr<CallSpineInterface> spine)
|
|
||||||
: spine_(std::move(spine)) {}
|
|
||||||
|
|
||||||
auto PushClientInitialMetadata(ClientMetadataHandle md) {
|
|
||||||
GPR_DEBUG_ASSERT(GetContext<Activity>() == &spine_->party());
|
|
||||||
return Map(spine_->client_initial_metadata().sender.Push(std::move(md)),
|
|
||||||
[](bool ok) { return StatusFlag(ok); });
|
|
||||||
}
|
|
||||||
|
|
||||||
auto PullServerInitialMetadata() {
|
|
||||||
GPR_DEBUG_ASSERT(GetContext<Activity>() == &spine_->party());
|
|
||||||
return Map(spine_->server_initial_metadata().receiver.Next(),
|
|
||||||
[](NextResult<ServerMetadataHandle> md)
|
|
||||||
-> ValueOrFailure<absl::optional<ServerMetadataHandle>> {
|
|
||||||
if (!md.has_value()) {
|
|
||||||
if (md.cancelled()) return Failure{};
|
|
||||||
return absl::optional<ServerMetadataHandle>();
|
|
||||||
}
|
|
||||||
return absl::optional<ServerMetadataHandle>(std::move(*md));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
auto PullServerTrailingMetadata() {
|
|
||||||
GPR_DEBUG_ASSERT(GetContext<Activity>() == &spine_->party());
|
|
||||||
return PrioritizedRace(
|
|
||||||
Map(spine_->server_trailing_metadata().receiver.Next(),
|
|
||||||
[spine = spine_](
|
|
||||||
NextResult<ServerMetadataHandle> md) -> ServerMetadataHandle {
|
|
||||||
GPR_ASSERT(md.has_value());
|
|
||||||
return std::move(*md);
|
|
||||||
}),
|
|
||||||
spine_->WaitForCancel());
|
|
||||||
}
|
|
||||||
|
|
||||||
auto PullMessage() {
|
|
||||||
GPR_DEBUG_ASSERT(GetContext<Activity>() == &spine_->party());
|
|
||||||
return spine_->server_to_client_messages().receiver.Next();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto PushMessage(MessageHandle message) {
|
|
||||||
GPR_DEBUG_ASSERT(GetContext<Activity>() == &spine_->party());
|
|
||||||
return Map(
|
|
||||||
spine_->client_to_server_messages().sender.Push(std::move(message)),
|
|
||||||
[](bool r) { return StatusFlag(r); });
|
|
||||||
}
|
|
||||||
|
|
||||||
void FinishSends() {
|
|
||||||
GPR_DEBUG_ASSERT(GetContext<Activity>() == &spine_->party());
|
|
||||||
spine_->client_to_server_messages().sender.Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Promise>
|
|
||||||
auto CancelIfFails(Promise promise) {
|
|
||||||
return spine_->CancelIfFails(std::move(promise));
|
|
||||||
}
|
|
||||||
|
|
||||||
void Cancel() {
|
|
||||||
GPR_DEBUG_ASSERT(GetContext<Activity>() == &spine_->party());
|
|
||||||
std::ignore =
|
|
||||||
spine_->Cancel(ServerMetadataFromStatus(absl::CancelledError()));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename PromiseFactory>
|
|
||||||
void SpawnGuarded(absl::string_view name, PromiseFactory promise_factory) {
|
|
||||||
spine_->SpawnGuarded(name, std::move(promise_factory));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename PromiseFactory>
|
|
||||||
void SpawnInfallible(absl::string_view name, PromiseFactory promise_factory) {
|
|
||||||
spine_->SpawnInfallible(name, std::move(promise_factory));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename PromiseFactory>
|
|
||||||
auto SpawnWaitable(absl::string_view name, PromiseFactory promise_factory) {
|
|
||||||
return spine_->party().SpawnWaitable(name, std::move(promise_factory));
|
|
||||||
}
|
|
||||||
|
|
||||||
Arena* arena() { return spine_->party().arena(); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
RefCountedPtr<CallSpineInterface> spine_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class CallHandler {
|
|
||||||
public:
|
|
||||||
explicit CallHandler(RefCountedPtr<CallSpineInterface> spine)
|
|
||||||
: spine_(std::move(spine)) {}
|
|
||||||
|
|
||||||
auto PullClientInitialMetadata() {
|
|
||||||
GPR_DEBUG_ASSERT(GetContext<Activity>() == &spine_->party());
|
|
||||||
return Map(spine_->client_initial_metadata().receiver.Next(),
|
|
||||||
[](NextResult<ClientMetadataHandle> md)
|
|
||||||
-> ValueOrFailure<ClientMetadataHandle> {
|
|
||||||
if (!md.has_value()) return Failure{};
|
|
||||||
return std::move(*md);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
auto PushServerInitialMetadata(absl::optional<ServerMetadataHandle> md) {
|
|
||||||
GPR_DEBUG_ASSERT(GetContext<Activity>() == &spine_->party());
|
|
||||||
return If(
|
|
||||||
md.has_value(),
|
|
||||||
[&md, this]() {
|
|
||||||
return Map(
|
|
||||||
spine_->server_initial_metadata().sender.Push(std::move(*md)),
|
|
||||||
[](bool ok) { return StatusFlag(ok); });
|
|
||||||
},
|
|
||||||
[this]() {
|
|
||||||
spine_->server_initial_metadata().sender.Close();
|
|
||||||
return []() -> StatusFlag { return Success{}; };
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
auto PushServerTrailingMetadata(ServerMetadataHandle md) {
|
|
||||||
GPR_DEBUG_ASSERT(GetContext<Activity>() == &spine_->party());
|
|
||||||
spine_->server_initial_metadata().sender.Close();
|
|
||||||
spine_->server_to_client_messages().sender.Close();
|
|
||||||
spine_->client_to_server_messages().receiver.CloseWithError();
|
|
||||||
spine_->CallOnDone();
|
|
||||||
return Map(spine_->server_trailing_metadata().sender.Push(std::move(md)),
|
|
||||||
[](bool ok) { return StatusFlag(ok); });
|
|
||||||
}
|
|
||||||
|
|
||||||
auto PullMessage() {
|
|
||||||
GPR_DEBUG_ASSERT(GetContext<Activity>() == &spine_->party());
|
|
||||||
return spine_->client_to_server_messages().receiver.Next();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto PushMessage(MessageHandle message) {
|
|
||||||
GPR_DEBUG_ASSERT(GetContext<Activity>() == &spine_->party());
|
|
||||||
return Map(
|
|
||||||
spine_->server_to_client_messages().sender.Push(std::move(message)),
|
|
||||||
[](bool ok) { return StatusFlag(ok); });
|
|
||||||
}
|
|
||||||
|
|
||||||
void Cancel(ServerMetadataHandle status) {
|
|
||||||
GPR_DEBUG_ASSERT(GetContext<Activity>() == &spine_->party());
|
|
||||||
std::ignore = spine_->Cancel(std::move(status));
|
|
||||||
}
|
|
||||||
|
|
||||||
void OnDone(absl::AnyInvocable<void()> fn) { spine_->OnDone(std::move(fn)); }
|
|
||||||
|
|
||||||
template <typename Promise>
|
|
||||||
auto CancelIfFails(Promise promise) {
|
|
||||||
return spine_->CancelIfFails(std::move(promise));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename PromiseFactory>
|
|
||||||
void SpawnGuarded(absl::string_view name, PromiseFactory promise_factory) {
|
|
||||||
spine_->SpawnGuarded(name, std::move(promise_factory));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename PromiseFactory>
|
|
||||||
void SpawnInfallible(absl::string_view name, PromiseFactory promise_factory) {
|
|
||||||
spine_->SpawnInfallible(name, std::move(promise_factory));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename PromiseFactory>
|
|
||||||
auto SpawnWaitable(absl::string_view name, PromiseFactory promise_factory) {
|
|
||||||
return spine_->party().SpawnWaitable(name, std::move(promise_factory));
|
|
||||||
}
|
|
||||||
|
|
||||||
Arena* arena() { return spine_->party().arena(); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
RefCountedPtr<CallSpineInterface> spine_;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CallInitiatorAndHandler {
|
|
||||||
CallInitiator initiator;
|
|
||||||
CallHandler handler;
|
|
||||||
};
|
|
||||||
|
|
||||||
CallInitiatorAndHandler MakeCall(
|
|
||||||
grpc_event_engine::experimental::EventEngine* event_engine, Arena* arena);
|
|
||||||
|
|
||||||
template <typename CallHalf>
|
|
||||||
auto OutgoingMessages(CallHalf h) {
|
|
||||||
struct Wrapper {
|
|
||||||
CallHalf h;
|
|
||||||
auto Next() { return h.PullMessage(); }
|
|
||||||
};
|
|
||||||
return Wrapper{std::move(h)};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Forward a call from `call_handler` to `call_initiator` (with initial metadata
|
|
||||||
// `client_initial_metadata`)
|
|
||||||
void ForwardCall(CallHandler call_handler, CallInitiator call_initiator,
|
|
||||||
ClientMetadataHandle client_initial_metadata);
|
|
||||||
|
|
||||||
} // namespace grpc_core
|
} // namespace grpc_core
|
||||||
|
|
||||||
// forward declarations
|
// forward declarations
|
||||||
|
|
|
||||||
|
|
@ -812,6 +812,7 @@ CORE_SOURCE_FILES = [
|
||||||
'src/core/lib/transport/bdp_estimator.cc',
|
'src/core/lib/transport/bdp_estimator.cc',
|
||||||
'src/core/lib/transport/call_filters.cc',
|
'src/core/lib/transport/call_filters.cc',
|
||||||
'src/core/lib/transport/call_final_info.cc',
|
'src/core/lib/transport/call_final_info.cc',
|
||||||
|
'src/core/lib/transport/call_spine.cc',
|
||||||
'src/core/lib/transport/connectivity_state.cc',
|
'src/core/lib/transport/connectivity_state.cc',
|
||||||
'src/core/lib/transport/error_utils.cc',
|
'src/core/lib/transport/error_utils.cc',
|
||||||
'src/core/lib/transport/handshaker.cc',
|
'src/core/lib/transport/handshaker.cc',
|
||||||
|
|
|
||||||
|
|
@ -2904,6 +2904,8 @@ src/core/lib/transport/call_filters.cc \
|
||||||
src/core/lib/transport/call_filters.h \
|
src/core/lib/transport/call_filters.h \
|
||||||
src/core/lib/transport/call_final_info.cc \
|
src/core/lib/transport/call_final_info.cc \
|
||||||
src/core/lib/transport/call_final_info.h \
|
src/core/lib/transport/call_final_info.h \
|
||||||
|
src/core/lib/transport/call_spine.cc \
|
||||||
|
src/core/lib/transport/call_spine.h \
|
||||||
src/core/lib/transport/connectivity_state.cc \
|
src/core/lib/transport/connectivity_state.cc \
|
||||||
src/core/lib/transport/connectivity_state.h \
|
src/core/lib/transport/connectivity_state.h \
|
||||||
src/core/lib/transport/custom_metadata.h \
|
src/core/lib/transport/custom_metadata.h \
|
||||||
|
|
|
||||||
|
|
@ -2685,6 +2685,8 @@ src/core/lib/transport/call_filters.cc \
|
||||||
src/core/lib/transport/call_filters.h \
|
src/core/lib/transport/call_filters.h \
|
||||||
src/core/lib/transport/call_final_info.cc \
|
src/core/lib/transport/call_final_info.cc \
|
||||||
src/core/lib/transport/call_final_info.h \
|
src/core/lib/transport/call_final_info.h \
|
||||||
|
src/core/lib/transport/call_spine.cc \
|
||||||
|
src/core/lib/transport/call_spine.h \
|
||||||
src/core/lib/transport/connectivity_state.cc \
|
src/core/lib/transport/connectivity_state.cc \
|
||||||
src/core/lib/transport/connectivity_state.h \
|
src/core/lib/transport/connectivity_state.h \
|
||||||
src/core/lib/transport/custom_metadata.h \
|
src/core/lib/transport/custom_metadata.h \
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue