GRPC C++  1.3.0
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
method_handler_impl.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_CODEGEN_METHOD_HANDLER_IMPL_H
35 #define GRPCXX_IMPL_CODEGEN_METHOD_HANDLER_IMPL_H
36 
40 
41 namespace grpc {
42 
43 // A wrapper class of an application provided rpc method handler.
44 template <class ServiceType, class RequestType, class ResponseType>
45 class RpcMethodHandler : public MethodHandler {
46  public:
47  RpcMethodHandler(std::function<Status(ServiceType*, ServerContext*,
48  const RequestType*, ResponseType*)>
49  func,
50  ServiceType* service)
51  : func_(func), service_(service) {}
52 
53  void RunHandler(const HandlerParameter& param) final {
54  RequestType req;
55  Status status =
57  ResponseType rsp;
58  if (status.ok()) {
59  status = func_(service_, param.server_context, &req, &rsp);
60  }
61 
62  GPR_CODEGEN_ASSERT(!param.server_context->sent_initial_metadata_);
65  ops;
66  ops.SendInitialMetadata(param.server_context->initial_metadata_,
67  param.server_context->initial_metadata_flags());
68  if (param.server_context->compression_level_set()) {
69  ops.set_compression_level(param.server_context->compression_level());
70  }
71  if (status.ok()) {
72  status = ops.SendMessage(rsp);
73  }
74  ops.ServerSendStatus(param.server_context->trailing_metadata_, status);
75  param.call->PerformOps(&ops);
76  param.call->cq()->Pluck(&ops);
77  }
78 
79  private:
80  // Application provided rpc handler function.
81  std::function<Status(ServiceType*, ServerContext*, const RequestType*,
82  ResponseType*)>
83  func_;
84  // The class the above handler function lives in.
85  ServiceType* service_;
86 };
87 
88 // A wrapper class of an application provided client streaming handler.
89 template <class ServiceType, class RequestType, class ResponseType>
90 class ClientStreamingHandler : public MethodHandler {
91  public:
93  std::function<Status(ServiceType*, ServerContext*,
94  ServerReader<RequestType>*, ResponseType*)>
95  func,
96  ServiceType* service)
97  : func_(func), service_(service) {}
98 
99  void RunHandler(const HandlerParameter& param) final {
100  ServerReader<RequestType> reader(param.call, param.server_context);
101  ResponseType rsp;
102  Status status = func_(service_, param.server_context, &reader, &rsp);
103 
104  GPR_CODEGEN_ASSERT(!param.server_context->sent_initial_metadata_);
107  ops;
108  ops.SendInitialMetadata(param.server_context->initial_metadata_,
109  param.server_context->initial_metadata_flags());
110  if (param.server_context->compression_level_set()) {
111  ops.set_compression_level(param.server_context->compression_level());
112  }
113  if (status.ok()) {
114  status = ops.SendMessage(rsp);
115  }
116  ops.ServerSendStatus(param.server_context->trailing_metadata_, status);
117  param.call->PerformOps(&ops);
118  param.call->cq()->Pluck(&ops);
119  }
120 
121  private:
122  std::function<Status(ServiceType*, ServerContext*, ServerReader<RequestType>*,
123  ResponseType*)>
124  func_;
125  ServiceType* service_;
126 };
127 
128 // A wrapper class of an application provided server streaming handler.
129 template <class ServiceType, class RequestType, class ResponseType>
130 class ServerStreamingHandler : public MethodHandler {
131  public:
133  std::function<Status(ServiceType*, ServerContext*, const RequestType*,
135  func,
136  ServiceType* service)
137  : func_(func), service_(service) {}
138 
139  void RunHandler(const HandlerParameter& param) final {
140  RequestType req;
141  Status status =
143 
144  if (status.ok()) {
145  ServerWriter<ResponseType> writer(param.call, param.server_context);
146  status = func_(service_, param.server_context, &req, &writer);
147  }
148 
150  if (!param.server_context->sent_initial_metadata_) {
151  ops.SendInitialMetadata(param.server_context->initial_metadata_,
152  param.server_context->initial_metadata_flags());
153  if (param.server_context->compression_level_set()) {
154  ops.set_compression_level(param.server_context->compression_level());
155  }
156  }
157  ops.ServerSendStatus(param.server_context->trailing_metadata_, status);
158  param.call->PerformOps(&ops);
159  param.call->cq()->Pluck(&ops);
160  }
161 
162  private:
163  std::function<Status(ServiceType*, ServerContext*, const RequestType*,
165  func_;
166  ServiceType* service_;
167 };
168 
169 // A wrapper class of an application provided bidi-streaming handler.
170 // This also applies to server-streamed implementation of a unary method
171 // with the additional requirement that such methods must have done a
172 // write for status to be ok
173 // Since this is used by more than 1 class, the service is not passed in.
174 // Instead, it is expected to be an implicitly-captured argument of func
175 // (through bind or something along those lines)
176 template <class Streamer, bool WriteNeeded>
178  public:
180  std::function<Status(ServerContext*, Streamer*)> func)
181  : func_(func), write_needed_(WriteNeeded) {}
182 
183  void RunHandler(const HandlerParameter& param) final {
184  Streamer stream(param.call, param.server_context);
185  Status status = func_(param.server_context, &stream);
186 
188  if (!param.server_context->sent_initial_metadata_) {
189  ops.SendInitialMetadata(param.server_context->initial_metadata_,
190  param.server_context->initial_metadata_flags());
191  if (param.server_context->compression_level_set()) {
192  ops.set_compression_level(param.server_context->compression_level());
193  }
194  if (write_needed_ && status.ok()) {
195  // If we needed a write but never did one, we need to mark the
196  // status as a fail
197  status = Status(StatusCode::INTERNAL,
198  "Service did not provide response message");
199  }
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(ServerContext*, Streamer*)> func_;
208  const bool write_needed_;
209 };
210 
211 template <class ServiceType, class RequestType, class ResponseType>
212 class BidiStreamingHandler
213  : public TemplatedBidiStreamingHandler<
214  ServerReaderWriter<ResponseType, RequestType>, false> {
215  public:
217  std::function<Status(ServiceType*, ServerContext*,
219  func,
220  ServiceType* service)
222  ServerReaderWriter<ResponseType, RequestType>, false>(std::bind(
223  func, service, std::placeholders::_1, std::placeholders::_2)) {}
224 };
225 
226 template <class RequestType, class ResponseType>
229  ServerUnaryStreamer<RequestType, ResponseType>, true> {
230  public:
232  std::function<Status(ServerContext*,
234  func)
236  ServerUnaryStreamer<RequestType, ResponseType>, true>(func) {}
237 };
238 
239 template <class RequestType, class ResponseType>
242  ServerSplitStreamer<RequestType, ResponseType>, false> {
243  public:
245  std::function<Status(ServerContext*,
247  func)
249  ServerSplitStreamer<RequestType, ResponseType>, false>(func) {}
250 };
251 
252 // Handle unknown method by returning UNIMPLEMENTED error.
254  public:
255  template <class T>
256  static void FillOps(ServerContext* context, T* ops) {
257  Status status(StatusCode::UNIMPLEMENTED, "");
258  if (!context->sent_initial_metadata_) {
259  ops->SendInitialMetadata(context->initial_metadata_,
260  context->initial_metadata_flags());
261  if (context->compression_level_set()) {
262  ops->set_compression_level(context->compression_level());
263  }
264  context->sent_initial_metadata_ = true;
265  }
266  ops->ServerSendStatus(context->trailing_metadata_, status);
267  }
268 
269  void RunHandler(const HandlerParameter& param) final {
271  FillOps(param.server_context, &ops);
272  param.call->PerformOps(&ops);
273  param.call->cq()->Pluck(&ops);
274  }
275 };
276 
277 } // namespace grpc
278 
279 #endif // GRPCXX_IMPL_CODEGEN_METHOD_HANDLER_IMPL_H
SplitServerStreamingHandler(std::function< Status(ServerContext *, ServerSplitStreamer< RequestType, ResponseType > *)> func)
Definition: method_handler_impl.h:244
grpc_compression_level compression_level() const
Definition: server_context.h:131
void RunHandler(const HandlerParameter &param) final
Definition: method_handler_impl.h:99
Definition: rpc_service_method.h:56
Definition: method_handler_impl.h:240
A class to represent a flow-controlled server-side streaming call.
Definition: sync_stream.h:641
#define GPR_CODEGEN_ASSERT(x)
Codegen specific version of GPR_ASSERT.
Definition: core_codegen_interface.h:122
ClientStreamingHandler(std::function< Status(ServiceType *, ServerContext *, ServerReader< RequestType > *, ResponseType *)> func, ServiceType *service)
Definition: method_handler_impl.h:92
A class to represent a flow-controlled unary call.
Definition: sync_stream.h:600
StreamedUnaryHandler(std::function< Status(ServerContext *, ServerUnaryStreamer< RequestType, ResponseType > *)> func)
Definition: method_handler_impl.h:231
ServerStreamingHandler(std::function< Status(ServiceType *, ServerContext *, const RequestType *, ServerWriter< ResponseType > *)> func, ServiceType *service)
Definition: method_handler_impl.h:132
static void FillOps(ServerContext *context, T *ops)
Definition: method_handler_impl.h:256
Definition: method_handler_impl.h:227
Definition: call.h:460
Definition: completion_queue.h:68
void RunHandler(const HandlerParameter &param) final
Definition: method_handler_impl.h:269
Defines how to serialize and deserialize some type.
Definition: serialization_traits.h:64
Definition: method_handler_impl.h:253
Definition: call.h:268
void RunHandler(const HandlerParameter &param) final
Definition: method_handler_impl.h:53
Definition: method_handler_impl.h:177
void RunHandler(const HandlerParameter &param) final
Definition: method_handler_impl.h:183
RpcMethodHandler(std::function< Status(ServiceType *, ServerContext *, const RequestType *, ResponseType *)> func, ServiceType *service)
Definition: method_handler_impl.h:47
Primary implementaiton of CallOpSetInterface.
Definition: call.h:623
void RunHandler(const HandlerParameter &param) final
Definition: method_handler_impl.h:139
Definition: server_context.h:94
Definition: completion_queue.h:70
BidiStreamingHandler(std::function< Status(ServiceType *, ServerContext *, ServerReaderWriter< ResponseType, RequestType > *)> func, ServiceType *service)
Definition: method_handler_impl.h:216
Definition: sync_stream.h:569
bool ok() const
Is the status OK?
Definition: status.h:76
Definition: rpc_service_method.h:59
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:217
bool compression_level_set() const
Definition: server_context.h:140
Internal errors.
Definition: status_code_enum.h:134
TemplatedBidiStreamingHandler(std::function< Status(ServerContext *, Streamer *)> func)
Definition: method_handler_impl.h:179