@@ -20,11 +20,12 @@ use parking_lot::Mutex;
20
20
use std:: ops:: Range ;
21
21
use std:: { convert:: TryInto , sync:: Arc } ;
22
22
23
- use crate :: GetOptions ;
23
+ use crate :: multipart :: { MultipartStore , PartId } ;
24
24
use crate :: {
25
- path:: Path , GetResult , GetResultPayload , ListResult , MultipartUpload , ObjectMeta , ObjectStore ,
26
- PutOptions , PutResult , Result ,
25
+ path:: Path , GetResult , GetResultPayload , ListResult , MultipartId , MultipartUpload , ObjectMeta ,
26
+ ObjectStore , PutOptions , PutResult , Result ,
27
27
} ;
28
+ use crate :: { GetOptions , UploadPart } ;
28
29
use async_trait:: async_trait;
29
30
use bytes:: Bytes ;
30
31
use futures:: { stream:: BoxStream , FutureExt , StreamExt } ;
@@ -110,12 +111,12 @@ async fn sleep(duration: Duration) {
110
111
/// **Note that the behavior of the wrapper is deterministic and might not reflect real-world
111
112
/// conditions!**
112
113
#[ derive( Debug ) ]
113
- pub struct ThrottledStore < T : ObjectStore > {
114
+ pub struct ThrottledStore < T > {
114
115
inner : T ,
115
116
config : Arc < Mutex < ThrottleConfig > > ,
116
117
}
117
118
118
- impl < T : ObjectStore > ThrottledStore < T > {
119
+ impl < T > ThrottledStore < T > {
119
120
/// Create new wrapper with zero waiting times.
120
121
pub fn new ( inner : T , config : ThrottleConfig ) -> Self {
121
122
Self {
@@ -157,8 +158,12 @@ impl<T: ObjectStore> ObjectStore for ThrottledStore<T> {
157
158
self . inner . put_opts ( location, bytes, opts) . await
158
159
}
159
160
160
- async fn put_multipart ( & self , _location : & Path ) -> Result < Box < dyn MultipartUpload > > {
161
- Err ( super :: Error :: NotImplemented )
161
+ async fn put_multipart ( & self , location : & Path ) -> Result < Box < dyn MultipartUpload > > {
162
+ let upload = self . inner . put_multipart ( location) . await ?;
163
+ Ok ( Box :: new ( ThrottledUpload {
164
+ upload,
165
+ sleep : self . config ( ) . wait_put_per_call ,
166
+ } ) )
162
167
}
163
168
164
169
async fn get ( & self , location : & Path ) -> Result < GetResult > {
@@ -316,6 +321,63 @@ where
316
321
. boxed ( )
317
322
}
318
323
324
+ #[ async_trait]
325
+ impl < T : MultipartStore > MultipartStore for ThrottledStore < T > {
326
+ async fn create_multipart ( & self , path : & Path ) -> Result < MultipartId > {
327
+ self . inner . create_multipart ( path) . await
328
+ }
329
+
330
+ async fn put_part (
331
+ & self ,
332
+ path : & Path ,
333
+ id : & MultipartId ,
334
+ part_idx : usize ,
335
+ data : Bytes ,
336
+ ) -> Result < PartId > {
337
+ sleep ( self . config ( ) . wait_put_per_call ) . await ;
338
+ self . inner . put_part ( path, id, part_idx, data) . await
339
+ }
340
+
341
+ async fn complete_multipart (
342
+ & self ,
343
+ path : & Path ,
344
+ id : & MultipartId ,
345
+ parts : Vec < PartId > ,
346
+ ) -> Result < PutResult > {
347
+ self . inner . complete_multipart ( path, id, parts) . await
348
+ }
349
+
350
+ async fn abort_multipart ( & self , path : & Path , id : & MultipartId ) -> Result < ( ) > {
351
+ self . inner . abort_multipart ( path, id) . await
352
+ }
353
+ }
354
+
355
+ #[ derive( Debug ) ]
356
+ struct ThrottledUpload {
357
+ upload : Box < dyn MultipartUpload > ,
358
+ sleep : Duration ,
359
+ }
360
+
361
+ #[ async_trait]
362
+ impl MultipartUpload for ThrottledUpload {
363
+ fn put_part ( & mut self , data : Bytes ) -> UploadPart {
364
+ let duration = self . sleep ;
365
+ let put = self . upload . put_part ( data) ;
366
+ Box :: pin ( async move {
367
+ sleep ( duration) . await ;
368
+ put. await
369
+ } )
370
+ }
371
+
372
+ async fn complete ( & mut self ) -> Result < PutResult > {
373
+ self . upload . complete ( ) . await
374
+ }
375
+
376
+ async fn abort ( & mut self ) -> Result < ( ) > {
377
+ self . upload . abort ( ) . await
378
+ }
379
+ }
380
+
319
381
#[ cfg( test) ]
320
382
mod tests {
321
383
use super :: * ;
@@ -351,6 +413,8 @@ mod tests {
351
413
list_with_delimiter ( & store) . await ;
352
414
rename_and_copy ( & store) . await ;
353
415
copy_if_not_exists ( & store) . await ;
416
+ stream_get ( & store) . await ;
417
+ multipart ( & store, & store) . await ;
354
418
}
355
419
356
420
#[ tokio:: test]
0 commit comments