我正在尝试从scala中找到处理jedis命令的最佳方法。我正在尝试实现finally块,并防止java异常冒泡到我的调用者。
以下代码是否有意义,并且如果我想确保在redis可能暂时关闭时处理异常,那么它是否能够在性能方面做得最好?这个特性会被一个对象扩展,我会调用objectname.del(key)。我觉得我结合了太多的概念(要么,选择,尝试,感觉应该有一个更清洁的方式)
trait MyExperiment {
implicit class TryOps[T](val t: Try[T]) {
def eventually[Ignore](effect: => Ignore): Try[T] = {
val ignoring = (_: Any) => { effect; t }
t transform (ignoring, ignoring)
}
}
val jpool:JedisPool = initialize()
// init the pool at object creation
private def initialize(): JedisPool =
{
val poolConfig = new JedisPoolConfig()
poolConfig.setMaxIdle(10)
poolConfig.setMinIdle(2)
poolConfig.setTestWhileIdle(true)
poolConfig.setTestOnBorrow(true)
poolConfig.setTestOnReturn(true)
poolConfig.setNumTestsPerEvictionRun(10)
new JedisPool( poolConfig , "localhost" )
}
// get a resource from pool. This can throw an error if redis is
// down
def getFromPool: Either[Throwable,Jedis] =
Try(jpool.getResource) match {
case Failure(m) => Left(m)
case Success(m) => Right(m)
}
// return an object to pool
// i believe this may also throw an error if redis is down?
def returnToPool(cache:Jedis): Unit =
Try(jpool.returnResource(cache))
// execute a command -- "del" in this case, (wrapped by
// the two methods above)
def del(key: String) : Option[Long] = {
getFromPool match {
case Left(m) => None
case Right(m) => Try(m.del(key)) eventually returnToPool(m) match {
case Success(r) => Option(r)
case Failure(r) => None
}
}
}
}
答案 0 :(得分:0)
不是一个确切的答案,但我在做了一些性能测试后继续前进。使用标准的java-ish异常块最终在高迭代时速度更快(10,000次迭代时,它比上面的(坏)代码快2.5倍)。这也清理了我的代码,虽然它更冗长。
所以我得到的答案是使用Java样式的异常块,它提供了 finally 构造。我相信它应该明显更快,只要异常是非常罕见的。