server_interface.h 15 KB

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