@@ -669,79 +669,118 @@ async fn backup_files(s3_client: &S3Client, bucket: String) -> anyhow::Result<()
669
669
. as_ref ( )
670
670
. to_string ( ) ;
671
671
let mut retry = 3 ;
672
- while let Err ( e) = s3_client
673
- . create_multipart_upload ( rusoto_s3:: CreateMultipartUploadRequest {
674
- bucket : bucket. clone ( ) ,
675
- key : file_name. clone ( ) ,
676
- storage_class : Some ( "DEEP_ARCHIVE" . to_string ( ) ) ,
677
- ..Default :: default ( )
678
- } )
679
- . await
680
- . and_then ( |create_result| {
681
- Ok ( async {
682
- let upload_id = create_result. upload_id . unwrap ( ) ;
683
-
684
- // Use 5MB chunks (minimum size for S3 multipart)
685
- const CHUNK_SIZE : usize = 5 * 1024 * 1024 ;
686
- let mut parts = Vec :: new ( ) ;
687
-
688
- for ( part_number, chunk) in buf. chunks ( CHUNK_SIZE ) . enumerate ( ) {
689
- let part_number = ( part_number + 1 ) as i64 ;
690
-
691
- let upload_result = s3_client
692
- . upload_part ( rusoto_s3:: UploadPartRequest {
693
- bucket : bucket. clone ( ) ,
694
- key : file_name. clone ( ) ,
695
- upload_id : upload_id. clone ( ) ,
696
- part_number,
697
- body : Some ( chunk. to_vec ( ) . into ( ) ) ,
698
- ..Default :: default ( )
699
- } )
700
- . await
701
- . unwrap ( ) ;
702
672
673
+ ' retry_loop: while retry > 0 {
674
+ let create_result = match s3_client
675
+ . create_multipart_upload ( rusoto_s3:: CreateMultipartUploadRequest {
676
+ bucket : bucket. clone ( ) ,
677
+ key : file_name. clone ( ) ,
678
+ storage_class : Some ( "DEEP_ARCHIVE" . to_string ( ) ) ,
679
+ ..Default :: default ( )
680
+ } )
681
+ . await
682
+ {
683
+ Ok ( result) => result,
684
+ Err ( e) => {
685
+ retry -= 1 ;
686
+ println ! ( "{file_name}: 创建上传请求失败: {e},剩余重试次数: {retry}" ) ;
687
+ continue ' retry_loop;
688
+ }
689
+ } ;
690
+
691
+ let upload_id = match create_result. upload_id {
692
+ Some ( id) => id,
693
+ None => {
694
+ retry -= 1 ;
695
+ println ! ( "{file_name}: 无法获取上传ID,剩余重试次数: {retry}" ) ;
696
+ continue ' retry_loop;
697
+ }
698
+ } ;
699
+
700
+ const CHUNK_SIZE : usize = 5 * 1024 * 1024 ;
701
+ let mut parts = Vec :: new ( ) ;
702
+ let mut upload_failed = false ;
703
+
704
+ for ( part_number, chunk) in buf. chunks ( CHUNK_SIZE ) . enumerate ( ) {
705
+ let part_number = ( part_number + 1 ) as i64 ;
706
+
707
+ match s3_client
708
+ . upload_part ( rusoto_s3:: UploadPartRequest {
709
+ bucket : bucket. clone ( ) ,
710
+ key : file_name. clone ( ) ,
711
+ upload_id : upload_id. clone ( ) ,
712
+ part_number,
713
+ body : Some ( chunk. to_vec ( ) . into ( ) ) ,
714
+ ..Default :: default ( )
715
+ } )
716
+ . await
717
+ {
718
+ Ok ( upload_result) => {
703
719
parts. push ( rusoto_s3:: CompletedPart {
704
720
e_tag : upload_result. e_tag ,
705
721
part_number : Some ( part_number) ,
706
722
} ) ;
707
723
}
724
+ Err ( e) => {
725
+ println ! ( "{file_name}: 分块 {part_number} 上传失败: {e}" ) ;
726
+ upload_failed = true ;
727
+ break ;
728
+ }
729
+ }
730
+ }
731
+
732
+ if upload_failed {
733
+ retry -= 1 ;
734
+ println ! ( "{file_name}: 分块上传失败,剩余重试次数: {retry}" ) ;
708
735
709
- s3_client
710
- . complete_multipart_upload ( rusoto_s3:: CompleteMultipartUploadRequest {
711
- bucket : bucket. clone ( ) ,
712
- key : file_name. clone ( ) ,
713
- upload_id,
714
- multipart_upload : Some ( rusoto_s3:: CompletedMultipartUpload {
715
- parts : Some ( parts) ,
716
- } ) ,
717
- ..Default :: default ( )
718
- } )
719
- . await
736
+ let _ = s3_client
737
+ . abort_multipart_upload ( rusoto_s3:: AbortMultipartUploadRequest {
738
+ bucket : bucket. clone ( ) ,
739
+ key : file_name. clone ( ) ,
740
+ upload_id : upload_id. clone ( ) ,
741
+ ..Default :: default ( )
742
+ } )
743
+ . await ;
744
+
745
+ continue ' retry_loop;
746
+ }
747
+
748
+ match s3_client
749
+ . complete_multipart_upload ( rusoto_s3:: CompleteMultipartUploadRequest {
750
+ bucket : bucket. clone ( ) ,
751
+ key : file_name. clone ( ) ,
752
+ upload_id,
753
+ multipart_upload : Some ( rusoto_s3:: CompletedMultipartUpload {
754
+ parts : Some ( parts) ,
755
+ } ) ,
756
+ ..Default :: default ( )
720
757
} )
721
- } )
722
- {
723
- retry -= 1 ;
724
- if retry <= 0 {
725
- break ;
758
+ . await
759
+ {
760
+ Ok ( _) => {
761
+ println ! ( "{file_name}: 上传成功!" ) ;
762
+ file_success += 1 ;
763
+ break ' retry_loop;
764
+ }
765
+ Err ( e) => {
766
+ retry -= 1 ;
767
+ println ! ( "{file_name}: 完成上传失败: {e},剩余重试次数: {retry}" ) ;
768
+ }
726
769
}
727
- println ! ( "{file_name}: 上传失败: {e},剩余重试次数: {retry}" )
728
770
}
771
+
729
772
if retry <= 0 {
730
- println ! ( "{file_name}: 上传失败!跳过此文件" )
731
- } else {
732
- println ! ( "{file_name}: 上传成功!" ) ;
733
- file_success += 1 ;
773
+ println ! ( "{file_name}: 上传失败!跳过此文件" ) ;
734
774
}
735
775
}
736
776
}
737
777
let file_failed = file_dir. read_dir ( ) ?. count ( ) - file_success;
738
- println ! ( "Backup files uploaded, success: {file_success}, failed: {file_failed}" , ) ;
739
- if ! file_failed = = 0 {
778
+ println ! ( "Backup files uploaded, success: {file_success}, failed: {file_failed}" ) ;
779
+ if file_failed ! = 0 {
740
780
Err ( anyhow:: anyhow!( "Upload backup files failed" ) )
741
781
} else {
742
782
Ok ( ( ) )
743
783
}
744
- //Upload files
745
784
}
746
785
747
786
async fn get_temp_files ( backend_url : & str , backend_token : & str ) -> anyhow:: Result < ApiResult > {
0 commit comments