From f73ad52864ea50641351b521430b9710a249dfed Mon Sep 17 00:00:00 2001 From: Derrick Hammer Date: Sat, 17 Feb 2024 06:37:45 -0500 Subject: [PATCH] feat: add support for resuming an existing upload --- renter/renter.go | 46 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/renter/renter.go b/renter/renter.go index a583c79..f957b07 100644 --- a/renter/renter.go +++ b/renter/renter.go @@ -151,16 +151,46 @@ func (r *RenterDefault) UploadObjectMultipart(ctx context.Context, params *Multi parts := uint64(math.Ceil(float64(size) / float64(slabSize))) uploadParts := make([]api.MultipartCompletedPart, parts) - upload, err := r.busClient.CreateMultipartUpload(ctx, bucket, fileName, api.CreateMultipartOptions{Key: object.NoOpKey}) - if err != nil { - return err + var uploadId string + start := uint64(0) + + if params.ExistingUploadID != "" { + existing, err := r.busClient.MultipartUploadParts(ctx, bucket, fileName, params.ExistingUploadID, 0, 0) + + if err != nil { + return err + } + + uploadId = params.ExistingUploadID + + for _, part := range existing.Parts { + if uint64(part.Size) != slabSize { + break + } + partNumber := part.PartNumber + uploadParts[partNumber-1] = api.MultipartCompletedPart{ + PartNumber: part.PartNumber, + ETag: part.ETag, + } + } + + if len(uploadParts) > 0 { + start = uint64(len(uploadParts)) - 1 + } + } else { + upload, err := r.busClient.CreateMultipartUpload(ctx, bucket, fileName, api.CreateMultipartOptions{Key: object.NoOpKey}) + if err != nil { + return err + } + + uploadId = upload.UploadID } if idHandler != nil { - idHandler(upload.UploadID) + idHandler(uploadId) } - for i := uint64(0); i < parts; i++ { + for i := start; i < parts; i++ { start := i * slabSize end := start + slabSize @@ -187,7 +217,7 @@ func (r *RenterDefault) UploadObjectMultipart(ctx context.Context, params *Multi return err } - ret, err := r.workerClient.UploadMultipartUploadPart(context.Background(), reader, bucket, fileName, upload.UploadID, partNumber, api.UploadMultipartUploadPartOptions{}) + ret, err := r.workerClient.UploadMultipartUploadPart(context.Background(), reader, bucket, fileName, uploadId, partNumber, api.UploadMultipartUploadPartOptions{}) if err != nil { return err } @@ -219,11 +249,13 @@ func (r *RenterDefault) UploadObjectMultipart(ctx context.Context, params *Multi return fmt.Errorf("failed to upload part %d: %s", i, err.Error()) case etag := <-nextChan: uploadParts[i].ETag = etag + case <-ctx.Done(): + return ctx.Err() } } - _, err = r.busClient.CompleteMultipartUpload(ctx, bucket, fileName, upload.UploadID, uploadParts) + _, err = r.busClient.CompleteMultipartUpload(ctx, bucket, fileName, uploadId, uploadParts) if err != nil { return err }