@@ -12,6 +12,7 @@ import (
12
12
"regexp"
13
13
"strconv"
14
14
"strings"
15
+ "sync"
15
16
"time"
16
17
17
18
alicred "github.com/aliyun/alibaba-cloud-sdk-go/sdk/auth/credentials"
@@ -912,11 +913,59 @@ func (rs *S3Storage) CreateUploader(ctx context.Context, name string) (ExternalF
912
913
}, nil
913
914
}
914
915
915
- // Create creates multi upload request.
916
- func (rs * S3Storage ) Create (ctx context.Context , name string ) (ExternalFileWriter , error ) {
917
- uploader , err := rs .CreateUploader (ctx , name )
916
+ type s3ObjectWriter struct {
917
+ wd * io.PipeWriter
918
+ wg * sync.WaitGroup
919
+ err error
920
+ }
921
+
922
+ // Write implement the io.Writer interface.
923
+ func (s * s3ObjectWriter ) Write (_ context.Context , p []byte ) (int , error ) {
924
+ return s .wd .Write (p )
925
+ }
926
+
927
+ // Close implement the io.Closer interface.
928
+ func (s * s3ObjectWriter ) Close (_ context.Context ) error {
929
+ err := s .wd .Close ()
918
930
if err != nil {
919
- return nil , err
931
+ return err
932
+ }
933
+ s .wg .Wait ()
934
+ return s .err
935
+ }
936
+
937
+ // Create creates multi upload request.
938
+ func (rs * S3Storage ) Create (ctx context.Context , name string , option * WriterOption ) (ExternalFileWriter , error ) {
939
+ var uploader ExternalFileWriter
940
+ var err error
941
+ if option == nil || option .Concurrency <= 1 {
942
+ uploader , err = rs .CreateUploader (ctx , name )
943
+ if err != nil {
944
+ return nil , err
945
+ }
946
+ } else {
947
+ up := s3manager .NewUploaderWithClient (rs .svc , func (u * s3manager.Uploader ) {
948
+ u .Concurrency = option .Concurrency
949
+ u .BufferProvider = s3manager .NewBufferedReadSeekerWriteToPool (option .Concurrency * 8 * 1024 * 1024 )
950
+ })
951
+ rd , wd := io .Pipe ()
952
+ upParams := & s3manager.UploadInput {
953
+ Bucket : aws .String (rs .options .Bucket ),
954
+ Key : aws .String (rs .options .Prefix + name ),
955
+ Body : rd ,
956
+ }
957
+ s3Writer := & s3ObjectWriter {wd : wd , wg : & sync.WaitGroup {}}
958
+ s3Writer .wg .Add (1 )
959
+ go func () {
960
+ _ , err := up .UploadWithContext (ctx , upParams )
961
+ err1 := rd .Close ()
962
+ if err != nil {
963
+ log .Warn ("upload to s3 failed" , zap .String ("filename" , name ), zap .Error (err ), zap .Error (err1 ))
964
+ }
965
+ s3Writer .err = err
966
+ s3Writer .wg .Done ()
967
+ }()
968
+ uploader = s3Writer
920
969
}
921
970
uploaderWriter := newBufferedWriter (uploader , hardcodedS3ChunkSize , NoCompression )
922
971
return uploaderWriter , nil
0 commit comments