rpc_service_method.h 5.2 KB

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