You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

server_interface.h 16 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  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. #ifndef GRPCPP_IMPL_CODEGEN_SERVER_INTERFACE_H
  19. #define GRPCPP_IMPL_CODEGEN_SERVER_INTERFACE_H
  20. // IWYU pragma: private
  21. #include <grpc/impl/codegen/port_platform.h>
  22. #include <grpc/impl/codegen/grpc_types.h>
  23. #include <grpcpp/impl/codegen/byte_buffer.h>
  24. #include <grpcpp/impl/codegen/call.h>
  25. #include <grpcpp/impl/codegen/call_hook.h>
  26. #include <grpcpp/impl/codegen/completion_queue_tag.h>
  27. #include <grpcpp/impl/codegen/core_codegen_interface.h>
  28. #include <grpcpp/impl/codegen/interceptor_common.h>
  29. #include <grpcpp/impl/codegen/rpc_service_method.h>
  30. #include <grpcpp/impl/codegen/server_context.h>
  31. namespace grpc
  32. {
  33. class AsyncGenericService;
  34. class Channel;
  35. class CompletionQueue;
  36. class GenericServerContext;
  37. class ServerCompletionQueue;
  38. class ServerCredentials;
  39. class Service;
  40. extern CoreCodegenInterface* g_core_codegen_interface;
  41. /// Models a gRPC server.
  42. ///
  43. /// Servers are configured and started via \a grpc::ServerBuilder.
  44. namespace internal
  45. {
  46. class ServerAsyncStreamingInterface;
  47. } // namespace internal
  48. class CallbackGenericService;
  49. namespace experimental
  50. {
  51. class ServerInterceptorFactoryInterface;
  52. } // namespace experimental
  53. class ServerInterface : public internal::CallHook
  54. {
  55. public:
  56. ~ServerInterface() override
  57. {
  58. }
  59. /// \a Shutdown does the following things:
  60. ///
  61. /// 1. Shutdown the server: deactivate all listening ports, mark it in
  62. /// "shutdown mode" so that further call Request's or incoming RPC matches
  63. /// are no longer allowed. Also return all Request'ed-but-not-yet-active
  64. /// calls as failed (!ok). This refers to calls that have been requested
  65. /// at the server by the server-side library or application code but that
  66. /// have not yet been matched to incoming RPCs from the client. Note that
  67. /// this would even include default calls added automatically by the gRPC
  68. /// C++ API without the user's input (e.g., "Unimplemented RPC method")
  69. ///
  70. /// 2. Block until all rpc method handlers invoked automatically by the sync
  71. /// API finish.
  72. ///
  73. /// 3. If all pending calls complete (and all their operations are
  74. /// retrieved by Next) before \a deadline expires, this finishes
  75. /// gracefully. Otherwise, forcefully cancel all pending calls associated
  76. /// with the server after \a deadline expires. In the case of the sync API,
  77. /// if the RPC function for a streaming call has already been started and
  78. /// takes a week to complete, the RPC function won't be forcefully
  79. /// terminated (since that would leave state corrupt and incomplete) and
  80. /// the method handler will just keep running (which will prevent the
  81. /// server from completing the "join" operation that it needs to do at
  82. /// shutdown time).
  83. ///
  84. /// All completion queue associated with the server (for example, for async
  85. /// serving) must be shutdown *after* this method has returned:
  86. /// See \a ServerBuilder::AddCompletionQueue for details.
  87. /// They must also be drained (by repeated Next) after being shutdown.
  88. ///
  89. /// \param deadline How long to wait until pending rpcs are forcefully
  90. /// terminated.
  91. template<class T>
  92. void Shutdown(const T& deadline)
  93. {
  94. ShutdownInternal(TimePoint<T>(deadline).raw_time());
  95. }
  96. /// Shutdown the server without a deadline and forced cancellation.
  97. ///
  98. /// All completion queue associated with the server (for example, for async
  99. /// serving) must be shutdown *after* this method has returned:
  100. /// See \a ServerBuilder::AddCompletionQueue for details.
  101. void Shutdown()
  102. {
  103. ShutdownInternal(
  104. g_core_codegen_interface->gpr_inf_future(GPR_CLOCK_MONOTONIC)
  105. );
  106. }
  107. /// Block waiting for all work to complete.
  108. ///
  109. /// \warning The server must be either shutting down or some other thread must
  110. /// call \a Shutdown for this function to ever return.
  111. virtual void Wait() = 0;
  112. protected:
  113. friend class grpc::Service;
  114. /// Register a service. This call does not take ownership of the service.
  115. /// The service must exist for the lifetime of the Server instance.
  116. virtual bool RegisterService(const std::string* host, Service* service) = 0;
  117. /// Register a generic service. This call does not take ownership of the
  118. /// service. The service must exist for the lifetime of the Server instance.
  119. virtual void RegisterAsyncGenericService(AsyncGenericService* service) = 0;
  120. /// Register a callback generic service. This call does not take ownership of
  121. /// the service. The service must exist for the lifetime of the Server
  122. /// instance. May not be abstract since this is a post-1.0 API addition.
  123. virtual void RegisterCallbackGenericService(CallbackGenericService*
  124. /*service*/)
  125. {
  126. }
  127. /// Tries to bind \a server to the given \a addr.
  128. ///
  129. /// It can be invoked multiple times.
  130. ///
  131. /// \param addr The address to try to bind to the server (eg, localhost:1234,
  132. /// 192.168.1.1:31416, [::1]:27182, etc.).
  133. /// \params creds The credentials associated with the server.
  134. ///
  135. /// \return bound port number on success, 0 on failure.
  136. ///
  137. /// \warning It's an error to call this method on an already started server.
  138. virtual int AddListeningPort(const std::string& addr, ServerCredentials* creds) = 0;
  139. /// Start the server.
  140. ///
  141. /// \param cqs Completion queues for handling asynchronous services. The
  142. /// caller is required to keep all completion queues live until the server is
  143. /// destroyed.
  144. /// \param num_cqs How many completion queues does \a cqs hold.
  145. virtual void Start(grpc::ServerCompletionQueue** cqs, size_t num_cqs) = 0;
  146. virtual void ShutdownInternal(gpr_timespec deadline) = 0;
  147. virtual int max_receive_message_size() const = 0;
  148. virtual grpc_server* server() = 0;
  149. void PerformOpsOnCall(internal::CallOpSetInterface* ops, internal::Call* call) override = 0;
  150. class BaseAsyncRequest : public internal::CompletionQueueTag
  151. {
  152. public:
  153. BaseAsyncRequest(ServerInterface* server, grpc::ServerContext* context, internal::ServerAsyncStreamingInterface* stream, grpc::CompletionQueue* call_cq, grpc::ServerCompletionQueue* notification_cq, void* tag, bool delete_on_finalize);
  154. ~BaseAsyncRequest() override;
  155. bool FinalizeResult(void** tag, bool* status) override;
  156. private:
  157. void ContinueFinalizeResultAfterInterception();
  158. protected:
  159. ServerInterface* const server_;
  160. grpc::ServerContext* const context_;
  161. internal::ServerAsyncStreamingInterface* const stream_;
  162. grpc::CompletionQueue* const call_cq_;
  163. grpc::ServerCompletionQueue* const notification_cq_;
  164. void* const tag_;
  165. const bool delete_on_finalize_;
  166. grpc_call* call_;
  167. internal::Call call_wrapper_;
  168. internal::InterceptorBatchMethodsImpl interceptor_methods_;
  169. bool done_intercepting_;
  170. };
  171. /// RegisteredAsyncRequest is not part of the C++ API
  172. class RegisteredAsyncRequest : public BaseAsyncRequest
  173. {
  174. public:
  175. RegisteredAsyncRequest(ServerInterface* server, grpc::ServerContext* context, internal::ServerAsyncStreamingInterface* stream, grpc::CompletionQueue* call_cq, grpc::ServerCompletionQueue* notification_cq, void* tag, const char* name, internal::RpcMethod::RpcType type);
  176. bool FinalizeResult(void** tag, bool* status) override
  177. {
  178. /* If we are done intercepting, then there is nothing more for us to do */
  179. if (done_intercepting_)
  180. {
  181. return BaseAsyncRequest::FinalizeResult(tag, status);
  182. }
  183. call_wrapper_ = grpc::internal::Call(
  184. call_, server_, call_cq_, server_->max_receive_message_size(), context_->set_server_rpc_info(name_, type_, *server_->interceptor_creators())
  185. );
  186. return BaseAsyncRequest::FinalizeResult(tag, status);
  187. }
  188. protected:
  189. void IssueRequest(void* registered_method, grpc_byte_buffer** payload, grpc::ServerCompletionQueue* notification_cq);
  190. const char* name_;
  191. const internal::RpcMethod::RpcType type_;
  192. };
  193. class NoPayloadAsyncRequest final : public RegisteredAsyncRequest
  194. {
  195. public:
  196. NoPayloadAsyncRequest(internal::RpcServiceMethod* registered_method, ServerInterface* server, grpc::ServerContext* context, internal::ServerAsyncStreamingInterface* stream, grpc::CompletionQueue* call_cq, grpc::ServerCompletionQueue* notification_cq, void* tag) :
  197. RegisteredAsyncRequest(
  198. server, context, stream, call_cq, notification_cq, tag, registered_method->name(), registered_method->method_type()
  199. )
  200. {
  201. IssueRequest(registered_method->server_tag(), nullptr, notification_cq);
  202. }
  203. // uses RegisteredAsyncRequest::FinalizeResult
  204. };
  205. template<class Message>
  206. class PayloadAsyncRequest final : public RegisteredAsyncRequest
  207. {
  208. public:
  209. PayloadAsyncRequest(internal::RpcServiceMethod* registered_method, ServerInterface* server, grpc::ServerContext* context, internal::ServerAsyncStreamingInterface* stream, grpc::CompletionQueue* call_cq, grpc::ServerCompletionQueue* notification_cq, void* tag, Message* request) :
  210. RegisteredAsyncRequest(
  211. server, context, stream, call_cq, notification_cq, tag, registered_method->name(), registered_method->method_type()
  212. ),
  213. registered_method_(registered_method),
  214. request_(request)
  215. {
  216. IssueRequest(registered_method->server_tag(), payload_.bbuf_ptr(), notification_cq);
  217. }
  218. ~PayloadAsyncRequest() override
  219. {
  220. payload_.Release(); // We do not own the payload_
  221. }
  222. bool FinalizeResult(void** tag, bool* status) override
  223. {
  224. /* If we are done intercepting, then there is nothing more for us to do */
  225. if (done_intercepting_)
  226. {
  227. return RegisteredAsyncRequest::FinalizeResult(tag, status);
  228. }
  229. if (*status)
  230. {
  231. if (!payload_.Valid() || !SerializationTraits<Message>::Deserialize(
  232. payload_.bbuf_ptr(), request_
  233. )
  234. .ok())
  235. {
  236. // If deserialization fails, we cancel the call and instantiate
  237. // a new instance of ourselves to request another call. We then
  238. // return false, which prevents the call from being returned to
  239. // the application.
  240. g_core_codegen_interface->grpc_call_cancel_with_status(
  241. call_, GRPC_STATUS_INTERNAL, "Unable to parse request", nullptr
  242. );
  243. g_core_codegen_interface->grpc_call_unref(call_);
  244. new PayloadAsyncRequest(registered_method_, server_, context_, stream_, call_cq_, notification_cq_, tag_, request_);
  245. delete this;
  246. return false;
  247. }
  248. }
  249. /* Set interception point for recv message */
  250. interceptor_methods_.AddInterceptionHookPoint(
  251. experimental::InterceptionHookPoints::POST_RECV_MESSAGE
  252. );
  253. interceptor_methods_.SetRecvMessage(request_, nullptr);
  254. return RegisteredAsyncRequest::FinalizeResult(tag, status);
  255. }
  256. private:
  257. internal::RpcServiceMethod* const registered_method_;
  258. Message* const request_;
  259. ByteBuffer payload_;
  260. };
  261. class GenericAsyncRequest : public BaseAsyncRequest
  262. {
  263. public:
  264. GenericAsyncRequest(ServerInterface* server, GenericServerContext* context, internal::ServerAsyncStreamingInterface* stream, grpc::CompletionQueue* call_cq, grpc::ServerCompletionQueue* notification_cq, void* tag, bool delete_on_finalize);
  265. bool FinalizeResult(void** tag, bool* status) override;
  266. private:
  267. grpc_call_details call_details_;
  268. };
  269. template<class Message>
  270. void RequestAsyncCall(internal::RpcServiceMethod* method, grpc::ServerContext* context, internal::ServerAsyncStreamingInterface* stream, grpc::CompletionQueue* call_cq, grpc::ServerCompletionQueue* notification_cq, void* tag, Message* message)
  271. {
  272. GPR_CODEGEN_ASSERT(method);
  273. new PayloadAsyncRequest<Message>(method, this, context, stream, call_cq, notification_cq, tag, message);
  274. }
  275. void RequestAsyncCall(internal::RpcServiceMethod* method, grpc::ServerContext* context, internal::ServerAsyncStreamingInterface* stream, grpc::CompletionQueue* call_cq, grpc::ServerCompletionQueue* notification_cq, void* tag)
  276. {
  277. GPR_CODEGEN_ASSERT(method);
  278. new NoPayloadAsyncRequest(method, this, context, stream, call_cq, notification_cq, tag);
  279. }
  280. void RequestAsyncGenericCall(GenericServerContext* context, internal::ServerAsyncStreamingInterface* stream, grpc::CompletionQueue* call_cq, grpc::ServerCompletionQueue* notification_cq, void* tag)
  281. {
  282. new GenericAsyncRequest(this, context, stream, call_cq, notification_cq, tag, true);
  283. }
  284. private:
  285. // EXPERIMENTAL
  286. // Getter method for the vector of interceptor factory objects.
  287. // Returns a nullptr (rather than being pure) since this is a post-1.0 method
  288. // and adding a new pure method to an interface would be a breaking change
  289. // (even though this is private and non-API)
  290. virtual std::vector<
  291. std::unique_ptr<experimental::ServerInterceptorFactoryInterface>>*
  292. interceptor_creators()
  293. {
  294. return nullptr;
  295. }
  296. // A method to get the callbackable completion queue associated with this
  297. // server. If the return value is nullptr, this server doesn't support
  298. // callback operations.
  299. // TODO(vjpai): Consider a better default like using a global CQ
  300. // Returns nullptr (rather than being pure) since this is a post-1.0 method
  301. // and adding a new pure method to an interface would be a breaking change
  302. // (even though this is private and non-API)
  303. virtual grpc::CompletionQueue* CallbackCQ()
  304. {
  305. return nullptr;
  306. }
  307. };
  308. } // namespace grpc
  309. #endif // GRPCPP_IMPL_CODEGEN_SERVER_INTERFACE_H