1616#define GRPC_SRC_CORE_CALL_FILTER_FUSION_H
1717#include < grpc/impl/grpc_types.h>
1818
19+ #include < cstddef>
20+ #include < memory>
21+ #include < string>
22+ #include < tuple>
1923#include < type_traits>
2024#include < utility>
2125
26+ #include " absl/log/check.h"
2227#include " absl/log/log.h"
28+ #include " absl/memory/memory.h"
2329#include " absl/status/status.h"
30+ #include " absl/strings/str_join.h"
2431#include " src/core/call/call_filters.h"
2532#include " src/core/call/metadata.h"
33+ #include " src/core/lib/channel/channel_args.h"
2634#include " src/core/lib/channel/promise_based_filter.h"
2735#include " src/core/lib/transport/call_final_info.h"
36+ #include " src/core/lib/transport/transport.h"
37+ #include " src/core/util/status_helper.h"
2838#include " src/core/util/type_list.h"
2939
3040struct grpc_transport_op ;
@@ -893,6 +903,58 @@ GRPC_FUSE_METHOD(OnClientToServerMessage, MessageHandle, true);
893903GRPC_FUSE_METHOD (OnServerToClientMessage, MessageHandle, false );
894904GRPC_FUSE_METHOD (OnFinalize, const grpc_call_final_info*, true );
895905
906+ template <typename ... Filters>
907+ struct FilterWrapper ;
908+
909+ template <typename Filter>
910+ struct FilterWrapper <Filter> {
911+ FilterWrapper (const ChannelArgs& args, ChannelFilter::Args filter_args)
912+ : filter_(Filter::Create(args, filter_args)) {}
913+
914+ absl::Status status () const { return filter_.status (); }
915+ bool StartTransportOp (grpc_transport_op* op) {
916+ CHECK (filter_.ok ());
917+ return (*filter_)->StartTransportOp (op);
918+ }
919+
920+ bool GetChannelInfo (const grpc_channel_info* info) {
921+ CHECK (filter_.ok ());
922+ return (*filter_)->GetChannelInfo (info);
923+ }
924+
925+ private:
926+ absl::StatusOr<std::unique_ptr<Filter>> filter_;
927+ };
928+
929+ template <typename Filter0, typename ... Filters>
930+ struct FilterWrapper <Filter0, Filters...> : public FilterWrapper<Filters...> {
931+ FilterWrapper (const ChannelArgs& args, ChannelFilter::Args filter_args)
932+ : filter0_(Filter0::Create(args, filter_args)),
933+ FilterWrapper<Filters...>(args, filter_args) {}
934+
935+ absl::Status status () const {
936+ if (filter0_.ok ()) {
937+ return FilterWrapper<Filters...>::status ();
938+ }
939+ return filter0_.status ();
940+ }
941+
942+ bool StartTransportOp (grpc_transport_op* op) {
943+ CHECK (filter0_.ok ());
944+ return (*filter0_)->StartTransportOp (op) ||
945+ FilterWrapper<Filters...>::StartTransportOp (op);
946+ }
947+
948+ bool GetChannelInfo (const grpc_channel_info* info) {
949+ CHECK (filter0_.ok ());
950+ return (*filter0_)->GetChannelInfo (info) ||
951+ FilterWrapper<Filters...>::GetChannelInfo (info);
952+ }
953+
954+ private:
955+ absl::StatusOr<std::unique_ptr<Filter0>> filter0_;
956+ };
957+
896958#undef GRPC_FUSE_METHOD
897959
898960template <typename ... Filters>
@@ -902,19 +964,29 @@ class FusedFilter : public ImplementChannelFilter<FusedFilter<Filters...>>,
902964 static const grpc_channel_filter kFilter ;
903965
904966 static absl::string_view TypeName () {
905- // TODO(vigneshbabu): - Concatenate the names of the constituent filters.
906- return " fused_filter" ;
967+ static const std::string kName = absl::StrCat (
968+ " Fused_Filter_" ,
969+ absl::StrJoin (std::make_tuple (Filters::TypeName ()...), " _" ));
970+ return kName ;
907971 }
908972
909973 static absl::StatusOr<std::unique_ptr<FusedFilter<Filters...>>> Create (
910- const ChannelArgs& args, ChannelFilter::Args) {
911- // TODO(vigneshbabu): - Implement this.
912- LOG (FATAL) << " Not implemented" ;
913- return nullptr ;
974+ const ChannelArgs& args, ChannelFilter::Args filter_args) {
975+ auto filters_wrapper =
976+ std::make_unique<FilterWrapper<Filters...>>(args, filter_args);
977+ GRPC_RETURN_IF_ERROR (filters_wrapper->status ());
978+ return absl::WrapUnique<FusedFilter<Filters...>>(
979+ new FusedFilter<Filters...>(std::move (filters_wrapper)));
914980 }
915981
916982 static constexpr bool IsFused = true ;
917983
984+ static constexpr bool FusedFilterHasAsyncErrorInterceptor () {
985+ return (
986+ promise_filter_detail::CallHasAsyncErrorInterceptor<Filters>::value ||
987+ ...);
988+ }
989+
918990 class Call : public FuseOnClientInitialMetadata <FusedFilter, Filters...>,
919991 public FuseOnServerInitialMetadata<FusedFilter, Filters...>,
920992 public FuseOnClientToServerMessage<FusedFilter, Filters...>,
@@ -947,27 +1019,18 @@ class FusedFilter : public ImplementChannelFilter<FusedFilter<Filters...>>,
9471019 };
9481020
9491021 bool StartTransportOp (grpc_transport_op* op) override {
950- return StartTransportOpInternal (op, Typelist<Filters...>() );
1022+ return filters_-> StartTransportOp (op );
9511023 }
9521024
9531025 bool GetChannelInfo (const grpc_channel_info* info) override {
954- return GetChannelInfoInternal (info, Typelist<Filters...>() );
1026+ return filters_-> GetChannelInfo (info );
9551027 }
9561028
9571029 private:
958- template <typename ... FilterTypes>
959- bool StartTransportOpInternal (grpc_transport_op* op,
960- Typelist<FilterTypes...>) {
961- return (std::get<FilterTypes>(filters_).StartTransportOp (op) || ...);
962- }
963-
964- template <typename ... FilterTypes>
965- bool GetChannelInfoInternal (const grpc_channel_info* info,
966- Typelist<FilterTypes...>) {
967- return (std::get<FilterTypes>(filters_).GetChannelInfo (info) || ...);
968- }
1030+ explicit FusedFilter (std::unique_ptr<FilterWrapper<Filters...>> filters)
1031+ : filters_(std::move(filters)) {};
9691032
970- std::tuple< Filters...> filters_;
1033+ std::unique_ptr<FilterWrapper< Filters...> > filters_;
9711034};
9721035
9731036} // namespace filters_detail
0 commit comments