impl/codegen/method_handler.h
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2015 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 #ifndef GRPCPP_IMPL_CODEGEN_METHOD_HANDLER_H
20 #define GRPCPP_IMPL_CODEGEN_METHOD_HANDLER_H
21 
22 // IWYU pragma: private, include <grpcpp/support/method_handler.h>
23 
28 
29 namespace grpc {
30 
31 namespace internal {
32 
33 // Invoke the method handler, fill in the status, and
34 // return whether or not we finished safely (without an exception).
35 // Note that exception handling is 0-cost in most compiler/library
36 // implementations (except when an exception is actually thrown),
37 // so this process doesn't require additional overhead in the common case.
38 // Additionally, we don't need to return if we caught an exception or not;
39 // the handling is the same in either case.
40 template <class Callable>
42 #if GRPC_ALLOW_EXCEPTIONS
43  try {
44  return handler();
45  } catch (...) {
47  "Unexpected error in RPC handling");
48  }
49 #else // GRPC_ALLOW_EXCEPTIONS
50  return handler();
51 #endif // GRPC_ALLOW_EXCEPTIONS
52 }
53 
57 
58 template <class ResponseType>
65  ops;
66  ops.SendInitialMetadata(&param.server_context->initial_metadata_,
69  ops.set_compression_level(param.server_context->compression_level());
70  }
71  if (status.ok()) {
72  status = ops.SendMessagePtr(rsp);
73  }
74  ops.ServerSendStatus(&param.server_context->trailing_metadata_, status);
75  param.call->PerformOps(&ops);
76  param.call->cq()->Pluck(&ops);
77 }
78 
80 
81 template <class RequestType>
85  buf.set_buffer(req);
87  &buf, static_cast<RequestType*>(request));
88  buf.Release();
89  if (status->ok()) {
90  return request;
91  }
92  request->~RequestType();
93  return nullptr;
94 }
95 
97 template <class ServiceType, class RequestType, class ResponseType,
98  class BaseRequestType = RequestType,
99  class BaseResponseType = ResponseType>
101  public:
104  const RequestType*, ResponseType*)>
105  func,
106  ServiceType* service)
107  : func_(func), service_(service) {}
108 
109  void RunHandler(const HandlerParameter& param) final {
110  ResponseType rsp;
111  grpc::Status status = param.status;
112  if (status.ok()) {
113  status = CatchingFunctionHandler([this, &param, &rsp] {
114  return func_(service_,
115  static_cast<grpc::ServerContext*>(param.server_context),
116  static_cast<RequestType*>(param.request), &rsp);
117  });
118  static_cast<RequestType*>(param.request)->~RequestType();
119  }
120  UnaryRunHandlerHelper(param, static_cast<BaseResponseType*>(&rsp), status);
121  }
122 
124  grpc::Status* status, void** /*handler_data*/) final {
126  call, sizeof(RequestType))) RequestType;
128  static_cast<BaseRequestType*>(request));
129  }
130 
131  private:
134  const RequestType*, ResponseType*)>
136  // The class the above handler function lives in.
137  ServiceType* service_;
138 };
139 
141 template <class ServiceType, class RequestType, class ResponseType>
143  public:
147  func,
148  ServiceType* service)
149  : func_(func), service_(service) {}
150 
151  void RunHandler(const HandlerParameter& param) final {
153  param.call, static_cast<grpc::ServerContext*>(param.server_context));
154  ResponseType rsp;
156  CatchingFunctionHandler([this, &param, &reader, &rsp] {
157  return func_(service_,
158  static_cast<grpc::ServerContext*>(param.server_context),
159  &reader, &rsp);
160  });
161 
165  ops;
166  if (!param.server_context->sent_initial_metadata_) {
167  ops.SendInitialMetadata(&param.server_context->initial_metadata_,
168  param.server_context->initial_metadata_flags());
169  if (param.server_context->compression_level_set()) {
170  ops.set_compression_level(param.server_context->compression_level());
171  }
172  }
173  if (status.ok()) {
174  status = ops.SendMessagePtr(&rsp);
175  }
176  ops.ServerSendStatus(&param.server_context->trailing_metadata_, status);
177  param.call->PerformOps(&ops);
178  param.call->cq()->Pluck(&ops);
179  }
180 
181  private:
185  ServiceType* service_;
186 };
187 
189 template <class ServiceType, class RequestType, class ResponseType>
191  public:
193  ServiceType*, grpc::ServerContext*,
195  func,
196  ServiceType* service)
197  : func_(func), service_(service) {}
198 
199  void RunHandler(const HandlerParameter& param) final {
200  grpc::Status status = param.status;
201  if (status.ok()) {
203  param.call, static_cast<grpc::ServerContext*>(param.server_context));
204  status = CatchingFunctionHandler([this, &param, &writer] {
205  return func_(service_,
206  static_cast<grpc::ServerContext*>(param.server_context),
207  static_cast<RequestType*>(param.request), &writer);
208  });
209  static_cast<RequestType*>(param.request)->~RequestType();
210  }
211 
214  ops;
215  if (!param.server_context->sent_initial_metadata_) {
216  ops.SendInitialMetadata(&param.server_context->initial_metadata_,
217  param.server_context->initial_metadata_flags());
218  if (param.server_context->compression_level_set()) {
219  ops.set_compression_level(param.server_context->compression_level());
220  }
221  }
222  ops.ServerSendStatus(&param.server_context->trailing_metadata_, status);
223  param.call->PerformOps(&ops);
224  if (param.server_context->has_pending_ops_) {
225  param.call->cq()->Pluck(&param.server_context->pending_ops_);
226  }
227  param.call->cq()->Pluck(&ops);
228  }
229 
231  grpc::Status* status, void** /*handler_data*/) final {
233  buf.set_buffer(req);
235  call, sizeof(RequestType))) RequestType();
236  *status =
238  buf.Release();
239  if (status->ok()) {
240  return request;
241  }
242  request->~RequestType();
243  return nullptr;
244  }
245 
246  private:
250  ServiceType* service_;
251 };
252 
260 template <class Streamer, bool WriteNeeded>
262  public:
265  : func_(func), write_needed_(WriteNeeded) {}
266 
267  void RunHandler(const HandlerParameter& param) final {
268  Streamer stream(param.call,
269  static_cast<grpc::ServerContext*>(param.server_context));
271  return func_(static_cast<grpc::ServerContext*>(param.server_context),
272  &stream);
273  });
274 
277  ops;
278  if (!param.server_context->sent_initial_metadata_) {
279  ops.SendInitialMetadata(&param.server_context->initial_metadata_,
280  param.server_context->initial_metadata_flags());
281  if (param.server_context->compression_level_set()) {
282  ops.set_compression_level(param.server_context->compression_level());
283  }
284  if (write_needed_ && status.ok()) {
285  // If we needed a write but never did one, we need to mark the
286  // status as a fail
288  "Service did not provide response message");
289  }
290  }
291  ops.ServerSendStatus(&param.server_context->trailing_metadata_, status);
292  param.call->PerformOps(&ops);
293  if (param.server_context->has_pending_ops_) {
294  param.call->cq()->Pluck(&param.server_context->pending_ops_);
295  }
296  param.call->cq()->Pluck(&ops);
297  }
298 
299  private:
301  const bool write_needed_;
302 };
303 
304 template <class ServiceType, class RequestType, class ResponseType>
307  ServerReaderWriter<ResponseType, RequestType>, false> {
308  public:
310  ServiceType*, grpc::ServerContext*,
312  func,
313  ServiceType* service)
314  // TODO(vjpai): When gRPC supports C++14, move-capture func in the below
317  [func, service](
320  return func(service, ctx, streamer);
321  }) {}
322 };
323 
324 template <class RequestType, class ResponseType>
327  ServerUnaryStreamer<RequestType, ResponseType>, true> {
328  public:
333  func)
336  std::move(func)) {}
337 };
338 
339 template <class RequestType, class ResponseType>
342  ServerSplitStreamer<RequestType, ResponseType>, false> {
343  public:
348  func)
351  std::move(func)) {}
352 };
353 
356 template <grpc::StatusCode code>
357 class ErrorMethodHandler : public grpc::internal::MethodHandler {
358  public:
360 
361  template <class T>
363  const std::string& message, T* ops) {
365  if (!context->sent_initial_metadata_) {
366  ops->SendInitialMetadata(&context->initial_metadata_,
368  if (context->compression_level_set()) {
369  ops->set_compression_level(context->compression_level());
370  }
371  context->sent_initial_metadata_ = true;
372  }
373  ops->ServerSendStatus(&context->trailing_metadata_, status);
374  }
375 
376  void RunHandler(const HandlerParameter& param) final {
379  ops;
380  FillOps(param.server_context, message_, &ops);
381  param.call->PerformOps(&ops);
382  param.call->cq()->Pluck(&ops);
383  }
384 
386  grpc::Status* /*status*/, void** /*handler_data*/) final {
387  // We have to destroy any request payload
388  if (req != nullptr) {
390  }
391  return nullptr;
392  }
393 
394  private:
396 };
397 
402 
403 } // namespace internal
404 } // namespace grpc
405 
406 #endif // GRPCPP_IMPL_CODEGEN_METHOD_HANDLER_H
grpc::internal::CallOpSendMessage
Definition: call_op_set.h:289
grpc::internal::ClientStreamingHandler::ClientStreamingHandler
ClientStreamingHandler(std::function< grpc::Status(ServiceType *, grpc::ServerContext *, ServerReader< RequestType > *, ResponseType *)> func, ServiceType *service)
Definition: impl/codegen/method_handler.h:144
grpc::status
auto status
Definition: cpp/client/credentials_test.cc:200
grpc::internal::RpcMethodHandler::Deserialize
void * Deserialize(grpc_call *call, grpc_byte_buffer *req, grpc::Status *status, void **) final
Definition: impl/codegen/method_handler.h:123
grpc::ServerWriter
Definition: include/grpcpp/impl/codegen/completion_queue.h:60
grpc._simple_stubs.RequestType
RequestType
Definition: _simple_stubs.py:27
grpc._simple_stubs.ResponseType
ResponseType
Definition: _simple_stubs.py:28
grpc::ServerContext
Definition: grpcpp/impl/codegen/server_context.h:566
ctx
Definition: benchmark-async.c:30
rpc_service_method.h
grpc::ServerContextBase::compression_level
grpc_compression_level compression_level() const
Return the compression algorithm to be used by the server call.
Definition: grpcpp/impl/codegen/server_context.h:236
grpc
Definition: grpcpp/alarm.h:33
grpc::internal::ServerStreamingHandler::func_
std::function< grpc::Status(ServiceType *, grpc::ServerContext *, const RequestType *, ServerWriter< ResponseType > *)> func_
Definition: impl/codegen/method_handler.h:249
false
#define false
Definition: setup_once.h:323
grpc::ServerContextBase::trailing_metadata_
std::multimap< std::string, std::string > trailing_metadata_
Definition: grpcpp/impl/codegen/server_context.h:476
grpc::internal::ClientStreamingHandler::func_
std::function< grpc::Status(ServiceType *, grpc::ServerContext *, ServerReader< RequestType > *, ResponseType *)> func_
Definition: impl/codegen/method_handler.h:184
benchmark.request
request
Definition: benchmark.py:77
buf
voidpf void * buf
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
grpc::CoreCodegenInterface::grpc_call_arena_alloc
virtual void * grpc_call_arena_alloc(grpc_call *call, size_t length)=0
grpc::ServerReaderWriter
Definition: grpcpp/impl/codegen/sync_stream.h:786
grpc::internal::ClientStreamingHandler::service_
ServiceType * service_
Definition: impl/codegen/method_handler.h:185
core_codegen_interface.h
grpc::internal::ErrorMethodHandler
Definition: include/grpcpp/impl/codegen/byte_buffer.h:49
grpc::ServerUnaryStreamer
Definition: grpcpp/impl/codegen/sync_stream.h:827
message
char * message
Definition: libuv/docs/code/tty-gravity/main.c:12
T
#define T(upbtypeconst, upbtype, ctype, default_value)
true
#define true
Definition: setup_once.h:324
call
FilterStackCall * call
Definition: call.cc:750
grpc::CompletionQueue::Pluck
bool Pluck(grpc::internal::CompletionQueueTag *tag)
Definition: include/grpcpp/impl/codegen/completion_queue.h:324
grpc::ServerContextBase::compression_level_set
bool compression_level_set() const
Definition: grpcpp/impl/codegen/server_context.h:251
grpc::internal::ErrorMethodHandler::RunHandler
void RunHandler(const HandlerParameter &param) final
Definition: impl/codegen/method_handler.h:376
grpc::internal::StreamedUnaryHandler::StreamedUnaryHandler
StreamedUnaryHandler(std::function< grpc::Status(grpc::ServerContext *, ServerUnaryStreamer< RequestType, ResponseType > *)> func)
Definition: impl/codegen/method_handler.h:329
grpc::SerializationTraits
Definition: grpcpp/impl/codegen/serialization_traits.h:60
grpc::internal::CallOpServerSendStatus
Definition: call_op_set.h:661
grpc::g_core_codegen_interface
CoreCodegenInterface * g_core_codegen_interface
Definition: include/grpcpp/impl/codegen/completion_queue.h:98
grpc::internal::ResourceExhaustedHandler
ErrorMethodHandler< grpc::StatusCode::RESOURCE_EXHAUSTED > ResourceExhaustedHandler
Definition: impl/codegen/method_handler.h:401
absl::move
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: abseil-cpp/absl/utility/utility.h:221
grpc::internal::MethodHandler::HandlerParameter::server_context
grpc::ServerContextBase *const server_context
Definition: grpcpp/impl/codegen/rpc_service_method.h:65
grpc::ServerContextBase
Base class of ServerContext.
Definition: grpcpp/impl/codegen/server_context.h:126
grpc::ServerContextBase::initial_metadata_flags
uint32_t initial_metadata_flags() const
Definition: grpcpp/impl/codegen/server_context.h:427
grpc::ServerSplitStreamer
Definition: grpcpp/impl/codegen/sync_stream.h:893
grpc.StatusCode.UNKNOWN
tuple UNKNOWN
Definition: src/python/grpcio/grpc/__init__.py:262
req
static uv_connect_t req
Definition: test-connection-fail.c:30
grpc::internal::ErrorMethodHandler::Deserialize
void * Deserialize(grpc_call *, grpc_byte_buffer *req, grpc::Status *, void **) final
Definition: impl/codegen/method_handler.h:385
grpc::internal::UnaryDeserializeHelper
void * UnaryDeserializeHelper(grpc_byte_buffer *, grpc::Status *, RequestType *)
A helper function with reduced templating to do deserializing.
Definition: impl/codegen/method_handler.h:82
grpc::internal::SplitServerStreamingHandler
Definition: impl/codegen/method_handler.h:340
grpc_call
struct grpc_call grpc_call
Definition: grpc_types.h:70
grpc_byte_buffer
Definition: grpc_types.h:43
grpc::internal::RpcMethodHandler::RpcMethodHandler
RpcMethodHandler(std::function< grpc::Status(ServiceType *, grpc::ServerContext *, const RequestType *, ResponseType *)> func, ServiceType *service)
Definition: impl/codegen/method_handler.h:102
grpc::ServerContextBase::initial_metadata_
std::multimap< std::string, std::string > initial_metadata_
Definition: grpcpp/impl/codegen/server_context.h:475
grpc::internal::Call::PerformOps
void PerformOps(CallOpSetInterface *ops)
Definition: include/grpcpp/impl/codegen/call.h:67
grpc::internal::StreamedUnaryHandler
Definition: impl/codegen/method_handler.h:325
grpc::ByteBuffer
A sequence of bytes.
Definition: include/grpcpp/impl/codegen/byte_buffer.h:61
grpc::internal::TemplatedBidiStreamingHandler::write_needed_
const bool write_needed_
Definition: impl/codegen/method_handler.h:301
grpc::internal::SplitServerStreamingHandler::SplitServerStreamingHandler
SplitServerStreamingHandler(std::function< grpc::Status(grpc::ServerContext *, ServerSplitStreamer< RequestType, ResponseType > *)> func)
Definition: impl/codegen/method_handler.h:344
byte_buffer.h
grpc::ClientContext::trailing_metadata_
grpc::internal::MetadataMap trailing_metadata_
Definition: grpcpp/impl/codegen/client_context.h:504
grpc::internal::CallOpSet
Definition: call_op_set.h:859
grpc::ClientContext::initial_metadata_flags
uint32_t initial_metadata_flags() const
Definition: grpcpp/impl/codegen/client_context.h:474
grpc::internal::TemplatedBidiStreamingHandler::func_
std::function< grpc::Status(grpc::ServerContext *, Streamer *)> func_
Definition: impl/codegen/method_handler.h:300
writer
void writer(void *n)
Definition: libuv/docs/code/locks/main.c:22
grpc::CoreCodegenInterface::grpc_byte_buffer_destroy
virtual void grpc_byte_buffer_destroy(grpc_byte_buffer *bb)=0
grpc::ServerContextBase::sent_initial_metadata_
bool sent_initial_metadata_
Definition: grpcpp/impl/codegen/server_context.h:472
grpc::internal::MethodHandler::HandlerParameter::call
Call *const call
Definition: grpcpp/impl/codegen/rpc_service_method.h:64
func
const EVP_CIPHER *(* func)(void)
Definition: cipher_extra.c:73
grpc::internal::CallOpSendInitialMetadata
Definition: call_op_set.h:219
grpc::internal::MethodHandler
Base class for running an RPC handler.
Definition: grpcpp/impl/codegen/rpc_service_method.h:40
grpc::internal::BidiStreamingHandler
Definition: impl/codegen/method_handler.h:305
client.handler
handler
Definition: examples/python/multiprocessing/client.py:87
grpc::internal::ErrorMethodHandler::FillOps
static void FillOps(grpc::ServerContextBase *context, const std::string &message, T *ops)
Definition: impl/codegen/method_handler.h:362
grpc::internal::ErrorMethodHandler::ErrorMethodHandler
ErrorMethodHandler(const std::string &message)
Definition: impl/codegen/method_handler.h:359
grpc::internal::Call::cq
grpc::CompletionQueue * cq() const
Definition: include/grpcpp/impl/codegen/call.h:72
std
Definition: grpcpp/impl/codegen/async_unary_call.h:407
grpc::internal::ServerStreamingHandler::service_
ServiceType * service_
Definition: impl/codegen/method_handler.h:250
grpc::internal::ServerStreamingHandler::Deserialize
void * Deserialize(grpc_call *call, grpc_byte_buffer *req, grpc::Status *status, void **) final
Definition: impl/codegen/method_handler.h:230
grpc::protobuf::util::Status
GRPC_CUSTOM_UTIL_STATUS Status
Definition: include/grpcpp/impl/codegen/config_protobuf.h:93
grpc::ServerReader
Definition: include/grpcpp/impl/codegen/completion_queue.h:58
grpc::internal::MethodHandler::HandlerParameter
Definition: grpcpp/impl/codegen/rpc_service_method.h:43
grpc::Status
Definition: include/grpcpp/impl/codegen/status.h:35
grpc::internal::ErrorMethodHandler::message_
const std::string message_
Definition: impl/codegen/method_handler.h:395
grpc::internal::RpcMethodHandler::func_
std::function< grpc::Status(ServiceType *, grpc::ServerContext *, const RequestType *, ResponseType *)> func_
Application provided rpc handler function.
Definition: impl/codegen/method_handler.h:135
grpc::internal::CatchingFunctionHandler
::grpc::Status CatchingFunctionHandler(Callable &&handler)
Definition: impl/codegen/method_handler.h:41
GPR_CODEGEN_ASSERT
#define GPR_CODEGEN_ASSERT(x)
Codegen specific version of GPR_ASSERT.
Definition: grpcpp/impl/codegen/core_codegen_interface.h:151
grpc::internal::ClientStreamingHandler::RunHandler
void RunHandler(const HandlerParameter &param) final
Definition: impl/codegen/method_handler.h:151
internal
Definition: benchmark/test/output_test_helper.cc:20
grpc::internal::ServerStreamingHandler::ServerStreamingHandler
ServerStreamingHandler(std::function< grpc::Status(ServiceType *, grpc::ServerContext *, const RequestType *, ServerWriter< ResponseType > *)> func, ServiceType *service)
Definition: impl/codegen/method_handler.h:192
context
grpc::ClientContext context
Definition: istio_echo_server_lib.cc:61
grpc::internal::UnknownMethodHandler
ErrorMethodHandler< grpc::StatusCode::UNIMPLEMENTED > UnknownMethodHandler
Definition: impl/codegen/method_handler.h:399
code
Definition: bloaty/third_party/zlib/contrib/infback9/inftree9.h:24
grpc::internal::TemplatedBidiStreamingHandler
Definition: include/grpcpp/impl/codegen/completion_queue.h:77
service
__attribute__((deprecated("Please use GRPCProtoMethod."))) @interface ProtoMethod NSString * service
Definition: ProtoMethod.h:25
grpc.StatusCode.INTERNAL
tuple INTERNAL
Definition: src/python/grpcio/grpc/__init__.py:277
function
std::function< bool(GrpcTool *, int, const char **, const CliCredentials &, GrpcToolOutputCallback)> function
Definition: grpc_tool.cc:250
grpc::internal::TemplatedBidiStreamingHandler::TemplatedBidiStreamingHandler
TemplatedBidiStreamingHandler(std::function< grpc::Status(grpc::ServerContext *, Streamer *)> func)
Definition: impl/codegen/method_handler.h:263
sync_stream.h
grpc::internal::TemplatedBidiStreamingHandler::RunHandler
void RunHandler(const HandlerParameter &param) final
Definition: impl/codegen/method_handler.h:267
ops
static grpc_op ops[6]
Definition: test/core/fling/client.cc:39
grpc::internal::ServerStreamingHandler
A wrapper class of an application provided server streaming handler.
Definition: include/grpcpp/impl/codegen/byte_buffer.h:47
grpc::internal::ClientStreamingHandler
A wrapper class of an application provided client streaming handler.
Definition: include/grpcpp/impl/codegen/completion_queue.h:73
grpc::internal::RpcMethodHandler::RunHandler
void RunHandler(const HandlerParameter &param) final
Definition: impl/codegen/method_handler.h:109
grpc::internal::RpcMethodHandler::service_
ServiceType * service_
Definition: impl/codegen/method_handler.h:137
grpc::internal::UnaryRunHandlerHelper
void UnaryRunHandlerHelper(const grpc::internal::MethodHandler::HandlerParameter &, ResponseType *, grpc::Status &)
Definition: impl/codegen/method_handler.h:59
reader
void reader(void *n)
Definition: libuv/docs/code/locks/main.c:8
grpc::internal::ServerStreamingHandler::RunHandler
void RunHandler(const HandlerParameter &param) final
Definition: impl/codegen/method_handler.h:199
grpc.RpcMethodHandler
Definition: src/python/grpcio/grpc/__init__.py:1288
grpc::internal::BidiStreamingHandler::BidiStreamingHandler
BidiStreamingHandler(std::function< grpc::Status(ServiceType *, grpc::ServerContext *, ServerReaderWriter< ResponseType, RequestType > *)> func, ServiceType *service)
Definition: impl/codegen/method_handler.h:309
stream
voidpf stream
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136


grpc
Author(s):
autogenerated on Thu Mar 13 2025 03:00:39