Misc Utils
tryWithSafeFinally
如果我们写代码
try {
out.write();
...
}catch {
...
}finally {
out.close();
}
有个问题是如果out.write
出错,那么有可能out.close
也会出错,如果out.close抛错就会掩盖out.write的错。
我觉得要是在Java里除非抛出RuntimeException,否则如果是CheckedExceptioin,那么需要catch out.close,那么你可以掩盖掉out.close,
而选择catch block里的。
但是在Scala里是不是就不会这样?
spark这个代码用两段代码合并来放到一个Throwable里
// Utils
def tryWithSafeFinally[T](block: => T)(finallyBlock: => Unit): T = {
var originalThrowable: Throwable = null
try {
block
} catch {
case t: Throwable =>
// Purposefully not using NonFatal, because even fatal exceptions
// we don't want to have our finallyBlock suppress
originalThrowable = t
throw originalThrowable
} finally {
try {
finallyBlock
} catch {
case t: Throwable =>
if (originalThrowable != null) {
originalThrowable.addSuppressed(t)
logWarning(s"Suppressing exception in finally: " + t.getMessage, t)
throw originalThrowable
} else {
throw t
}
}
}
}
使用上这么用
// CheckPoint
def serialize(checkpoint: Checkpoint, conf: SparkConf): Array[Byte] = {
val compressionCodec = CompressionCodec.createCodec(conf)
val bos = new ByteArrayOutputStream()
val zos = compressionCodec.compressedOutputStream(bos)
val oos = new ObjectOutputStream(zos)
Utils.tryWithSafeFinally {
oos.writeObject(checkpoint)
} {
oos.close()
}
bos.toByteArray
}