blob: 07dbd7fd202fe58fbb2a7fb9291771455f68a2cf [file] [log] [blame]
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001/*
2 *
Craig Tiller06059952015-02-18 08:34:56 -08003 * Copyright 2015, Google Inc.
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08004 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
Nicolas "Pixel" Noble1ff52d52015-03-01 05:24:36 +010034#ifndef GRPCXX_SERVER_H
35#define GRPCXX_SERVER_H
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080036
Craig Tillercbd04852015-02-10 17:39:54 -080037#include <list>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080038#include <memory>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080039
40#include <grpc++/completion_queue.h>
41#include <grpc++/config.h>
Craig Tillerbb5227f2015-02-11 13:34:48 -080042#include <grpc++/impl/call.h>
Yang Gaoc4b6ffb2015-04-23 16:35:24 -070043#include <grpc++/impl/grpc_library.h>
Nicolas "Pixel" Nobleff2828b2015-04-03 03:16:46 +020044#include <grpc++/impl/sync.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080045#include <grpc++/status.h>
David Garcia Quintasbeac88c2015-08-10 13:39:52 -070046#include <grpc/compression.h>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080047
48struct grpc_server;
49
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080050namespace grpc {
Craig Tiller50a7a682015-06-04 12:53:40 -070051
Craig Tiller8c8d0aa2015-02-12 11:38:36 -080052class AsynchronousService;
Yang Gao005eb882015-03-11 22:17:13 -070053class GenericServerContext;
Yang Gao49996492015-03-12 16:40:19 -070054class AsyncGenericService;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080055class RpcService;
56class RpcServiceMethod;
Craig Tiller81fafa82015-06-04 08:51:17 -070057class ServerAsyncStreamingInterface;
yangg9e21f722014-12-08 15:49:52 -080058class ServerCredentials;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080059class ThreadPoolInterface;
60
61// Currently it only supports handling rpcs in a single thread.
Craig Tillerce40de52015-06-05 07:14:58 -070062class Server GRPC_FINAL : public GrpcLibrary, private CallHook {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080063 public:
64 ~Server();
65
66 // Shutdown the server, block until all rpc processing finishes.
67 void Shutdown();
68
Craig Tiller6e57b9e2015-02-24 15:46:22 -080069 // Block waiting for all work to complete (the server must either
70 // be shutting down or some other thread must call Shutdown for this
71 // function to ever return)
72 void Wait();
73
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080074 private:
Yang Gao49996492015-03-12 16:40:19 -070075 friend class AsyncGenericService;
Craig Tiller81fafa82015-06-04 08:51:17 -070076 friend class AsynchronousService;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080077 friend class ServerBuilder;
78
Craig Tiller1c9a2a92015-02-12 14:10:25 -080079 class SyncRequest;
80 class AsyncRequest;
Craig Tillerbce999f2015-05-27 09:55:51 -070081 class ShutdownRequest;
Craig Tillercbd04852015-02-10 17:39:54 -080082
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080083 // ServerBuilder use only
Yang Gao3921c562015-04-30 16:07:06 -070084 Server(ThreadPoolInterface* thread_pool, bool thread_pool_owned,
David Garcia Quintasbeac88c2015-08-10 13:39:52 -070085 int max_message_size, grpc_compression_options compression_options);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080086 // Register a service. This call does not take ownership of the service.
87 // The service must exist for the lifetime of the Server instance.
Craig Tiller822d2c72015-07-07 16:08:00 -070088 bool RegisterService(const grpc::string *host, RpcService* service);
89 bool RegisterAsyncService(const grpc::string *host, AsynchronousService* service);
Yang Gao49996492015-03-12 16:40:19 -070090 void RegisterAsyncGenericService(AsyncGenericService* service);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080091 // Add a listening port. Can be called multiple times.
Nicolas Noblecfd60732015-03-18 16:27:43 -070092 int AddListeningPort(const grpc::string& addr, ServerCredentials* creds);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080093 // Start the server.
Craig Tiller0db1bef2015-02-09 13:47:39 -080094 bool Start();
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080095
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080096 void HandleQueueClosed();
97 void RunRpc();
98 void ScheduleCallback();
99
Craig Tillerce40de52015-06-05 07:14:58 -0700100 void PerformOpsOnCall(CallOpSetInterface* ops, Call* call) GRPC_OVERRIDE;
Craig Tillerbb5227f2015-02-11 13:34:48 -0800101
Craig Tiller50a7a682015-06-04 12:53:40 -0700102 class BaseAsyncRequest : public CompletionQueueTag {
103 public:
Craig Tiller7bc97bc2015-06-04 17:22:54 -0700104 BaseAsyncRequest(Server* server, ServerContext* context,
Craig Tillerce40de52015-06-05 07:14:58 -0700105 ServerAsyncStreamingInterface* stream,
106 CompletionQueue* call_cq, void* tag);
Craig Tiller7bc97bc2015-06-04 17:22:54 -0700107 virtual ~BaseAsyncRequest();
Craig Tiller50a7a682015-06-04 12:53:40 -0700108
Craig Tiller7bc97bc2015-06-04 17:22:54 -0700109 bool FinalizeResult(void** tag, bool* status) GRPC_OVERRIDE;
110
111 protected:
Craig Tiller7bc97bc2015-06-04 17:22:54 -0700112 Server* const server_;
113 ServerContext* const context_;
114 ServerAsyncStreamingInterface* const stream_;
115 CompletionQueue* const call_cq_;
Craig Tiller50955812015-06-05 08:03:17 -0700116 void* const tag_;
Craig Tiller7bc97bc2015-06-04 17:22:54 -0700117 grpc_call* call_;
118 grpc_metadata_array initial_metadata_array_;
Craig Tiller50a7a682015-06-04 12:53:40 -0700119 };
120
121 class RegisteredAsyncRequest : public BaseAsyncRequest {
122 public:
123 RegisteredAsyncRequest(Server* server, ServerContext* context,
Craig Tillerce40de52015-06-05 07:14:58 -0700124 ServerAsyncStreamingInterface* stream,
125 CompletionQueue* call_cq, void* tag);
Craig Tiller7bc97bc2015-06-04 17:22:54 -0700126
127 // uses BaseAsyncRequest::FinalizeResult
128
129 protected:
Craig Tillerce40de52015-06-05 07:14:58 -0700130 void IssueRequest(void* registered_method, grpc_byte_buffer** payload,
131 ServerCompletionQueue* notification_cq);
Craig Tiller50a7a682015-06-04 12:53:40 -0700132 };
133
Craig Tiller7bc97bc2015-06-04 17:22:54 -0700134 class NoPayloadAsyncRequest GRPC_FINAL : public RegisteredAsyncRequest {
Craig Tiller50a7a682015-06-04 12:53:40 -0700135 public:
Craig Tillerce40de52015-06-05 07:14:58 -0700136 NoPayloadAsyncRequest(void* registered_method, Server* server,
137 ServerContext* context,
138 ServerAsyncStreamingInterface* stream,
139 CompletionQueue* call_cq,
140 ServerCompletionQueue* notification_cq, void* tag)
141 : RegisteredAsyncRequest(server, context, stream, call_cq, tag) {
Craig Tiller7bc97bc2015-06-04 17:22:54 -0700142 IssueRequest(registered_method, nullptr, notification_cq);
Craig Tiller50a7a682015-06-04 12:53:40 -0700143 }
Craig Tiller7bc97bc2015-06-04 17:22:54 -0700144
145 // uses RegisteredAsyncRequest::FinalizeResult
Craig Tiller50a7a682015-06-04 12:53:40 -0700146 };
147
148 template <class Message>
Craig Tiller7bc97bc2015-06-04 17:22:54 -0700149 class PayloadAsyncRequest GRPC_FINAL : public RegisteredAsyncRequest {
150 public:
Craig Tillerce40de52015-06-05 07:14:58 -0700151 PayloadAsyncRequest(void* registered_method, Server* server,
152 ServerContext* context,
153 ServerAsyncStreamingInterface* stream,
154 CompletionQueue* call_cq,
155 ServerCompletionQueue* notification_cq, void* tag,
156 Message* request)
157 : RegisteredAsyncRequest(server, context, stream, call_cq, tag),
158 request_(request) {
Craig Tiller7bc97bc2015-06-04 17:22:54 -0700159 IssueRequest(registered_method, &payload_, notification_cq);
Craig Tiller50a7a682015-06-04 12:53:40 -0700160 }
Craig Tiller7bc97bc2015-06-04 17:22:54 -0700161
162 bool FinalizeResult(void** tag, bool* status) GRPC_OVERRIDE {
Craig Tillerce40de52015-06-05 07:14:58 -0700163 bool serialization_status =
164 *status && payload_ &&
165 SerializationTraits<Message>::Deserialize(payload_, request_,
166 server_->max_message_size_)
Craig Tiller2622ddb2015-06-16 17:30:26 -0700167 .ok();
Craig Tiller7bc97bc2015-06-04 17:22:54 -0700168 bool ret = RegisteredAsyncRequest::FinalizeResult(tag, status);
169 *status = serialization_status && *status;
170 return ret;
171 }
172
173 private:
174 grpc_byte_buffer* payload_;
175 Message* const request_;
Craig Tiller50a7a682015-06-04 12:53:40 -0700176 };
177
Craig Tiller7bc97bc2015-06-04 17:22:54 -0700178 class GenericAsyncRequest GRPC_FINAL : public BaseAsyncRequest {
179 public:
180 GenericAsyncRequest(Server* server, GenericServerContext* context,
Craig Tillerce40de52015-06-05 07:14:58 -0700181 ServerAsyncStreamingInterface* stream,
182 CompletionQueue* call_cq,
183 ServerCompletionQueue* notification_cq, void* tag);
Craig Tiller7bc97bc2015-06-04 17:22:54 -0700184
185 bool FinalizeResult(void** tag, bool* status) GRPC_OVERRIDE;
186
187 private:
188 grpc_call_details call_details_;
Craig Tiller50a7a682015-06-04 12:53:40 -0700189 };
190
Craig Tiller81fafa82015-06-04 08:51:17 -0700191 template <class Message>
Craig Tiller1c9a2a92015-02-12 14:10:25 -0800192 void RequestAsyncCall(void* registered_method, ServerContext* context,
Craig Tiller573523f2015-02-17 07:38:26 -0800193 ServerAsyncStreamingInterface* stream,
Craig Tillerf9e6adf2015-05-06 11:45:59 -0700194 CompletionQueue* call_cq,
Craig Tillerce40de52015-06-05 07:14:58 -0700195 ServerCompletionQueue* notification_cq, void* tag,
196 Message* message) {
197 new PayloadAsyncRequest<Message>(registered_method, this, context, stream,
198 call_cq, notification_cq, tag, message);
Craig Tiller7bc97bc2015-06-04 17:22:54 -0700199 }
Craig Tiller81fafa82015-06-04 08:51:17 -0700200
201 void RequestAsyncCall(void* registered_method, ServerContext* context,
202 ServerAsyncStreamingInterface* stream,
203 CompletionQueue* call_cq,
Craig Tillerce40de52015-06-05 07:14:58 -0700204 ServerCompletionQueue* notification_cq, void* tag) {
205 new NoPayloadAsyncRequest(registered_method, this, context, stream, call_cq,
206 notification_cq, tag);
Craig Tiller7bc97bc2015-06-04 17:22:54 -0700207 }
Craig Tiller1c9a2a92015-02-12 14:10:25 -0800208
Yang Gao49996492015-03-12 16:40:19 -0700209 void RequestAsyncGenericCall(GenericServerContext* context,
210 ServerAsyncStreamingInterface* stream,
Craig Tiller7bc97bc2015-06-04 17:22:54 -0700211 CompletionQueue* call_cq,
Craig Tillerf9e6adf2015-05-06 11:45:59 -0700212 ServerCompletionQueue* notification_cq,
Craig Tiller7bc97bc2015-06-04 17:22:54 -0700213 void* tag) {
Craig Tillerce40de52015-06-05 07:14:58 -0700214 new GenericAsyncRequest(this, context, stream, call_cq, notification_cq,
215 tag);
Craig Tiller7bc97bc2015-06-04 17:22:54 -0700216 }
Yang Gao1c402332015-03-05 16:39:25 -0800217
Yang Gao3921c562015-04-30 16:07:06 -0700218 const int max_message_size_;
219
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800220 // Completion queue.
Craig Tiller3b29b562015-02-11 12:58:46 -0800221 CompletionQueue cq_;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800222
223 // Sever status
Nicolas "Pixel" Nobleff2828b2015-04-03 03:16:46 +0200224 grpc::mutex mu_;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800225 bool started_;
226 bool shutdown_;
227 // The number of threads which are running callbacks.
228 int num_running_cb_;
Nicolas "Pixel" Nobleff2828b2015-04-03 03:16:46 +0200229 grpc::condition_variable callback_cv_;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800230
Nicolas Noble30862032015-04-24 18:17:45 -0700231 std::list<SyncRequest>* sync_methods_;
Craig Tillercbd04852015-02-10 17:39:54 -0800232
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800233 // Pointer to the c grpc server.
Craig Tiller42bc87c2015-02-23 08:50:19 -0800234 grpc_server* const server_;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800235
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800236 ThreadPoolInterface* thread_pool_;
237 // Whether the thread pool is created and owned by the server.
238 bool thread_pool_owned_;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800239};
240
241} // namespace grpc
242
Nicolas "Pixel" Noble1ff52d52015-03-01 05:24:36 +0100243#endif // GRPCXX_SERVER_H