blob: 1364bfe20f1bfab22951f6ef8983a9ddbb2d655b [file] [log] [blame]
David Garcia Quintas44f32492016-01-14 18:00:04 -08001/*
2 *
David Garcia Quintas61908542016-01-20 11:21:27 -08003 * Copyright 2015-2016, Google Inc.
David Garcia Quintas44f32492016-01-14 18:00:04 -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
34#ifndef GRPCXX_SERVER_INTERFACE_H
35#define GRPCXX_SERVER_INTERFACE_H
36
37#include <grpc++/completion_queue.h>
38#include <grpc++/impl/call.h>
David Garcia Quintasa701ed72016-01-19 18:14:29 -080039#include <grpc++/impl/rpc_service_method.h>
David Garcia Quintas44f32492016-01-14 18:00:04 -080040
41namespace grpc {
42
David Garcia Quintasa701ed72016-01-19 18:14:29 -080043class AsyncGenericService;
David Garcia Quintas44f32492016-01-14 18:00:04 -080044class AsynchronousService;
45class GenericServerContext;
David Garcia Quintas44f32492016-01-14 18:00:04 -080046class RpcService;
47class RpcServiceMethod;
48class ServerAsyncStreamingInterface;
49class ServerContext;
David Garcia Quintasa701ed72016-01-19 18:14:29 -080050class ServerCredentials;
51class Service;
David Garcia Quintas44f32492016-01-14 18:00:04 -080052class ThreadPoolInterface;
53
54/// Models a gRPC server.
55///
56/// Servers are configured and started via \a grpc::ServerBuilder.
57class ServerInterface : public CallHook {
58 public:
David Garcia Quintas1f4e72c2016-01-19 14:45:32 -080059 virtual ~ServerInterface() {}
60
David Garcia Quintas44f32492016-01-14 18:00:04 -080061 /// Shutdown the server, blocking until all rpc processing finishes.
62 /// Forcefully terminate pending calls after \a deadline expires.
63 ///
64 /// \param deadline How long to wait until pending rpcs are forcefully
65 /// terminated.
66 template <class T>
67 void Shutdown(const T& deadline) {
68 ShutdownInternal(TimePoint<T>(deadline).raw_time());
69 }
70
71 /// Shutdown the server, waiting for all rpc processing to finish.
72 void Shutdown() { ShutdownInternal(gpr_inf_future(GPR_CLOCK_MONOTONIC)); }
73
74 /// Block waiting for all work to complete.
75 ///
76 /// \warning The server must be either shutting down or some other thread must
77 /// call \a Shutdown for this function to ever return.
78 virtual void Wait() = 0;
79
80 protected:
81 friend class AsynchronousService;
David Garcia Quintasa701ed72016-01-19 18:14:29 -080082 friend class Service;
David Garcia Quintas44f32492016-01-14 18:00:04 -080083
84 /// Register a service. This call does not take ownership of the service.
85 /// The service must exist for the lifetime of the Server instance.
David Garcia Quintasa701ed72016-01-19 18:14:29 -080086 virtual bool RegisterService(const grpc::string* host, Service* service) = 0;
David Garcia Quintas44f32492016-01-14 18:00:04 -080087
88 /// Register a generic service. This call does not take ownership of the
89 /// service. The service must exist for the lifetime of the Server instance.
90 virtual void RegisterAsyncGenericService(AsyncGenericService* service) = 0;
91
92 /// Tries to bind \a server to the given \a addr.
93 ///
94 /// It can be invoked multiple times.
95 ///
96 /// \param addr The address to try to bind to the server (eg, localhost:1234,
97 /// 192.168.1.1:31416, [::1]:27182, etc.).
98 /// \params creds The credentials associated with the server.
99 ///
100 /// \return bound port number on sucess, 0 on failure.
101 ///
102 /// \warning It's an error to call this method on an already started server.
David Garcia Quintasf3ddb7c2016-01-20 16:02:22 -0800103 virtual int AddListeningPort(const grpc::string& addr,
104 ServerCredentials* creds) = 0;
David Garcia Quintas44f32492016-01-14 18:00:04 -0800105
106 /// Start the server.
107 ///
108 /// \param cqs Completion queues for handling asynchronous services. The
109 /// caller is required to keep all completion queues live until the server is
110 /// destroyed.
111 /// \param num_cqs How many completion queues does \a cqs hold.
112 ///
113 /// \return true on a successful shutdown.
114 virtual bool Start(ServerCompletionQueue** cqs, size_t num_cqs) = 0;
115
116 /// Process one or more incoming calls.
117 virtual void RunRpc() = 0;
118
119 /// Schedule \a RunRpc to run in the threadpool.
120 virtual void ScheduleCallback() = 0;
121
122 virtual void ShutdownInternal(gpr_timespec deadline) = 0;
123
124 virtual int max_message_size() const = 0;
125
126 virtual grpc_server* server() = 0;
127
128 virtual void PerformOpsOnCall(CallOpSetInterface* ops, Call* call) = 0;
129
130 class BaseAsyncRequest : public CompletionQueueTag {
131 public:
132 BaseAsyncRequest(ServerInterface* server, ServerContext* context,
133 ServerAsyncStreamingInterface* stream,
134 CompletionQueue* call_cq, void* tag,
135 bool delete_on_finalize);
136 virtual ~BaseAsyncRequest() {}
137
138 bool FinalizeResult(void** tag, bool* status) GRPC_OVERRIDE;
139
140 protected:
141 ServerInterface* const server_;
142 ServerContext* const context_;
143 ServerAsyncStreamingInterface* const stream_;
144 CompletionQueue* const call_cq_;
145 void* const tag_;
146 const bool delete_on_finalize_;
147 grpc_call* call_;
148 grpc_metadata_array initial_metadata_array_;
149 };
150
151 class RegisteredAsyncRequest : public BaseAsyncRequest {
152 public:
153 RegisteredAsyncRequest(ServerInterface* server, ServerContext* context,
154 ServerAsyncStreamingInterface* stream,
155 CompletionQueue* call_cq, void* tag);
156
157 // uses BaseAsyncRequest::FinalizeResult
158
159 protected:
160 void IssueRequest(void* registered_method, grpc_byte_buffer** payload,
161 ServerCompletionQueue* notification_cq);
162 };
163
164 class NoPayloadAsyncRequest GRPC_FINAL : public RegisteredAsyncRequest {
165 public:
166 NoPayloadAsyncRequest(void* registered_method, ServerInterface* server,
167 ServerContext* context,
168 ServerAsyncStreamingInterface* stream,
169 CompletionQueue* call_cq,
170 ServerCompletionQueue* notification_cq, void* tag)
171 : RegisteredAsyncRequest(server, context, stream, call_cq, tag) {
172 IssueRequest(registered_method, nullptr, notification_cq);
173 }
174
175 // uses RegisteredAsyncRequest::FinalizeResult
176 };
177
178 template <class Message>
179 class PayloadAsyncRequest GRPC_FINAL : public RegisteredAsyncRequest {
180 public:
181 PayloadAsyncRequest(void* registered_method, ServerInterface* server,
182 ServerContext* context,
183 ServerAsyncStreamingInterface* stream,
184 CompletionQueue* call_cq,
185 ServerCompletionQueue* notification_cq, void* tag,
186 Message* request)
187 : RegisteredAsyncRequest(server, context, stream, call_cq, tag),
188 request_(request) {
189 IssueRequest(registered_method, &payload_, notification_cq);
190 }
191
192 bool FinalizeResult(void** tag, bool* status) GRPC_OVERRIDE {
193 bool serialization_status =
194 *status && payload_ &&
195 SerializationTraits<Message>::Deserialize(
196 payload_, request_, server_->max_message_size()).ok();
197 bool ret = RegisteredAsyncRequest::FinalizeResult(tag, status);
198 *status = serialization_status&&* status;
199 return ret;
200 }
201
202 private:
203 grpc_byte_buffer* payload_;
204 Message* const request_;
205 };
206
207 class GenericAsyncRequest : public BaseAsyncRequest {
208 public:
209 GenericAsyncRequest(ServerInterface* server, GenericServerContext* context,
210 ServerAsyncStreamingInterface* stream,
211 CompletionQueue* call_cq,
212 ServerCompletionQueue* notification_cq, void* tag,
213 bool delete_on_finalize);
214
215 bool FinalizeResult(void** tag, bool* status) GRPC_OVERRIDE;
216
217 private:
218 grpc_call_details call_details_;
219 };
220
221 template <class Message>
David Garcia Quintasa701ed72016-01-19 18:14:29 -0800222 void RequestAsyncCall(RpcServiceMethod* method, ServerContext* context,
David Garcia Quintas44f32492016-01-14 18:00:04 -0800223 ServerAsyncStreamingInterface* stream,
224 CompletionQueue* call_cq,
225 ServerCompletionQueue* notification_cq, void* tag,
226 Message* message) {
David Garcia Quintasa701ed72016-01-19 18:14:29 -0800227 GPR_ASSERT(method);
228 new PayloadAsyncRequest<Message>(method->server_tag(), this, context,
229 stream, call_cq, notification_cq, tag,
230 message);
David Garcia Quintas44f32492016-01-14 18:00:04 -0800231 }
232
David Garcia Quintasa701ed72016-01-19 18:14:29 -0800233 void RequestAsyncCall(RpcServiceMethod* method, ServerContext* context,
David Garcia Quintas44f32492016-01-14 18:00:04 -0800234 ServerAsyncStreamingInterface* stream,
235 CompletionQueue* call_cq,
236 ServerCompletionQueue* notification_cq, void* tag) {
David Garcia Quintasa701ed72016-01-19 18:14:29 -0800237 GPR_ASSERT(method);
238 new NoPayloadAsyncRequest(method->server_tag(), this, context, stream,
239 call_cq, notification_cq, tag);
David Garcia Quintas44f32492016-01-14 18:00:04 -0800240 }
241
242 void RequestAsyncGenericCall(GenericServerContext* context,
243 ServerAsyncStreamingInterface* stream,
244 CompletionQueue* call_cq,
245 ServerCompletionQueue* notification_cq,
246 void* tag) {
247 new GenericAsyncRequest(this, context, stream, call_cq, notification_cq,
248 tag, true);
249 }
250};
251
252} // namespace grpc
253
254#endif // GRPCXX_SERVER_INTERFACE_H