非阻塞尾递归

Non blocking tail recursive

我有一个尾递归实现如下

@tailrec
def generate() : String = {
  val token = UUID.randomUUID().toString
  val isTokenExist = Await.result(get(token), 5.seconds).isDefined
  if(isTokenExist) generate()
  else token
}

get(token) 将 return 一个 Future[Option[Token]].

我知道在 Future 中阻塞是不好的。我试图 return 一个 Future[String] 而不是 String。但似乎这是不可能的,除非我等待 isTokenExist 完成。

还有其他 way/suggestion 来实现这个吗?

get(token)是怎么回事,第一次超过5s,第二次就不会超过了?

如果您真的需要检查(并且碰撞 非常 不太可能),您可能只需要阻止即可。否则,如果5s不够,方法永远不会return,很长一段时间后你会得到一个Whosebug。

我可能会保持简单:

def generate() : String = {
  val token = UUID.randomUUID().toString
  if(get(token).isDefined) generate()
  else token
}

如果您需要在此代码中优化某些内容,可能是 get(token) 方法。

如果你将 get(token) 包装在未来,那么你可以使用未来的 onComplete 功能。类似于:

val f: Future[Token] = Future {
  get(token)
}
f onComplete {
     case Success(token) => generate()
     case Failure(t) => println("An error has occured: " + t.getMessage)
}

有关更多信息,请查看:http://docs.scala-lang.org/overviews/core/futures.html

generate 在这种情况下不必是尾递归的,因为它使用 Futures(请阅读:How do I make a function involving futures tail recursive? 进行解释)。

这对你有用吗?

  def generate: Future[String] = {
    val token = UUID.randomUUID().toString
    get(token).flatMap {
      case None => generate
      case _    => Future.successful(token)
    }
  }