sync_stream.h 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945
  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_SYNC_STREAM_H
  18. #define GRPCPP_IMPL_CODEGEN_SYNC_STREAM_H
  19. // IWYU pragma: private, include <grpcpp/support/sync_stream.h>
  20. #include <grpcpp/impl/codegen/call.h>
  21. #include <grpcpp/impl/codegen/channel_interface.h>
  22. #include <grpcpp/impl/codegen/client_context.h>
  23. #include <grpcpp/impl/codegen/completion_queue.h>
  24. #include <grpcpp/impl/codegen/core_codegen_interface.h>
  25. #include <grpcpp/impl/codegen/server_context.h>
  26. #include <grpcpp/impl/codegen/service_type.h>
  27. #include <grpcpp/impl/codegen/status.h>
  28. namespace grpc {
  29. namespace internal {
  30. /// Common interface for all synchronous client side streaming.
  31. class ClientStreamingInterface {
  32. public:
  33. virtual ~ClientStreamingInterface() {}
  34. /// Block waiting until the stream finishes and a final status of the call is
  35. /// available.
  36. ///
  37. /// It is appropriate to call this method exactly once when both:
  38. /// * the calling code (client-side) has no more message to send
  39. /// (this can be declared implicitly by calling this method, or
  40. /// explicitly through an earlier call to <i>WritesDone</i> method of the
  41. /// class in use, e.g. \a ClientWriterInterface::WritesDone or
  42. /// \a ClientReaderWriterInterface::WritesDone).
  43. /// * there are no more messages to be received from the server (which can
  44. /// be known implicitly, or explicitly from an earlier call to \a
  45. /// ReaderInterface::Read that returned "false").
  46. ///
  47. /// This function will return either:
  48. /// - when all incoming messages have been read and the server has
  49. /// returned status.
  50. /// - when the server has returned a non-OK status.
  51. /// - OR when the call failed for some reason and the library generated a
  52. /// status.
  53. ///
  54. /// Return values:
  55. /// - \a Status contains the status code, message and details for the call
  56. /// - the \a ClientContext associated with this call is updated with
  57. /// possible trailing metadata sent from the server.
  58. virtual grpc::Status Finish() = 0;
  59. };
  60. /// Common interface for all synchronous server side streaming.
  61. class ServerStreamingInterface {
  62. public:
  63. virtual ~ServerStreamingInterface() {}
  64. /// Block to send initial metadata to client.
  65. /// This call is optional, but if it is used, it cannot be used concurrently
  66. /// with or after the \a Finish method.
  67. ///
  68. /// The initial metadata that will be sent to the client will be
  69. /// taken from the \a ServerContext associated with the call.
  70. virtual void SendInitialMetadata() = 0;
  71. };
  72. /// An interface that yields a sequence of messages of type \a R.
  73. template <class R>
  74. class ReaderInterface {
  75. public:
  76. virtual ~ReaderInterface() {}
  77. /// Get an upper bound on the next message size available for reading on this
  78. /// stream.
  79. virtual bool NextMessageSize(uint32_t* sz) = 0;
  80. /// Block to read a message and parse to \a msg. Returns \a true on success.
  81. /// This is thread-safe with respect to \a Write or \WritesDone methods on
  82. /// the same stream. It should not be called concurrently with another \a
  83. /// Read on the same stream as the order of delivery will not be defined.
  84. ///
  85. /// \param[out] msg The read message.
  86. ///
  87. /// \return \a false when there will be no more incoming messages, either
  88. /// because the other side has called \a WritesDone() or the stream has failed
  89. /// (or been cancelled).
  90. virtual bool Read(R* msg) = 0;
  91. };
  92. /// An interface that can be fed a sequence of messages of type \a W.
  93. template <class W>
  94. class WriterInterface {
  95. public:
  96. virtual ~WriterInterface() {}
  97. /// Block to write \a msg to the stream with WriteOptions \a options.
  98. /// This is thread-safe with respect to \a ReaderInterface::Read
  99. ///
  100. /// \param msg The message to be written to the stream.
  101. /// \param options The WriteOptions affecting the write operation.
  102. ///
  103. /// \return \a true on success, \a false when the stream has been closed.
  104. virtual bool Write(const W& msg, grpc::WriteOptions options) = 0;
  105. /// Block to write \a msg to the stream with default write options.
  106. /// This is thread-safe with respect to \a ReaderInterface::Read
  107. ///
  108. /// \param msg The message to be written to the stream.
  109. ///
  110. /// \return \a true on success, \a false when the stream has been closed.
  111. inline bool Write(const W& msg) { return Write(msg, grpc::WriteOptions()); }
  112. /// Write \a msg and coalesce it with the writing of trailing metadata, using
  113. /// WriteOptions \a options.
  114. ///
  115. /// For client, WriteLast is equivalent of performing Write and WritesDone in
  116. /// a single step. \a msg and trailing metadata are coalesced and sent on wire
  117. /// by calling this function. For server, WriteLast buffers the \a msg.
  118. /// The writing of \a msg is held until the service handler returns,
  119. /// where \a msg and trailing metadata are coalesced and sent on wire.
  120. /// Note that WriteLast can only buffer \a msg up to the flow control window
  121. /// size. If \a msg size is larger than the window size, it will be sent on
  122. /// wire without buffering.
  123. ///
  124. /// \param[in] msg The message to be written to the stream.
  125. /// \param[in] options The WriteOptions to be used to write this message.
  126. void WriteLast(const W& msg, grpc::WriteOptions options) {
  127. Write(msg, options.set_last_message());
  128. }
  129. };
  130. } // namespace internal
  131. /// Client-side interface for streaming reads of message of type \a R.
  132. template <class R>
  133. class ClientReaderInterface : public internal::ClientStreamingInterface,
  134. public internal::ReaderInterface<R> {
  135. public:
  136. /// Block to wait for initial metadata from server. The received metadata
  137. /// can only be accessed after this call returns. Should only be called before
  138. /// the first read. Calling this method is optional, and if it is not called
  139. /// the metadata will be available in ClientContext after the first read.
  140. virtual void WaitForInitialMetadata() = 0;
  141. };
  142. namespace internal {
  143. template <class R>
  144. class ClientReaderFactory {
  145. public:
  146. template <class W>
  147. static ClientReader<R>* Create(grpc::ChannelInterface* channel,
  148. const grpc::internal::RpcMethod& method,
  149. grpc::ClientContext* context,
  150. const W& request) {
  151. return new ClientReader<R>(channel, method, context, request);
  152. }
  153. };
  154. } // namespace internal
  155. /// Synchronous (blocking) client-side API for doing server-streaming RPCs,
  156. /// where the stream of messages coming from the server has messages
  157. /// of type \a R.
  158. template <class R>
  159. class ClientReader final : public ClientReaderInterface<R> {
  160. public:
  161. /// See the \a ClientStreamingInterface.WaitForInitialMetadata method for
  162. /// semantics.
  163. ///
  164. // Side effect:
  165. /// Once complete, the initial metadata read from
  166. /// the server will be accessible through the \a ClientContext used to
  167. /// construct this object.
  168. void WaitForInitialMetadata() override {
  169. GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
  170. grpc::internal::CallOpSet<grpc::internal::CallOpRecvInitialMetadata> ops;
  171. ops.RecvInitialMetadata(context_);
  172. call_.PerformOps(&ops);
  173. cq_.Pluck(&ops); /// status ignored
  174. }
  175. bool NextMessageSize(uint32_t* sz) override {
  176. int result = call_.max_receive_message_size();
  177. *sz = (result > 0) ? result : UINT32_MAX;
  178. return true;
  179. }
  180. /// See the \a ReaderInterface.Read method for semantics.
  181. /// Side effect:
  182. /// This also receives initial metadata from the server, if not
  183. /// already received (if initial metadata is received, it can be then
  184. /// accessed through the \a ClientContext associated with this call).
  185. bool Read(R* msg) override {
  186. grpc::internal::CallOpSet<grpc::internal::CallOpRecvInitialMetadata,
  187. grpc::internal::CallOpRecvMessage<R>>
  188. ops;
  189. if (!context_->initial_metadata_received_) {
  190. ops.RecvInitialMetadata(context_);
  191. }
  192. ops.RecvMessage(msg);
  193. call_.PerformOps(&ops);
  194. return cq_.Pluck(&ops) && ops.got_message;
  195. }
  196. /// See the \a ClientStreamingInterface.Finish method for semantics.
  197. ///
  198. /// Side effect:
  199. /// The \a ClientContext associated with this call is updated with
  200. /// possible metadata received from the server.
  201. grpc::Status Finish() override {
  202. grpc::internal::CallOpSet<grpc::internal::CallOpClientRecvStatus> ops;
  203. grpc::Status status;
  204. ops.ClientRecvStatus(context_, &status);
  205. call_.PerformOps(&ops);
  206. GPR_CODEGEN_ASSERT(cq_.Pluck(&ops));
  207. return status;
  208. }
  209. private:
  210. friend class internal::ClientReaderFactory<R>;
  211. grpc::ClientContext* context_;
  212. grpc::CompletionQueue cq_;
  213. grpc::internal::Call call_;
  214. /// Block to create a stream and write the initial metadata and \a request
  215. /// out. Note that \a context will be used to fill in custom initial
  216. /// metadata used to send to the server when starting the call.
  217. template <class W>
  218. ClientReader(grpc::ChannelInterface* channel,
  219. const grpc::internal::RpcMethod& method,
  220. grpc::ClientContext* context, const W& request)
  221. : context_(context),
  222. cq_(grpc_completion_queue_attributes{
  223. GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_DEFAULT_POLLING,
  224. nullptr}), // Pluckable cq
  225. call_(channel->CreateCall(method, context, &cq_)) {
  226. grpc::internal::CallOpSet<grpc::internal::CallOpSendInitialMetadata,
  227. grpc::internal::CallOpSendMessage,
  228. grpc::internal::CallOpClientSendClose>
  229. ops;
  230. ops.SendInitialMetadata(&context->send_initial_metadata_,
  231. context->initial_metadata_flags());
  232. // TODO(ctiller): don't assert
  233. GPR_CODEGEN_ASSERT(ops.SendMessagePtr(&request).ok());
  234. ops.ClientSendClose();
  235. call_.PerformOps(&ops);
  236. cq_.Pluck(&ops);
  237. }
  238. };
  239. /// Client-side interface for streaming writes of message type \a W.
  240. template <class W>
  241. class ClientWriterInterface : public internal::ClientStreamingInterface,
  242. public internal::WriterInterface<W> {
  243. public:
  244. /// Half close writing from the client. (signal that the stream of messages
  245. /// coming from the client is complete).
  246. /// Blocks until currently-pending writes are completed.
  247. /// Thread safe with respect to \a ReaderInterface::Read operations only
  248. ///
  249. /// \return Whether the writes were successful.
  250. virtual bool WritesDone() = 0;
  251. };
  252. namespace internal {
  253. template <class W>
  254. class ClientWriterFactory {
  255. public:
  256. template <class R>
  257. static ClientWriter<W>* Create(grpc::ChannelInterface* channel,
  258. const grpc::internal::RpcMethod& method,
  259. grpc::ClientContext* context, R* response) {
  260. return new ClientWriter<W>(channel, method, context, response);
  261. }
  262. };
  263. } // namespace internal
  264. /// Synchronous (blocking) client-side API for doing client-streaming RPCs,
  265. /// where the outgoing message stream coming from the client has messages of
  266. /// type \a W.
  267. template <class W>
  268. class ClientWriter : public ClientWriterInterface<W> {
  269. public:
  270. /// See the \a ClientStreamingInterface.WaitForInitialMetadata method for
  271. /// semantics.
  272. ///
  273. // Side effect:
  274. /// Once complete, the initial metadata read from the server will be
  275. /// accessible through the \a ClientContext used to construct this object.
  276. void WaitForInitialMetadata() {
  277. GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
  278. grpc::internal::CallOpSet<grpc::internal::CallOpRecvInitialMetadata> ops;
  279. ops.RecvInitialMetadata(context_);
  280. call_.PerformOps(&ops);
  281. cq_.Pluck(&ops); // status ignored
  282. }
  283. /// See the WriterInterface.Write(const W& msg, WriteOptions options) method
  284. /// for semantics.
  285. ///
  286. /// Side effect:
  287. /// Also sends initial metadata if not already sent (using the
  288. /// \a ClientContext associated with this call).
  289. using internal::WriterInterface<W>::Write;
  290. bool Write(const W& msg, grpc::WriteOptions options) override {
  291. grpc::internal::CallOpSet<grpc::internal::CallOpSendInitialMetadata,
  292. grpc::internal::CallOpSendMessage,
  293. grpc::internal::CallOpClientSendClose>
  294. ops;
  295. if (options.is_last_message()) {
  296. options.set_buffer_hint();
  297. ops.ClientSendClose();
  298. }
  299. if (context_->initial_metadata_corked_) {
  300. ops.SendInitialMetadata(&context_->send_initial_metadata_,
  301. context_->initial_metadata_flags());
  302. context_->set_initial_metadata_corked(false);
  303. }
  304. if (!ops.SendMessagePtr(&msg, options).ok()) {
  305. return false;
  306. }
  307. call_.PerformOps(&ops);
  308. return cq_.Pluck(&ops);
  309. }
  310. bool WritesDone() override {
  311. grpc::internal::CallOpSet<grpc::internal::CallOpClientSendClose> ops;
  312. ops.ClientSendClose();
  313. call_.PerformOps(&ops);
  314. return cq_.Pluck(&ops);
  315. }
  316. /// See the ClientStreamingInterface.Finish method for semantics.
  317. /// Side effects:
  318. /// - Also receives initial metadata if not already received.
  319. /// - Attempts to fill in the \a response parameter passed
  320. /// to the constructor of this instance with the response
  321. /// message from the server.
  322. grpc::Status Finish() override {
  323. grpc::Status status;
  324. if (!context_->initial_metadata_received_) {
  325. finish_ops_.RecvInitialMetadata(context_);
  326. }
  327. finish_ops_.ClientRecvStatus(context_, &status);
  328. call_.PerformOps(&finish_ops_);
  329. GPR_CODEGEN_ASSERT(cq_.Pluck(&finish_ops_));
  330. return status;
  331. }
  332. private:
  333. friend class internal::ClientWriterFactory<W>;
  334. /// Block to create a stream (i.e. send request headers and other initial
  335. /// metadata to the server). Note that \a context will be used to fill
  336. /// in custom initial metadata. \a response will be filled in with the
  337. /// single expected response message from the server upon a successful
  338. /// call to the \a Finish method of this instance.
  339. template <class R>
  340. ClientWriter(grpc::ChannelInterface* channel,
  341. const grpc::internal::RpcMethod& method,
  342. grpc::ClientContext* context, R* response)
  343. : context_(context),
  344. cq_(grpc_completion_queue_attributes{
  345. GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_DEFAULT_POLLING,
  346. nullptr}), // Pluckable cq
  347. call_(channel->CreateCall(method, context, &cq_)) {
  348. finish_ops_.RecvMessage(response);
  349. finish_ops_.AllowNoMessage();
  350. if (!context_->initial_metadata_corked_) {
  351. grpc::internal::CallOpSet<grpc::internal::CallOpSendInitialMetadata> ops;
  352. ops.SendInitialMetadata(&context->send_initial_metadata_,
  353. context->initial_metadata_flags());
  354. call_.PerformOps(&ops);
  355. cq_.Pluck(&ops);
  356. }
  357. }
  358. grpc::ClientContext* context_;
  359. grpc::internal::CallOpSet<grpc::internal::CallOpRecvInitialMetadata,
  360. grpc::internal::CallOpGenericRecvMessage,
  361. grpc::internal::CallOpClientRecvStatus>
  362. finish_ops_;
  363. grpc::CompletionQueue cq_;
  364. grpc::internal::Call call_;
  365. };
  366. /// Client-side interface for bi-directional streaming with
  367. /// client-to-server stream messages of type \a W and
  368. /// server-to-client stream messages of type \a R.
  369. template <class W, class R>
  370. class ClientReaderWriterInterface : public internal::ClientStreamingInterface,
  371. public internal::WriterInterface<W>,
  372. public internal::ReaderInterface<R> {
  373. public:
  374. /// Block to wait for initial metadata from server. The received metadata
  375. /// can only be accessed after this call returns. Should only be called before
  376. /// the first read. Calling this method is optional, and if it is not called
  377. /// the metadata will be available in ClientContext after the first read.
  378. virtual void WaitForInitialMetadata() = 0;
  379. /// Half close writing from the client. (signal that the stream of messages
  380. /// coming from the client is complete).
  381. /// Blocks until currently-pending writes are completed.
  382. /// Thread-safe with respect to \a ReaderInterface::Read
  383. ///
  384. /// \return Whether the writes were successful.
  385. virtual bool WritesDone() = 0;
  386. };
  387. namespace internal {
  388. template <class W, class R>
  389. class ClientReaderWriterFactory {
  390. public:
  391. static ClientReaderWriter<W, R>* Create(
  392. grpc::ChannelInterface* channel, const grpc::internal::RpcMethod& method,
  393. grpc::ClientContext* context) {
  394. return new ClientReaderWriter<W, R>(channel, method, context);
  395. }
  396. };
  397. } // namespace internal
  398. /// Synchronous (blocking) client-side API for bi-directional streaming RPCs,
  399. /// where the outgoing message stream coming from the client has messages of
  400. /// type \a W, and the incoming messages stream coming from the server has
  401. /// messages of type \a R.
  402. template <class W, class R>
  403. class ClientReaderWriter final : public ClientReaderWriterInterface<W, R> {
  404. public:
  405. /// Block waiting to read initial metadata from the server.
  406. /// This call is optional, but if it is used, it cannot be used concurrently
  407. /// with or after the \a Finish method.
  408. ///
  409. /// Once complete, the initial metadata read from the server will be
  410. /// accessible through the \a ClientContext used to construct this object.
  411. void WaitForInitialMetadata() override {
  412. GPR_CODEGEN_ASSERT(!context_->initial_metadata_received_);
  413. grpc::internal::CallOpSet<grpc::internal::CallOpRecvInitialMetadata> ops;
  414. ops.RecvInitialMetadata(context_);
  415. call_.PerformOps(&ops);
  416. cq_.Pluck(&ops); // status ignored
  417. }
  418. bool NextMessageSize(uint32_t* sz) override {
  419. int result = call_.max_receive_message_size();
  420. *sz = (result > 0) ? result : UINT32_MAX;
  421. return true;
  422. }
  423. /// See the \a ReaderInterface.Read method for semantics.
  424. /// Side effect:
  425. /// Also receives initial metadata if not already received (updates the \a
  426. /// ClientContext associated with this call in that case).
  427. bool Read(R* msg) override {
  428. grpc::internal::CallOpSet<grpc::internal::CallOpRecvInitialMetadata,
  429. grpc::internal::CallOpRecvMessage<R>>
  430. ops;
  431. if (!context_->initial_metadata_received_) {
  432. ops.RecvInitialMetadata(context_);
  433. }
  434. ops.RecvMessage(msg);
  435. call_.PerformOps(&ops);
  436. return cq_.Pluck(&ops) && ops.got_message;
  437. }
  438. /// See the \a WriterInterface.Write method for semantics.
  439. ///
  440. /// Side effect:
  441. /// Also sends initial metadata if not already sent (using the
  442. /// \a ClientContext associated with this call to fill in values).
  443. using internal::WriterInterface<W>::Write;
  444. bool Write(const W& msg, grpc::WriteOptions options) override {
  445. grpc::internal::CallOpSet<grpc::internal::CallOpSendInitialMetadata,
  446. grpc::internal::CallOpSendMessage,
  447. grpc::internal::CallOpClientSendClose>
  448. ops;
  449. if (options.is_last_message()) {
  450. options.set_buffer_hint();
  451. ops.ClientSendClose();
  452. }
  453. if (context_->initial_metadata_corked_) {
  454. ops.SendInitialMetadata(&context_->send_initial_metadata_,
  455. context_->initial_metadata_flags());
  456. context_->set_initial_metadata_corked(false);
  457. }
  458. if (!ops.SendMessagePtr(&msg, options).ok()) {
  459. return false;
  460. }
  461. call_.PerformOps(&ops);
  462. return cq_.Pluck(&ops);
  463. }
  464. bool WritesDone() override {
  465. grpc::internal::CallOpSet<grpc::internal::CallOpClientSendClose> ops;
  466. ops.ClientSendClose();
  467. call_.PerformOps(&ops);
  468. return cq_.Pluck(&ops);
  469. }
  470. /// See the ClientStreamingInterface.Finish method for semantics.
  471. ///
  472. /// Side effect:
  473. /// - the \a ClientContext associated with this call is updated with
  474. /// possible trailing metadata sent from the server.
  475. grpc::Status Finish() override {
  476. grpc::internal::CallOpSet<grpc::internal::CallOpRecvInitialMetadata,
  477. grpc::internal::CallOpClientRecvStatus>
  478. ops;
  479. if (!context_->initial_metadata_received_) {
  480. ops.RecvInitialMetadata(context_);
  481. }
  482. grpc::Status status;
  483. ops.ClientRecvStatus(context_, &status);
  484. call_.PerformOps(&ops);
  485. GPR_CODEGEN_ASSERT(cq_.Pluck(&ops));
  486. return status;
  487. }
  488. private:
  489. friend class internal::ClientReaderWriterFactory<W, R>;
  490. grpc::ClientContext* context_;
  491. grpc::CompletionQueue cq_;
  492. grpc::internal::Call call_;
  493. /// Block to create a stream and write the initial metadata and \a request
  494. /// out. Note that \a context will be used to fill in custom initial metadata
  495. /// used to send to the server when starting the call.
  496. ClientReaderWriter(grpc::ChannelInterface* channel,
  497. const grpc::internal::RpcMethod& method,
  498. grpc::ClientContext* context)
  499. : context_(context),
  500. cq_(grpc_completion_queue_attributes{
  501. GRPC_CQ_CURRENT_VERSION, GRPC_CQ_PLUCK, GRPC_CQ_DEFAULT_POLLING,
  502. nullptr}), // Pluckable cq
  503. call_(channel->CreateCall(method, context, &cq_)) {
  504. if (!context_->initial_metadata_corked_) {
  505. grpc::internal::CallOpSet<grpc::internal::CallOpSendInitialMetadata> ops;
  506. ops.SendInitialMetadata(&context->send_initial_metadata_,
  507. context->initial_metadata_flags());
  508. call_.PerformOps(&ops);
  509. cq_.Pluck(&ops);
  510. }
  511. }
  512. };
  513. /// Server-side interface for streaming reads of message of type \a R.
  514. template <class R>
  515. class ServerReaderInterface : public internal::ServerStreamingInterface,
  516. public internal::ReaderInterface<R> {};
  517. /// Synchronous (blocking) server-side API for doing client-streaming RPCs,
  518. /// where the incoming message stream coming from the client has messages of
  519. /// type \a R.
  520. template <class R>
  521. class ServerReader final : public ServerReaderInterface<R> {
  522. public:
  523. /// See the \a ServerStreamingInterface.SendInitialMetadata method
  524. /// for semantics. Note that initial metadata will be affected by the
  525. /// \a ServerContext associated with this call.
  526. void SendInitialMetadata() override {
  527. GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
  528. grpc::internal::CallOpSet<grpc::internal::CallOpSendInitialMetadata> ops;
  529. ops.SendInitialMetadata(&ctx_->initial_metadata_,
  530. ctx_->initial_metadata_flags());
  531. if (ctx_->compression_level_set()) {
  532. ops.set_compression_level(ctx_->compression_level());
  533. }
  534. ctx_->sent_initial_metadata_ = true;
  535. call_->PerformOps(&ops);
  536. call_->cq()->Pluck(&ops);
  537. }
  538. bool NextMessageSize(uint32_t* sz) override {
  539. int result = call_->max_receive_message_size();
  540. *sz = (result > 0) ? result : UINT32_MAX;
  541. return true;
  542. }
  543. bool Read(R* msg) override {
  544. grpc::internal::CallOpSet<grpc::internal::CallOpRecvMessage<R>> ops;
  545. ops.RecvMessage(msg);
  546. call_->PerformOps(&ops);
  547. bool ok = call_->cq()->Pluck(&ops) && ops.got_message;
  548. if (!ok) {
  549. ctx_->MaybeMarkCancelledOnRead();
  550. }
  551. return ok;
  552. }
  553. private:
  554. grpc::internal::Call* const call_;
  555. ServerContext* const ctx_;
  556. template <class ServiceType, class RequestType, class ResponseType>
  557. friend class internal::ClientStreamingHandler;
  558. ServerReader(grpc::internal::Call* call, grpc::ServerContext* ctx)
  559. : call_(call), ctx_(ctx) {}
  560. };
  561. /// Server-side interface for streaming writes of message of type \a W.
  562. template <class W>
  563. class ServerWriterInterface : public internal::ServerStreamingInterface,
  564. public internal::WriterInterface<W> {};
  565. /// Synchronous (blocking) server-side API for doing for doing a
  566. /// server-streaming RPCs, where the outgoing message stream coming from the
  567. /// server has messages of type \a W.
  568. template <class W>
  569. class ServerWriter final : public ServerWriterInterface<W> {
  570. public:
  571. /// See the \a ServerStreamingInterface.SendInitialMetadata method
  572. /// for semantics.
  573. /// Note that initial metadata will be affected by the
  574. /// \a ServerContext associated with this call.
  575. void SendInitialMetadata() override {
  576. GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
  577. grpc::internal::CallOpSet<grpc::internal::CallOpSendInitialMetadata> ops;
  578. ops.SendInitialMetadata(&ctx_->initial_metadata_,
  579. ctx_->initial_metadata_flags());
  580. if (ctx_->compression_level_set()) {
  581. ops.set_compression_level(ctx_->compression_level());
  582. }
  583. ctx_->sent_initial_metadata_ = true;
  584. call_->PerformOps(&ops);
  585. call_->cq()->Pluck(&ops);
  586. }
  587. /// See the \a WriterInterface.Write method for semantics.
  588. ///
  589. /// Side effect:
  590. /// Also sends initial metadata if not already sent (using the
  591. /// \a ClientContext associated with this call to fill in values).
  592. using internal::WriterInterface<W>::Write;
  593. bool Write(const W& msg, grpc::WriteOptions options) override {
  594. if (options.is_last_message()) {
  595. options.set_buffer_hint();
  596. }
  597. if (!ctx_->pending_ops_.SendMessagePtr(&msg, options).ok()) {
  598. return false;
  599. }
  600. if (!ctx_->sent_initial_metadata_) {
  601. ctx_->pending_ops_.SendInitialMetadata(&ctx_->initial_metadata_,
  602. ctx_->initial_metadata_flags());
  603. if (ctx_->compression_level_set()) {
  604. ctx_->pending_ops_.set_compression_level(ctx_->compression_level());
  605. }
  606. ctx_->sent_initial_metadata_ = true;
  607. }
  608. call_->PerformOps(&ctx_->pending_ops_);
  609. // if this is the last message we defer the pluck until AFTER we start
  610. // the trailing md op. This prevents hangs. See
  611. // https://github.com/grpc/grpc/issues/11546
  612. if (options.is_last_message()) {
  613. ctx_->has_pending_ops_ = true;
  614. return true;
  615. }
  616. ctx_->has_pending_ops_ = false;
  617. return call_->cq()->Pluck(&ctx_->pending_ops_);
  618. }
  619. private:
  620. grpc::internal::Call* const call_;
  621. grpc::ServerContext* const ctx_;
  622. template <class ServiceType, class RequestType, class ResponseType>
  623. friend class internal::ServerStreamingHandler;
  624. ServerWriter(grpc::internal::Call* call, grpc::ServerContext* ctx)
  625. : call_(call), ctx_(ctx) {}
  626. };
  627. /// Server-side interface for bi-directional streaming.
  628. template <class W, class R>
  629. class ServerReaderWriterInterface : public internal::ServerStreamingInterface,
  630. public internal::WriterInterface<W>,
  631. public internal::ReaderInterface<R> {};
  632. /// Actual implementation of bi-directional streaming
  633. namespace internal {
  634. template <class W, class R>
  635. class ServerReaderWriterBody final {
  636. public:
  637. ServerReaderWriterBody(grpc::internal::Call* call, grpc::ServerContext* ctx)
  638. : call_(call), ctx_(ctx) {}
  639. void SendInitialMetadata() {
  640. GPR_CODEGEN_ASSERT(!ctx_->sent_initial_metadata_);
  641. grpc::internal::CallOpSet<grpc::internal::CallOpSendInitialMetadata> ops;
  642. ops.SendInitialMetadata(&ctx_->initial_metadata_,
  643. ctx_->initial_metadata_flags());
  644. if (ctx_->compression_level_set()) {
  645. ops.set_compression_level(ctx_->compression_level());
  646. }
  647. ctx_->sent_initial_metadata_ = true;
  648. call_->PerformOps(&ops);
  649. call_->cq()->Pluck(&ops);
  650. }
  651. bool NextMessageSize(uint32_t* sz) {
  652. int result = call_->max_receive_message_size();
  653. *sz = (result > 0) ? result : UINT32_MAX;
  654. return true;
  655. }
  656. bool Read(R* msg) {
  657. grpc::internal::CallOpSet<grpc::internal::CallOpRecvMessage<R>> ops;
  658. ops.RecvMessage(msg);
  659. call_->PerformOps(&ops);
  660. bool ok = call_->cq()->Pluck(&ops) && ops.got_message;
  661. if (!ok) {
  662. ctx_->MaybeMarkCancelledOnRead();
  663. }
  664. return ok;
  665. }
  666. bool Write(const W& msg, grpc::WriteOptions options) {
  667. if (options.is_last_message()) {
  668. options.set_buffer_hint();
  669. }
  670. if (!ctx_->pending_ops_.SendMessagePtr(&msg, options).ok()) {
  671. return false;
  672. }
  673. if (!ctx_->sent_initial_metadata_) {
  674. ctx_->pending_ops_.SendInitialMetadata(&ctx_->initial_metadata_,
  675. ctx_->initial_metadata_flags());
  676. if (ctx_->compression_level_set()) {
  677. ctx_->pending_ops_.set_compression_level(ctx_->compression_level());
  678. }
  679. ctx_->sent_initial_metadata_ = true;
  680. }
  681. call_->PerformOps(&ctx_->pending_ops_);
  682. // if this is the last message we defer the pluck until AFTER we start
  683. // the trailing md op. This prevents hangs. See
  684. // https://github.com/grpc/grpc/issues/11546
  685. if (options.is_last_message()) {
  686. ctx_->has_pending_ops_ = true;
  687. return true;
  688. }
  689. ctx_->has_pending_ops_ = false;
  690. return call_->cq()->Pluck(&ctx_->pending_ops_);
  691. }
  692. private:
  693. grpc::internal::Call* const call_;
  694. grpc::ServerContext* const ctx_;
  695. };
  696. } // namespace internal
  697. /// Synchronous (blocking) server-side API for a bidirectional
  698. /// streaming call, where the incoming message stream coming from the client has
  699. /// messages of type \a R, and the outgoing message streaming coming from
  700. /// the server has messages of type \a W.
  701. template <class W, class R>
  702. class ServerReaderWriter final : public ServerReaderWriterInterface<W, R> {
  703. public:
  704. /// See the \a ServerStreamingInterface.SendInitialMetadata method
  705. /// for semantics. Note that initial metadata will be affected by the
  706. /// \a ServerContext associated with this call.
  707. void SendInitialMetadata() override { body_.SendInitialMetadata(); }
  708. bool NextMessageSize(uint32_t* sz) override {
  709. return body_.NextMessageSize(sz);
  710. }
  711. bool Read(R* msg) override { return body_.Read(msg); }
  712. /// See the \a WriterInterface.Write(const W& msg, WriteOptions options)
  713. /// method for semantics.
  714. /// Side effect:
  715. /// Also sends initial metadata if not already sent (using the \a
  716. /// ServerContext associated with this call).
  717. using internal::WriterInterface<W>::Write;
  718. bool Write(const W& msg, grpc::WriteOptions options) override {
  719. return body_.Write(msg, options);
  720. }
  721. private:
  722. internal::ServerReaderWriterBody<W, R> body_;
  723. friend class internal::TemplatedBidiStreamingHandler<ServerReaderWriter<W, R>,
  724. false>;
  725. ServerReaderWriter(grpc::internal::Call* call, grpc::ServerContext* ctx)
  726. : body_(call, ctx) {}
  727. };
  728. /// A class to represent a flow-controlled unary call. This is something
  729. /// of a hybrid between conventional unary and streaming. This is invoked
  730. /// through a unary call on the client side, but the server responds to it
  731. /// as though it were a single-ping-pong streaming call. The server can use
  732. /// the \a NextMessageSize method to determine an upper-bound on the size of
  733. /// the message. A key difference relative to streaming: ServerUnaryStreamer
  734. /// must have exactly 1 Read and exactly 1 Write, in that order, to function
  735. /// correctly. Otherwise, the RPC is in error.
  736. template <class RequestType, class ResponseType>
  737. class ServerUnaryStreamer final
  738. : public ServerReaderWriterInterface<ResponseType, RequestType> {
  739. public:
  740. /// Block to send initial metadata to client.
  741. /// Implicit input parameter:
  742. /// - the \a ServerContext associated with this call will be used for
  743. /// sending initial metadata.
  744. void SendInitialMetadata() override { body_.SendInitialMetadata(); }
  745. /// Get an upper bound on the request message size from the client.
  746. bool NextMessageSize(uint32_t* sz) override {
  747. return body_.NextMessageSize(sz);
  748. }
  749. /// Read a message of type \a R into \a msg. Completion will be notified by \a
  750. /// tag on the associated completion queue.
  751. /// This is thread-safe with respect to \a Write or \a WritesDone methods. It
  752. /// should not be called concurrently with other streaming APIs
  753. /// on the same stream. It is not meaningful to call it concurrently
  754. /// with another \a ReaderInterface::Read on the same stream since reads on
  755. /// the same stream are delivered in order.
  756. ///
  757. /// \param[out] msg Where to eventually store the read message.
  758. /// \param[in] tag The tag identifying the operation.
  759. bool Read(RequestType* request) override {
  760. if (read_done_) {
  761. return false;
  762. }
  763. read_done_ = true;
  764. return body_.Read(request);
  765. }
  766. /// Block to write \a msg to the stream with WriteOptions \a options.
  767. /// This is thread-safe with respect to \a ReaderInterface::Read
  768. ///
  769. /// \param msg The message to be written to the stream.
  770. /// \param options The WriteOptions affecting the write operation.
  771. ///
  772. /// \return \a true on success, \a false when the stream has been closed.
  773. using internal::WriterInterface<ResponseType>::Write;
  774. bool Write(const ResponseType& response,
  775. grpc::WriteOptions options) override {
  776. if (write_done_ || !read_done_) {
  777. return false;
  778. }
  779. write_done_ = true;
  780. return body_.Write(response, options);
  781. }
  782. private:
  783. internal::ServerReaderWriterBody<ResponseType, RequestType> body_;
  784. bool read_done_;
  785. bool write_done_;
  786. friend class internal::TemplatedBidiStreamingHandler<
  787. ServerUnaryStreamer<RequestType, ResponseType>, true>;
  788. ServerUnaryStreamer(grpc::internal::Call* call, grpc::ServerContext* ctx)
  789. : body_(call, ctx), read_done_(false), write_done_(false) {}
  790. };
  791. /// A class to represent a flow-controlled server-side streaming call.
  792. /// This is something of a hybrid between server-side and bidi streaming.
  793. /// This is invoked through a server-side streaming call on the client side,
  794. /// but the server responds to it as though it were a bidi streaming call that
  795. /// must first have exactly 1 Read and then any number of Writes.
  796. template <class RequestType, class ResponseType>
  797. class ServerSplitStreamer final
  798. : public ServerReaderWriterInterface<ResponseType, RequestType> {
  799. public:
  800. /// Block to send initial metadata to client.
  801. /// Implicit input parameter:
  802. /// - the \a ServerContext associated with this call will be used for
  803. /// sending initial metadata.
  804. void SendInitialMetadata() override { body_.SendInitialMetadata(); }
  805. /// Get an upper bound on the request message size from the client.
  806. bool NextMessageSize(uint32_t* sz) override {
  807. return body_.NextMessageSize(sz);
  808. }
  809. /// Read a message of type \a R into \a msg. Completion will be notified by \a
  810. /// tag on the associated completion queue.
  811. /// This is thread-safe with respect to \a Write or \a WritesDone methods. It
  812. /// should not be called concurrently with other streaming APIs
  813. /// on the same stream. It is not meaningful to call it concurrently
  814. /// with another \a ReaderInterface::Read on the same stream since reads on
  815. /// the same stream are delivered in order.
  816. ///
  817. /// \param[out] msg Where to eventually store the read message.
  818. /// \param[in] tag The tag identifying the operation.
  819. bool Read(RequestType* request) override {
  820. if (read_done_) {
  821. return false;
  822. }
  823. read_done_ = true;
  824. return body_.Read(request);
  825. }
  826. /// Block to write \a msg to the stream with WriteOptions \a options.
  827. /// This is thread-safe with respect to \a ReaderInterface::Read
  828. ///
  829. /// \param msg The message to be written to the stream.
  830. /// \param options The WriteOptions affecting the write operation.
  831. ///
  832. /// \return \a true on success, \a false when the stream has been closed.
  833. using internal::WriterInterface<ResponseType>::Write;
  834. bool Write(const ResponseType& response,
  835. grpc::WriteOptions options) override {
  836. return read_done_ && body_.Write(response, options);
  837. }
  838. private:
  839. internal::ServerReaderWriterBody<ResponseType, RequestType> body_;
  840. bool read_done_;
  841. friend class internal::TemplatedBidiStreamingHandler<
  842. ServerSplitStreamer<RequestType, ResponseType>, false>;
  843. ServerSplitStreamer(grpc::internal::Call* call, grpc::ServerContext* ctx)
  844. : body_(call, ctx), read_done_(false) {}
  845. };
  846. } // namespace grpc
  847. #endif // GRPCPP_IMPL_CODEGEN_SYNC_STREAM_H