@@ -118,16 +118,53 @@ protected function writeMultiPart(string $urn, StreamInterface $stream, ?string
118118 ] + $ this ->getSSECParameters (),
119119 ]);
120120
121- try {
122- $ uploader ->upload ();
123- } catch (S3MultipartUploadException $ e ) {
121+ $ attempts = 0 ;
122+ $ uploaded = false ;
123+ $ concurrency = $ this ->concurrency ;
124+ $ exception = null ;
125+ $ state = null ;
126+
127+ // retry multipart upload once with concurrency at half on failure
128+ while (!$ uploaded && $ attempts <= 1 ) {
129+ $ uploader = new MultipartUploader ($ this ->getConnection (), $ stream , [
130+ 'bucket ' => $ this ->bucket ,
131+ 'concurrency ' => $ concurrency ,
132+ 'key ' => $ urn ,
133+ 'part_size ' => $ this ->uploadPartSize ,
134+ 'state ' => $ state ,
135+ 'params ' => [
136+ 'ContentType ' => $ mimetype ,
137+ 'Metadata ' => $ this ->buildS3Metadata ($ metaData ),
138+ 'StorageClass ' => $ this ->storageClass ,
139+ ] + $ this ->getSSECParameters (),
140+ ]);
141+
142+ try {
143+ $ uploader ->upload ();
144+ $ uploaded = true ;
145+ } catch (S3MultipartUploadException $ e ) {
146+ $ exception = $ e ;
147+ $ attempts ++;
148+
149+ if ($ concurrency > 1 ) {
150+ $ concurrency = round ($ concurrency / 2 );
151+ }
152+
153+ if ($ stream ->isSeekable ()) {
154+ $ stream ->rewind ();
155+ }
156+ }
157+ }
158+
159+ if (!$ uploaded ) {
124160 // if anything goes wrong with multipart, make sure that you don´t poison and
125161 // slow down s3 bucket with orphaned fragments
126- $ uploadInfo = $ e ->getState ()->getId ();
127- if ($ e ->getState ()->isInitiated () && (array_key_exists ('UploadId ' , $ uploadInfo ))) {
162+ $ uploadInfo = $ exception ->getState ()->getId ();
163+ if ($ exception ->getState ()->isInitiated () && (array_key_exists ('UploadId ' , $ uploadInfo ))) {
128164 $ this ->getConnection ()->abortMultipartUpload ($ uploadInfo );
129165 }
130- throw new \OCA \DAV \Connector \Sabre \Exception \BadGateway ('Error while uploading to S3 bucket ' , 0 , $ e );
166+
167+ throw new \OCA \DAV \Connector \Sabre \Exception \BadGateway ('Error while uploading to S3 bucket ' , 0 , $ exception );
131168 }
132169 }
133170
0 commit comments