rpc_service_method.h 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /*
  2. *
  3. * Copyright 2016 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. #ifndef GRPCPP_IMPL_CODEGEN_RPC_SERVICE_METHOD_H
  19. #define GRPCPP_IMPL_CODEGEN_RPC_SERVICE_METHOD_H
  20. // IWYU pragma: private, include <grpcpp/impl/rpc_service_method.h>
  21. #include <climits>
  22. #include <functional>
  23. #include <map>
  24. #include <memory>
  25. #include <vector>
  26. #include <grpc/impl/codegen/log.h>
  27. #include <grpcpp/impl/codegen/byte_buffer.h>
  28. #include <grpcpp/impl/codegen/config.h>
  29. #include <grpcpp/impl/codegen/rpc_method.h>
  30. #include <grpcpp/impl/codegen/status.h>
  31. namespace grpc {
  32. class ServerContextBase;
  33. namespace internal {
  34. /// Base class for running an RPC handler.
  35. class MethodHandler {
  36. public:
  37. virtual ~MethodHandler() {}
  38. struct HandlerParameter {
  39. /// Constructor for HandlerParameter
  40. ///
  41. /// \param c : the gRPC Call structure for this server call
  42. /// \param context : the ServerContext structure for this server call
  43. /// \param req : the request payload, if appropriate for this RPC
  44. /// \param req_status : the request status after any interceptors have run
  45. /// \param handler_data: internal data for the handler.
  46. /// \param requester : used only by the callback API. It is a function
  47. /// called by the RPC Controller to request another RPC (and also
  48. /// to set up the state required to make that request possible)
  49. HandlerParameter(Call* c, grpc::ServerContextBase* context, void* req,
  50. Status req_status, void* handler_data,
  51. std::function<void()> requester)
  52. : call(c),
  53. server_context(context),
  54. request(req),
  55. status(req_status),
  56. internal_data(handler_data),
  57. call_requester(std::move(requester)) {}
  58. ~HandlerParameter() {}
  59. Call* const call;
  60. grpc::ServerContextBase* const server_context;
  61. void* const request;
  62. const Status status;
  63. void* const internal_data;
  64. const std::function<void()> call_requester;
  65. };
  66. virtual void RunHandler(const HandlerParameter& param) = 0;
  67. /* Returns a pointer to the deserialized request. \a status reflects the
  68. result of deserialization. This pointer and the status should be filled in
  69. a HandlerParameter and passed to RunHandler. It is illegal to access the
  70. pointer after calling RunHandler. Ownership of the deserialized request is
  71. retained by the handler. Returns nullptr if deserialization failed. */
  72. virtual void* Deserialize(grpc_call* /*call*/, grpc_byte_buffer* req,
  73. Status* /*status*/, void** /*handler_data*/) {
  74. GPR_CODEGEN_ASSERT(req == nullptr);
  75. return nullptr;
  76. }
  77. };
  78. /// Server side rpc method class
  79. class RpcServiceMethod : public RpcMethod {
  80. public:
  81. /// Takes ownership of the handler
  82. RpcServiceMethod(const char* name, RpcMethod::RpcType type,
  83. MethodHandler* handler)
  84. : RpcMethod(name, type),
  85. server_tag_(nullptr),
  86. api_type_(ApiType::SYNC),
  87. handler_(handler) {}
  88. enum class ApiType {
  89. SYNC,
  90. ASYNC,
  91. RAW,
  92. CALL_BACK, // not CALLBACK because that is reserved in Windows
  93. RAW_CALL_BACK,
  94. };
  95. void set_server_tag(void* tag) { server_tag_ = tag; }
  96. void* server_tag() const { return server_tag_; }
  97. /// if MethodHandler is nullptr, then this is an async method
  98. MethodHandler* handler() const { return handler_.get(); }
  99. ApiType api_type() const { return api_type_; }
  100. void SetHandler(MethodHandler* handler) { handler_.reset(handler); }
  101. void SetServerApiType(RpcServiceMethod::ApiType type) {
  102. if ((api_type_ == ApiType::SYNC) &&
  103. (type == ApiType::ASYNC || type == ApiType::RAW)) {
  104. // this marks this method as async
  105. handler_.reset();
  106. } else if (api_type_ != ApiType::SYNC) {
  107. // this is not an error condition, as it allows users to declare a server
  108. // like WithRawMethod_foo<AsyncService>. However since it
  109. // overwrites behavior, it should be logged.
  110. gpr_log(
  111. GPR_INFO,
  112. "You are marking method %s as '%s', even though it was "
  113. "previously marked '%s'. This behavior will overwrite the original "
  114. "behavior. If you expected this then ignore this message.",
  115. name(), TypeToString(api_type_), TypeToString(type));
  116. }
  117. api_type_ = type;
  118. }
  119. private:
  120. void* server_tag_;
  121. ApiType api_type_;
  122. std::unique_ptr<MethodHandler> handler_;
  123. const char* TypeToString(RpcServiceMethod::ApiType type) {
  124. switch (type) {
  125. case ApiType::SYNC:
  126. return "sync";
  127. case ApiType::ASYNC:
  128. return "async";
  129. case ApiType::RAW:
  130. return "raw";
  131. case ApiType::CALL_BACK:
  132. return "callback";
  133. case ApiType::RAW_CALL_BACK:
  134. return "raw_callback";
  135. default:
  136. GPR_UNREACHABLE_CODE(return "unknown");
  137. }
  138. }
  139. };
  140. } // namespace internal
  141. } // namespace grpc
  142. #endif // GRPCPP_IMPL_CODEGEN_RPC_SERVICE_METHOD_H