-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Add basic support for Multipart Upload #2
Conversation
test/multipart_test.gleam
Outdated
|> list.map(fn(pair) { | ||
let #(body, part_number) = pair | ||
let assert Ok(res) = | ||
upload_part.request(bucket:, key:, upload_id:, part_number:, body:) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should I actually perform these uploads in parallel so that we have an example use case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you! I've left some questions inline
test/multipart_test.gleam
Outdated
}) | ||
|
||
// Complete the multipart upload | ||
// NOTE: The Parts must be sorted in ascending order for this operation |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does this mean?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's too confusing. I'm going to remove this note, and perhaps make complete_multipart_upload.request()
sort the parts
argument to prevent the error case I'm alluding to in this note.
The reason for sorting is that when calling complete_multipart_upload.request()
, the parts
argument must be ordered by the part_number
, e.g. [Part(.., part_number: 1), Part(.., part_number: 2), Part(.., part_number: 3)]
, otherwise the S3 server would respond to such request with an error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done in 71ba290, but maybe I should skip sorting and let the request fail when the user gives us incorrect parts?
bucket: String, | ||
key: String, | ||
upload_id: String, | ||
part_number: Int, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is a part number?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From UploadPart docs (https://docs.aws.amazon.com/AmazonS3/latest/API/API_UploadPart.html):
Part numbers can be any number from 1 to 10,000, inclusive. A part number uniquely identifies a part and also defines its position within the object being created. If you upload a new part using the same part number that was used with a previous part, the previously uploaded part is overwritten.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add this a doc comment please 🙏
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done in fd7e3c6
import gleam/list | ||
import gleam/string | ||
import gleeunit/should | ||
import helpers |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add tests for the various possible errors
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done in 3be6630
test/multipart_test.gleam
Outdated
let assert Ok(res) = | ||
get_object.request(bucket, key) | ||
|> get_object.build(helpers.creds) | ||
|> httpc.send_bits | ||
let assert Ok(get_object.Found(contents)) = get_object.response(res) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move this to a function in helpers.gleam please
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what you mean. Should I make a helper that takes a bucket, key, creds, and a list of parts as BitArrays, and verifies the object?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah! helper.get_object
or something which returns the contents
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done in 57a99e4
test/multipart_test.gleam
Outdated
should.not_equal(res.upload_id, "") | ||
|
||
// Upload some parts (they can be sent in parallel) | ||
// NOTE: The minimum Part size for multipart upload is 5MiB (hardcoded in minio) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like part 3 is smaller than that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's not a problem. I've updated the note in b0d5139
Maybe it's better to let the user get the error from S3, an incorrect order might be caused by a bug somewhere in the user's code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Beautiful! One tiny thing inline, and could you also update the changelog please. Thanks
Done, I also updated the readme |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you!
This PR adds support for
CreateMultipartUpload
,UploadPart
andCompleteMultipartUpload
S3 APIs. This lets the users of this library upload large files more quickly, by uploading multiple chunks in parallel.There are other Multipart Upload APIs that could be implemented in the future:
The full list of these APIs can be found on MinIO's docs: https://min.io/docs/minio/linux/reference/s3-api-compatibility.html#multipart-uploads