@@ -10,6 +10,7 @@ use std::{
1010 pin:: { Pin , pin} ,
1111 sync:: Arc ,
1212 task:: { Context , Poll } ,
13+ time:: Duration ,
1314} ;
1415use url:: Url ;
1516
@@ -36,8 +37,13 @@ impl<Client: HttpClient> HttpPuller<Client> {
3637 }
3738}
3839
39- type ResponseFut < Client > =
40- Pin < Box < dyn Future < Output = Result < GetResponse < Client > , GetRequestError < Client > > > + Send > > ;
40+ type ResponseFut < Client > = Pin <
41+ Box <
42+ dyn Future <
43+ Output = Result < GetResponse < Client > , ( GetRequestError < Client > , Option < Duration > ) > ,
44+ > + Send ,
45+ > ,
46+ > ;
4147enum ResponseState < Client : HttpClient > {
4248 Pending ( ResponseFut < Client > ) ,
4349 Ready ( GetResponse < Client > ) ,
@@ -49,7 +55,7 @@ impl<Client: HttpClient + 'static> RandPuller for HttpPuller<Client> {
4955 fn pull (
5056 & mut self ,
5157 range : & ProgressEntry ,
52- ) -> impl TryStream < Ok = Bytes , Error = Self :: Error > + Send + Unpin {
58+ ) -> impl TryStream < Ok = Bytes , Error = ( Self :: Error , Option < Duration > ) > + Send + Unpin {
5359 RandRequestStream {
5460 client : self . client . clone ( ) ,
5561 url : self . url . clone ( ) ,
@@ -76,7 +82,7 @@ struct RandRequestStream<Client: HttpClient + 'static> {
7682 file_id : FileId ,
7783}
7884impl < Client : HttpClient > Stream for RandRequestStream < Client > {
79- type Item = Result < Bytes , HttpError < Client > > ;
85+ type Item = Result < Bytes , ( HttpError < Client > , Option < Duration > ) > ;
8086 fn poll_next ( mut self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Option < Self :: Item > > {
8187 let chunk_global;
8288 match & mut self . state {
@@ -89,15 +95,18 @@ impl<Client: HttpClient> Stream for RandRequestStream<Client> {
8995 let new_file_id = FileId :: new ( etag, last_modified) ;
9096 if new_file_id != self . file_id {
9197 self . state = ResponseState :: None ;
92- Poll :: Ready ( Some ( Err ( HttpError :: MismatchedBody ( new_file_id) ) ) )
98+ Poll :: Ready ( Some ( Err ( (
99+ HttpError :: MismatchedBody ( new_file_id) ,
100+ None ,
101+ ) ) ) )
93102 } else {
94103 self . state = ResponseState :: Ready ( resp) ;
95104 self . poll_next ( cx)
96105 }
97106 }
98- Err ( e ) => {
107+ Err ( ( e , d ) ) => {
99108 self . state = ResponseState :: None ;
100- Poll :: Ready ( Some ( Err ( HttpError :: Request ( e) ) ) )
109+ Poll :: Ready ( Some ( Err ( ( HttpError :: Request ( e) , d ) ) ) )
101110 }
102111 } ,
103112 Poll :: Pending => Poll :: Pending ,
@@ -128,15 +137,17 @@ impl<Client: HttpClient> Stream for RandRequestStream<Client> {
128137 }
129138 Err ( e) => {
130139 self . state = ResponseState :: None ;
131- Poll :: Ready ( Some ( Err ( HttpError :: Chunk ( e) ) ) )
140+ Poll :: Ready ( Some ( Err ( ( HttpError :: Chunk ( e) , None ) ) ) )
132141 }
133142 }
134143 }
135144}
136145
137146impl < Client : HttpClient + ' static > SeqPuller for HttpPuller < Client > {
138147 type Error = HttpError < Client > ;
139- fn pull ( & mut self ) -> impl TryStream < Ok = Bytes , Error = Self :: Error > + Send + Unpin {
148+ fn pull (
149+ & mut self ,
150+ ) -> impl TryStream < Ok = Bytes , Error = ( Self :: Error , Option < Duration > ) > + Send + Unpin {
140151 SeqRequestStream {
141152 state : if let Some ( resp) = & self . resp
142153 && let Some ( resp) = resp. lock ( ) . take ( )
@@ -155,7 +166,7 @@ struct SeqRequestStream<Client: HttpClient + 'static> {
155166 file_id : FileId ,
156167}
157168impl < Client : HttpClient > Stream for SeqRequestStream < Client > {
158- type Item = Result < Bytes , HttpError < Client > > ;
169+ type Item = Result < Bytes , ( HttpError < Client > , Option < Duration > ) > ;
159170 fn poll_next ( mut self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Option < Self :: Item > > {
160171 let chunk_global;
161172 match & mut self . state {
@@ -168,21 +179,24 @@ impl<Client: HttpClient> Stream for SeqRequestStream<Client> {
168179 let new_file_id = FileId :: new ( etag, last_modified) ;
169180 if new_file_id != self . file_id {
170181 self . state = ResponseState :: None ;
171- Poll :: Ready ( Some ( Err ( HttpError :: MismatchedBody ( new_file_id) ) ) )
182+ Poll :: Ready ( Some ( Err ( (
183+ HttpError :: MismatchedBody ( new_file_id) ,
184+ None ,
185+ ) ) ) )
172186 } else {
173187 self . state = ResponseState :: Ready ( resp) ;
174188 self . poll_next ( cx)
175189 }
176190 }
177- Err ( e ) => {
191+ Err ( ( e , d ) ) => {
178192 self . state = ResponseState :: None ;
179- Poll :: Ready ( Some ( Err ( HttpError :: Request ( e) ) ) )
193+ Poll :: Ready ( Some ( Err ( ( HttpError :: Request ( e) , d ) ) ) )
180194 }
181195 } ,
182196 Poll :: Pending => Poll :: Pending ,
183197 } ;
184198 }
185- ResponseState :: None => return Poll :: Ready ( Some ( Err ( HttpError :: Irrecoverable ) ) ) ,
199+ ResponseState :: None => return Poll :: Ready ( Some ( Err ( ( HttpError :: Irrecoverable , None ) ) ) ) ,
186200 ResponseState :: Ready ( resp) => {
187201 let mut chunk = pin ! ( resp. chunk( ) ) ;
188202 match chunk. try_poll_unpin ( cx) {
@@ -197,7 +211,7 @@ impl<Client: HttpClient> Stream for SeqRequestStream<Client> {
197211 Ok ( chunk) => Poll :: Ready ( Some ( Ok ( chunk) ) ) ,
198212 Err ( e) => {
199213 self . state = ResponseState :: None ;
200- Poll :: Ready ( Some ( Err ( HttpError :: Chunk ( e) ) ) )
214+ Poll :: Ready ( Some ( Err ( ( HttpError :: Chunk ( e) , None ) ) ) )
201215 }
202216 }
203217 }
0 commit comments