-
Notifications
You must be signed in to change notification settings - Fork 10
Upload cancellation – graceful stop for TUS & classic uploads #66
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
Conversation
9c880b0 to
07e0c0c
Compare
2a2b373 to
28cf181
Compare
| .setResponseCode(201) | ||
| .addHeader("Tus-Resumable", "1.0.0") | ||
| .addHeader("Location", locationPath) | ||
| .addHeader("Upload-Offset", firstChunkSize.toString()) |
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.
by the way, note that you're not actually testing here what the mock web server received from CreateTusUploadRemoteOperation but you are just telling it to return some fixed integer.
A better way might be:
server.setDispatcher(new Dispatcher() {
@Override
public MockResponse dispatch(RecordedRequest request) {
// Read body bytes
byte[] bodyBytes = request.getBody().readByteArray();
int bodySize = bodyBytes.length;
return new MockResponse()
.setResponseCode(201)
.addHeader("Tus-Resumable", "1.0.0")
.addHeader("Location", locationPath)
.addHeader("Upload-Offset", bodySize);
}
});
// (after this test, re-set the dispatcher again to default)
(did not test this, AI written pseudocode ^)
That way, we also test that the CreateTusUploadRemoteOperation is actually sending the chunk size amount/length to the (mock) server. So you're also testing if there is accidently too little or too much sent.
(only do it in this test, not for all tests.. just to get a bit more coverage).
(you could even extend it by comparing in the dispatch handler if bodyBytes == first chunk 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.
fixed, look the "real" pr please. Give ur opinion if its what u expected
92fe248 to
81b8be0
Compare
|
@guruz github trolled me kinda, but duplicates are gone :) |
aeb28c2 to
21d2f1d
Compare
|
Thanks, I will test it. btw, wrong commit subject " feat: Add initial implementation and TusUploadHelper ". Shouldn't it be "TUS: Fix #71" |
|
its from vs code i let it auto generate |
|
OK, please let's have nice commit subjects. Else it's pointless to even have them if they're wrong or confusing :) |
|
yes sorry |
|
ill correct it later |
21d2f1d to
0fd5654
Compare
0fd5654 to
0318e33
Compare
|
Two things I've noticed so far:
I also see this falling back to single PUT, now I'm not sure anymore if this is good for a big file @TheOneRing opinion? |
@guruz Thanks for testing! Here are my answers: Regarding point 1 (Progress 0 when switching tabs): Regarding point 2 (TUS upload expired/404):
Result: The upload correctly fails with a Retry signal to WorkManager. It does not actually switch to a single PUT (which is good for large files). Instead, after the WorkManager backoff delay, it restarts the job. Since we cleared the state in step 3, it begins a fresh TUS upload from scratch. Regarding the wait time: Possible improvements:
(Technically we could also try to bypass the WorkManager backoff if we detect a 404, but that might be risky if the server is actually down). |
|
No single put is made. |
guruz
left a comment
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.
Let's merge this, it works. We can create follow up issues in the issue tracker.
Graceful Upload Cancellation
Summary
This PR introduces a robust "Graceful Stop" mechanism for file uploads. It ensures that when an upload is cancelled (by the user or the system), the process terminates cleanly without leaving the database or file system in an inconsistent state.
Important
Dependency Note: This branch is built on top of PR #36 (TUS Implementation).
You will see TUS-related commits in the history (e.g.,
b7bae7d), but they are NOT part of this review.This PR requires the TUS implementation as a foundation. Once PR #36 is merged/rebased, this branch will be updated.
Please review ONLY the cancellation-specific commits listed below.
🎯 Review Scope
Please focus your review on these groups of changes:
Group 1: Cancellation Logic (Core Feature)
df1562ca276f60foregroundJob.cancel()calls021f314Group 2: Misc Fixes (Included in this branch)
07e0c0ce8c2971c5f67dc🛠️ Technical Deep Dive
1. The
isStopped()CheckpointThe Problem:
Standard
WorkManagercancellation sends a signal, but if the code is stuck in a loop uploading chunks, it might ignore the signal until the loop finishes.The Solution:
We injected
isStopped()checks inside the critical upload loops.2. Handling
CancellationExceptionThe Problem:
Previously, a cancellation was often caught by a generic
catch (e: Exception)block, causing the app to mark the upload asFAILED(red error icon) instead ofCANCELLED(paused state).The Solution:
We now explicitly catch
CancellationExceptionin the Worker.3. Resource Cleanup
The Problem:
Cancelling an upload abruptly could leave file streams open, locking the file on disk.
The Solution:
We implemented strict
try-finallyblocks to ensure streams are closed immediately upon cancellation.🧪 Verification