GRPC C++ 0.10.0.0

- Main Page
- Namespaces
- Data Structures
- Files

- File List
- Globals

All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
stream.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_STREAM_H
35 #define GRPCXX_STREAM_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 // Common interface for all client side streaming.
49 class ClientStreamingInterface {
50 public:
51 virtual ~ClientStreamingInterface() {}
52
53 // Wait until the stream finishes, and return the final status. When the
54 // client side declares it has no more message to send, either implicitly or
55 // by calling WritesDone, it needs to make sure there is no more message to
56 // be received from the server, either implicitly or by getting a false from
57 // a Read(). Otherwise, this implicitly cancels the stream.
58 virtual Status Finish() = 0;
59 };
60
61 // An interface that yields a sequence of R messages.
62 template <class R>
63 class ReaderInterface {
64 public:
65 virtual ~ReaderInterface() {}
66
67 // Blocking read a message and parse to msg. Returns true on success.
68 // The method returns false when there will be no more incoming messages,
69 // either because the other side has called WritesDone or the stream has
70 // failed (or been cancelled).
71 virtual bool Read(R* msg) = 0;
72 };
73
74 // An interface that can be fed a sequence of W messages.
75 template <class W>
76 class WriterInterface {
77 public:
78 virtual ~WriterInterface() {}
79
80 // Blocking write msg to the stream. Returns true on success.
81 // Returns false when the stream has been closed.
82 virtual bool Write(const W& msg, const WriteOptions& options) = 0;
83
84 inline bool Write(const W& msg) {
85 return Write(msg, WriteOptions());
86 }
87 };
88
89 template <class R>
90 class ClientReaderInterface : public ClientStreamingInterface,
91 public ReaderInterface<R> {
92 public:
93 virtual void WaitForInitialMetadata() = 0;
94 };
95
96 template <class R>
97 class ClientReader GRPC_FINAL : public ClientReaderInterface<R> {
98 public:
99 // Blocking create a stream and write the first request out.
100 template <class W>
101 ClientReader(ChannelInterface* channel, const RpcMethod& method,
102 ClientContext* context, const W& request)
103 : context_(context), call_(channel->CreateCall(method, context, &cq_)) {
104 CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
105 CallOpClientSendClose> ops;
106 ops.SendInitialMetadata(context->send_initial_metadata_);
107 // TODO(ctiller): don't assert
108 GPR_ASSERT(ops.SendMessage(request).ok());
109 ops.ClientSendClose();
110 call_.PerformOps(&ops);
111 cq_.Pluck(&ops);
112 }
113
114 // Blocking wait for initial metadata from server. The received metadata
115 // can only be accessed after this call returns. Should only be called before
116 // the first read. Calling this method is optional, and if it is not called
117 // the metadata will be available in ClientContext after the first read.
118 void WaitForInitialMetadata() {
119 GPR_ASSERT(!context_->initial_metadata_received_);
120
121 CallOpSet<CallOpRecvInitialMetadata> ops;
122 ops.RecvInitialMetadata(context_);
123 call_.PerformOps(&ops);
124 cq_.Pluck(&ops); // status ignored
125 }
126
127 bool Read(R* msg) GRPC_OVERRIDE {
128 CallOpSet<CallOpRecvInitialMetadata, CallOpRecvMessage<R>> ops;
129 if (!context_->initial_metadata_received_) {
130 ops.RecvInitialMetadata(context_);
131 }
132 ops.RecvMessage(msg);
133 call_.PerformOps(&ops);
134 return cq_.Pluck(&ops) && ops.got_message;
135 }
136
137 Status Finish() GRPC_OVERRIDE {
138 CallOpSet<CallOpClientRecvStatus> ops;
139 Status status;
140 ops.ClientRecvStatus(context_, &status);
141 call_.PerformOps(&ops);
142 GPR_ASSERT(cq_.Pluck(&ops));
143 return status;
144 }
145
146 private:
147 ClientContext* context_;
148 CompletionQueue cq_;
149 Call call_;
150 };
151
152 template <class W>
153 class ClientWriterInterface : public ClientStreamingInterface,
154 public WriterInterface<W> {
155 public:
156 virtual bool WritesDone() = 0;
157 };
158
159 template <class W>
160 class ClientWriter : public ClientWriterInterface<W> {
161 public:
162 // Blocking create a stream.
163 template <class R>
164 ClientWriter(ChannelInterface* channel, const RpcMethod& method,
165 ClientContext* context, R* response)
166 : context_(context), call_(channel->CreateCall(method, context, &cq_)) {
167 finish_ops_.RecvMessage(response);
168
169 CallOpSet<CallOpSendInitialMetadata> ops;
170 ops.SendInitialMetadata(context->send_initial_metadata_);
171 call_.PerformOps(&ops);
172 cq_.Pluck(&ops);
173 }
174
175 using WriterInterface<W>::Write;
176 bool Write(const W& msg, const WriteOptions& options) GRPC_OVERRIDE {
177 CallOpSet<CallOpSendMessage> ops;
178 if (!ops.SendMessage(msg, options).ok()) {
179 return false;
180 }
181 call_.PerformOps(&ops);
182 return cq_.Pluck(&ops);
183 }
184
185 bool WritesDone() GRPC_OVERRIDE {
186 CallOpSet<CallOpClientSendClose> ops;
187 ops.ClientSendClose();
188 call_.PerformOps(&ops);
189 return cq_.Pluck(&ops);
190 }
191
192 // Read the final response and wait for the final status.
193 Status Finish() GRPC_OVERRIDE {
194 Status status;
195 finish_ops_.ClientRecvStatus(context_, &status);
196 call_.PerformOps(&finish_ops_);
197 GPR_ASSERT(cq_.Pluck(&finish_ops_));
198 return status;
199 }
200
201 private:
202 ClientContext* context_;
203 CallOpSet<CallOpGenericRecvMessage, CallOpClientRecvStatus> finish_ops_;
204 CompletionQueue cq_;
205 Call call_;
206 };
207
208 // Client-side interface for bi-directional streaming.
209 template <class W, class R>
210 class ClientReaderWriterInterface : public ClientStreamingInterface,
211 public WriterInterface<W>,
212 public ReaderInterface<R> {
213 public:
214 virtual void WaitForInitialMetadata() = 0;
215 virtual bool WritesDone() = 0;
216 };
217
218 template <class W, class R>
219 class ClientReaderWriter GRPC_FINAL : public ClientReaderWriterInterface<W, R> {
220 public:
221 // Blocking create a stream.
222 ClientReaderWriter(ChannelInterface* channel, const RpcMethod& method,
223 ClientContext* context)
224 : context_(context), call_(channel->CreateCall(method, context, &cq_)) {
225 CallOpSet<CallOpSendInitialMetadata> ops;
226 ops.SendInitialMetadata(context->send_initial_metadata_);
227 call_.PerformOps(&ops);
228 cq_.Pluck(&ops);
229 }
230
231 // Blocking wait for initial metadata from server. The received metadata
232 // can only be accessed after this call returns. Should only be called before
233 // the first read. Calling this method is optional, and if it is not called
234 // the metadata will be available in ClientContext after the first read.
235 void WaitForInitialMetadata() {
236 GPR_ASSERT(!context_->initial_metadata_received_);
237
238 CallOpSet<CallOpRecvInitialMetadata> ops;
239 ops.RecvInitialMetadata(context_);
240 call_.PerformOps(&ops);
241 cq_.Pluck(&ops); // status ignored
242 }
243
244 bool Read(R* msg) GRPC_OVERRIDE {
245 CallOpSet<CallOpRecvInitialMetadata, CallOpRecvMessage<R>> ops;
246 if (!context_->initial_metadata_received_) {
247 ops.RecvInitialMetadata(context_);
248 }
249 ops.RecvMessage(msg);
250 call_.PerformOps(&ops);
251 return cq_.Pluck(&ops) && ops.got_message;
252 }
253
254 using WriterInterface<W>::Write;
255 bool Write(const W& msg, const WriteOptions& options) GRPC_OVERRIDE {
256 CallOpSet<CallOpSendMessage> ops;
257 if (!ops.SendMessage(msg, options).ok()) return false;
258 call_.PerformOps(&ops);
259 return cq_.Pluck(&ops);
260 }
261
262 bool WritesDone() GRPC_OVERRIDE {
263 CallOpSet<CallOpClientSendClose> ops;
264 ops.ClientSendClose();
265 call_.PerformOps(&ops);
266 return cq_.Pluck(&ops);
267 }
268
269 Status Finish() GRPC_OVERRIDE {
270 CallOpSet<CallOpClientRecvStatus> ops;
271 Status status;
272 ops.ClientRecvStatus(context_, &status);
273 call_.PerformOps(&ops);
274 GPR_ASSERT(cq_.Pluck(&ops));
275 return status;
276 }
277
278 private:
279 ClientContext* context_;
280 CompletionQueue cq_;
281 Call call_;
282 };
283
284 template <class R>
285 class ServerReader GRPC_FINAL : public ReaderInterface<R> {
286 public:
287 ServerReader(Call* call, ServerContext* ctx) : call_(call), ctx_(ctx) {}
288
289 void SendInitialMetadata() {
290 GPR_ASSERT(!ctx_->sent_initial_metadata_);
291
292 CallOpSet<CallOpSendInitialMetadata> ops;
293 ops.SendInitialMetadata(ctx_->initial_metadata_);
294 ctx_->sent_initial_metadata_ = true;
295 call_->PerformOps(&ops);
296 call_->cq()->Pluck(&ops);
297 }
298
299 bool Read(R* msg) GRPC_OVERRIDE {
300 CallOpSet<CallOpRecvMessage<R>> ops;
301 ops.RecvMessage(msg);
302 call_->PerformOps(&ops);
303 return call_->cq()->Pluck(&ops) && ops.got_message;
304 }
305
306 private:
307 Call* const call_;
308 ServerContext* const ctx_;
309 };
310
311 template <class W>
312 class ServerWriter GRPC_FINAL : public WriterInterface<W> {
313 public:
314 ServerWriter(Call* call, ServerContext* ctx) : call_(call), ctx_(ctx) {}
315
316 void SendInitialMetadata() {
317 GPR_ASSERT(!ctx_->sent_initial_metadata_);
318
319 CallOpSet<CallOpSendInitialMetadata> ops;
320 ops.SendInitialMetadata(ctx_->initial_metadata_);
321 ctx_->sent_initial_metadata_ = true;
322 call_->PerformOps(&ops);
323 call_->cq()->Pluck(&ops);
324 }
325
326 using WriterInterface<W>::Write;
327 bool Write(const W& msg, const WriteOptions& options) GRPC_OVERRIDE {
328 CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage> ops;
329 if (!ops.SendMessage(msg, options).ok()) {
330 return false;
331 }
332 if (!ctx_->sent_initial_metadata_) {
333 ops.SendInitialMetadata(ctx_->initial_metadata_);
334 ctx_->sent_initial_metadata_ = true;
335 }
336 call_->PerformOps(&ops);
337 return call_->cq()->Pluck(&ops);
338 }
339
340 private:
341 Call* const call_;
342 ServerContext* const ctx_;
343 };
344
345 // Server-side interface for bi-directional streaming.
346 template <class W, class R>
347 class ServerReaderWriter GRPC_FINAL : public WriterInterface<W>,
348 public ReaderInterface<R> {
349 public:
350 ServerReaderWriter(Call* call, ServerContext* ctx) : call_(call), ctx_(ctx) {}
351
352 void SendInitialMetadata() {
353 GPR_ASSERT(!ctx_->sent_initial_metadata_);
354
355 CallOpSet<CallOpSendInitialMetadata> ops;
356 ops.SendInitialMetadata(ctx_->initial_metadata_);
357 ctx_->sent_initial_metadata_ = true;
358 call_->PerformOps(&ops);
359 call_->cq()->Pluck(&ops);
360 }
361
362 bool Read(R* msg) GRPC_OVERRIDE {
363 CallOpSet<CallOpRecvMessage<R>> ops;
364 ops.RecvMessage(msg);
365 call_->PerformOps(&ops);
366 return call_->cq()->Pluck(&ops) && ops.got_message;
367 }
368
369 using WriterInterface<W>::Write;
370 bool Write(const W& msg, const WriteOptions& options) GRPC_OVERRIDE {
371 CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage> ops;
372 if (!ops.SendMessage(msg, options).ok()) {
373 return false;
374 }
375 if (!ctx_->sent_initial_metadata_) {
376 ops.SendInitialMetadata(ctx_->initial_metadata_);
377 ctx_->sent_initial_metadata_ = true;
378 }
379 call_->PerformOps(&ops);
380 return call_->cq()->Pluck(&ops);
381 }
382
383 private:
384 Call* const call_;
385 ServerContext* const ctx_;
386 };
387
388 // Async interfaces
389 // Common interface for all client side streaming.
390 class ClientAsyncStreamingInterface {
391 public:
392 virtual ~ClientAsyncStreamingInterface() {}
393
394 virtual void ReadInitialMetadata(void* tag) = 0;
395
396 virtual void Finish(Status* status, void* tag) = 0;
397 };
398
399 // An interface that yields a sequence of R messages.
400 template <class R>
401 class AsyncReaderInterface {
402 public:
403 virtual ~AsyncReaderInterface() {}
404
405 virtual void Read(R* msg, void* tag) = 0;
406 };
407
408 // An interface that can be fed a sequence of W messages.
409 template <class W>
410 class AsyncWriterInterface {
411 public:
412 virtual ~AsyncWriterInterface() {}
413
414 virtual void Write(const W& msg, void* tag) = 0;
415 };
416
417 template <class R>
418 class ClientAsyncReaderInterface : public ClientAsyncStreamingInterface,
419 public AsyncReaderInterface<R> {};
420
421 template <class R>
422 class ClientAsyncReader GRPC_FINAL : public ClientAsyncReaderInterface<R> {
423 public:
424 // Create a stream and write the first request out.
425 template <class W>
426 ClientAsyncReader(ChannelInterface* channel, CompletionQueue* cq,
427 const RpcMethod& method, ClientContext* context,
428 const W& request, void* tag)
429 : context_(context), call_(channel->CreateCall(method, context, cq)) {
430 init_ops_.set_output_tag(tag);
431 init_ops_.SendInitialMetadata(context->send_initial_metadata_);
432 // TODO(ctiller): don't assert
433 GPR_ASSERT(init_ops_.SendMessage(request).ok());
434 init_ops_.ClientSendClose();
435 call_.PerformOps(&init_ops_);
436 }
437
438 void ReadInitialMetadata(void* tag) GRPC_OVERRIDE {
439 GPR_ASSERT(!context_->initial_metadata_received_);
440
441 meta_ops_.set_output_tag(tag);
442 meta_ops_.RecvInitialMetadata(context_);
443 call_.PerformOps(&meta_ops_);
444 }
445
446 void Read(R* msg, void* tag) GRPC_OVERRIDE {
447 read_ops_.set_output_tag(tag);
448 if (!context_->initial_metadata_received_) {
449 read_ops_.RecvInitialMetadata(context_);
450 }
451 read_ops_.RecvMessage(msg);
452 call_.PerformOps(&read_ops_);
453 }
454
455 void Finish(Status* status, void* tag) GRPC_OVERRIDE {
456 finish_ops_.set_output_tag(tag);
457 if (!context_->initial_metadata_received_) {
458 finish_ops_.RecvInitialMetadata(context_);
459 }
460 finish_ops_.ClientRecvStatus(context_, status);
461 call_.PerformOps(&finish_ops_);
462 }
463
464 private:
465 ClientContext* context_;
466 Call call_;
467 CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage, CallOpClientSendClose>
468 init_ops_;
469 CallOpSet<CallOpRecvInitialMetadata> meta_ops_;
470 CallOpSet<CallOpRecvInitialMetadata, CallOpRecvMessage<R>> read_ops_;
471 CallOpSet<CallOpRecvInitialMetadata, CallOpClientRecvStatus> finish_ops_;
472 };
473
474 template <class W>
475 class ClientAsyncWriterInterface : public ClientAsyncStreamingInterface,
476 public AsyncWriterInterface<W> {
477 public:
478 virtual void WritesDone(void* tag) = 0;
479 };
480
481 template <class W>
482 class ClientAsyncWriter GRPC_FINAL : public ClientAsyncWriterInterface<W> {
483 public:
484 template <class R>
485 ClientAsyncWriter(ChannelInterface* channel, CompletionQueue* cq,
486 const RpcMethod& method, ClientContext* context,
487 R* response, void* tag)
488 : context_(context), call_(channel->CreateCall(method, context, cq)) {
489 finish_ops_.RecvMessage(response);
490
491 init_ops_.set_output_tag(tag);
492 init_ops_.SendInitialMetadata(context->send_initial_metadata_);
493 call_.PerformOps(&init_ops_);
494 }
495
496 void ReadInitialMetadata(void* tag) GRPC_OVERRIDE {
497 GPR_ASSERT(!context_->initial_metadata_received_);
498
499 meta_ops_.set_output_tag(tag);
500 meta_ops_.RecvInitialMetadata(context_);
501 call_.PerformOps(&meta_ops_);
502 }
503
504 void Write(const W& msg, void* tag) GRPC_OVERRIDE {
505 write_ops_.set_output_tag(tag);
506 // TODO(ctiller): don't assert
507 GPR_ASSERT(write_ops_.SendMessage(msg).ok());
508 call_.PerformOps(&write_ops_);
509 }
510
511 void WritesDone(void* tag) GRPC_OVERRIDE {
512 writes_done_ops_.set_output_tag(tag);
513 writes_done_ops_.ClientSendClose();
514 call_.PerformOps(&writes_done_ops_);
515 }
516
517 void Finish(Status* status, void* tag) GRPC_OVERRIDE {
518 finish_ops_.set_output_tag(tag);
519 if (!context_->initial_metadata_received_) {
520 finish_ops_.RecvInitialMetadata(context_);
521 }
522 finish_ops_.ClientRecvStatus(context_, status);
523 call_.PerformOps(&finish_ops_);
524 }
525
526 private:
527 ClientContext* context_;
528 Call call_;
529 CallOpSet<CallOpSendInitialMetadata> init_ops_;
530 CallOpSet<CallOpRecvInitialMetadata> meta_ops_;
531 CallOpSet<CallOpSendMessage> write_ops_;
532 CallOpSet<CallOpClientSendClose> writes_done_ops_;
533 CallOpSet<CallOpRecvInitialMetadata, CallOpGenericRecvMessage,
534 CallOpClientRecvStatus> finish_ops_;
535 };
536
537 // Client-side interface for bi-directional streaming.
538 template <class W, class R>
539 class ClientAsyncReaderWriterInterface : public ClientAsyncStreamingInterface,
540 public AsyncWriterInterface<W>,
541 public AsyncReaderInterface<R> {
542 public:
543 virtual void WritesDone(void* tag) = 0;
544 };
545
546 template <class W, class R>
547 class ClientAsyncReaderWriter GRPC_FINAL
548 : public ClientAsyncReaderWriterInterface<W, R> {
549 public:
550 ClientAsyncReaderWriter(ChannelInterface* channel, CompletionQueue* cq,
551 const RpcMethod& method, ClientContext* context,
552 void* tag)
553 : context_(context), call_(channel->CreateCall(method, context, cq)) {
554 init_ops_.set_output_tag(tag);
555 init_ops_.SendInitialMetadata(context->send_initial_metadata_);
556 call_.PerformOps(&init_ops_);
557 }
558
559 void ReadInitialMetadata(void* tag) GRPC_OVERRIDE {
560 GPR_ASSERT(!context_->initial_metadata_received_);
561
562 meta_ops_.set_output_tag(tag);
563 meta_ops_.RecvInitialMetadata(context_);
564 call_.PerformOps(&meta_ops_);
565 }
566
567 void Read(R* msg, void* tag) GRPC_OVERRIDE {
568 read_ops_.set_output_tag(tag);
569 if (!context_->initial_metadata_received_) {
570 read_ops_.RecvInitialMetadata(context_);
571 }
572 read_ops_.RecvMessage(msg);
573 call_.PerformOps(&read_ops_);
574 }
575
576 void Write(const W& msg, void* tag) GRPC_OVERRIDE {
577 write_ops_.set_output_tag(tag);
578 // TODO(ctiller): don't assert
579 GPR_ASSERT(write_ops_.SendMessage(msg).ok());
580 call_.PerformOps(&write_ops_);
581 }
582
583 void WritesDone(void* tag) GRPC_OVERRIDE {
584 writes_done_ops_.set_output_tag(tag);
585 writes_done_ops_.ClientSendClose();
586 call_.PerformOps(&writes_done_ops_);
587 }
588
589 void Finish(Status* status, void* tag) GRPC_OVERRIDE {
590 finish_ops_.set_output_tag(tag);
591 if (!context_->initial_metadata_received_) {
592 finish_ops_.RecvInitialMetadata(context_);
593 }
594 finish_ops_.ClientRecvStatus(context_, status);
595 call_.PerformOps(&finish_ops_);
596 }
597
598 private:
599 ClientContext* context_;
600 Call call_;
601 CallOpSet<CallOpSendInitialMetadata> init_ops_;
602 CallOpSet<CallOpRecvInitialMetadata> meta_ops_;
603 CallOpSet<CallOpRecvInitialMetadata, CallOpRecvMessage<R>> read_ops_;
604 CallOpSet<CallOpSendMessage> write_ops_;
605 CallOpSet<CallOpClientSendClose> writes_done_ops_;
606 CallOpSet<CallOpRecvInitialMetadata, CallOpClientRecvStatus> finish_ops_;
607 };
608
609 template <class W, class R>
610 class ServerAsyncReader GRPC_FINAL : public ServerAsyncStreamingInterface,
611 public AsyncReaderInterface<R> {
612 public:
613 explicit ServerAsyncReader(ServerContext* ctx)
614 : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
615
616 void SendInitialMetadata(void* tag) GRPC_OVERRIDE {
617 GPR_ASSERT(!ctx_->sent_initial_metadata_);
618
619 meta_ops_.set_output_tag(tag);
620 meta_ops_.SendInitialMetadata(ctx_->initial_metadata_);
621 ctx_->sent_initial_metadata_ = true;
622 call_.PerformOps(&meta_ops_);
623 }
624
625 void Read(R* msg, void* tag) GRPC_OVERRIDE {
626 read_ops_.set_output_tag(tag);
627 read_ops_.RecvMessage(msg);
628 call_.PerformOps(&read_ops_);
629 }
630
631 void Finish(const W& msg, const Status& status, void* tag) {
632 finish_ops_.set_output_tag(tag);
633 if (!ctx_->sent_initial_metadata_) {
634 finish_ops_.SendInitialMetadata(ctx_->initial_metadata_);
635 ctx_->sent_initial_metadata_ = true;
636 }
637 // The response is dropped if the status is not OK.
638 if (status.ok()) {
639 finish_ops_.ServerSendStatus(
640 ctx_->trailing_metadata_,
641 finish_ops_.SendMessage(msg));
642 } else {
643 finish_ops_.ServerSendStatus(ctx_->trailing_metadata_, status);
644 }
645 call_.PerformOps(&finish_ops_);
646 }
647
648 void FinishWithError(const Status& status, void* tag) {
649 GPR_ASSERT(!status.ok());
650 finish_ops_.set_output_tag(tag);
651 if (!ctx_->sent_initial_metadata_) {
652 finish_ops_.SendInitialMetadata(ctx_->initial_metadata_);
653 ctx_->sent_initial_metadata_ = true;
654 }
655 finish_ops_.ServerSendStatus(ctx_->trailing_metadata_, status);
656 call_.PerformOps(&finish_ops_);
657 }
658
659 private:
660 void BindCall(Call* call) GRPC_OVERRIDE { call_ = *call; }
661
662 Call call_;
663 ServerContext* ctx_;
664 CallOpSet<CallOpSendInitialMetadata> meta_ops_;
665 CallOpSet<CallOpRecvMessage<R>> read_ops_;
666 CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage,
667 CallOpServerSendStatus> finish_ops_;
668 };
669
670 template <class W>
671 class ServerAsyncWriter GRPC_FINAL : public ServerAsyncStreamingInterface,
672 public AsyncWriterInterface<W> {
673 public:
674 explicit ServerAsyncWriter(ServerContext* ctx)
675 : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
676
677 void SendInitialMetadata(void* tag) GRPC_OVERRIDE {
678 GPR_ASSERT(!ctx_->sent_initial_metadata_);
679
680 meta_ops_.set_output_tag(tag);
681 meta_ops_.SendInitialMetadata(ctx_->initial_metadata_);
682 ctx_->sent_initial_metadata_ = true;
683 call_.PerformOps(&meta_ops_);
684 }
685
686 void Write(const W& msg, void* tag) GRPC_OVERRIDE {
687 write_ops_.set_output_tag(tag);
688 if (!ctx_->sent_initial_metadata_) {
689 write_ops_.SendInitialMetadata(ctx_->initial_metadata_);
690 ctx_->sent_initial_metadata_ = true;
691 }
692 // TODO(ctiller): don't assert
693 GPR_ASSERT(write_ops_.SendMessage(msg).ok());
694 call_.PerformOps(&write_ops_);
695 }
696
697 void Finish(const Status& status, void* tag) {
698 finish_ops_.set_output_tag(tag);
699 if (!ctx_->sent_initial_metadata_) {
700 finish_ops_.SendInitialMetadata(ctx_->initial_metadata_);
701 ctx_->sent_initial_metadata_ = true;
702 }
703 finish_ops_.ServerSendStatus(ctx_->trailing_metadata_, status);
704 call_.PerformOps(&finish_ops_);
705 }
706
707 private:
708 void BindCall(Call* call) GRPC_OVERRIDE { call_ = *call; }
709
710 Call call_;
711 ServerContext* ctx_;
712 CallOpSet<CallOpSendInitialMetadata> meta_ops_;
713 CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage> write_ops_;
714 CallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus> finish_ops_;
715 };
716
717 // Server-side interface for bi-directional streaming.
718 template <class W, class R>
719 class ServerAsyncReaderWriter GRPC_FINAL : public ServerAsyncStreamingInterface,
720 public AsyncWriterInterface<W>,
721 public AsyncReaderInterface<R> {
722 public:
723 explicit ServerAsyncReaderWriter(ServerContext* ctx)
724 : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
725
726 void SendInitialMetadata(void* tag) GRPC_OVERRIDE {
727 GPR_ASSERT(!ctx_->sent_initial_metadata_);
728
729 meta_ops_.set_output_tag(tag);
730 meta_ops_.SendInitialMetadata(ctx_->initial_metadata_);
731 ctx_->sent_initial_metadata_ = true;
732 call_.PerformOps(&meta_ops_);
733 }
734
735 void Read(R* msg, void* tag) GRPC_OVERRIDE {
736 read_ops_.set_output_tag(tag);
737 read_ops_.RecvMessage(msg);
738 call_.PerformOps(&read_ops_);
739 }
740
741 void Write(const W& msg, void* tag) GRPC_OVERRIDE {
742 write_ops_.set_output_tag(tag);
743 if (!ctx_->sent_initial_metadata_) {
744 write_ops_.SendInitialMetadata(ctx_->initial_metadata_);
745 ctx_->sent_initial_metadata_ = true;
746 }
747 // TODO(ctiller): don't assert
748 GPR_ASSERT(write_ops_.SendMessage(msg).ok());
749 call_.PerformOps(&write_ops_);
750 }
751
752 void Finish(const Status& status, void* tag) {
753 finish_ops_.set_output_tag(tag);
754 if (!ctx_->sent_initial_metadata_) {
755 finish_ops_.SendInitialMetadata(ctx_->initial_metadata_);
756 ctx_->sent_initial_metadata_ = true;
757 }
758 finish_ops_.ServerSendStatus(ctx_->trailing_metadata_, status);
759 call_.PerformOps(&finish_ops_);
760 }
761
762 private:
763 void BindCall(Call* call) GRPC_OVERRIDE { call_ = *call; }
764
765 Call call_;
766 ServerContext* ctx_;
767 CallOpSet<CallOpSendInitialMetadata> meta_ops_;
768 CallOpSet<CallOpRecvMessage<R>> read_ops_;
769 CallOpSet<CallOpSendInitialMetadata, CallOpSendMessage> write_ops_;
770 CallOpSet<CallOpSendInitialMetadata, CallOpServerSendStatus> finish_ops_;
771 };
772
773 } // namespace grpc
774
775 #endif // GRPCXX_STREAM_H
grpc::ClientAsyncStreamingInterface
Definition: stream.h:390
grpc::ClientAsyncReaderWriter
Definition: client_context.h:70
grpc::ClientReader
Definition: client_context.h:60
grpc::ClientReaderWriter::Read
bool Read(R *msg) GRPC_OVERRIDE
Definition: stream.h:244
grpc::ClientWriterInterface
Definition: stream.h:153
grpc::ClientAsyncWriter::Write
void Write(const W &msg, void *tag) GRPC_OVERRIDE
Definition: stream.h:504
grpc::ServerAsyncReaderWriter::Read
void Read(R *msg, void *tag) GRPC_OVERRIDE
Definition: stream.h:735
grpc::ClientAsyncWriter::WritesDone
void WritesDone(void *tag) GRPC_OVERRIDE
Definition: stream.h:511
grpc::ClientReaderWriterInterface::WaitForInitialMetadata
virtual void WaitForInitialMetadata()=0
completion_queue.h
grpc::Call::cq
CompletionQueue * cq()
Definition: call.h:575
grpc::ServerReaderWriter::SendInitialMetadata
void SendInitialMetadata()
Definition: stream.h:352
grpc::ClientReaderInterface
Definition: stream.h:90
grpc::ServerWriter::SendInitialMetadata
void SendInitialMetadata()
Definition: stream.h:316
grpc::ServerReaderWriter::ServerReaderWriter
ServerReaderWriter(Call *call, ServerContext *ctx)
Definition: stream.h:350
grpc::ServerAsyncWriter::SendInitialMetadata
void SendInitialMetadata(void *tag) GRPC_OVERRIDE
Definition: stream.h:677
grpc::ReaderInterface
Definition: stream.h:63
grpc::ServerReader::SendInitialMetadata
void SendInitialMetadata()
Definition: stream.h:289
grpc::ClientAsyncReaderWriterInterface::WritesDone
virtual void WritesDone(void *tag)=0
grpc::CallOpClientRecvStatus
Definition: call.h:431
grpc::AsyncWriterInterface::Write
virtual void Write(const W &msg, void *tag)=0
grpc::ReaderInterface::~ReaderInterface
virtual ~ReaderInterface()
Definition: stream.h:65
grpc::ServerAsyncWriter::Write
void Write(const W &msg, void *tag) GRPC_OVERRIDE
Definition: stream.h:686
channel_interface.h
GRPC_FINAL
#define GRPC_FINAL
Definition: config.h:71
grpc::ClientAsyncReaderWriter::Write
void Write(const W &msg, void *tag) GRPC_OVERRIDE
Definition: stream.h:576
grpc::ServerAsyncReader::Read
void Read(R *msg, void *tag) GRPC_OVERRIDE
Definition: stream.h:625
grpc::ServerAsyncReaderWriter::SendInitialMetadata
void SendInitialMetadata(void *tag) GRPC_OVERRIDE
Definition: stream.h:726
grpc::ServerWriter::Write
bool Write(const W &msg, const WriteOptions &options) GRPC_OVERRIDE
Definition: stream.h:327
grpc::ClientReader::Finish
Status Finish() GRPC_OVERRIDE
Definition: stream.h:137
grpc::ClientAsyncWriterInterface::WritesDone
virtual void WritesDone(void *tag)=0
grpc::ClientContext
Definition: client_context.h:74
grpc::ClientReaderWriter::Finish
Status Finish() GRPC_OVERRIDE
Definition: stream.h:269
grpc::ServerAsyncReader::FinishWithError
void FinishWithError(const Status &status, void *tag)
Definition: stream.h:648
grpc::ClientAsyncWriter::ClientAsyncWriter
ClientAsyncWriter(ChannelInterface *channel, CompletionQueue *cq, const RpcMethod &method, ClientContext *context, R *response, void *tag)
Definition: stream.h:485
grpc::ServerAsyncReaderWriter::Write
void Write(const W &msg, void *tag) GRPC_OVERRIDE
Definition: stream.h:741
grpc::CallOpSendMessage
Definition: call.h:190
grpc::ServerReader::ServerReader
ServerReader(Call *call, ServerContext *ctx)
Definition: stream.h:287
grpc::ClientWriter::WritesDone
bool WritesDone() GRPC_OVERRIDE
Definition: stream.h:185
grpc::AsyncReaderInterface::~AsyncReaderInterface
virtual ~AsyncReaderInterface()
Definition: stream.h:403
grpc::ClientWriter::Write
bool Write(const W &msg, const WriteOptions &options) GRPC_OVERRIDE
Definition: stream.h:176
grpc::CallOpClientSendClose
Definition: call.h:341
grpc::ClientStreamingInterface::~ClientStreamingInterface
virtual ~ClientStreamingInterface()
Definition: stream.h:51
grpc::ClientAsyncReaderInterface
Definition: stream.h:418
grpc::ClientReader::ClientReader
ClientReader(ChannelInterface *channel, const RpcMethod &method, ClientContext *context, const W &request)
Definition: stream.h:101
grpc::ServerReaderWriter::Read
bool Read(R *msg) GRPC_OVERRIDE
Definition: stream.h:362
grpc::ClientAsyncReaderWriter::WritesDone
void WritesDone(void *tag) GRPC_OVERRIDE
Definition: stream.h:583
grpc::ClientWriter::Finish
Status Finish() GRPC_OVERRIDE
Definition: stream.h:193
grpc::Call
Definition: call.h:565
grpc::ClientAsyncReaderWriterInterface
Definition: stream.h:539
grpc::ClientReader::Read
bool Read(R *msg) GRPC_OVERRIDE
Definition: stream.h:127
grpc::ClientWriterInterface::WritesDone
virtual bool WritesDone()=0
grpc::ChannelInterface
Definition: channel_interface.h:52
grpc::ServerAsyncWriter::ServerAsyncWriter
ServerAsyncWriter(ServerContext *ctx)
Definition: stream.h:674
grpc::ClientAsyncReaderWriter::Finish
void Finish(Status *status, void *tag) GRPC_OVERRIDE
Definition: stream.h:589
grpc::ClientAsyncWriter::ReadInitialMetadata
void ReadInitialMetadata(void *tag) GRPC_OVERRIDE
Definition: stream.h:496
grpc::AsyncWriterInterface
Definition: stream.h:410
call.h
grpc::ClientAsyncWriter
Definition: client_context.h:68
grpc::CallOpSet
Primary implementaiton of CallOpSetInterface.
Definition: call.h:506
grpc::CallOpClientSendClose::ClientSendClose
void ClientSendClose()
Definition: call.h:345
grpc::ServerContext
Definition: server_context.h:86
grpc::ServerAsyncReader::Finish
void Finish(const W &msg, const Status &status, void *tag)
Definition: stream.h:631
grpc::WriteOptions
Per-message write options.
Definition: call.h:64
grpc::ClientReaderInterface::WaitForInitialMetadata
virtual void WaitForInitialMetadata()=0
grpc::ClientReaderWriterInterface::WritesDone
virtual bool WritesDone()=0
grpc::WriterInterface::Write
bool Write(const W &msg)
Definition: stream.h:84
grpc::CompletionQueue
Definition: completion_queue.h:87
grpc::ClientAsyncStreamingInterface::~ClientAsyncStreamingInterface
virtual ~ClientAsyncStreamingInterface()
Definition: stream.h:392
grpc::ClientAsyncReaderWriter::ClientAsyncReaderWriter
ClientAsyncReaderWriter(ChannelInterface *channel, CompletionQueue *cq, const RpcMethod &method, ClientContext *context, void *tag)
Definition: stream.h:550
grpc::ClientAsyncWriter::Finish
void Finish(Status *status, void *tag) GRPC_OVERRIDE
Definition: stream.h:517
grpc::ServerAsyncWriter::Finish
void Finish(const Status &status, void *tag)
Definition: stream.h:697
status.h
grpc::ClientAsyncStreamingInterface::ReadInitialMetadata
virtual void ReadInitialMetadata(void *tag)=0
grpc::RpcMethod
Definition: rpc_method.h:39
grpc::ClientStreamingInterface::Finish
virtual Status Finish()=0
client_context.h
grpc::ServerReaderWriter::Write
bool Write(const W &msg, const WriteOptions &options) GRPC_OVERRIDE
Definition: stream.h:370
grpc::ClientAsyncReader::Finish
void Finish(Status *status, void *tag) GRPC_OVERRIDE
Definition: stream.h:455
grpc::Call::PerformOps
void PerformOps(CallOpSetInterface *ops)
grpc::WriterInterface
Definition: stream.h:76
grpc::Status::ok
bool ok() const
Definition: status.h:55
service_type.h
grpc::ClientReaderWriter::ClientReaderWriter
ClientReaderWriter(ChannelInterface *channel, const RpcMethod &method, ClientContext *context)
Definition: stream.h:222
grpc::ClientReaderWriterInterface
Definition: stream.h:210
grpc::Status
Definition: status.h:42
grpc::ReaderInterface::Read
virtual bool Read(R *msg)=0
grpc::ClientStreamingInterface
Definition: stream.h:49
grpc::ClientAsyncStreamingInterface::Finish
virtual void Finish(Status *status, void *tag)=0
grpc::ServerAsyncReader::SendInitialMetadata
void SendInitialMetadata(void *tag) GRPC_OVERRIDE
Definition: stream.h:616
grpc::ServerWriter::ServerWriter
ServerWriter(Call *call, ServerContext *ctx)
Definition: stream.h:314
grpc::CallOpSendInitialMetadata
Definition: call.h:159
grpc::ClientReaderWriter::WaitForInitialMetadata
void WaitForInitialMetadata()
Definition: stream.h:235
grpc::ServerReader::Read
bool Read(R *msg) GRPC_OVERRIDE
Definition: stream.h:299
grpc::ClientAsyncReader::Read
void Read(R *msg, void *tag) GRPC_OVERRIDE
Definition: stream.h:446
grpc::WriterInterface::Write
virtual bool Write(const W &msg, const WriteOptions &options)=0
grpc::ClientAsyncReaderWriter::Read
void Read(R *msg, void *tag) GRPC_OVERRIDE
Definition: stream.h:567
grpc::ClientReaderWriter
Definition: client_context.h:64
grpc::ServerAsyncReaderWriter::ServerAsyncReaderWriter
ServerAsyncReaderWriter(ServerContext *ctx)
Definition: stream.h:723
grpc::ClientAsyncReader
Definition: client_context.h:66
grpc::AsyncWriterInterface::~AsyncWriterInterface
virtual ~AsyncWriterInterface()
Definition: stream.h:412
grpc::ServerAsyncReaderWriter::Finish
void Finish(const Status &status, void *tag)
Definition: stream.h:752
grpc::ClientReader::WaitForInitialMetadata
void WaitForInitialMetadata()
Definition: stream.h:118
GRPC_OVERRIDE
#define GRPC_OVERRIDE
Definition: config.h:77
grpc::ClientAsyncReaderWriter::ReadInitialMetadata
void ReadInitialMetadata(void *tag) GRPC_OVERRIDE
Definition: stream.h:559
grpc::ClientWriter
Definition: client_context.h:62
grpc::CallOpRecvInitialMetadata
Definition: call.h:402
grpc::ClientAsyncReader::ClientAsyncReader
ClientAsyncReader(ChannelInterface *channel, CompletionQueue *cq, const RpcMethod &method, ClientContext *context, const W &request, void *tag)
Definition: stream.h:426
grpc::ClientWriter::ClientWriter
ClientWriter(ChannelInterface *channel, const RpcMethod &method, ClientContext *context, R *response)
Definition: stream.h:164
grpc::ClientReaderWriter::Write
bool Write(const W &msg, const WriteOptions &options) GRPC_OVERRIDE
Definition: stream.h:255
grpc::AsyncReaderInterface::Read
virtual void Read(R *msg, void *tag)=0
grpc::WriterInterface::~WriterInterface
virtual ~WriterInterface()
Definition: stream.h:78
grpc::CallOpGenericRecvMessage
Definition: call.h:298
server_context.h
grpc::ServerAsyncReader::ServerAsyncReader
ServerAsyncReader(ServerContext *ctx)
Definition: stream.h:613
grpc::AsyncReaderInterface
Definition: stream.h:401
grpc::ClientReaderWriter::WritesDone
bool WritesDone() GRPC_OVERRIDE
Definition: stream.h:262
grpc::ClientAsyncReader::ReadInitialMetadata
void ReadInitialMetadata(void *tag) GRPC_OVERRIDE
Definition: stream.h:438
grpc::ClientAsyncWriterInterface
Definition: stream.h:475