mirror of
https://github.com/sigoden/dufs.git
synced 2026-04-08 16:49:02 +03:00
[GH-ISSUE #276] Avoid writing half-uploaded files #146
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @Lukinoh on GitHub (Oct 31, 2023).
Original GitHub issue: https://github.com/sigoden/dufs/issues/276
Specific Demand
Hello,
Currently, when you upload a file, it is written sequentially.
So if an error occurs, you could have only half-file written to the disk.
A simple way to reproduce the behaviour is to start uploading a big file, and press F5.
I don't know if it is a use case that makes sense for you to handle in an other way.
Anyway, here is my simple suggestion.
Implement Suggestion
Disclaimer - I have literally 0 experiences or practice in Rust. First, time writing something with it.
So the idea is to write the file in a temporary location until the download is finished. Then, move the file to the correct place.
I did a PoC you can find here.
Technical comments:
We cannot create a file to determine if we can write in the directory. Otherwise, the file would appear before it is completely uploaded.
So, I used the metadata of the parent folder to determine if the folder is read-only or not.
To find where to store the temporary file, I dumbly took the first reference I found. So the solution is based on the crate tempfile. It allows you to create temporary files or folders.
Unfortunately, the temporary file is not compatible with
tokio::io::copy. Hence, I created a temporary directory in which I create the temporary file usingtokio::fs::File::create.And... while writing this feature request, I found that an async_tempfile exists which seems to be compatible with
tokio.@sigoden commented on GitHub (Nov 3, 2023):
Isn't it easier to just delete the interrupted file directly?
Tmpfile has two shortcomings:
/tmp.Seeing files being downloaded is not a disadvantage; having one uploading and one downloading at the same time is a feature.
@Lukinoh commented on GitHub (Nov 3, 2023):
Actually, that was my first implementation, but it does not work very well.
If you upload a file, and then do F5, the file will be displayed even if it has failed to upload, because the endpoint answer before the file is deleted.
Moreover, if other users access the page, they will see the file while it is not yet fully uploaded.
I am not sure of the behaviour if the
/tmpfolder does not exist beforehand. I am curious if he creates it, or if it fails, I will check later.@Lukinoh commented on GitHub (Nov 4, 2023):
It fails.
I gave a look to the
tempdirfunction, and it is based onstd::env::tempdir.On Unix,
tempdirreturns the value of theTMPDIRenvironment variable if it is set, otherwise for non-Android it returns/tmp.Hence, you could workaround the "not same disk issue" by changing the "TMPDIR" value.
But I am not sure that's the best solution, and won't totally solve the issue with docker image of dufs.
I am sorry, I am not sure to understand this sentence.
Otherwise, we could just improve a bit the simple solution you implemented by doing as the web browsers do.
Instead of writing the file with its name directly, it is written with a temporary name file.
It has the advantages to highlight the fact that a file is being uploaded to the server, while avoiding that a user thinks the file is ready to be downloaded.
In Chrome when you download a file, it creates a temporary file called

not confirmed NUMBER.crdownload:And once the download is finished, it is renamed with the correct name.
Or in Firefox when you download a file, it will create two files:

And once the download is finished, the
partfile is renamed with the correct name.@sigoden commented on GitHub (Nov 4, 2023):
The problem has already been solved. Just delete the files if they have not been completely uploaded.