11use crate :: { models:: Envelope , Error , HttpClient } ;
22use bytes:: Bytes ;
3+ use flate2:: { write:: GzEncoder , Compression } ;
34use http:: { Request , Response , Uri } ;
45use serde:: Deserialize ;
56#[ cfg( feature = "metrics" ) ]
67use std:: io:: Read ;
8+ use std:: io:: Write ;
79
810const STATUS_OK : u16 = 200 ;
911const STATUS_PARTIAL_CONTENT : u16 = 206 ;
@@ -33,9 +35,10 @@ pub(crate) async fn send(
3335 endpoint : & Uri ,
3436 items : Vec < Envelope > ,
3537) -> Result < ( ) , Error > {
36- let payload = serde_json :: to_vec ( & items) . map_err ( Error :: UploadSerializeRequest ) ?;
38+ let payload = serialize_request_body ( items) ?;
3739 let request = Request :: post ( endpoint)
3840 . header ( http:: header:: CONTENT_TYPE , "application/json" )
41+ . header ( http:: header:: CONTENT_ENCODING , "gzip" )
3942 . body ( payload)
4043 . expect ( "request should be valid" ) ;
4144
@@ -50,11 +53,12 @@ pub(crate) async fn send(
5053/// Sends a telemetry items to the server.
5154#[ cfg( feature = "metrics" ) ]
5255pub ( crate ) fn send_sync ( endpoint : & Uri , items : Vec < Envelope > ) -> Result < ( ) , Error > {
53- let payload = serde_json :: to_vec ( & items) . map_err ( Error :: UploadSerializeRequest ) ?;
56+ let payload = serialize_request_body ( items) ?;
5457
5558 // TODO Implement retries
5659 let response = match ureq:: post ( & endpoint. to_string ( ) )
5760 . set ( http:: header:: CONTENT_TYPE . as_str ( ) , "application/json" )
61+ . set ( http:: header:: CONTENT_ENCODING . as_str ( ) , "gzip" )
5862 . send_bytes ( & payload)
5963 {
6064 Ok ( response) => response,
@@ -79,6 +83,20 @@ pub(crate) fn send_sync(endpoint: &Uri, items: Vec<Envelope>) -> Result<(), Erro
7983 )
8084}
8185
86+ fn serialize_request_body ( items : Vec < Envelope > ) -> Result < Vec < u8 > , Error > {
87+ // Weirdly gzip_encoder.write_all(serde_json::to_vec()) seems to be faster than
88+ // serde_json::to_writer(gzip_encoder). In a local test operating on items that result in
89+ // ~13MiB of JSON, this is what I've seen:
90+ // gzip_encoder.write_all(serde_json::to_vec()): 159ms
91+ // serde_json::to_writer(gzip_encoder): 247ms
92+ let serialized = serde_json:: to_vec ( & items) . map_err ( Error :: UploadSerializeRequest ) ?;
93+ let mut gzip_encoder = GzEncoder :: new ( Vec :: new ( ) , Compression :: default ( ) ) ;
94+ gzip_encoder
95+ . write_all ( & serialized)
96+ . map_err ( Error :: UploadCompressRequest ) ?;
97+ gzip_encoder. finish ( ) . map_err ( Error :: UploadCompressRequest )
98+ }
99+
82100fn handle_response ( response : Response < Bytes > ) -> Result < ( ) , Error > {
83101 match response. status ( ) . as_u16 ( ) {
84102 STATUS_OK => Ok ( ( ) ) ,
0 commit comments