GRPC C++  0.12.0.0
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
rpc_service_method.h
Go to the documentation of this file.
1 /*
2  *
3  * Copyright 2015, Google Inc.
4  * 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_IMPL_RPC_SERVICE_METHOD_H
35 #define GRPCXX_IMPL_RPC_SERVICE_METHOD_H
36 
37 #include <climits>
38 #include <functional>
39 #include <map>
40 #include <memory>
41 #include <vector>
42 
43 #include <grpc++/impl/rpc_method.h>
44 #include <grpc++/support/config.h>
45 #include <grpc++/support/status.h>
47 
48 namespace grpc {
49 class ServerContext;
50 class StreamContextInterface;
51 
52 // TODO(rocking): we might need to split this file into multiple ones.
53 
54 // Base class for running an RPC handler.
56  public:
57  virtual ~MethodHandler() {}
59  HandlerParameter(Call* c, ServerContext* context, grpc_byte_buffer* req,
60  int max_size)
61  : call(c),
62  server_context(context),
63  request(req),
64  max_message_size(max_size) {}
67  // Handler required to grpc_byte_buffer_destroy this
68  grpc_byte_buffer* request;
70  };
71  virtual void RunHandler(const HandlerParameter& param) = 0;
72 };
73 
74 // A wrapper class of an application provided rpc method handler.
75 template <class ServiceType, class RequestType, class ResponseType>
76 class RpcMethodHandler : public MethodHandler {
77  public:
79  std::function<Status(ServiceType*, ServerContext*, const RequestType*,
80  ResponseType*)> func,
81  ServiceType* service)
82  : func_(func), service_(service) {}
83 
84  void RunHandler(const HandlerParameter& param) GRPC_FINAL {
85  RequestType req;
87  param.request, &req, param.max_message_size);
88  ResponseType rsp;
89  if (status.ok()) {
90  status = func_(service_, param.server_context, &req, &rsp);
91  }
92 
93  GPR_ASSERT(!param.server_context->sent_initial_metadata_);
96  ops.SendInitialMetadata(param.server_context->initial_metadata_);
97  if (status.ok()) {
98  status = ops.SendMessage(rsp);
99  }
100  ops.ServerSendStatus(param.server_context->trailing_metadata_, status);
101  param.call->PerformOps(&ops);
102  param.call->cq()->Pluck(&ops);
103  }
104 
105  private:
106  // Application provided rpc handler function.
107  std::function<Status(ServiceType*, ServerContext*, const RequestType*,
108  ResponseType*)> func_;
109  // The class the above handler function lives in.
110  ServiceType* service_;
111 };
112 
113 // A wrapper class of an application provided client streaming handler.
114 template <class ServiceType, class RequestType, class ResponseType>
115 class ClientStreamingHandler : public MethodHandler {
116  public:
118  std::function<Status(ServiceType*, ServerContext*,
119  ServerReader<RequestType>*, ResponseType*)> func,
120  ServiceType* service)
121  : func_(func), service_(service) {}
122 
124  ServerReader<RequestType> reader(param.call, param.server_context);
125  ResponseType rsp;
126  Status status = func_(service_, param.server_context, &reader, &rsp);
127 
128  GPR_ASSERT(!param.server_context->sent_initial_metadata_);
131  ops.SendInitialMetadata(param.server_context->initial_metadata_);
132  if (status.ok()) {
133  status = ops.SendMessage(rsp);
134  }
135  ops.ServerSendStatus(param.server_context->trailing_metadata_, status);
136  param.call->PerformOps(&ops);
137  param.call->cq()->Pluck(&ops);
138  }
139 
140  private:
141  std::function<Status(ServiceType*, ServerContext*, ServerReader<RequestType>*,
142  ResponseType*)> func_;
143  ServiceType* service_;
144 };
145 
146 // A wrapper class of an application provided server streaming handler.
147 template <class ServiceType, class RequestType, class ResponseType>
148 class ServerStreamingHandler : public MethodHandler {
149  public:
151  std::function<Status(ServiceType*, ServerContext*, const RequestType*,
153  ServiceType* service)
154  : func_(func), service_(service) {}
155 
157  RequestType req;
159  param.request, &req, param.max_message_size);
160 
161  if (status.ok()) {
162  ServerWriter<ResponseType> writer(param.call, param.server_context);
163  status = func_(service_, param.server_context, &req, &writer);
164  }
165 
167  if (!param.server_context->sent_initial_metadata_) {
168  ops.SendInitialMetadata(param.server_context->initial_metadata_);
169  }
170  ops.ServerSendStatus(param.server_context->trailing_metadata_, status);
171  param.call->PerformOps(&ops);
172  param.call->cq()->Pluck(&ops);
173  }
174 
175  private:
176  std::function<Status(ServiceType*, ServerContext*, const RequestType*,
178  ServiceType* service_;
179 };
180 
181 // A wrapper class of an application provided bidi-streaming handler.
182 template <class ServiceType, class RequestType, class ResponseType>
183 class BidiStreamingHandler : public MethodHandler {
184  public:
186  std::function<Status(ServiceType*, ServerContext*,
188  func,
189  ServiceType* service)
190  : func_(func), service_(service) {}
191 
194  param.server_context);
195  Status status = func_(service_, param.server_context, &stream);
196 
198  if (!param.server_context->sent_initial_metadata_) {
199  ops.SendInitialMetadata(param.server_context->initial_metadata_);
200  }
201  ops.ServerSendStatus(param.server_context->trailing_metadata_, status);
202  param.call->PerformOps(&ops);
203  param.call->cq()->Pluck(&ops);
204  }
205 
206  private:
207  std::function<Status(ServiceType*, ServerContext*,
209  ServiceType* service_;
210 };
211 
212 // Handle unknown method by returning UNIMPLEMENTED error.
214  public:
215  template <class T>
216  static void FillOps(ServerContext* context, T* ops) {
217  Status status(StatusCode::UNIMPLEMENTED, "");
218  if (!context->sent_initial_metadata_) {
219  ops->SendInitialMetadata(context->initial_metadata_);
220  context->sent_initial_metadata_ = true;
221  }
222  ops->ServerSendStatus(context->trailing_metadata_, status);
223  }
224 
227  FillOps(param.server_context, &ops);
228  param.call->PerformOps(&ops);
229  param.call->cq()->Pluck(&ops);
230  }
231 };
232 
233 // Server side rpc method class
234 class RpcServiceMethod : public RpcMethod {
235  public:
236  // Takes ownership of the handler
239  : RpcMethod(name, type), handler_(handler) {}
240 
241  MethodHandler* handler() { return handler_.get(); }
242 
243  private:
244  std::unique_ptr<MethodHandler> handler_;
245 };
246 
247 // This class contains all the method information for an rpc service. It is
248 // used for registering a service on a grpc server.
249 class RpcService {
250  public:
251  // Takes ownership.
252  void AddMethod(RpcServiceMethod* method) { methods_.emplace_back(method); }
253 
254  RpcServiceMethod* GetMethod(int i) { return methods_[i].get(); }
255  int GetMethodCount() const {
256  // On win x64, int is only 32bit
257  GPR_ASSERT(methods_.size() <= INT_MAX);
258  return (int)methods_.size();
259  }
260 
261  private:
262  std::vector<std::unique_ptr<RpcServiceMethod>> methods_;
263 };
264 
265 } // namespace grpc
266 
267 #endif // GRPCXX_IMPL_RPC_SERVICE_METHOD_H
Definition: rpc_service_method.h:55
void AddMethod(RpcServiceMethod *method)
Definition: rpc_service_method.h:252
RpcServiceMethod * GetMethod(int i)
Definition: rpc_service_method.h:254
ClientStreamingHandler(std::function< Status(ServiceType *, ServerContext *, ServerReader< RequestType > *, ResponseType *)> func, ServiceType *service)
Definition: rpc_service_method.h:117
void RunHandler(const HandlerParameter &param)
Definition: rpc_service_method.h:225
ServerStreamingHandler(std::function< Status(ServiceType *, ServerContext *, const RequestType *, ServerWriter< ResponseType > *)> func, ServiceType *service)
Definition: rpc_service_method.h:150
int max_message_size
Definition: rpc_service_method.h:69
static void FillOps(ServerContext *context, T *ops)
Definition: rpc_service_method.h:216
ServerContext * server_context
Definition: rpc_service_method.h:66
RpcType
Definition: rpc_method.h:45
Call * call
Definition: rpc_service_method.h:65
void RunHandler(const HandlerParameter &param)
Definition: rpc_service_method.h:156
Definition: call.h:352
#define GRPC_FINAL
Definition: config.h:71
void RunHandler(const HandlerParameter &param)
Definition: rpc_service_method.h:123
Definition: completion_queue.h:55
Definition: rpc_service_method.h:234
Defines how to serialize and deserialize some type.
Definition: serialization_traits.h:64
Definition: rpc_service_method.h:213
Definition: call.h:179
Definition: rpc_service_method.h:249
virtual void RunHandler(const HandlerParameter &param)=0
void RunHandler(const HandlerParameter &param)
Definition: rpc_service_method.h:192
Definition: call.h:559
Definition: completion_queue.h:61
RpcMethodHandler(std::function< Status(ServiceType *, ServerContext *, const RequestType *, ResponseType *)> func, ServiceType *service)
Definition: rpc_service_method.h:78
virtual ~MethodHandler()
Definition: rpc_service_method.h:57
Primary implementaiton of CallOpSetInterface.
Definition: call.h:501
Definition: server_context.h:89
void RunHandler(const HandlerParameter &param)
Definition: rpc_service_method.h:84
Definition: completion_queue.h:57
Definition: rpc_method.h:43
BidiStreamingHandler(std::function< Status(ServiceType *, ServerContext *, ServerReaderWriter< ResponseType, RequestType > *)> func, ServiceType *service)
Definition: rpc_service_method.h:185
Server-side interface for bi-directional streaming.
Definition: completion_queue.h:59
bool ok() const
Is the status OK?
Definition: status.h:67
Definition: rpc_service_method.h:58
Did it work? If it didn't, why?
Definition: status.h:45
Operation is not implemented or not supported/enabled in this service.
Definition: status_code_enum.h:130
Definition: call.h:147
HandlerParameter(Call *c, ServerContext *context, grpc_byte_buffer *req, int max_size)
Definition: rpc_service_method.h:59
const char * name() const
Definition: rpc_method.h:61
MethodHandler * handler()
Definition: rpc_service_method.h:241
int GetMethodCount() const
Definition: rpc_service_method.h:255
grpc_byte_buffer * request
Definition: rpc_service_method.h:68
RpcServiceMethod(const char *name, RpcMethod::RpcType type, MethodHandler *handler)
Definition: rpc_service_method.h:237