GRPC C++  1.6.0
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
async_unary_call.h
Go to the documentation of this file.
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 
19 #ifndef GRPCXX_IMPL_CODEGEN_ASYNC_UNARY_CALL_H
20 #define GRPCXX_IMPL_CODEGEN_ASYNC_UNARY_CALL_H
21 
22 #include <assert.h>
29 
30 namespace grpc {
31 
32 class CompletionQueue;
33 extern CoreCodegenInterface* g_core_codegen_interface;
34 
37 template <class R>
39  public:
41 
48  virtual void ReadInitialMetadata(void* tag) = 0;
49 
64  virtual void Finish(R* msg, Status* status, void* tag) = 0;
65 };
66 
69 template <class R>
72  public:
78  template <class W>
80  CompletionQueue* cq,
81  const RpcMethod& method,
82  ClientContext* context,
83  const W& request) {
84  Call call = channel->CreateCall(method, context, cq);
86  call.call(), sizeof(ClientAsyncResponseReader)))
87  ClientAsyncResponseReader(call, context, request);
88  }
89 
90  // always allocated against a call arena, no memory free required
91  static void operator delete(void* ptr, std::size_t size) {
92  assert(size == sizeof(ClientAsyncResponseReader));
93  }
94 
101  void ReadInitialMetadata(void* tag) {
102  GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
103 
104  meta_buf.set_output_tag(tag);
105  meta_buf.RecvInitialMetadata(context_);
106  call_.PerformOps(&meta_buf);
107  }
108 
114  void Finish(R* msg, Status* status, void* tag) {
115  finish_buf.set_output_tag(tag);
116  if (!context_->initial_metadata_received_) {
117  finish_buf.RecvInitialMetadata(context_);
118  }
119  finish_buf.RecvMessage(msg);
120  finish_buf.AllowNoMessage();
121  finish_buf.ClientRecvStatus(context_, status);
122  call_.PerformOps(&finish_buf);
123  }
124 
125  private:
126  ClientContext* const context_;
127  Call call_;
128 
129  template <class W>
130  ClientAsyncResponseReader(Call call, ClientContext* context, const W& request)
131  : context_(context), call_(call) {
132  init_buf.SendInitialMetadata(context->send_initial_metadata_,
133  context->initial_metadata_flags());
134  // TODO(ctiller): don't assert
135  GPR_CODEGEN_ASSERT(init_buf.SendMessage(request).ok());
136  init_buf.ClientSendClose();
137  call_.PerformOps(&init_buf);
138  }
139 
140  // disable operator new
141  static void* operator new(std::size_t size);
142  static void* operator new(std::size_t size, void* p) { return p; }
143 
144  SneakyCallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
145  CallOpClientSendClose>
146  init_buf;
147  CallOpSet<CallOpRecvInitialMetadata> meta_buf;
148  CallOpSet<CallOpRecvInitialMetadata, CallOpRecvMessage<R>,
149  CallOpClientRecvStatus>
150  finish_buf;
151 };
152 
155 template <class W>
157  public:
159  : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
160 
168  void SendInitialMetadata(void* tag) override {
169  GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
170 
171  meta_buf_.set_output_tag(tag);
172  meta_buf_.SendInitialMetadata(ctx_->initial_metadata_,
173  ctx_->initial_metadata_flags());
174  if (ctx_->compression_level_set()) {
175  meta_buf_.set_compression_level(ctx_->compression_level());
176  }
177  ctx_->sent_initial_metadata_ = true;
178  call_.PerformOps(&meta_buf_);
179  }
180 
196  void Finish(const W& msg, const Status& status, void* tag) {
197  finish_buf_.set_output_tag(tag);
198  if (!ctx_->sent_initial_metadata_) {
199  finish_buf_.SendInitialMetadata(ctx_->initial_metadata_,
200  ctx_->initial_metadata_flags());
201  if (ctx_->compression_level_set()) {
202  finish_buf_.set_compression_level(ctx_->compression_level());
203  }
204  ctx_->sent_initial_metadata_ = true;
205  }
206  // The response is dropped if the status is not OK.
207  if (status.ok()) {
208  finish_buf_.ServerSendStatus(ctx_->trailing_metadata_,
209  finish_buf_.SendMessage(msg));
210  } else {
211  finish_buf_.ServerSendStatus(ctx_->trailing_metadata_, status);
212  }
213  call_.PerformOps(&finish_buf_);
214  }
215 
228  void FinishWithError(const Status& status, void* tag) {
229  GPR_CODEGEN_ASSERT(!status.ok());
230  finish_buf_.set_output_tag(tag);
231  if (!ctx_->sent_initial_metadata_) {
232  finish_buf_.SendInitialMetadata(ctx_->initial_metadata_,
233  ctx_->initial_metadata_flags());
234  if (ctx_->compression_level_set()) {
235  finish_buf_.set_compression_level(ctx_->compression_level());
236  }
237  ctx_->sent_initial_metadata_ = true;
238  }
239  finish_buf_.ServerSendStatus(ctx_->trailing_metadata_, status);
240  call_.PerformOps(&finish_buf_);
241  }
242 
243  private:
244  void BindCall(Call* call) override { call_ = *call; }
245 
246  Call call_;
247  ServerContext* ctx_;
248  CallOpSet<CallOpSendInitialMetadata> meta_buf_;
249  CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
250  CallOpServerSendStatus>
251  finish_buf_;
252 };
253 
254 } // namespace grpc
255 
256 namespace std {
257 template <class R>
258 class default_delete<grpc::ClientAsyncResponseReader<R>> {
259  public:
260  void operator()(void* p) {}
261 };
262 template <class R>
263 class default_delete<grpc::ClientAsyncResponseReaderInterface<R>> {
264  public:
265  void operator()(void* p) {}
266 };
267 }
268 
269 #endif // GRPCXX_IMPL_CODEGEN_ASYNC_UNARY_CALL_H
void FinishWithError(const Status &status, void *tag)
Indicate that the stream is to be finished with a non-OK status, and request notification for when th...
Definition: async_unary_call.h:228
virtual ~ClientAsyncResponseReaderInterface()
Definition: async_unary_call.h:40
grpc_compression_level compression_level() const
Return the compression algorithm to be used by the server call.
Definition: server_context.h:170
virtual void Finish(R *msg, Status *status, void *tag)=0
Request to receive the server's response msg and final status for the call, and to notify tag on this...
void Finish(const W &msg, const Status &status, void *tag)
Indicate that the stream is to be finished and request notification when the server has sent the appr...
Definition: async_unary_call.h:196
#define GPR_CODEGEN_ASSERT(x)
Codegen specific version of GPR_ASSERT.
Definition: core_codegen_interface.h:126
Definition: service_type.h:38
void Finish(R *msg, Status *status, void *tag)
See ClientAysncResponseReaderInterface::Finish for semantics.
Definition: async_unary_call.h:114
virtual void ReadInitialMetadata(void *tag)=0
Request notification of the reading of initial metadata.
static ClientAsyncResponseReader * Create(ChannelInterface *channel, CompletionQueue *cq, const RpcMethod &method, ClientContext *context, const W &request)
Start a call and write the request out.
Definition: async_unary_call.h:79
Async API for client-side unary RPCs, where the message response received from the server is of type ...
Definition: async_unary_call.h:70
A ClientContext allows the person implementing a service client to:
Definition: client_context.h:153
void operator()(void *p)
Definition: async_unary_call.h:260
void SendInitialMetadata(void *tag) override
See ServerAsyncStreamingInterface::SendInitialMetadata for semantics.
Definition: async_unary_call.h:168
void ReadInitialMetadata(void *tag)
See ClientAsyncResponseReaderInterface::ReadInitialMetadata for semantics.
Definition: async_unary_call.h:101
An interface relevant for async client side unary RPCS (which send one request message to a server an...
Definition: async_unary_call.h:38
void operator()(void *p)
Definition: async_unary_call.h:265
Straightforward wrapping of the C call object.
Definition: call.h:647
Codegen interface for grpc::Channel.
Definition: channel_interface.h:49
CoreCodegenInterface * g_core_codegen_interface
Definition: call.h:49
A ServerContext allows the person implementing a service handler to:
Definition: server_context.h:95
A thin wrapper around grpc_completion_queue (see src/core/lib/surface/completion_queue.h).
Definition: completion_queue.h:86
virtual void * grpc_call_arena_alloc(grpc_call *call, size_t length)=0
ServerAsyncResponseWriter(ServerContext *ctx)
Definition: async_unary_call.h:158
Descriptor of an RPC method.
Definition: rpc_method.h:29
void PerformOps(CallOpSetInterface *ops)
Definition: call.h:663
bool ok() const
Is the status OK?
Definition: status.h:64
Did it work? If it didn't, why?
Definition: status.h:30
Async server-side API for handling unary calls, where the single response message sent to the client ...
Definition: async_unary_call.h:156
grpc_call * call() const
Definition: call.h:667
bool compression_level_set() const
Return a bool indicating whether the compression level for this call has been set (either implicitly ...
Definition: server_context.h:185