-
Notifications
You must be signed in to change notification settings - Fork 473
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
When using deferred length with S3 compatible service, last part of multi-upload is ignored #396
Comments
Interesting situation. Can you share the client code? Can you confirm that one of the PATCH requests include the Upload-Length header? Otherwise, tusd does not know that the upload is complete and will not attach the last part. |
I confirm that the last PATCH request contains the Upload-Length header : I had already checked and anyway, it works very well when I use the file store. I did some tests and I found that for the last chunk containing the Upload-Length header:
As I use 5Mb chunks, I solved the problem by removing the test concerning the length of the chunks (lines 351-352). It's fine for me but obviously it's not a good solution. I hope this will help you. |
Thank you very much for the details! They definitely help a lot! |
My solution works for me but does not fix the issue because the test I removed is necessary when chunk size is less than 5Mb. |
I have the same problem with one small chunk (< 5 mb). AWS S3 after upload contains 3 files:
|
Thanks for reporting! I will try to look into it soon but I cannot promise anything. Would you be able to look into it as well? |
Sorry, I'm not so experienced with GO lang, but I could test some branch for you |
Any progress on that? ;) |
I have identified the root cause, but unfortunately that patch is a bit more complex and I am lacking a bit of time right now. I hope to be able to work on this in maybe two weeks. |
@Acconut I'm running into this as well after upgrading one of our services from pre-1.x. Can you share what the root cause is? If it would be helpful, I'm willing to work with you on preparing a fix, testing, etc. |
@acj Sure, I would love any help here! The problem is that the last chunk of an upload with a deferred length is not stored directly as a part for the multipart upload on S3. Instead, we store it as an object with the A solution, I think, would be to ensure inside the FinishUpload method of the s3store that any remaining incomplete part is copied to a part of the multipart upload. This way, the data will not get lost when completing the multipart upload. I hope you are able to understand what I mean and that you are not confused with all the different parts :) |
@Acconut Yep, I remember from when we worked on it together a few years ago 😄 (#219) We've been depending on deferred-length uploads to S3 in production, so the feature was working in a previous version of tusd. I'm not sure when it got broken. I investigated this a bit today, and I think the problem is that the s3Upload struct's FileInfo field gets out of sync (specifically Size and SizeIsDeferred) when we call DeclareLength here: tusd/pkg/handler/unrouted_handler.go Lines 560 to 567 in d152c5b
We update I noticed that DeclareLength's receiver is a value type. If I modify it to be a pointer (to match the semantics of WriteChunk) like so: -func (upload s3Upload) DeclareLength(ctx context.Context, length int64) error {
+func (upload *s3Upload) DeclareLength(ctx context.Context, length int64) error { ... then everything works as expected. The upload completes, and the S3 object has the correct bytes. So, it seems like a subtle interaction between UnroutedHandler and S3Store. If my fix above seems reasonable, I'll open a PR for it. Do you have any suggestions for how capture this in a test? |
@Acconut ping |
Thank you for the investigation, @acj! I think you are correct but we likely have two different bugs in here, depending on whether the request with the
I can work on the second issue, but it would be great if you could open a PR for the first problem, @acj! |
@Acconut PR opened 👍 Thanks for the additional details. I think I understand your reasoning in the second point, but I can't reproduce that behavior after fixing the first issue. Here's an example from uploading a small (~1MB file) to a tusd instance with default config running the code from #462:
I've tried larger files as well and see the same behavior. The upload completes as expected, and there's no leftover .info file in S3. |
❤️
Oh, I see. I thought that S3Store.WriteChunk would not be called for an empty body, but that's not the case. So, you are completely right and your fix patched everything 🎉 Thank you very much! |
Describe the bug
I use tusd with an S3 compatible service (Scaleway). When I upload a file by chunks with Upload-Defer-Length to 1, the last part is not concatenated with the previous parts.
See following screenshot, obtained with chunk size of 5 Mb.
Here is the content of .info file:
Setup details
The text was updated successfully, but these errors were encountered: