GRPC C++  1.0.0
async_unary_call.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_ASYNC_UNARY_CALL_H
35 #define GRPCXX_IMPL_CODEGEN_ASYNC_UNARY_CALL_H
36 
43 #include <grpc/impl/codegen/log.h>
44 
45 namespace grpc {
46 
47 class CompletionQueue;
48 extern CoreCodegenInterface* g_core_codegen_interface;
49 
50 template <class R>
52  public:
54  virtual void ReadInitialMetadata(void* tag) = 0;
55  virtual void Finish(R* msg, Status* status, void* tag) = 0;
56 };
57 
58 template <class R>
61  public:
62  template <class W>
64  const RpcMethod& method, ClientContext* context,
65  const W& request)
66  : context_(context),
67  call_(channel->CreateCall(method, context, cq)),
68  collection_(new CallOpSetCollection) {
69  collection_->init_buf_.SetCollection(collection_);
70  collection_->init_buf_.SendInitialMetadata(
71  context->send_initial_metadata_, context->initial_metadata_flags());
72  // TODO(ctiller): don't assert
73  GPR_CODEGEN_ASSERT(collection_->init_buf_.SendMessage(request).ok());
74  collection_->init_buf_.ClientSendClose();
75  call_.PerformOps(&collection_->init_buf_);
76  }
77 
78  void ReadInitialMetadata(void* tag) {
79  GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
80 
81  collection_->meta_buf_.SetCollection(collection_);
82  collection_->meta_buf_.set_output_tag(tag);
83  collection_->meta_buf_.RecvInitialMetadata(context_);
84  call_.PerformOps(&collection_->meta_buf_);
85  }
86 
87  void Finish(R* msg, Status* status, void* tag) {
88  collection_->finish_buf_.SetCollection(collection_);
89  collection_->finish_buf_.set_output_tag(tag);
90  if (!context_->initial_metadata_received_) {
91  collection_->finish_buf_.RecvInitialMetadata(context_);
92  }
93  collection_->finish_buf_.RecvMessage(msg);
94  collection_->finish_buf_.AllowNoMessage();
95  collection_->finish_buf_.ClientRecvStatus(context_, status);
96  call_.PerformOps(&collection_->finish_buf_);
97  }
98 
99  private:
100  ClientContext* context_;
101  Call call_;
102 
103  class CallOpSetCollection : public CallOpSetCollectionInterface {
104  public:
107  init_buf_;
111  finish_buf_;
112  };
113  std::shared_ptr<CallOpSetCollection> collection_;
114 };
115 
116 template <class W>
119  public:
121  : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
122 
124  GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
125 
126  meta_buf_.set_output_tag(tag);
127  meta_buf_.SendInitialMetadata(ctx_->initial_metadata_,
128  ctx_->initial_metadata_flags());
129  if (ctx_->compression_level_set()) {
130  meta_buf_.set_compression_level(ctx_->compression_level());
131  }
132  ctx_->sent_initial_metadata_ = true;
133  call_.PerformOps(&meta_buf_);
134  }
135 
136  void Finish(const W& msg, const Status& status, void* tag) {
137  finish_buf_.set_output_tag(tag);
138  if (!ctx_->sent_initial_metadata_) {
139  finish_buf_.SendInitialMetadata(ctx_->initial_metadata_,
140  ctx_->initial_metadata_flags());
141  if (ctx_->compression_level_set()) {
142  finish_buf_.set_compression_level(ctx_->compression_level());
143  }
144  ctx_->sent_initial_metadata_ = true;
145  }
146  // The response is dropped if the status is not OK.
147  if (status.ok()) {
148  finish_buf_.ServerSendStatus(ctx_->trailing_metadata_,
149  finish_buf_.SendMessage(msg));
150  } else {
151  finish_buf_.ServerSendStatus(ctx_->trailing_metadata_, status);
152  }
153  call_.PerformOps(&finish_buf_);
154  }
155 
156  void FinishWithError(const Status& status, void* tag) {
157  GPR_CODEGEN_ASSERT(!status.ok());
158  finish_buf_.set_output_tag(tag);
159  if (!ctx_->sent_initial_metadata_) {
160  finish_buf_.SendInitialMetadata(ctx_->initial_metadata_,
161  ctx_->initial_metadata_flags());
162  if (ctx_->compression_level_set()) {
163  finish_buf_.set_compression_level(ctx_->compression_level());
164  }
165  ctx_->sent_initial_metadata_ = true;
166  }
167  finish_buf_.ServerSendStatus(ctx_->trailing_metadata_, status);
168  call_.PerformOps(&finish_buf_);
169  }
170 
171  private:
172  void BindCall(Call* call) GRPC_OVERRIDE { call_ = *call; }
173 
174  Call call_;
175  ServerContext* ctx_;
179  finish_buf_;
180 };
181 
182 } // namespace grpc
183 
184 #endif // GRPCXX_IMPL_CODEGEN_ASYNC_UNARY_CALL_H
void FinishWithError(const Status &status, void *tag)
Definition: async_unary_call.h:156
virtual ~ClientAsyncResponseReaderInterface()
Definition: async_unary_call.h:53
virtual void Finish(R *msg, Status *status, void *tag)=0
void Finish(const W &msg, const Status &status, void *tag)
Definition: async_unary_call.h:136
#define GPR_CODEGEN_ASSERT(x)
Codegen specific version of GPR_ASSERT.
Definition: core_codegen_interface.h:97
Definition: call.h:500
Definition: service_type.h:53
void SendInitialMetadata(void *tag) GRPC_OVERRIDE
Definition: async_unary_call.h:123
void Finish(R *msg, Status *status, void *tag)
Definition: async_unary_call.h:87
virtual void ReadInitialMetadata(void *tag)=0
An abstract collection of CallOpSet&#39;s, to be used whenever CallOpSet objects must be thought of as a ...
Definition: call.h:555
Definition: call.h:427
Definition: async_unary_call.h:59
Definition: client_context.h:154
void ReadInitialMetadata(void *tag)
Definition: async_unary_call.h:78
Definition: call.h:232
Definition: call.h:407
Definition: async_unary_call.h:51
Definition: call.h:645
Definition: alarm.h:48
Codegen interface for grpc::Channel.
Definition: channel_interface.h:64
CoreCodegenInterface * g_core_codegen_interface
Definition: call.h:62
Primary implementaiton of CallOpSetInterface.
Definition: call.h:593
Definition: server_context.h:91
A thin wrapper around grpc_completion_queue (see / src/core/surface/completion_queue.h).
Definition: completion_queue.h:97
#define GRPC_FINAL
Definition: config.h:72
ClientAsyncResponseReader(ChannelInterface *channel, CompletionQueue *cq, const RpcMethod &method, ClientContext *context, const W &request)
Definition: async_unary_call.h:63
ServerAsyncResponseWriter(ServerContext *ctx)
Definition: async_unary_call.h:120
Definition: rpc_method.h:43
bool ok() const
Is the status OK?
Definition: status.h:67
Did it work? If it didn&#39;t, why?
Definition: status.h:45
Definition: async_unary_call.h:117
Definition: call.h:181
A CallOpSet that does not post completions to the completion queue.
Definition: call.h:636
#define GRPC_OVERRIDE
Definition: config.h:78