async_stream.h 45 KB

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