关闭由超时未来创建的资源
Closing resource created by timed-out future
当我们有创建资源的方法时,有时只需要等待指定的时间。例如,我们要等待 10 秒才能连接到数据库。
我尝试使用 future 和 Await.result 来获得它。不幸的是,Await.result 在指定时间后抛出异常,但不会杀死正在进行的未来。所以在超时之后我们以 TimeoutException 结束,但如果未来最终完成,我们没有任何能力关闭返回的结果。
示例:
import java.io.Closeable
import java.util.concurrent.TimeoutException
import scala.concurrent.Await
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.DurationInt
import scala.concurrent.future
object Test {
object ConnectionManager {
class Connection extends Closeable {
println("Connected")
override def close = println("DB closed")
}
def connect = {
println("Connecting to DB...")
Thread.sleep(1000 * 7)
new Connection
}
}
def main(args: Array[String]): Unit = {
val f = future {
ConnectionManager.connect
}
try {
val result = Await.result(f, 5 seconds)
result.close
} catch {
case e: TimeoutException => println("Connection timeout")
}
Thread.sleep(10 * 1000)
println("Finished")
}
}
结果是:
Connecting to DB...
Connection timeout
Connected
Finished
因此连接已创建但从未关闭
您可以将 f.onSuccess { case c => c.close }
添加到 catch
子句中。
当我们有创建资源的方法时,有时只需要等待指定的时间。例如,我们要等待 10 秒才能连接到数据库。
我尝试使用 future 和 Await.result 来获得它。不幸的是,Await.result 在指定时间后抛出异常,但不会杀死正在进行的未来。所以在超时之后我们以 TimeoutException 结束,但如果未来最终完成,我们没有任何能力关闭返回的结果。 示例:
import java.io.Closeable
import java.util.concurrent.TimeoutException
import scala.concurrent.Await
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.DurationInt
import scala.concurrent.future
object Test {
object ConnectionManager {
class Connection extends Closeable {
println("Connected")
override def close = println("DB closed")
}
def connect = {
println("Connecting to DB...")
Thread.sleep(1000 * 7)
new Connection
}
}
def main(args: Array[String]): Unit = {
val f = future {
ConnectionManager.connect
}
try {
val result = Await.result(f, 5 seconds)
result.close
} catch {
case e: TimeoutException => println("Connection timeout")
}
Thread.sleep(10 * 1000)
println("Finished")
}
}
结果是:
Connecting to DB...
Connection timeout
Connected
Finished
因此连接已创建但从未关闭
您可以将 f.onSuccess { case c => c.close }
添加到 catch
子句中。