Uh oh!
There was an error while loading. Please reload this page.
[SPARK-14914] Fix Resource not closed after using, mostly for unit tests - #12693
[SPARK-14914] Fix Resource not closed after using, mostly for unit tests#12693taoli91 wants to merge 16 commits into
Conversation
Helping script for windows to download dependency and start zinc to support incremental building on windows.
| val serializer = SparkEnv.get.serializer.newInstance() | ||
| val deserializeStream = serializer.deserializeStream(fileInputStream) | ||
| // make sure that the file is closed if error occurrs during deserialization | ||
| val deserializeStream = |
There was a problem hiding this comment.
You should use finally in contexts like this.
There was a problem hiding this comment.
@srowen The deserializeStream will be closed. We only need this when the deserializeStream method throws exception and we have no chance to go to the line 258, in which the deserializeStream will be closed, with the inner fileInputStream.
There was a problem hiding this comment.
Sorry, I mean put this in the block below that closes the deserialization stream, at best.
There was a problem hiding this comment.
Sorry, I mean put this in the block below that closes the deserialization stream, at best.
@srowen It seems we need extra code to accommodate the scope problem if putting the close in other clauses. Probably it's cleaner to stick with this solution.
There was a problem hiding this comment.
I'm not sure what you mean -- it's less code. Just open the deserializeStream inside the block and close it in the finally block that follows. Actually, closing deserializeStream will already (should already) close the underlying stream anyway. It doesn't handle errors while making the stream from the original stream, but, constructors of the deserializer streams aren't reading the stream anyway. I suspect it's fine as-is, but it would be extra-defensive to also close the fileInputStream, yes.
There was a problem hiding this comment.
@srowen Probably a code snippet will explain things better. Do you mean this:
vardeserializeStream:DeserializationStream=nullvalpartitioner=Utils.tryWithSafeFinally[Partitioner] {
deserializeStream = serializer.deserializeStream(fileInputStream)
deserializeStream.readObject[Partitioner]
} {
deserializeStream.close()
}There are a few things I am concerning
- The semantic has slightly changed (
deserializeStreamis nowvarinstead ofval) - I'm not sure is it always safe to close an partially initialized
deserializeStream, in the case of the deserialization throwing exception. I'm pretty sure that if we close thefileInputStreamfirst may cause the closingdeserializeSteamthrowing exception complaining that the input has been closed already.
FYI, I found this problem by while running the test case "checkpointing partitioners" in which the corruptPartitionerFile flag is turned on in the CheckpointSuite.
There was a problem hiding this comment.
Yeah that's what I mean. Well, if I were right that serializer.deserializeStream can't fail, then the existing code would already be fine, so this suggestion doesn't help unless fileInputStream gets a similar treatment, and that's too complex. I'm curious how that fails given the current implementation, but, even if it couldn't now, it could in the future.
You might normally resolve this with nested try blocks; I think streams aren't supposed to fail if closed twice, so, safe to close the underlying stream for good measure. Still at that point it's no less complex, so I can see that this is as clear as anything.
srowen
commented
Apr 26, 2016
This cleanup looks generally good |
| @@ -39,18 +39,15 @@ class MapWithStateSuite extends SparkFunSuite | |||
| before { | |||
| StreamingContext.getActive().foreach { _.stop(stopSparkContext = false) } | |||
There was a problem hiding this comment.
Just noticed. I think
foreach(_.stop(stopSparkContext =false))might be better although this is not the part of this PR.
| eventSet.remove(event) | ||
| try { | ||
| val logStart = SparkListenerLogStart(SPARK_VERSION) | ||
| val lines = readLines(logData) |
There was a problem hiding this comment.
Here, I think readLines is the only thing that reads logData? after it's done you could close the stream. Maybe that's tidier than wrapping so much in the try-finally block.
There was a problem hiding this comment.
@srowen I tried:
vallogData=EventLoggingListener.openEventLog(newPath(eventLogger.logPath), fileSystem)
varlines:Seq[String] =nulltry {
lines = readLines(logData)
} finally {
logData.close()
}It thrown IOException complaining that Stream closed.
I think the readLines is sort of lazy such that it won't read the file until we actually move the iterator.
There was a problem hiding this comment.
OK sounds fine. How about pulling out eventSet at least?
andrewor14
commented
May 9, 2016
add to whitelist |
SparkQA
commented
May 9, 2016
Test build #58158 has finished for PR 12693 at commit
|
taoli91
commented
May 10, 2016
@andrewor14 I've fixed the failure. Could you please try it again? Thanks |
SparkQA
commented
May 10, 2016
Test build #58206 has finished for PR 12693 at commit
|
taoli91
commented
May 10, 2016
Well it's wired, I can't repro the test failure locally. |
taoli91
commented
May 12, 2016
I can't repro the failure on my environment. It seems my changes on this commit shouldn't change the logic of the Launcher part. Is it possible that it's a random failure? |
taoli91
commented
May 16, 2016
@andrewor14 Could you please schedule another test for me? |
andrewor14
commented
May 16, 2016
retest this please |
andrewor14
commented
May 16, 2016
you should be able to trigger it too |
SparkQA
commented
May 16, 2016
Test build #58652 has finished for PR 12693 at commit
|
|
srowen
commented
Sep 21, 2016
@taoli91 if you want to rebase this I'd be happy to finish the review too. It looked like it was almost there or already done. |
Oh, sorry, this was not Windows specific issue. Sorry for the comment above. |
tdas
commented
Oct 25, 2016
@HyukjinKwon could you rebase this PR. Thanks for the detailed work to find these issues. This is a very useful PR and would be good to merge if you rebase the PR. |
HyukjinKwon
commented
Oct 25, 2016
Sure, I definitely will. |
Closesapache#11610Closesapache#15411Closesapache#15501Closesapache#12613Closesapache#12518Closesapache#12026Closesapache#15524Closesapache#12693Closesapache#12358Closesapache#15588Closesapache#15635Closesapache#15678Closesapache#14699Closesapache#9008
Closesapache#11610Closesapache#15411Closesapache#15501Closesapache#12613Closesapache#12518Closesapache#12026Closesapache#15524Closesapache#12693Closesapache#12358Closesapache#15588Closesapache#15635Closesapache#15678Closesapache#14699Closesapache#9008 Author: Sean Owen <sowen@cloudera.com> Closesapache#15685 from srowen/CloseStalePRs.
What changes were proposed in this pull request?
Close
FileStreams,ZipFiles etc to release the resources after using. Not closing the resources will cause IO Exception to be raised while deleting temp files.How was this patch tested?
Run unit test on both windows and Linux. Note that this fix can't resolve all the problem of Unit tests on Windows.