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
moving BucketUtils.deleteOnExit -> IOUtils #5332
Conversation
lbergelson
commented
Oct 19, 2018
- replacing existing deleteRecursivelyOnExit method with deleteOnExit
- closes Unify BucketUtils.deleteRecursively()/deleteOnExit() with IOUtils.deleteRecursivelyOnExit() #5319
Codecov Report
@@ Coverage Diff @@
## master #5332 +/- ##
===============================================
- Coverage 87.083% 87.078% -0.005%
- Complexity 31232 31480 +248
===============================================
Files 1915 1930 +15
Lines 144130 145044 +914
Branches 15901 16074 +173
===============================================
+ Hits 125513 126302 +789
- Misses 12834 12890 +56
- Partials 5783 5852 +69
|
* | ||
* @param fileToDelete file or directory to be deleted at JVM shutdown. | ||
*/ | ||
public static void deleteOnExit(final Path fileToDelete){ |
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 added time ago a method in htsjdk which does a similar think (IOUtils.deleteOnExit), which has a common shutdown hook to delete all at the same time (DeleteOnExitPathHook) mimicking the behavior of the java.io.File#deleteOnExit
.
I would suggest to add a common hook to delete recursively, and change the name of this method. Like that, it would not create too many threads to delete on exit.
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.
@magicDGS Yeah, yours is better than this. I guess I should mimic what you did.
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've copied your class to do this now so it shouldn't create many threads.
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 would also rename this method to deleteRecursivelyOnExit
to be explicit - otherwise, the difference with the htsjdk version is not clear. Also, it would be nice to backport this to htsjdk at some point, and thus it will be easier to migrate afterwards.
* replacing existing deleteRecursivelyOnExit method with deleteOnExit * closes #5319
8ed010c
to
bfd8eac
Compare
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.
Back to @lbergelson with my comments
IOUtils.deleteOnExit(IOUtils.getPath(path + TabixUtils.STANDARD_INDEX_EXTENSION)); | ||
IOUtils.deleteOnExit(IOUtils.getPath(path + ".bai")); | ||
IOUtils.deleteOnExit(IOUtils.getPath(path + ".md5")); | ||
IOUtils.deleteOnExit(IOUtils.getPath(path.replaceAll(extension + "$", ".bai"))); //if path ends with extension, replace it with .bai |
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.
Should we add the fasta indices here too, now that we're in the business of writing fastas?
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.
Should we change this to just create each file in it's own directory instead of trying to delete every possible index?
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'm going to punt on this one and do it in the follow up PR because it touches code in a few different places.
* @param rootPath is the file/directory to be deleted | ||
*/ | ||
public static void deleteRecursively(final Path rootPath) throws IOException { | ||
final List<Path> pathsToDelete = Files.walk(rootPath) |
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.
Is Files.walk()
guaranteed to succeed on a non-directory? I feel like when @nalinigans implemented the original recursive deletion method, she might have had a legitimate reason for avoiding doing recursive deletion on non-directories.
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.
According to the doc the result of calling it on a single file is the file itself.
The {@code Stream} returned is guaranteed to have at least one
* element, the starting file itself.
/** | ||
* Class to hold a set of {@link Path} to be delete on the JVM exit through a shutdown hook. | ||
* | ||
* <p>This class is a modification of {@link htsjdk.samtools.util.nio} |
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.
Complete this @link
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.
woops, done
* | ||
* <p>This class is a modification of {@link htsjdk.samtools.util.nio} | ||
*/ | ||
class DeleteRecursivelyOnExitPathHook { |
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.
Document the reason why this class is package-protected.
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.
done
/** | ||
* Adds a {@link Path} for deletion on JVM exit. | ||
* | ||
* @param path path to be deleted. |
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.
Add a note here that path
can be a (non-empty) directory.
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.
good call, done
@@ -695,15 +694,15 @@ public static Path createTempPath(String name, String 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.
This method seems redundant with BucketUtils.getTempFilePath()
, which you've preserved.
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.
Also should probably be unified with IOUtils.createTempFileInDirectory()
/IOUtils.createTempFile()
above, since those are the methods called by the widely-used BaseTest.createTempFile()
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 refactored a ton of stuff in the next PR. Let's revisit this there instead. I may have done that already.
@@ -987,4 +969,27 @@ public static String getGenomicsDBPath(final String path) { | |||
} | |||
return genomicsdbPath; | |||
} | |||
|
|||
/** | |||
* Schedule a file to be deleted on JVM shutdown. |
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.
file -> file or directory
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.
deleted -> deleted recursively
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.
And add explicit note that this calls IOUtils.deleteRecursively()
on fileToDelete
at shutdown
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.
done
File tempFile = createTempFile(String.format("testWriteThenReadFileIntoByteArray_%d_%d", fileSize, readBufferSize), "tmp"); | ||
|
||
byte[] dataWritten = getDeterministicRandomData(fileSize); | ||
IOUtils.writeByteArrayToFile(dataWritten, tempFile); | ||
byte[] dataRead = IOUtils.readFileIntoByteArray(tempFile, readBufferSize); | ||
|
||
Assert.assertEquals(dataRead.length, dataWritten.length); | ||
Assert.assertTrue(Arrays.equals(dataRead, dataWritten)); | ||
Assert.assertEquals(dataWritten, dataRead); |
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.
Order of args seems wrong here -- dataRead
is the "actual" value here, isn't it?
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.
yes, good catch
@@ -329,7 +330,7 @@ public void testWriteThenReadStreamIntoByteArray ( int fileSize, int readBufferS | |||
byte[] dataRead = IOUtils.readStreamIntoByteArray(new FileInputStream(tempFile), readBufferSize); | |||
|
|||
Assert.assertEquals(dataRead.length, dataWritten.length); | |||
Assert.assertTrue(Arrays.equals(dataRead, dataWritten)); | |||
Assert.assertEquals(dataWritten, dataRead); |
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.
Again, actual and expected values might be swapped here.
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.
done
|
||
final File dir = new File(GATKBaseTest.publicTestDir + "I_SHOULD_HAVE_BEEN_DELETED"); | ||
IOUtils.deleteRecursivelyOnExit(dir); | ||
final File dir = new File( "I_SHOULD_HAVE_BEEN_DELETED"); |
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.
Do you really want to create this file in the working directory?
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 more visible that way.... but I can move it back to where it was...
@droazen Could you take a second pass on this when you get a chance? |
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.
👍 Latest version looks good @lbergelson. Still a bunch of refactoring to be done in this part of the codebase, but it can wait until the next PR. Merging!