Skip to content

Commit

Permalink
s3ng: Provide objectSize when uploading
Browse files Browse the repository at this point in the history
According to the documentation for `PutObject`,
setting objectSize to -1 causes a multipart Put
operation until the input stream reaches EOF,
which can result in high memory usage.
Something similar has already been reported in
minio/minio-go#1496

This PR changes the behavior so it tries to determine
the file size before uploading it. Should the given
io.Reader not be a file, it falls back to using `-1`.

In my testing this change has reduced the memory
usage when uploading files to OICS quite a bit:
From over 1GB for a
single user, down to <300MB.
  • Loading branch information
AndreasSko committed Jul 30, 2021
1 parent fcb7a30 commit 1b2643a
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 1 deletion.
5 changes: 5 additions & 0 deletions changelog/unreleased/provide-size-for-s3-upload.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Bugfix: Provide file size when uploading with S3ng storage

The memory usage could be high when uploading bigger files using the S3ng storage.
By providing the actual file size, the upload partSize can now be properly determined, reducing
the overall memory usage.
12 changes: 11 additions & 1 deletion pkg/storage/fs/s3ng/blobstore/blobstore.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"context"
"io"
"net/url"
"os"

"github.com/minio/minio-go/v7"
"github.com/minio/minio-go/v7/pkg/credentials"
Expand Down Expand Up @@ -60,7 +61,16 @@ func New(endpoint, region, bucket, accessKey, secretKey string) (*Blobstore, err

// Upload stores some data in the blobstore under the given key
func (bs *Blobstore) Upload(key string, reader io.Reader) error {
_, err := bs.client.PutObject(context.Background(), bs.bucket, key, reader, -1, minio.PutObjectOptions{ContentType: "application/octet-stream"})
size := int64(-1)
if file, ok := reader.(*os.File); ok {
info, err := file.Stat()
if err != nil {
return errors.Wrapf(err, "could not determine file size for object '%s'", key)
}
size = info.Size()
}

_, err := bs.client.PutObject(context.Background(), bs.bucket, key, reader, size, minio.PutObjectOptions{ContentType: "application/octet-stream"})

if err != nil {
return errors.Wrapf(err, "could not store object '%s' into bucket '%s'", key, bs.bucket)
Expand Down

0 comments on commit 1b2643a

Please sign in to comment.