chenBright commented on PR #2946: URL: https://github.com/apache/brpc/pull/2946#issuecomment-2796451993
> 有点复杂了。我觉得把compress和序列化方式耦合在一起不太好,组合太多了。 可以考虑先序列化成一个SerializedRequest,然后再传进Compress。 解压的时候先Decompress成一个SerializedRequest,然后再反序列化。 或者能不能把序列化/反序列化的工作交给用户自己去做呢?用户只要传递SerializedRequest/SerializedResponse和框架交互就可以了。 gzip和zlib的compress和序列化方式耦合的原因应该是protobuf接口导致的,GzipInputStream/GzipOutputStream将解压/压缩过程作为输入/输出流的一部分了。这应该是出于性能考虑吧,我测了一下,耦合的性能比非耦合的性能高: ```shell # 1kb I20250411 11:00:48.295392 2989 brpc_http_rpc_protocol_unittest.cpp:1884] Compress 100000 times, cost 444246ns/call I20250411 11:00:57.442049 2989 brpc_http_rpc_protocol_unittest.cpp:1893] Compress 100000 times, cost 91466ns/call # 16kb I20250411 11:49:16.398469 110097 brpc_http_rpc_protocol_unittest.cpp:1884] Compress 100000 times, cost 75561ns/call I20250411 11:49:17.467223 110097 brpc_http_rpc_protocol_unittest.cpp:1893] Compress 100000 times, cost 10687ns/call ``` 所以,还是有必要保留耦合的实现。而protobuf不支持的snappy的实现是非耦合的(题外话:可能也可以实现为耦合方式,提高性能)。 所以得同时支持这两种模式。 抽象一下,将compress和序列化方式两个过程尽量解耦: ```c++ // CompressCallback provides raw data for compression, // and a buffer for storing compressed data. class CompressCallback : public CompressBase { public: // Converts the data into `output' for later compression. virtual bool Convert(google::protobuf::io::ZeroCopyOutputStream* output) = 0; // Returns the buffer for storing compressed data. virtual butil::IOBuf& Buffer() = 0; }; // DecompressCallback provides raw data stored in a buffer for decompression, // and handles the decompressed data. class DecompressCallback : public CompressBase { public: // Converts the decompressed `input'. virtual bool Convert(google::protobuf::io::ZeroCopyInputStream* intput) = 0; // Returns the buffer containing compressed data. virtual const butil::IOBuf& Buffer() = 0; }; struct CompressHandler { // Compress data from CompressCallback::Convert() into CompressCallback::Buffer(). bool (*Compress)(CompressCallback& callback); // Decompress data from DecompressCallback::Buffer() into DecompressCallback::Convert(). bool (*Decompress)(DecompressCallback& callback); // Name of the compression algorithm, must be string constant. const char* name; }; ``` 每种序列化方式的CompressObject/DecompressObject实现了序列化/反序列化逻辑,到时作为回调传给CompressHandler,每种CompressHandler根据自己的特点,选择时候使用耦合的实现,以及在合适的位置调用回调函数进行序列化/反序列化。 -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: dev-unsubscr...@brpc.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@brpc.apache.org For additional commands, e-mail: dev-h...@brpc.apache.org