【问题标题】:Jedis in scala and handling errorsscala中的绝地武士和处理错误
【发布时间】:2015-03-12 03:58:28
【问题描述】:

我正在尝试找到处理来自 scala 的 jedis 命令的最佳方法。我正在尝试实现 finally 块,并防止 java 异常冒泡到我的调用者。

如果我想确保在 redis 可能暂时关闭时处理异常,以下代码是否有意义,并且在性能方面我能做到最好吗?这个特征将被一个对象扩展,我会调用 objectname.del(key)。我觉得我结合了太多概念(Either、Option、Try,感觉应该有更简洁的方式)

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
      }
    }
  }
}

【问题讨论】:

  • 为什么不使用github.com/debasishg/scala-redis-nbgithub.com/debasishg/scala-redis,以Scala 方式做事:)
  • 因为至少我知道 jredis 是一个久经考验的组件,而我找不到任何人在生产中使用 scala-redis 的战争故事,以及它的性能如何(我确实找到了这个,这不会让 scala-redis 大放异彩:gist.github.com/felipehummel/3909583) 。而且因为我不想在遇到小问题时学习和挑选现成的产品。
  • 嗯,应该是“我想学习而不是现成的……”。对决定你只能在五分钟内编辑评论的人感到不满。
  • 我有一个关于在生产中使用 scala-redis 的战争故事。它没有正确实现 pipeline() 。 github.com/debasishg/scala-redis/issues/131

标签: scala


【解决方案1】:

不是一个确切的答案,但我在做了一些性能测试后继续前进。使用标准的 java-ish 异常块最终在高迭代时要快得多(在 10,000 次迭代时,它比上面的(坏)代码快大约 2.5 倍)。这也清理了我的代码,虽然它更冗长。

所以我得到的答案是使用为 finally 构造提供的 Java 样式的异常块。只要异常很少发生,我相信它应该会明显更快。

【讨论】:

    猜你喜欢
    • 2015-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-09
    • 2014-01-24
    • 2017-10-07
    • 2015-12-18
    相关资源
    最近更新 更多