You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

async_stream.h 53 kB

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