11/// `OpenDAL` backend for rustic.
22use std:: { collections:: HashMap , path:: PathBuf , str:: FromStr , sync:: OnceLock } ;
33
4- use anyhow:: Result ;
4+ use anyhow:: { anyhow , Error , Result } ;
55use bytes:: Bytes ;
6+ use bytesize:: ByteSize ;
67use log:: trace;
78use opendal:: {
8- layers:: { BlockingLayer , ConcurrentLimitLayer , LoggingLayer , RetryLayer } ,
9+ layers:: { BlockingLayer , ConcurrentLimitLayer , LoggingLayer , RetryLayer , ThrottleLayer } ,
910 BlockingOperator , ErrorKind , Metakey , Operator , Scheme ,
1011} ;
1112use rayon:: prelude:: { IntoParallelIterator , ParallelIterator } ;
@@ -34,6 +35,31 @@ fn runtime() -> &'static Runtime {
3435 } )
3536}
3637
38+ /// Throttling parameters
39+ ///
40+ /// Note: Throttle implements FromStr to read it from something like "10kiB,10MB"
41+ #[ derive( Debug , Clone , Copy ) ]
42+ pub struct Throttle {
43+ bandwidth : u32 ,
44+ burst : u32 ,
45+ }
46+
47+ impl FromStr for Throttle {
48+ type Err = Error ;
49+ fn from_str ( s : & str ) -> Result < Self > {
50+ let mut values = s
51+ . split ( ',' )
52+ . map ( |s| ByteSize :: from_str ( s) . map_err ( |err| anyhow ! ( "Error: {err}" ) ) )
53+ . map ( |b| -> Result < u32 > { Ok ( b?. as_u64 ( ) . try_into ( ) ?) } ) ;
54+ let bandwidth = values
55+ . next ( )
56+ . ok_or_else ( || anyhow ! ( "no bandwidth given" ) ) ??;
57+ let burst = values. next ( ) . ok_or_else ( || anyhow ! ( "no burst given" ) ) ??;
58+ let throttle = Throttle { bandwidth, burst } ;
59+ Ok ( throttle)
60+ }
61+ }
62+
3763impl OpenDALBackend {
3864 /// Create a new openDAL backend.
3965 ///
@@ -60,10 +86,19 @@ impl OpenDALBackend {
6086 . map ( |c| usize:: from_str ( c) )
6187 . transpose ( ) ?;
6288
89+ let throttle = options
90+ . get ( "throttle" )
91+ . map ( |t| Throttle :: from_str ( t) )
92+ . transpose ( ) ?;
93+
6394 let schema = Scheme :: from_str ( path. as_ref ( ) ) ?;
6495 let mut operator = Operator :: via_map ( schema, options) ?
6596 . layer ( RetryLayer :: new ( ) . with_max_times ( max_retries) . with_jitter ( ) ) ;
6697
98+ if let Some ( Throttle { bandwidth, burst } ) = throttle {
99+ operator = operator. layer ( ThrottleLayer :: new ( bandwidth, burst) ) ;
100+ }
101+
67102 if let Some ( connections) = connections {
68103 operator = operator. layer ( ConcurrentLimitLayer :: new ( connections) ) ;
69104 }
0 commit comments