progressive_reader.h 4.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. // Licensed to the Apache Software Foundation (ASF) under one
  2. // or more contributor license agreements. See the NOTICE file
  3. // distributed with this work for additional information
  4. // regarding copyright ownership. The ASF licenses this file
  5. // to you under the Apache License, Version 2.0 (the
  6. // "License"); you may not use this file except in compliance
  7. // with the License. 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,
  12. // software distributed under the License is distributed on an
  13. // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  14. // KIND, either express or implied. See the License for the
  15. // specific language governing permissions and limitations
  16. // under the License.
  17. #ifndef BRPC_PROGRESSIVE_READER_H
  18. #define BRPC_PROGRESSIVE_READER_H
  19. #include "brpc/shared_object.h"
  20. namespace brpc {
  21. // [Implement by user]
  22. // To read a very long or infinitely long response progressively.
  23. // Client-side usage:
  24. // cntl.response_will_be_read_progressively(); // before RPC
  25. // ...
  26. // channel.CallMethod(NULL, &cntl, NULL, NULL, NULL/*done*/);
  27. // ...
  28. // cntl.ReadProgressiveAttachmentBy(new MyProgressiveReader); // after RPC
  29. // ...
  30. class ProgressiveReader {
  31. public:
  32. // Called when one part was read.
  33. // Error returned is treated as *permenant* and the socket where the
  34. // data was read will be closed.
  35. // A temporary error may be handled by blocking this function, which
  36. // may block the HTTP parsing on the socket.
  37. virtual butil::Status OnReadOnePart(const void* data, size_t length) = 0;
  38. // Called when there's nothing to read anymore. The `status' is a hint for
  39. // why this method is called.
  40. // - status.ok(): the message is complete and successfully consumed.
  41. // - otherwise: socket was broken or OnReadOnePart() failed.
  42. // This method will be called once and only once. No other methods will
  43. // be called after. User can release the memory of this object inside.
  44. virtual void OnEndOfMessage(const butil::Status& status) = 0;
  45. protected:
  46. virtual ~ProgressiveReader() {}
  47. };
  48. // [Implement by protocol handlers]
  49. // Share ProgressiveReader between protocol handlers and controllers.
  50. // Take chunked HTTP response as an example:
  51. // 1. The protocol handler parses headers and goes to ProcessHttpResponse
  52. // before reading all body.
  53. // 2. ProcessHttpResponse sets controller's RPA which is just the HttpContext
  54. // in this case. The RPC ends at the end of ProcessHttpResponse.
  55. // 3. When the RPC ends, user may call Controller.ReadProgressiveAttachmentBy()
  56. // to read the body. If user does not set a reader, controller sets one
  57. // ignoring all bytes read before self's destruction.
  58. // The call chain:
  59. // Controller.ReadProgressiveAttachmentBy()
  60. // -> ReadableProgressiveAttachment.ReadProgressiveAttachmentBy()
  61. // -> HttpMesage.SetBodyReader()
  62. // -> ProgressiveReader.OnReadOnePart()
  63. // Already-read body will be fed immediately and the reader is remembered.
  64. // 4. The protocol handler also sets a reference to the RPA in the socket.
  65. // When new part arrives, HttpMessage.on_body is called, which calls
  66. // ProgressiveReader.OnReadOnePart() when reader is set.
  67. // 5. When all body is read, the socket releases the reference to the RPA.
  68. // If controller is deleted after all body is read, the RPA should be
  69. // destroyed at controller's deletion. If controller is deleted before
  70. // all body is read, the RPA should be destroyed when all body is read
  71. // or the socket is destroyed.
  72. class ReadableProgressiveAttachment : public SharedObject {
  73. public:
  74. // Read the constantly-appending attachment by a ProgressiveReader.
  75. // Any error occurred should destroy the reader by calling r->Destroy().
  76. // r->Destroy() should be guaranteed to be called once and only once.
  77. virtual void ReadProgressiveAttachmentBy(ProgressiveReader* r) = 0;
  78. };
  79. } // namespace brpc
  80. #endif // BRPC_PROGRESSIVE_READER_H