@@ -21,6 +21,7 @@ use crate::futures01::Async;
2121use crate :: futures01:: Poll ;
2222use crate :: ipfs:: ContentPath ;
2323use crate :: ipfs:: IpfsClient ;
24+ use crate :: ipfs:: RetryPolicy ;
2425use crate :: prelude:: { LinkResolver as LinkResolverTrait , * } ;
2526
2627#[ derive( Clone , CheapClone , Derivative ) ]
@@ -36,6 +37,9 @@ pub struct IpfsResolver {
3637 max_file_size : usize ,
3738 max_map_file_size : usize ,
3839 max_cache_file_size : usize ,
40+
41+ /// When set to `true`, it means infinite retries, ignoring the timeout setting.
42+ retry : bool ,
3943}
4044
4145impl IpfsResolver {
@@ -51,6 +55,7 @@ impl IpfsResolver {
5155 max_file_size : env. max_ipfs_file_bytes ,
5256 max_map_file_size : env. max_ipfs_map_file_size ,
5357 max_cache_file_size : env. max_ipfs_cache_file_size ,
58+ retry : false ,
5459 }
5560 }
5661}
@@ -64,8 +69,9 @@ impl LinkResolverTrait for IpfsResolver {
6469 }
6570
6671 fn with_retries ( & self ) -> Box < dyn LinkResolverTrait > {
67- // IPFS clients have internal retries enabled by default.
68- Box :: new ( self . cheap_clone ( ) )
72+ let mut s = self . cheap_clone ( ) ;
73+ s. retry = true ;
74+ Box :: new ( s)
6975 }
7076
7177 async fn cat ( & self , logger : & Logger , link : & Link ) -> Result < Vec < u8 > , Error > {
@@ -81,9 +87,16 @@ impl LinkResolverTrait for IpfsResolver {
8187
8288 trace ! ( logger, "IPFS cat cache miss" ; "hash" => path. to_string( ) ) ;
8389
90+ let ( timeout, retry_policy) = if self . retry {
91+ ( None , RetryPolicy :: NonDeterministic )
92+ } else {
93+ ( Some ( timeout) , RetryPolicy :: Networking )
94+ } ;
95+
8496 let data = self
8597 . client
86- . cat ( & path, max_file_size, Some ( timeout) )
98+ . clone ( )
99+ . cat ( & path, max_file_size, timeout, retry_policy)
87100 . await ?
88101 . to_vec ( ) ;
89102
@@ -111,20 +124,39 @@ impl LinkResolverTrait for IpfsResolver {
111124
112125 trace ! ( logger, "IPFS block get" ; "hash" => path. to_string( ) ) ;
113126
114- let data = self . client . get_block ( & path, Some ( timeout) ) . await ?. to_vec ( ) ;
127+ let ( timeout, retry_policy) = if self . retry {
128+ ( None , RetryPolicy :: NonDeterministic )
129+ } else {
130+ ( Some ( timeout) , RetryPolicy :: Networking )
131+ } ;
132+
133+ let data = self
134+ . client
135+ . clone ( )
136+ . get_block ( & path, timeout, retry_policy)
137+ . await ?
138+ . to_vec ( ) ;
115139
116140 Ok ( data)
117141 }
118142
119143 async fn json_stream ( & self , logger : & Logger , link : & Link ) -> Result < JsonValueStream , Error > {
120144 let path = ContentPath :: new ( & link. link ) ?;
121145 let max_map_file_size = self . max_map_file_size ;
146+ let timeout = self . timeout ;
122147
123148 trace ! ( logger, "IPFS JSON stream" ; "hash" => path. to_string( ) ) ;
124149
150+ let ( timeout, retry_policy) = if self . retry {
151+ ( None , RetryPolicy :: NonDeterministic )
152+ } else {
153+ ( Some ( timeout) , RetryPolicy :: Networking )
154+ } ;
155+
125156 let mut stream = self
126157 . client
127- . cat_stream ( & path, None )
158+ . clone ( )
159+ . cat_stream ( & path, timeout, retry_policy)
128160 . await ?
129161 . fuse ( )
130162 . boxed ( )
@@ -228,11 +260,8 @@ mod tests {
228260
229261 let logger = crate :: log:: discard ( ) ;
230262
231- let client = IpfsRpcClient :: new_unchecked ( ServerAddress :: local_rpc_api ( ) , & logger)
232- . unwrap ( )
233- . into_boxed ( ) ;
234-
235- let resolver = IpfsResolver :: new ( client. into ( ) , Arc :: new ( env_vars) ) ;
263+ let client = IpfsRpcClient :: new_unchecked ( ServerAddress :: local_rpc_api ( ) , & logger) . unwrap ( ) ;
264+ let resolver = IpfsResolver :: new ( Arc :: new ( client) , Arc :: new ( env_vars) ) ;
236265
237266 let err = IpfsResolver :: cat ( & resolver, & logger, & Link { link : cid. clone ( ) } )
238267 . await
@@ -250,9 +279,8 @@ mod tests {
250279 . to_owned ( ) ;
251280
252281 let logger = crate :: log:: discard ( ) ;
253- let client =
254- IpfsRpcClient :: new_unchecked ( ServerAddress :: local_rpc_api ( ) , & logger) ?. into_boxed ( ) ;
255- let resolver = IpfsResolver :: new ( client. into ( ) , Arc :: new ( env_vars) ) ;
282+ let client = IpfsRpcClient :: new_unchecked ( ServerAddress :: local_rpc_api ( ) , & logger) ?;
283+ let resolver = IpfsResolver :: new ( Arc :: new ( client) , Arc :: new ( env_vars) ) ;
256284
257285 let stream = IpfsResolver :: json_stream ( & resolver, & logger, & Link { link : cid } ) . await ?;
258286 stream. map_ok ( |sv| sv. value ) . try_collect ( ) . await
0 commit comments