-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Add ability to change [FileMode] of the download by introducing [Dio… #2281
base: main
Are you sure you want to change the base?
Conversation
Can you please explain how this change enables resuming downloads? |
When downloading a file a stream is opened and a Random Access File are opened in the client side to store bytes changing the file access mode to [FileMode.append] or [FileMode.writeOnlyAppend] with change the behavior to write to the end of the file So if you had already started downloading a file and for some reason the download stopped let's say a network problem and you set [deleteOnError = false], the file had already downloaded 50% and it's not deleted it exists but is not complete You check if the file exists and get it's size then you request to download the file again by requesting a partial content setting the range header to file size, that means skip downloading the 50% you already downloaded then you append the remaining 50% to the end of the file and here it's you resumed your download with minimum ease. |
Ok, I will add tests. |
I wonder whether it makes sense to automatically add range header in the case of a resuming download, that way it would work out of the box, without the user needing to implement anything. The server needs to support them though. (This is not something which necessarily needs to be added to this PR though, I guess) |
Yes, it's a good idea. I think it's rare to find a server that doesn't support range requests. |
I added test case for the file mode append, now can you review the code again |
path, | ||
cancelToken: cancelToken, | ||
onReceiveProgress: (c, t) { | ||
if (c > 5000) { |
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.
The test seems fake when it involves the real world's use case. Predicting the length of bytes is meanless since:
- You've set the condition to cancel when bytes reach 5000.
- No actual content has been validated.
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.
canceling the request is mandatory for this test to work because I am cancelling the first download request after loading 5000 bytes and make the second request to verify adding to existing file we are requesting 1024102410
we are loading 5000 first then 5000 as appending in the check we are checking if the summation of the two first requests equals file size and the test confirms this
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 I mean is validating the length cannot prove the content is being written correctly. Say you have a content sequence abcdefg
, if you wrote efgabcd
which is the same length, the length comparison is then fake.
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.
validating the sequence of content is not our job we just need to validate that the bytes are added to the existed file, We just enabled developer to change file access mode.
We need to validate bytes order if we are making a complete feature of resuming the download including checking the existing file size and requesting a range size.
dio/lib/src/dio_file_mode.dart
Outdated
/// - [DioFileMode.append]: Mode for opening a file for reading and writing | ||
/// to the end of it. The file is created if it does not already exist. | ||
/// {@endtemplate} | ||
enum DioFileMode { |
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.
The name is a bit overwhelming. The type is only used for the download process.
Also the enhanced enum is not working on our minimum SDK support.
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 will convert it to extension
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.
any suggestion for naming
RandomAccessFile raf = file.openSync( | ||
mode: fileMode.map( | ||
write: () => FileMode.write, | ||
append: () => FileMode.append, |
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 will happen if the request is not range-supported?
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 a thing developer will validate before using this feature. in the package we are only enabling developers to append data to an existing file.
the feature will be useless if there is no range-support but it's a rare 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.
it's a thing developer will validate before using this feature. in the package we are only enabling developers to append data to an existing file.
Will they? When such features are provided without proper warning or case coverage, developers will have like 50 percent chance to be aware of the edges of the feature, but the user that uses their products will likely have zero chance to know whether their developers have implemented this correctly, so that means we break users experiences.
the feature will be useless if there is no range-support but it's a rare case
It is common that we live in old systems, and that is what happened with Dio as you may find them in our repo issues.
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.
Will they? When such features are provided without proper warning or case coverage, developers will have like 50 percent chance to be aware of the edges of the feature, but the user that uses their products will likely have zero chance to know whether their developers have implemented this correctly, so that means we break users experiences.
as I said It's not our responsibility to check for range support, we just enabled users to change file access mode
change [DioFileMode] to [FileAccessMode] change [Dio.download(fileMode:)] to [dio.download(fileAccessMode:)]
…FileMode]
New Pull Request Checklist
main
branch to avoid conflicts (via merge from master or rebase)CHANGELOG.md
in the corresponding packageAdditional context and info (if any)
Add the ability to change the [FileMode] of the download without altering the default value, which is [FileMode.write], to make resuming downloads easier to implement by introducing [DioFileMode] and mapping it to FileMode in [DioForNative]
without breaking web_adapter