gRPC  0.6.0
 All Classes Namespaces Functions Variables Enumerations Properties Pages
async_unary_call.h
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_ASYNC_UNARY_CALL_H
35 #define GRPCXX_ASYNC_UNARY_CALL_H
36 
37 #include <grpc++/channel_interface.h>
38 #include <grpc++/client_context.h>
39 #include <grpc++/completion_queue.h>
40 #include <grpc++/server_context.h>
41 #include <grpc++/impl/call.h>
42 #include <grpc++/impl/service_type.h>
43 #include <grpc++/status.h>
44 #include <grpc/support/log.h>
45 
46 namespace grpc {
47 
48 template <class R>
50  public:
52  virtual void ReadInitialMetadata(void* tag) = 0;
53  virtual void Finish(R* msg, Status* status, void* tag) = 0;
54 
55 };
56 
57 template <class R>
60  public:
62  const RpcMethod& method, ClientContext* context,
63  const grpc::protobuf::Message& request)
64  : context_(context), call_(channel->CreateCall(method, context, cq)) {
65  init_buf_.AddSendInitialMetadata(&context->send_initial_metadata_);
66  init_buf_.AddSendMessage(request);
67  init_buf_.AddClientSendClose();
68  call_.PerformOps(&init_buf_);
69  }
70 
71  void ReadInitialMetadata(void* tag) {
72  GPR_ASSERT(!context_->initial_metadata_received_);
73 
74  meta_buf_.Reset(tag);
75  meta_buf_.AddRecvInitialMetadata(context_);
76  call_.PerformOps(&meta_buf_);
77  }
78 
79  void Finish(R* msg, Status* status, void* tag) {
80  finish_buf_.Reset(tag);
81  if (!context_->initial_metadata_received_) {
82  finish_buf_.AddRecvInitialMetadata(context_);
83  }
84  finish_buf_.AddRecvMessage(msg);
85  finish_buf_.AddClientRecvStatus(context_, status);
86  call_.PerformOps(&finish_buf_);
87  }
88 
89  private:
90  ClientContext* context_;
91  Call call_;
92  SneakyCallOpBuffer init_buf_;
93  CallOpBuffer meta_buf_;
94  CallOpBuffer finish_buf_;
95 };
96 
97 template <class W>
98 class ServerAsyncResponseWriter GRPC_FINAL
99  : public ServerAsyncStreamingInterface {
100  public:
101  explicit ServerAsyncResponseWriter(ServerContext* ctx)
102  : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
103 
104  void SendInitialMetadata(void* tag) GRPC_OVERRIDE {
105  GPR_ASSERT(!ctx_->sent_initial_metadata_);
106 
107  meta_buf_.Reset(tag);
108  meta_buf_.AddSendInitialMetadata(&ctx_->initial_metadata_);
109  ctx_->sent_initial_metadata_ = true;
110  call_.PerformOps(&meta_buf_);
111  }
112 
113  void Finish(const W& msg, const Status& status, void* tag) {
114  finish_buf_.Reset(tag);
115  if (!ctx_->sent_initial_metadata_) {
116  finish_buf_.AddSendInitialMetadata(&ctx_->initial_metadata_);
117  ctx_->sent_initial_metadata_ = true;
118  }
119  // The response is dropped if the status is not OK.
120  if (status.IsOk()) {
121  finish_buf_.AddSendMessage(msg);
122  }
123  finish_buf_.AddServerSendStatus(&ctx_->trailing_metadata_, status);
124  call_.PerformOps(&finish_buf_);
125  }
126 
127  void FinishWithError(const Status& status, void* tag) {
128  GPR_ASSERT(!status.IsOk());
129  finish_buf_.Reset(tag);
130  if (!ctx_->sent_initial_metadata_) {
131  finish_buf_.AddSendInitialMetadata(&ctx_->initial_metadata_);
132  ctx_->sent_initial_metadata_ = true;
133  }
134  finish_buf_.AddServerSendStatus(&ctx_->trailing_metadata_, status);
135  call_.PerformOps(&finish_buf_);
136  }
137 
138  private:
139  void BindCall(Call* call) GRPC_OVERRIDE { call_ = *call; }
140 
141  Call call_;
142  ServerContext* ctx_;
143  CallOpBuffer meta_buf_;
144  CallOpBuffer finish_buf_;
145 };
146 
147 } // namespace grpc
148 
149 #endif // GRPCXX_ASYNC_UNARY_CALL_H
Definition: completion_queue.h:76
Definition: channel_interface.h:52
Definition: status.h:42
Definition: channel.h:53
Definition: client_context.h:70
Definition: client_context.h:72
Definition: proto_utils.cc:45
Definition: async_unary_call.h:49
Definition: _call.h:44
Definition: rpc_method.h:39
Definition: channel_create.c:62