18 #ifndef GRPCPP_IMPL_SERVER_CALLBACK_HANDLERS_H
19 #define GRPCPP_IMPL_SERVER_CALLBACK_HANDLERS_H
31 #include "absl/log/absl_check.h"
32 #include "absl/status/status.h"
37 template <
class RequestType,
class ResponseType>
42 const RequestType*, ResponseType*)>
44 : get_reactor_(
std::move(get_reactor)) {}
48 allocator_ = allocator;
54 auto* allocator_state =
59 sizeof(ServerCallbackUnaryImpl)))
60 ServerCallbackUnaryImpl(
62 param.call, allocator_state, param.call_requester);
63 param.server_context->BeginCompletionOp(
64 param.call, [call](
bool) { call->MaybeDone(); }, call);
67 if (param.status.ok()) {
68 reactor = grpc::internal::CatchingReactorGetter<ServerUnaryReactor>(
74 if (reactor ==
nullptr) {
83 call->SetupReactor(reactor);
90 RequestType* request =
nullptr;
92 if (allocator_ !=
nullptr) {
99 *handler_data = allocator_state;
100 request = allocator_state->
request();
111 const RequestType*, ResponseType*)>
128 reactor_.load(std::memory_order_relaxed)->InternalInlineable());
131 finish_ops_.set_core_cq_tag(&finish_tag_);
133 if (!ctx_->sent_initial_metadata_) {
135 ctx_->initial_metadata_flags());
136 if (ctx_->compression_level_set()) {
137 finish_ops_.set_compression_level(ctx_->compression_level());
139 ctx_->MarkInitialMetadataSent();
143 finish_ops_.ServerSendStatus(
144 &ctx_->trailing_metadata_,
145 finish_ops_.SendMessagePtr(response(), ctx_->memory_allocator()));
147 finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, s);
149 finish_ops_.set_core_cq_tag(&finish_tag_);
150 finish_ops_.FillOps(&call_);
153 void SendInitialMetadata()
override {
154 ABSL_CHECK(!ctx_->sent_initial_metadata_);
164 ServerUnaryReactor* reactor =
165 reactor_.load(std::memory_order_relaxed);
166 reactor->OnSendInitialMetadataDone(ok);
167 this->MaybeDone(true);
170 meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_,
171 ctx_->initial_metadata_flags());
172 if (ctx_->compression_level_set()) {
173 meta_ops_.set_compression_level(ctx_->compression_level());
175 ctx_->MarkInitialMetadataSent();
176 meta_ops_.set_core_cq_tag(&meta_tag_);
177 meta_ops_.FillOps(&call_);
183 ServerCallbackUnaryImpl(
185 MessageHolder<RequestType, ResponseType>* allocator_state,
186 std::function<
void()> call_requester)
189 allocator_state_(allocator_state),
190 call_requester_(
std::move(call_requester)) {
191 ctx_->set_message_allocator_state(allocator_state);
200 void SetupReactor(ServerUnaryReactor* reactor) {
201 reactor_.store(reactor, std::memory_order_relaxed);
204 this->
MaybeDone(reactor->InternalInlineable());
207 const RequestType* request() {
return allocator_state_->request(); }
208 ResponseType* response() {
return allocator_state_->response(); }
210 void CallOnDone()
override {
211 reactor_.load(std::memory_order_relaxed)->OnDone();
213 auto call_requester = std::move(call_requester_);
214 allocator_state_->Release();
215 if (ctx_->context_allocator() !=
nullptr) {
216 ctx_->context_allocator()->Release(ctx_);
218 this->~ServerCallbackUnaryImpl();
223 ServerReactor* reactor()
override {
224 return reactor_.load(std::memory_order_relaxed);
238 MessageHolder<RequestType, ResponseType>*
const allocator_state_;
239 std::function<void()> call_requester_;
250 std::atomic<ServerUnaryReactor*> reactor_;
252 std::atomic<intptr_t> callbacks_outstanding_{
257 template <
class RequestType,
class ResponseType>
264 : get_reactor_(
std::move(get_reactor)) {}
270 sizeof(ServerCallbackReaderImpl)))
271 ServerCallbackReaderImpl(
273 param.call, param.call_requester);
277 param.server_context->BeginCompletionOp(
279 [reader](
bool) { reader->MaybeDone(
false); },
283 if (param.status.ok()) {
285 grpc::internal::CatchingReactorGetter<ServerReadReactor<RequestType>>(
291 if (reactor ==
nullptr) {
299 reader->SetupReactor(reactor);
319 this->MaybeDone(false);
322 if (!ctx_->sent_initial_metadata_) {
324 ctx_->initial_metadata_flags());
325 if (ctx_->compression_level_set()) {
326 finish_ops_.set_compression_level(ctx_->compression_level());
328 ctx_->MarkInitialMetadataSent();
332 finish_ops_.ServerSendStatus(
333 &ctx_->trailing_metadata_,
334 finish_ops_.SendMessagePtr(&resp_, ctx_->memory_allocator()));
336 finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, s);
338 finish_ops_.set_core_cq_tag(&finish_tag_);
339 finish_ops_.FillOps(&call_);
342 void SendInitialMetadata()
override {
343 ABSL_CHECK(!ctx_->sent_initial_metadata_);
351 ServerReadReactor<RequestType>* reactor =
352 reactor_.load(std::memory_order_relaxed);
353 reactor->OnSendInitialMetadataDone(ok);
354 this->MaybeDone(true);
357 meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_,
358 ctx_->initial_metadata_flags());
359 if (ctx_->compression_level_set()) {
360 meta_ops_.set_compression_level(ctx_->compression_level());
362 ctx_->MarkInitialMetadataSent();
363 meta_ops_.set_core_cq_tag(&meta_tag_);
364 meta_ops_.FillOps(&call_);
367 void Read(RequestType* req)
override {
369 read_ops_.RecvMessage(req);
370 read_ops_.FillOps(&call_);
378 std::function<
void()> call_requester)
379 : ctx_(ctx), call_(*call), call_requester_(
std::move(call_requester)) {}
383 void SetupReactor(ServerReadReactor<RequestType>* reactor) {
384 reactor_.store(reactor, std::memory_order_relaxed);
390 [
this, reactor](
bool ok) {
391 if (GPR_UNLIKELY(!ok)) {
392 ctx_->MaybeMarkCancelledOnRead();
394 reactor->OnReadDone(ok);
395 this->MaybeDone(
true);
398 read_ops_.set_core_cq_tag(&read_tag_);
407 ~ServerCallbackReaderImpl() {}
409 ResponseType* response() {
return &resp_; }
411 void CallOnDone()
override {
412 reactor_.load(std::memory_order_relaxed)->OnDone();
414 auto call_requester = std::move(call_requester_);
415 if (ctx_->context_allocator() !=
nullptr) {
416 ctx_->context_allocator()->Release(ctx_);
418 this->~ServerCallbackReaderImpl();
423 ServerReactor* reactor()
override {
424 return reactor_.load(std::memory_order_relaxed);
442 std::function<void()> call_requester_;
444 std::atomic<ServerReadReactor<RequestType>*> reactor_;
446 std::atomic<intptr_t> callbacks_outstanding_{
451 template <
class RequestType,
class ResponseType>
458 : get_reactor_(
std::move(get_reactor)) {}
464 sizeof(ServerCallbackWriterImpl)))
465 ServerCallbackWriterImpl(
467 param.call,
static_cast<RequestType*
>(param.request),
468 param.call_requester);
472 param.server_context->BeginCompletionOp(
474 [writer](
bool) { writer->MaybeDone(
false); },
478 if (param.status.ok()) {
485 if (reactor ==
nullptr) {
493 writer->SetupReactor(reactor);
507 request->~RequestType();
528 this->MaybeDone(false);
531 finish_ops_.set_core_cq_tag(&finish_tag_);
533 if (!ctx_->sent_initial_metadata_) {
535 ctx_->initial_metadata_flags());
536 if (ctx_->compression_level_set()) {
537 finish_ops_.set_compression_level(ctx_->compression_level());
539 ctx_->MarkInitialMetadataSent();
541 finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, s);
542 finish_ops_.FillOps(&call_);
545 void SendInitialMetadata()
override {
546 ABSL_CHECK(!ctx_->sent_initial_metadata_);
554 ServerWriteReactor<ResponseType>* reactor =
555 reactor_.load(std::memory_order_relaxed);
556 reactor->OnSendInitialMetadataDone(ok);
557 this->MaybeDone(true);
560 meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_,
561 ctx_->initial_metadata_flags());
562 if (ctx_->compression_level_set()) {
563 meta_ops_.set_compression_level(ctx_->compression_level());
565 ctx_->MarkInitialMetadataSent();
566 meta_ops_.set_core_cq_tag(&meta_tag_);
567 meta_ops_.FillOps(&call_);
575 if (!ctx_->sent_initial_metadata_) {
576 write_ops_.SendInitialMetadata(&ctx_->initial_metadata_,
577 ctx_->initial_metadata_flags());
578 if (ctx_->compression_level_set()) {
579 write_ops_.set_compression_level(ctx_->compression_level());
581 ctx_->MarkInitialMetadataSent();
585 write_ops_.SendMessagePtr(resp, options, ctx_->memory_allocator())
587 write_ops_.FillOps(&call_);
595 finish_ops_.SendMessagePtr(resp, options, ctx_->memory_allocator())
597 Finish(std::move(s));
601 friend class CallbackServerStreamingHandler<RequestType, ResponseType>;
605 std::function<
void()> call_requester)
609 call_requester_(
std::move(call_requester)) {}
613 void SetupReactor(ServerWriteReactor<ResponseType>* reactor) {
614 reactor_.store(reactor, std::memory_order_relaxed);
620 [
this, reactor](
bool ok) {
621 reactor->OnWriteDone(ok);
622 this->MaybeDone(true);
625 write_ops_.set_core_cq_tag(&write_tag_);
626 this->BindReactor(reactor);
627 this->MaybeCallOnCancel(reactor);
631 this->MaybeDone(
false);
633 ~ServerCallbackWriterImpl() {
634 if (req_ !=
nullptr) {
635 req_->~RequestType();
639 const RequestType* request() {
return req_; }
641 void CallOnDone()
override {
642 reactor_.load(std::memory_order_relaxed)->OnDone();
644 auto call_requester = std::move(call_requester_);
645 if (ctx_->context_allocator() !=
nullptr) {
646 ctx_->context_allocator()->Release(ctx_);
648 this->~ServerCallbackWriterImpl();
653 ServerReactor* reactor()
override {
654 return reactor_.load(std::memory_order_relaxed);
672 const RequestType* req_;
673 std::function<void()> call_requester_;
675 std::atomic<ServerWriteReactor<ResponseType>*> reactor_;
677 std::atomic<intptr_t> callbacks_outstanding_{
682 template <
class RequestType,
class ResponseType>
689 : get_reactor_(
std::move(get_reactor)) {}
694 param.call->call(),
sizeof(ServerCallbackReaderWriterImpl)))
695 ServerCallbackReaderWriterImpl(
697 param.call, param.call_requester);
701 param.server_context->BeginCompletionOp(
703 [stream](
bool) { stream->MaybeDone(
false); },
707 if (param.status.ok()) {
714 if (reactor ==
nullptr) {
723 stream->SetupReactor(reactor);
727 std::function<ServerBidiReactor<RequestType, ResponseType>*(
731 class ServerCallbackReaderWriterImpl
744 this->MaybeDone(false);
747 finish_ops_.set_core_cq_tag(&finish_tag_);
749 if (!ctx_->sent_initial_metadata_) {
751 ctx_->initial_metadata_flags());
752 if (ctx_->compression_level_set()) {
753 finish_ops_.set_compression_level(ctx_->compression_level());
755 ctx_->MarkInitialMetadataSent();
757 finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, s);
758 finish_ops_.FillOps(&call_);
761 void SendInitialMetadata()
override {
762 ABSL_CHECK(!ctx_->sent_initial_metadata_);
770 ServerBidiReactor<RequestType, ResponseType>* reactor =
771 reactor_.load(std::memory_order_relaxed);
772 reactor->OnSendInitialMetadataDone(ok);
773 this->MaybeDone(true);
776 meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_,
777 ctx_->initial_metadata_flags());
778 if (ctx_->compression_level_set()) {
779 meta_ops_.set_compression_level(ctx_->compression_level());
781 ctx_->MarkInitialMetadataSent();
782 meta_ops_.set_core_cq_tag(&meta_tag_);
783 meta_ops_.FillOps(&call_);
791 if (!ctx_->sent_initial_metadata_) {
792 write_ops_.SendInitialMetadata(&ctx_->initial_metadata_,
793 ctx_->initial_metadata_flags());
794 if (ctx_->compression_level_set()) {
795 write_ops_.set_compression_level(ctx_->compression_level());
797 ctx_->MarkInitialMetadataSent();
801 write_ops_.SendMessagePtr(resp, options, ctx_->memory_allocator())
803 write_ops_.FillOps(&call_);
810 finish_ops_.SendMessagePtr(resp, options, ctx_->memory_allocator())
812 Finish(std::move(s));
815 void Read(RequestType* req)
override {
817 read_ops_.RecvMessage(req);
818 read_ops_.FillOps(&call_);
822 friend class CallbackBidiHandler<RequestType, ResponseType>;
826 std::function<
void()> call_requester)
827 : ctx_(ctx), call_(*call), call_requester_(
std::move(call_requester)) {}
831 void SetupReactor(ServerBidiReactor<RequestType, ResponseType>* reactor) {
832 reactor_.store(reactor, std::memory_order_relaxed);
838 [
this, reactor](
bool ok) {
839 reactor->OnWriteDone(ok);
840 this->MaybeDone(true);
843 write_ops_.set_core_cq_tag(&write_tag_);
846 [
this, reactor](
bool ok) {
847 if (GPR_UNLIKELY(!ok)) {
848 ctx_->MaybeMarkCancelledOnRead();
850 reactor->OnReadDone(ok);
851 this->MaybeDone(
true);
854 read_ops_.set_core_cq_tag(&read_tag_);
855 this->BindReactor(reactor);
856 this->MaybeCallOnCancel(reactor);
860 this->MaybeDone(
false);
863 void CallOnDone()
override {
864 reactor_.load(std::memory_order_relaxed)->OnDone();
866 auto call_requester = std::move(call_requester_);
867 if (ctx_->context_allocator() !=
nullptr) {
868 ctx_->context_allocator()->Release(ctx_);
870 this->~ServerCallbackReaderWriterImpl();
875 ServerReactor* reactor()
override {
876 return reactor_.load(std::memory_order_relaxed);
897 std::function<void()> call_requester_;
899 std::atomic<ServerBidiReactor<RequestType, ResponseType>*> reactor_;
901 std::atomic<intptr_t> callbacks_outstanding_{
908 namespace experimental {
911 template <
class RequestType>
919 : get_reactor_(
std::move(get_reactor)), service_(service) {
920 ABSL_CHECK(service_ !=
nullptr && service_->is_virtual_service_);
926 auto* allocator_state =
928 param.internal_data);
931 inner_server =
static_cast<grpc::Server*
>(service_->server_);
932 ABSL_CHECK(inner_server !=
nullptr);
935 sizeof(ServerCallbackSessionImpl)))
936 ServerCallbackSessionImpl(
938 param.call, allocator_state, param.call_requester, inner_server);
940 param.server_context->BeginCompletionOp(
941 param.call, [call](
bool) { call->MaybeDone(); }, call);
944 if (param.status.ok()) {
952 if (reactor ==
nullptr) {
961 call->SetupReactor(reactor);
968 RequestType* request =
nullptr;
974 *handler_data = allocator_state;
975 request = allocator_state->
request();
990 class ServerCallbackSessionImpl
994 if (ctx_->IsCancelled()) {
996 reactor_.load(std::memory_order_relaxed)->InternalInlineable());
1009 reactor_.load(std::memory_order_relaxed)->InternalInlineable());
1011 &finish_ops_,
true);
1012 finish_ops_.set_core_cq_tag(&finish_tag_);
1014 bool is_first_metadata = !ctx_->sent_initial_metadata_;
1015 if (is_first_metadata) {
1016 finish_ops_.SendInitialMetadata(&ctx_->initial_metadata_,
1017 ctx_->initial_metadata_flags());
1018 if (ctx_->compression_level_set()) {
1019 finish_ops_.set_compression_level(ctx_->compression_level());
1021 ctx_->MarkInitialMetadataSent();
1023 finish_ops_.ServerSendStatus(&ctx_->trailing_metadata_, s);
1024 finish_ops_.set_core_cq_tag(&finish_tag_);
1025 finish_ops_.FillOps(&call_);
1028 void SendInitialMetadata()
override {
1029 ABSL_CHECK(!ctx_->sent_initial_metadata_);
1039 grpc::experimental::ServerSessionReactor* reactor =
1040 reactor_.load(std::memory_order_relaxed);
1041 reactor->OnSendInitialMetadataDone(ok);
1042 this->MaybeDone(true);
1045 meta_ops_.SendInitialMetadata(&ctx_->initial_metadata_,
1046 ctx_->initial_metadata_flags());
1047 if (ctx_->compression_level_set()) {
1048 meta_ops_.set_compression_level(ctx_->compression_level());
1050 ctx_->MarkInitialMetadataSent();
1051 meta_ops_.set_core_cq_tag(&meta_tag_);
1052 meta_ops_.FillOps(&call_);
1056 BindInnerServer(inner_server_);
1059 void BindInnerServer(
grpc::Server* inner_server)
override {
1061 call_.call(), inner_server, &transport_, &endpoint_);
1064 void InitiateGracefulShutdown(
1065 absl::AnyInvocable<
void(
absl::Status)> on_shutdown)
override {
1067 transport_, endpoint_, std::move(on_shutdown));
1071 friend class CallbackSessionHandler<RequestType>;
1073 ServerCallbackSessionImpl(
1075 MessageHolder<RequestType, grpc::ByteBuffer>* allocator_state,
1076 std::function<
void()> call_requester,
grpc::Server* inner_server)
1079 allocator_state_(allocator_state),
1080 call_requester_(
std::move(call_requester)),
1081 inner_server_(inner_server) {
1082 ABSL_CHECK(inner_server_ !=
nullptr);
1083 ctx_->set_message_allocator_state(allocator_state);
1093 reactor_.store(reactor, std::memory_order_relaxed);
1094 this->BindReactor(reactor);
1095 this->MaybeCallOnCancel(reactor);
1099 const RequestType* request() {
return allocator_state_->request(); }
1101 void CallOnDone()
override {
1102 reactor_.load(std::memory_order_relaxed)->OnDone();
1104 auto call_requester = std::move(call_requester_);
1105 allocator_state_->Release();
1106 if (ctx_->context_allocator() !=
nullptr) {
1107 ctx_->context_allocator()->Release(ctx_);
1109 this->~ServerCallbackSessionImpl();
1115 return reactor_.load(std::memory_order_relaxed);
1128 grpc_core::Transport* transport_ =
nullptr;
1129 grpc_endpoint* endpoint_ =
nullptr;
1130 MessageHolder<RequestType, grpc::ByteBuffer>*
const allocator_state_;
1131 std::function<void()> call_requester_;
1134 std::atomic<grpc::experimental::ServerSessionReactor*> reactor_;
1136 std::atomic<intptr_t> callbacks_outstanding_{
1145 #endif // GRPCPP_IMPL_SERVER_CALLBACK_HANDLERS_H