micronaut-core
micronaut-core copied to clipboard
MicronautHttpData cannot delete temporary files on Windows
Expected Behavior
Temporary files created by file upload should be deleted on Windows
Actual Behaviour
On Windows 10 (it works fine on Linux), the temporary file created by a file upload is not deleted, increasing the disk size. Moreover, a warning is issued:
Steps To Reproduce
The endpoint where we upload the file is the following:
@ExecuteOn(TaskExecutors.IO)
@Post(uri = "/{namespace}/{id}", consumes = MediaType.MULTIPART_FORM_DATA)
public Execution create(
@Parameter(description = "The inputs") HttpRequest<?> inputs,
@Parameter(description = "The inputs of type file") @Nullable @Part Publisher<StreamingFileUpload> files
) throws IOException {
}
The files are process like that:
Map<String, String> uploads = Flux.from(files)
.subscribeOn(Schedulers.boundedElastic())
.map(throwFunction(file -> {
File tempFile = File.createTempFile(file.getFilename() + "_", ".upl");
Publisher<Boolean> uploadPublisher = file.transferTo(tempFile);
Boolean bool = Mono.from(uploadPublisher).block();
if (Boolean.FALSE.equals(bool)) {
throw new RuntimeException("Can't upload");
}
URI from = storageInterface.from(execution, file.getFilename(), tempFile);
//noinspection ResultOfMethodCallIgnored
tempFile.delete();
return new AbstractMap.SimpleEntry<>(
file.getFilename(),
from.toString()
);
}))
.collectMap(AbstractMap.SimpleEntry::getKey, AbstractMap.SimpleEntry::getValue)
.block();
Environment Information
- OS: Windows 10
- Java 17
Example Application
No response
Version
4.3.4
I don't think we can do much about this if we can't delete files we created.
But isnt the bug exactly that? Why can't these files be deleted? There are no permission limitations on my machine so I think the bug is maybe somehow related to how micronaut checks for permission in this particular case. Or it's trying to delete the file while it is created (I.e in a protected state).
@M-E-Rademaker mn just calls Files.deleteIfExists. We don't check for permissions or anything. I don't see what we can do about that call failing.
@yawkat i have no experience in Java, so sorry if what I am writing is nonsense, however, looking at the docs of Files.deleteIfExists it seems that they allude to something that may be the root of the problem
They write in the docs
On some operating systems it may not be possible to remove a file when it is open and in use by this Java virtual machine or other programs.
I suppose this manifests in a permission denied type of error on windows.
It may still be that you at mn are not the right person to ask to handle that issue but it looks like some sort of mechanism that waits/checks until the file is no longer in use by some other process and only then (re)tries to delete the file could fix it on windows.
It's just a bit of a general guess without knowing any of the details.
I really need to solve (have it solved) this. As these large temp files are a real pain
perhaps in the meantime you can write some background task to cleanup the files.
Maybe we can schedule the file to be deleted by the VM at exit time (File.deleteOnExit), which would mitigate the issue between restarts of the application.
In this case, the log may be lowered to INFO, as Micronaut will provide mitigation.
Of course, it would be better to understand why the file can be created and not deleted by the same process/user and fix the cause (if it's for ex that the file is still in use and the call to delete too premature).
the file still being opened elsewhere is a good theory. linux allows deletion in that case, but windows doesnt. it's possible that we or the application is leaving a stream open somewhere. but i dont have a way to debug this.