async_stream.h 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069
  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. #ifndef GRPCPP_IMPL_CODEGEN_ASYNC_STREAM_H
  19. #define GRPCPP_IMPL_CODEGEN_ASYNC_STREAM_H
  20. #include <grpcpp/impl/codegen/call.h>
  21. #include <grpcpp/impl/codegen/channel_interface.h>
  22. #include <grpcpp/impl/codegen/core_codegen_interface.h>
  23. #include <grpcpp/impl/codegen/server_context.h>
  24. #include <grpcpp/impl/codegen/service_type.h>
  25. #include <grpcpp/impl/codegen/status.h>
  26. namespace grpc {
  27. class CompletionQueue;
  28. namespace internal {
  29. /// Common interface for all client side asynchronous streaming.
  30. class ClientAsyncStreamingInterface {
  31. public:
  32. virtual ~ClientAsyncStreamingInterface() {}
  33. /// Start the call that was set up by the constructor, but only if the
  34. /// constructor was invoked through the "Prepare" API which doesn't actually
  35. /// start the call
  36. virtual void StartCall(void* tag) = 0;
  37. /// Request notification of the reading of the initial metadata. Completion
  38. /// will be notified by \a tag on the associated completion queue.
  39. /// This call is optional, but if it is used, it cannot be used concurrently
  40. /// with or after the \a AsyncReaderInterface::Read method.
  41. ///
  42. /// \param[in] tag Tag identifying this request.
  43. virtual void ReadInitialMetadata(void* tag) = 0;
  44. /// Indicate that the stream is to be finished and request notification for
  45. /// when the call has been ended.
  46. /// Should not be used concurrently with other operations.
  47. ///
  48. /// It is appropriate to call this method when both:
  49. /// * the client side has no more message to send
  50. /// (this can be declared implicitly by calling this method, or
  51. /// explicitly through an earlier call to the <i>WritesDone</i> method
  52. /// of the class in use, e.g. \a ClientAsyncWriterInterface::WritesDone or
  53. /// \a ClientAsyncReaderWriterInterface::WritesDone).
  54. /// * there are no more messages to be received from the server (this can
  55. /// be known implicitly by the calling code, or explicitly from an
  56. /// earlier call to \a AsyncReaderInterface::Read that yielded a failed
  57. /// result, e.g. cq->Next(&read_tag, &ok) filled in 'ok' with 'false').
  58. ///
  59. /// This function will return when either:
  60. /// - all incoming messages have been read and the server has returned
  61. /// a status.
  62. /// - the server has returned a non-OK status.
  63. /// - the call failed for some reason and the library generated a
  64. /// status.
  65. ///
  66. /// Note that implementations of this method attempt to receive initial
  67. /// metadata from the server if initial metadata hasn't yet been received.
  68. ///
  69. /// \param[in] tag Tag identifying this request.
  70. /// \param[out] status To be updated with the operation status.
  71. virtual void Finish(Status* status, void* tag) = 0;
  72. };
  73. /// An interface that yields a sequence of messages of type \a R.
  74. template <class R>
  75. class AsyncReaderInterface {
  76. public:
  77. virtual ~AsyncReaderInterface() {}
  78. /// Read a message of type \a R into \a msg. Completion will be notified by \a
  79. /// tag on the associated completion queue.
  80. /// This is thread-safe with respect to \a Write or \a WritesDone methods. It
  81. /// should not be called concurrently with other streaming APIs
  82. /// on the same stream. It is not meaningful to call it concurrently
  83. /// with another \a AsyncReaderInterface::Read on the same stream since reads
  84. /// on the same stream are delivered in order.
  85. ///
  86. /// \param[out] msg Where to eventually store the read message.
  87. /// \param[in] tag The tag identifying the operation.
  88. ///
  89. /// Side effect: note that this method attempt to receive initial metadata for
  90. /// a stream if it hasn't yet been received.
  91. virtual void Read(R* msg, void* tag) = 0;
  92. };
  93. /// An interface that can be fed a sequence of messages of type \a W.
  94. template <class W>
  95. class AsyncWriterInterface {
  96. public:
  97. virtual ~AsyncWriterInterface() {}
  98. /// Request the writing of \a msg with identifying tag \a tag.
  99. ///
  100. /// Only one write may be outstanding at any given time. This means that
  101. /// after calling Write, one must wait to receive \a tag from the completion
  102. /// queue BEFORE calling Write again.
  103. /// This is thread-safe with respect to \a AsyncReaderInterface::Read
  104. ///
  105. /// \param[in] msg The message to be written.
  106. /// \param[in] tag The tag identifying the operation.
  107. virtual void Write(const W& msg, void* tag) = 0;
  108. /// Request the writing of \a msg using WriteOptions \a options with
  109. /// identifying tag \a tag.
  110. ///
  111. /// Only one write may be outstanding at any given time. This means that
  112. /// after calling Write, one must wait to receive \a tag from the completion
  113. /// queue BEFORE calling Write again.
  114. /// WriteOptions \a options is used to set the write options of this message.
  115. /// This is thread-safe with respect to \a AsyncReaderInterface::Read
  116. ///
  117. /// \param[in] msg The message to be written.
  118. /// \param[in] options The WriteOptions to be used to write this message.
  119. /// \param[in] tag The tag identifying the operation.
  120. virtual void Write(const W& msg, WriteOptions options, void* tag) = 0;
  121. /// Request the writing of \a msg and coalesce it with the writing
  122. /// of trailing metadata, using WriteOptions \a options with
  123. /// identifying tag \a tag.
  124. ///
  125. /// For client, WriteLast is equivalent of performing Write and
  126. /// WritesDone in a single step.
  127. /// For server, WriteLast buffers the \a msg. The writing of \a msg is held
  128. /// until Finish is called, where \a msg and trailing metadata are coalesced
  129. /// and write is initiated. Note that WriteLast can only buffer \a msg up to
  130. /// the flow control window size. If \a msg size is larger than the window
  131. /// size, it will be sent on wire without buffering.
  132. ///
  133. /// \param[in] msg The message to be written.
  134. /// \param[in] options The WriteOptions to be used to write this message.
  135. /// \param[in] tag The tag identifying the operation.
  136. void WriteLast(const W& msg, WriteOptions options, void* tag) {
  137. Write(msg, options.set_last_message(), tag);
  138. }
  139. };
  140. } // namespace internal
  141. template <class R>
  142. class ClientAsyncReaderInterface
  143. : public internal::ClientAsyncStreamingInterface,
  144. public internal::AsyncReaderInterface<R> {};
  145. namespace internal {
  146. template <class R>
  147. class ClientAsyncReaderFactory {
  148. public:
  149. /// Create a stream object.
  150. /// Write the first request out if \a start is set.
  151. /// \a tag will be notified on \a cq when the call has been started and
  152. /// \a request has been written out. If \a start is not set, \a tag must be
  153. /// nullptr and the actual call must be initiated by StartCall
  154. /// Note that \a context will be used to fill in custom initial metadata
  155. /// used to send to the server when starting the call.
  156. template <class W>
  157. static ClientAsyncReader<R>* Create(ChannelInterface* channel,
  158. CompletionQueue* cq,
  159. const ::grpc::internal::RpcMethod& method,
  160. ClientContext* context, const W& request,
  161. bool start, void* tag) {
  162. ::grpc::internal::Call call = channel->CreateCall(method, context, cq);
  163. return new (g_core_codegen_interface->grpc_call_arena_alloc(
  164. call.call(), sizeof(ClientAsyncReader<R>)))
  165. ClientAsyncReader<R>(call, context, request, start, tag);
  166. }
  167. };
  168. } // namespace internal
  169. /// Async client-side API for doing server-streaming RPCs,
  170. /// where the incoming message stream coming from the server has
  171. /// messages of type \a R.
  172. template <class R>
  173. class ClientAsyncReader final : public ClientAsyncReaderInterface<R> {
  174. public:
  175. // always allocated against a call arena, no memory free required
  176. static void operator delete(void* ptr, std::size_t size) {
  177. assert(size == sizeof(ClientAsyncReader));
  178. }
  179. void StartCall(void* tag) override {
  180. assert(!started_);
  181. started_ = true;
  182. StartCallInternal(tag);
  183. }
  184. /// See the \a ClientAsyncStreamingInterface.ReadInitialMetadata
  185. /// method for semantics.
  186. ///
  187. /// Side effect:
  188. /// - upon receiving initial metadata from the server,
  189. /// the \a ClientContext associated with this call is updated, and the
  190. /// calling code can access the received metadata through the
  191. /// \a ClientContext.
  192. void ReadInitialMetadata(void* tag) override {
  193. assert(started_);
  194. GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
  195. meta_ops_.set_output_tag(tag);
  196. meta_ops_.RecvInitialMetadata(context_);
  197. call_.PerformOps(&meta_ops_);
  198. }
  199. void Read(R* msg, void* tag) override {
  200. assert(started_);
  201. read_ops_.set_output_tag(tag);
  202. if (!context_->initial_metadata_received_) {
  203. read_ops_.RecvInitialMetadata(context_);
  204. }
  205. read_ops_.RecvMessage(msg);
  206. call_.PerformOps(&read_ops_);
  207. }
  208. /// See the \a ClientAsyncStreamingInterface.Finish method for semantics.
  209. ///
  210. /// Side effect:
  211. /// - the \a ClientContext associated with this call is updated with
  212. /// possible initial and trailing metadata received from the server.
  213. void Finish(Status* status, void* tag) override {
  214. assert(started_);
  215. finish_ops_.set_output_tag(tag);
  216. if (!context_->initial_metadata_received_) {
  217. finish_ops_.RecvInitialMetadata(context_);
  218. }
  219. finish_ops_.ClientRecvStatus(context_, status);
  220. call_.PerformOps(&finish_ops_);
  221. }
  222. private:
  223. friend class internal::ClientAsyncReaderFactory<R>;
  224. template <class W>
  225. ClientAsyncReader(::grpc::internal::Call call, ClientContext* context,
  226. const W& request, bool start, void* tag)
  227. : context_(context), call_(call), started_(start) {
  228. // TODO(ctiller): don't assert
  229. GPR_CODEGEN_ASSERT(init_ops_.SendMessage(request).ok());
  230. init_ops_.ClientSendClose();
  231. if (start) {
  232. StartCallInternal(tag);
  233. } else {
  234. assert(tag == nullptr);
  235. }
  236. }
  237. void StartCallInternal(void* tag) {
  238. init_ops_.SendInitialMetadata(context_->send_initial_metadata_,
  239. context_->initial_metadata_flags());
  240. init_ops_.set_output_tag(tag);
  241. call_.PerformOps(&init_ops_);
  242. }
  243. ClientContext* context_;
  244. ::grpc::internal::Call call_;
  245. bool started_;
  246. ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
  247. ::grpc::internal::CallOpSendMessage,
  248. ::grpc::internal::CallOpClientSendClose>
  249. init_ops_;
  250. ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata>
  251. meta_ops_;
  252. ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
  253. ::grpc::internal::CallOpRecvMessage<R>>
  254. read_ops_;
  255. ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
  256. ::grpc::internal::CallOpClientRecvStatus>
  257. finish_ops_;
  258. };
  259. /// Common interface for client side asynchronous writing.
  260. template <class W>
  261. class ClientAsyncWriterInterface
  262. : public internal::ClientAsyncStreamingInterface,
  263. public internal::AsyncWriterInterface<W> {
  264. public:
  265. /// Signal the client is done with the writes (half-close the client stream).
  266. /// Thread-safe with respect to \a AsyncReaderInterface::Read
  267. ///
  268. /// \param[in] tag The tag identifying the operation.
  269. virtual void WritesDone(void* tag) = 0;
  270. };
  271. namespace internal {
  272. template <class W>
  273. class ClientAsyncWriterFactory {
  274. public:
  275. /// Create a stream object.
  276. /// Start the RPC if \a start is set
  277. /// \a tag will be notified on \a cq when the call has been started (i.e.
  278. /// intitial metadata sent) and \a request has been written out.
  279. /// If \a start is not set, \a tag must be nullptr and the actual call
  280. /// must be initiated by StartCall
  281. /// Note that \a context will be used to fill in custom initial metadata
  282. /// used to send to the server when starting the call.
  283. /// \a response will be filled in with the single expected response
  284. /// message from the server upon a successful call to the \a Finish
  285. /// method of this instance.
  286. template <class R>
  287. static ClientAsyncWriter<W>* Create(ChannelInterface* channel,
  288. CompletionQueue* cq,
  289. const ::grpc::internal::RpcMethod& method,
  290. ClientContext* context, R* response,
  291. bool start, void* tag) {
  292. ::grpc::internal::Call call = channel->CreateCall(method, context, cq);
  293. return new (g_core_codegen_interface->grpc_call_arena_alloc(
  294. call.call(), sizeof(ClientAsyncWriter<W>)))
  295. ClientAsyncWriter<W>(call, context, response, start, tag);
  296. }
  297. };
  298. } // namespace internal
  299. /// Async API on the client side for doing client-streaming RPCs,
  300. /// where the outgoing message stream going to the server contains
  301. /// messages of type \a W.
  302. template <class W>
  303. class ClientAsyncWriter final : public ClientAsyncWriterInterface<W> {
  304. public:
  305. // always allocated against a call arena, no memory free required
  306. static void operator delete(void* ptr, std::size_t size) {
  307. assert(size == sizeof(ClientAsyncWriter));
  308. }
  309. void StartCall(void* tag) override {
  310. assert(!started_);
  311. started_ = true;
  312. StartCallInternal(tag);
  313. }
  314. /// See the \a ClientAsyncStreamingInterface.ReadInitialMetadata method for
  315. /// semantics.
  316. ///
  317. /// Side effect:
  318. /// - upon receiving initial metadata from the server, the \a ClientContext
  319. /// associated with this call is updated, and the calling code can access
  320. /// the received metadata through the \a ClientContext.
  321. void ReadInitialMetadata(void* tag) override {
  322. assert(started_);
  323. GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
  324. meta_ops_.set_output_tag(tag);
  325. meta_ops_.RecvInitialMetadata(context_);
  326. call_.PerformOps(&meta_ops_);
  327. }
  328. void Write(const W& msg, void* tag) override {
  329. assert(started_);
  330. write_ops_.set_output_tag(tag);
  331. // TODO(ctiller): don't assert
  332. GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok());
  333. call_.PerformOps(&write_ops_);
  334. }
  335. void Write(const W& msg, WriteOptions options, void* tag) override {
  336. assert(started_);
  337. write_ops_.set_output_tag(tag);
  338. if (options.is_last_message()) {
  339. options.set_buffer_hint();
  340. write_ops_.ClientSendClose();
  341. }
  342. // TODO(ctiller): don't assert
  343. GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok());
  344. call_.PerformOps(&write_ops_);
  345. }
  346. void WritesDone(void* tag) override {
  347. assert(started_);
  348. write_ops_.set_output_tag(tag);
  349. write_ops_.ClientSendClose();
  350. call_.PerformOps(&write_ops_);
  351. }
  352. /// See the \a ClientAsyncStreamingInterface.Finish method for semantics.
  353. ///
  354. /// Side effect:
  355. /// - the \a ClientContext associated with this call is updated with
  356. /// possible initial and trailing metadata received from the server.
  357. /// - attempts to fill in the \a response parameter passed to this class's
  358. /// constructor with the server's response message.
  359. void Finish(Status* status, void* tag) override {
  360. assert(started_);
  361. finish_ops_.set_output_tag(tag);
  362. if (!context_->initial_metadata_received_) {
  363. finish_ops_.RecvInitialMetadata(context_);
  364. }
  365. finish_ops_.ClientRecvStatus(context_, status);
  366. call_.PerformOps(&finish_ops_);
  367. }
  368. private:
  369. friend class internal::ClientAsyncWriterFactory<W>;
  370. template <class R>
  371. ClientAsyncWriter(::grpc::internal::Call call, ClientContext* context,
  372. R* response, bool start, void* tag)
  373. : context_(context), call_(call), started_(start) {
  374. finish_ops_.RecvMessage(response);
  375. finish_ops_.AllowNoMessage();
  376. if (start) {
  377. StartCallInternal(tag);
  378. } else {
  379. assert(tag == nullptr);
  380. }
  381. }
  382. void StartCallInternal(void* tag) {
  383. write_ops_.SendInitialMetadata(context_->send_initial_metadata_,
  384. context_->initial_metadata_flags());
  385. // if corked bit is set in context, we just keep the initial metadata
  386. // buffered up to coalesce with later message send. No op is performed.
  387. if (!context_->initial_metadata_corked_) {
  388. write_ops_.set_output_tag(tag);
  389. call_.PerformOps(&write_ops_);
  390. }
  391. }
  392. ClientContext* context_;
  393. ::grpc::internal::Call call_;
  394. bool started_;
  395. ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata>
  396. meta_ops_;
  397. ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
  398. ::grpc::internal::CallOpSendMessage,
  399. ::grpc::internal::CallOpClientSendClose>
  400. write_ops_;
  401. ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
  402. ::grpc::internal::CallOpGenericRecvMessage,
  403. ::grpc::internal::CallOpClientRecvStatus>
  404. finish_ops_;
  405. };
  406. /// Async client-side interface for bi-directional streaming,
  407. /// where the client-to-server message stream has messages of type \a W,
  408. /// and the server-to-client message stream has messages of type \a R.
  409. template <class W, class R>
  410. class ClientAsyncReaderWriterInterface
  411. : public internal::ClientAsyncStreamingInterface,
  412. public internal::AsyncWriterInterface<W>,
  413. public internal::AsyncReaderInterface<R> {
  414. public:
  415. /// Signal the client is done with the writes (half-close the client stream).
  416. /// Thread-safe with respect to \a AsyncReaderInterface::Read
  417. ///
  418. /// \param[in] tag The tag identifying the operation.
  419. virtual void WritesDone(void* tag) = 0;
  420. };
  421. namespace internal {
  422. template <class W, class R>
  423. class ClientAsyncReaderWriterFactory {
  424. public:
  425. /// Create a stream object.
  426. /// Start the RPC request if \a start is set.
  427. /// \a tag will be notified on \a cq when the call has been started (i.e.
  428. /// intitial metadata sent). If \a start is not set, \a tag must be
  429. /// nullptr and the actual call must be initiated by StartCall
  430. /// Note that \a context will be used to fill in custom initial metadata
  431. /// used to send to the server when starting the call.
  432. static ClientAsyncReaderWriter<W, R>* Create(
  433. ChannelInterface* channel, CompletionQueue* cq,
  434. const ::grpc::internal::RpcMethod& method, ClientContext* context,
  435. bool start, void* tag) {
  436. ::grpc::internal::Call call = channel->CreateCall(method, context, cq);
  437. return new (g_core_codegen_interface->grpc_call_arena_alloc(
  438. call.call(), sizeof(ClientAsyncReaderWriter<W, R>)))
  439. ClientAsyncReaderWriter<W, R>(call, context, start, tag);
  440. }
  441. };
  442. } // namespace internal
  443. /// Async client-side interface for bi-directional streaming,
  444. /// where the outgoing message stream going to the server
  445. /// has messages of type \a W, and the incoming message stream coming
  446. /// from the server has messages of type \a R.
  447. template <class W, class R>
  448. class ClientAsyncReaderWriter final
  449. : public ClientAsyncReaderWriterInterface<W, R> {
  450. public:
  451. // always allocated against a call arena, no memory free required
  452. static void operator delete(void* ptr, std::size_t size) {
  453. assert(size == sizeof(ClientAsyncReaderWriter));
  454. }
  455. void StartCall(void* tag) override {
  456. assert(!started_);
  457. started_ = true;
  458. StartCallInternal(tag);
  459. }
  460. /// See the \a ClientAsyncStreamingInterface.ReadInitialMetadata method
  461. /// for semantics of this method.
  462. ///
  463. /// Side effect:
  464. /// - upon receiving initial metadata from the server, the \a ClientContext
  465. /// is updated with it, and then the receiving initial metadata can
  466. /// be accessed through this \a ClientContext.
  467. void ReadInitialMetadata(void* tag) override {
  468. assert(started_);
  469. GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
  470. meta_ops_.set_output_tag(tag);
  471. meta_ops_.RecvInitialMetadata(context_);
  472. call_.PerformOps(&meta_ops_);
  473. }
  474. void Read(R* msg, void* tag) override {
  475. assert(started_);
  476. read_ops_.set_output_tag(tag);
  477. if (!context_->initial_metadata_received_) {
  478. read_ops_.RecvInitialMetadata(context_);
  479. }
  480. read_ops_.RecvMessage(msg);
  481. call_.PerformOps(&read_ops_);
  482. }
  483. void Write(const W& msg, void* tag) override {
  484. assert(started_);
  485. write_ops_.set_output_tag(tag);
  486. // TODO(ctiller): don't assert
  487. GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok());
  488. call_.PerformOps(&write_ops_);
  489. }
  490. void Write(const W& msg, WriteOptions options, void* tag) override {
  491. assert(started_);
  492. write_ops_.set_output_tag(tag);
  493. if (options.is_last_message()) {
  494. options.set_buffer_hint();
  495. write_ops_.ClientSendClose();
  496. }
  497. // TODO(ctiller): don't assert
  498. GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok());
  499. call_.PerformOps(&write_ops_);
  500. }
  501. void WritesDone(void* tag) override {
  502. assert(started_);
  503. write_ops_.set_output_tag(tag);
  504. write_ops_.ClientSendClose();
  505. call_.PerformOps(&write_ops_);
  506. }
  507. /// See the \a ClientAsyncStreamingInterface.Finish method for semantics.
  508. /// Side effect
  509. /// - the \a ClientContext associated with this call is updated with
  510. /// possible initial and trailing metadata sent from the server.
  511. void Finish(Status* status, void* tag) override {
  512. assert(started_);
  513. finish_ops_.set_output_tag(tag);
  514. if (!context_->initial_metadata_received_) {
  515. finish_ops_.RecvInitialMetadata(context_);
  516. }
  517. finish_ops_.ClientRecvStatus(context_, status);
  518. call_.PerformOps(&finish_ops_);
  519. }
  520. private:
  521. friend class internal::ClientAsyncReaderWriterFactory<W, R>;
  522. ClientAsyncReaderWriter(::grpc::internal::Call call, ClientContext* context,
  523. bool start, void* tag)
  524. : context_(context), call_(call), started_(start) {
  525. if (start) {
  526. StartCallInternal(tag);
  527. } else {
  528. assert(tag == nullptr);
  529. }
  530. }
  531. void StartCallInternal(void* tag) {
  532. write_ops_.SendInitialMetadata(context_->send_initial_metadata_,
  533. context_->initial_metadata_flags());
  534. // if corked bit is set in context, we just keep the initial metadata
  535. // buffered up to coalesce with later message send. No op is performed.
  536. if (!context_->initial_metadata_corked_) {
  537. write_ops_.set_output_tag(tag);
  538. call_.PerformOps(&write_ops_);
  539. }
  540. }
  541. ClientContext* context_;
  542. ::grpc::internal::Call call_;
  543. bool started_;
  544. ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata>
  545. meta_ops_;
  546. ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
  547. ::grpc::internal::CallOpRecvMessage<R>>
  548. read_ops_;
  549. ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
  550. ::grpc::internal::CallOpSendMessage,
  551. ::grpc::internal::CallOpClientSendClose>
  552. write_ops_;
  553. ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvInitialMetadata,
  554. ::grpc::internal::CallOpClientRecvStatus>
  555. finish_ops_;
  556. };
  557. template <class W, class R>
  558. class ServerAsyncReaderInterface
  559. : public internal::ServerAsyncStreamingInterface,
  560. public internal::AsyncReaderInterface<R> {
  561. public:
  562. /// Indicate that the stream is to be finished with a certain status code
  563. /// and also send out \a msg response to the client.
  564. /// Request notification for when the server has sent the response and the
  565. /// appropriate signals to the client to end the call.
  566. /// Should not be used concurrently with other operations.
  567. ///
  568. /// It is appropriate to call this method when:
  569. /// * all messages from the client have been received (either known
  570. /// implictly, or explicitly because a previous
  571. /// \a AsyncReaderInterface::Read operation with a non-ok result,
  572. /// e.g., cq->Next(&read_tag, &ok) filled in 'ok' with 'false').
  573. ///
  574. /// This operation will end when the server has finished sending out initial
  575. /// metadata (if not sent already), response message, and status, or if
  576. /// some failure occurred when trying to do so.
  577. ///
  578. /// \param[in] tag Tag identifying this request.
  579. /// \param[in] status To be sent to the client as the result of this call.
  580. /// \param[in] msg To be sent to the client as the response for this call.
  581. virtual void Finish(const W& msg, const Status& status, void* tag) = 0;
  582. /// Indicate that the stream is to be finished with a certain
  583. /// non-OK status code.
  584. /// Request notification for when the server has sent the appropriate
  585. /// signals to the client to end the call.
  586. /// Should not be used concurrently with other operations.
  587. ///
  588. /// This call is meant to end the call with some error, and can be called at
  589. /// any point that the server would like to "fail" the call (though note
  590. /// this shouldn't be called concurrently with any other "sending" call, like
  591. /// \a AsyncWriterInterface::Write).
  592. ///
  593. /// This operation will end when the server has finished sending out initial
  594. /// metadata (if not sent already), and status, or if some failure occurred
  595. /// when trying to do so.
  596. ///
  597. /// \param[in] tag Tag identifying this request.
  598. /// \param[in] status To be sent to the client as the result of this call.
  599. /// - Note: \a status must have a non-OK code.
  600. virtual void FinishWithError(const Status& status, void* tag) = 0;
  601. };
  602. /// Async server-side API for doing client-streaming RPCs,
  603. /// where the incoming message stream from the client has messages of type \a R,
  604. /// and the single response message sent from the server is type \a W.
  605. template <class W, class R>
  606. class ServerAsyncReader final : public ServerAsyncReaderInterface<W, R> {
  607. public:
  608. explicit ServerAsyncReader(ServerContext* ctx)
  609. : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
  610. /// See \a ServerAsyncStreamingInterface::SendInitialMetadata for semantics.
  611. ///
  612. /// Implicit input parameter:
  613. /// - The initial metadata that will be sent to the client from this op will
  614. /// be taken from the \a ServerContext associated with the call.
  615. void SendInitialMetadata(void* tag) override {
  616. GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
  617. meta_ops_.set_output_tag(tag);
  618. meta_ops_.SendInitialMetadata(ctx_->initial_metadata_,
  619. ctx_->initial_metadata_flags());
  620. if (ctx_->compression_level_set()) {
  621. meta_ops_.set_compression_level(ctx_->compression_level());
  622. }
  623. ctx_->sent_initial_metadata_ = true;
  624. call_.PerformOps(&meta_ops_);
  625. }
  626. void Read(R* msg, void* tag) override {
  627. read_ops_.set_output_tag(tag);
  628. read_ops_.RecvMessage(msg);
  629. call_.PerformOps(&read_ops_);
  630. }
  631. /// See the \a ServerAsyncReaderInterface.Read method for semantics
  632. ///
  633. /// Side effect:
  634. /// - also sends initial metadata if not alreay sent.
  635. /// - uses the \a ServerContext associated with this call to send possible
  636. /// initial and trailing metadata.
  637. ///
  638. /// Note: \a msg is not sent if \a status has a non-OK code.
  639. void Finish(const W& msg, const Status& status, void* tag) override {
  640. finish_ops_.set_output_tag(tag);
  641. if (!ctx_->sent_initial_metadata_) {
  642. finish_ops_.SendInitialMetadata(ctx_->initial_metadata_,
  643. ctx_->initial_metadata_flags());
  644. if (ctx_->compression_level_set()) {
  645. finish_ops_.set_compression_level(ctx_->compression_level());
  646. }
  647. ctx_->sent_initial_metadata_ = true;
  648. }
  649. // The response is dropped if the status is not OK.
  650. if (status.ok()) {
  651. finish_ops_.ServerSendStatus(ctx_->trailing_metadata_,
  652. finish_ops_.SendMessage(msg));
  653. } else {
  654. finish_ops_.ServerSendStatus(ctx_->trailing_metadata_, status);
  655. }
  656. call_.PerformOps(&finish_ops_);
  657. }
  658. /// See the \a ServerAsyncReaderInterface.Read method for semantics
  659. ///
  660. /// Side effect:
  661. /// - also sends initial metadata if not alreay sent.
  662. /// - uses the \a ServerContext associated with this call to send possible
  663. /// initial and trailing metadata.
  664. void FinishWithError(const Status& status, void* tag) override {
  665. GPR_CODEGEN_ASSERT(!status.ok());
  666. finish_ops_.set_output_tag(tag);
  667. if (!ctx_->sent_initial_metadata_) {
  668. finish_ops_.SendInitialMetadata(ctx_->initial_metadata_,
  669. ctx_->initial_metadata_flags());
  670. if (ctx_->compression_level_set()) {
  671. finish_ops_.set_compression_level(ctx_->compression_level());
  672. }
  673. ctx_->sent_initial_metadata_ = true;
  674. }
  675. finish_ops_.ServerSendStatus(ctx_->trailing_metadata_, status);
  676. call_.PerformOps(&finish_ops_);
  677. }
  678. private:
  679. void BindCall(::grpc::internal::Call* call) override { call_ = *call; }
  680. ::grpc::internal::Call call_;
  681. ServerContext* ctx_;
  682. ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata>
  683. meta_ops_;
  684. ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvMessage<R>> read_ops_;
  685. ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
  686. ::grpc::internal::CallOpSendMessage,
  687. ::grpc::internal::CallOpServerSendStatus>
  688. finish_ops_;
  689. };
  690. template <class W>
  691. class ServerAsyncWriterInterface
  692. : public internal::ServerAsyncStreamingInterface,
  693. public internal::AsyncWriterInterface<W> {
  694. public:
  695. /// Indicate that the stream is to be finished with a certain status code.
  696. /// Request notification for when the server has sent the appropriate
  697. /// signals to the client to end the call.
  698. /// Should not be used concurrently with other operations.
  699. ///
  700. /// It is appropriate to call this method when either:
  701. /// * all messages from the client have been received (either known
  702. /// implictly, or explicitly because a previous \a
  703. /// AsyncReaderInterface::Read operation with a non-ok
  704. /// result (e.g., cq->Next(&read_tag, &ok) filled in 'ok' with 'false'.
  705. /// * it is desired to end the call early with some non-OK status code.
  706. ///
  707. /// This operation will end when the server has finished sending out initial
  708. /// metadata (if not sent already), response message, and status, or if
  709. /// some failure occurred when trying to do so.
  710. ///
  711. /// \param[in] tag Tag identifying this request.
  712. /// \param[in] status To be sent to the client as the result of this call.
  713. virtual void Finish(const Status& status, void* tag) = 0;
  714. /// Request the writing of \a msg and coalesce it with trailing metadata which
  715. /// contains \a status, using WriteOptions options with
  716. /// identifying tag \a tag.
  717. ///
  718. /// WriteAndFinish is equivalent of performing WriteLast and Finish
  719. /// in a single step.
  720. ///
  721. /// \param[in] msg The message to be written.
  722. /// \param[in] options The WriteOptions to be used to write this message.
  723. /// \param[in] status The Status that server returns to client.
  724. /// \param[in] tag The tag identifying the operation.
  725. virtual void WriteAndFinish(const W& msg, WriteOptions options,
  726. const Status& status, void* tag) = 0;
  727. };
  728. /// Async server-side API for doing server streaming RPCs,
  729. /// where the outgoing message stream from the server has messages of type \a W.
  730. template <class W>
  731. class ServerAsyncWriter final : public ServerAsyncWriterInterface<W> {
  732. public:
  733. explicit ServerAsyncWriter(ServerContext* ctx)
  734. : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
  735. /// See \a ServerAsyncStreamingInterface::SendInitialMetadata for semantics.
  736. ///
  737. /// Implicit input parameter:
  738. /// - The initial metadata that will be sent to the client from this op will
  739. /// be taken from the \a ServerContext associated with the call.
  740. ///
  741. /// \param[in] tag Tag identifying this request.
  742. void SendInitialMetadata(void* tag) override {
  743. GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
  744. meta_ops_.set_output_tag(tag);
  745. meta_ops_.SendInitialMetadata(ctx_->initial_metadata_,
  746. ctx_->initial_metadata_flags());
  747. if (ctx_->compression_level_set()) {
  748. meta_ops_.set_compression_level(ctx_->compression_level());
  749. }
  750. ctx_->sent_initial_metadata_ = true;
  751. call_.PerformOps(&meta_ops_);
  752. }
  753. void Write(const W& msg, void* tag) override {
  754. write_ops_.set_output_tag(tag);
  755. EnsureInitialMetadataSent(&write_ops_);
  756. // TODO(ctiller): don't assert
  757. GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok());
  758. call_.PerformOps(&write_ops_);
  759. }
  760. void Write(const W& msg, WriteOptions options, void* tag) override {
  761. write_ops_.set_output_tag(tag);
  762. if (options.is_last_message()) {
  763. options.set_buffer_hint();
  764. }
  765. EnsureInitialMetadataSent(&write_ops_);
  766. // TODO(ctiller): don't assert
  767. GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok());
  768. call_.PerformOps(&write_ops_);
  769. }
  770. /// See the \a ServerAsyncWriterInterface.WriteAndFinish method for semantics.
  771. ///
  772. /// Implicit input parameter:
  773. /// - the \a ServerContext associated with this call is used
  774. /// for sending trailing (and initial) metadata to the client.
  775. ///
  776. /// Note: \a status must have an OK code.
  777. void WriteAndFinish(const W& msg, WriteOptions options, const Status& status,
  778. void* tag) override {
  779. write_ops_.set_output_tag(tag);
  780. EnsureInitialMetadataSent(&write_ops_);
  781. options.set_buffer_hint();
  782. GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok());
  783. write_ops_.ServerSendStatus(ctx_->trailing_metadata_, status);
  784. call_.PerformOps(&write_ops_);
  785. }
  786. /// See the \a ServerAsyncWriterInterface.Finish method for semantics.
  787. ///
  788. /// Implicit input parameter:
  789. /// - the \a ServerContext associated with this call is used for sending
  790. /// trailing (and initial if not already sent) metadata to the client.
  791. ///
  792. /// Note: there are no restrictions are the code of
  793. /// \a status,it may be non-OK
  794. void Finish(const Status& status, void* tag) override {
  795. finish_ops_.set_output_tag(tag);
  796. EnsureInitialMetadataSent(&finish_ops_);
  797. finish_ops_.ServerSendStatus(ctx_->trailing_metadata_, status);
  798. call_.PerformOps(&finish_ops_);
  799. }
  800. private:
  801. void BindCall(::grpc::internal::Call* call) override { call_ = *call; }
  802. template <class T>
  803. void EnsureInitialMetadataSent(T* ops) {
  804. if (!ctx_->sent_initial_metadata_) {
  805. ops->SendInitialMetadata(ctx_->initial_metadata_,
  806. ctx_->initial_metadata_flags());
  807. if (ctx_->compression_level_set()) {
  808. ops->set_compression_level(ctx_->compression_level());
  809. }
  810. ctx_->sent_initial_metadata_ = true;
  811. }
  812. }
  813. ::grpc::internal::Call call_;
  814. ServerContext* ctx_;
  815. ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata>
  816. meta_ops_;
  817. ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
  818. ::grpc::internal::CallOpSendMessage,
  819. ::grpc::internal::CallOpServerSendStatus>
  820. write_ops_;
  821. ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
  822. ::grpc::internal::CallOpServerSendStatus>
  823. finish_ops_;
  824. };
  825. /// Server-side interface for asynchronous bi-directional streaming.
  826. template <class W, class R>
  827. class ServerAsyncReaderWriterInterface
  828. : public internal::ServerAsyncStreamingInterface,
  829. public internal::AsyncWriterInterface<W>,
  830. public internal::AsyncReaderInterface<R> {
  831. public:
  832. /// Indicate that the stream is to be finished with a certain status code.
  833. /// Request notification for when the server has sent the appropriate
  834. /// signals to the client to end the call.
  835. /// Should not be used concurrently with other operations.
  836. ///
  837. /// It is appropriate to call this method when either:
  838. /// * all messages from the client have been received (either known
  839. /// implictly, or explicitly because a previous \a
  840. /// AsyncReaderInterface::Read operation
  841. /// with a non-ok result (e.g., cq->Next(&read_tag, &ok) filled in 'ok'
  842. /// with 'false'.
  843. /// * it is desired to end the call early with some non-OK status code.
  844. ///
  845. /// This operation will end when the server has finished sending out initial
  846. /// metadata (if not sent already), response message, and status, or if some
  847. /// failure occurred when trying to do so.
  848. ///
  849. /// \param[in] tag Tag identifying this request.
  850. /// \param[in] status To be sent to the client as the result of this call.
  851. virtual void Finish(const Status& status, void* tag) = 0;
  852. /// Request the writing of \a msg and coalesce it with trailing metadata which
  853. /// contains \a status, using WriteOptions options with
  854. /// identifying tag \a tag.
  855. ///
  856. /// WriteAndFinish is equivalent of performing WriteLast and Finish in a
  857. /// single step.
  858. ///
  859. /// \param[in] msg The message to be written.
  860. /// \param[in] options The WriteOptions to be used to write this message.
  861. /// \param[in] status The Status that server returns to client.
  862. /// \param[in] tag The tag identifying the operation.
  863. virtual void WriteAndFinish(const W& msg, WriteOptions options,
  864. const Status& status, void* tag) = 0;
  865. };
  866. /// Async server-side API for doing bidirectional streaming RPCs,
  867. /// where the incoming message stream coming from the client has messages of
  868. /// type \a R, and the outgoing message stream coming from the server has
  869. /// messages of type \a W.
  870. template <class W, class R>
  871. class ServerAsyncReaderWriter final
  872. : public ServerAsyncReaderWriterInterface<W, R> {
  873. public:
  874. explicit ServerAsyncReaderWriter(ServerContext* ctx)
  875. : call_(nullptr, nullptr, nullptr), ctx_(ctx) {}
  876. /// See \a ServerAsyncStreamingInterface::SendInitialMetadata for semantics.
  877. ///
  878. /// Implicit input parameter:
  879. /// - The initial metadata that will be sent to the client from this op will
  880. /// be taken from the \a ServerContext associated with the call.
  881. ///
  882. /// \param[in] tag Tag identifying this request.
  883. void SendInitialMetadata(void* tag) override {
  884. GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
  885. meta_ops_.set_output_tag(tag);
  886. meta_ops_.SendInitialMetadata(ctx_->initial_metadata_,
  887. ctx_->initial_metadata_flags());
  888. if (ctx_->compression_level_set()) {
  889. meta_ops_.set_compression_level(ctx_->compression_level());
  890. }
  891. ctx_->sent_initial_metadata_ = true;
  892. call_.PerformOps(&meta_ops_);
  893. }
  894. void Read(R* msg, void* tag) override {
  895. read_ops_.set_output_tag(tag);
  896. read_ops_.RecvMessage(msg);
  897. call_.PerformOps(&read_ops_);
  898. }
  899. void Write(const W& msg, void* tag) override {
  900. write_ops_.set_output_tag(tag);
  901. EnsureInitialMetadataSent(&write_ops_);
  902. // TODO(ctiller): don't assert
  903. GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg).ok());
  904. call_.PerformOps(&write_ops_);
  905. }
  906. void Write(const W& msg, WriteOptions options, void* tag) override {
  907. write_ops_.set_output_tag(tag);
  908. if (options.is_last_message()) {
  909. options.set_buffer_hint();
  910. }
  911. EnsureInitialMetadataSent(&write_ops_);
  912. GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok());
  913. call_.PerformOps(&write_ops_);
  914. }
  915. /// See the \a ServerAsyncReaderWriterInterface.WriteAndFinish
  916. /// method for semantics.
  917. ///
  918. /// Implicit input parameter:
  919. /// - the \a ServerContext associated with this call is used
  920. /// for sending trailing (and initial) metadata to the client.
  921. ///
  922. /// Note: \a status must have an OK code.
  923. void WriteAndFinish(const W& msg, WriteOptions options, const Status& status,
  924. void* tag) override {
  925. write_ops_.set_output_tag(tag);
  926. EnsureInitialMetadataSent(&write_ops_);
  927. options.set_buffer_hint();
  928. GPR_CODEGEN_ASSERT(write_ops_.SendMessage(msg, options).ok());
  929. write_ops_.ServerSendStatus(ctx_->trailing_metadata_, status);
  930. call_.PerformOps(&write_ops_);
  931. }
  932. /// See the \a ServerAsyncReaderWriterInterface.Finish method for semantics.
  933. ///
  934. /// Implicit input parameter:
  935. /// - the \a ServerContext associated with this call is used for sending
  936. /// trailing (and initial if not already sent) metadata to the client.
  937. ///
  938. /// Note: there are no restrictions are the code of \a status,
  939. /// it may be non-OK
  940. void Finish(const Status& status, void* tag) override {
  941. finish_ops_.set_output_tag(tag);
  942. EnsureInitialMetadataSent(&finish_ops_);
  943. finish_ops_.ServerSendStatus(ctx_->trailing_metadata_, status);
  944. call_.PerformOps(&finish_ops_);
  945. }
  946. private:
  947. friend class ::grpc::Server;
  948. void BindCall(::grpc::internal::Call* call) override { call_ = *call; }
  949. template <class T>
  950. void EnsureInitialMetadataSent(T* ops) {
  951. if (!ctx_->sent_initial_metadata_) {
  952. ops->SendInitialMetadata(ctx_->initial_metadata_,
  953. ctx_->initial_metadata_flags());
  954. if (ctx_->compression_level_set()) {
  955. ops->set_compression_level(ctx_->compression_level());
  956. }
  957. ctx_->sent_initial_metadata_ = true;
  958. }
  959. }
  960. ::grpc::internal::Call call_;
  961. ServerContext* ctx_;
  962. ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata>
  963. meta_ops_;
  964. ::grpc::internal::CallOpSet<::grpc::internal::CallOpRecvMessage<R>> read_ops_;
  965. ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
  966. ::grpc::internal::CallOpSendMessage,
  967. ::grpc::internal::CallOpServerSendStatus>
  968. write_ops_;
  969. ::grpc::internal::CallOpSet<::grpc::internal::CallOpSendInitialMetadata,
  970. ::grpc::internal::CallOpServerSendStatus>
  971. finish_ops_;
  972. };
  973. } // namespace grpc
  974. #endif // GRPCPP_IMPL_CODEGEN_ASYNC_STREAM_H