如何防止在上一个调用未完成之前调用返回 Future 的方法

How to prevent a method returning a Future from being invoked until a previous call does not complete

我有一个 Play 插件,它每 15 秒执行一个方法,如下所示:

import scala.concurrent.Future
import scala.concurrent.duration._
import play.api.libs.concurrent.Akka
import play.api.libs.concurrent.Execution.Implicits.defaultContext
import play.api.{Application, Plugin}
import akka.actor.Cancellable

class AuthPlugin(app: Application) extends Plugin {

  private var cancellableTokenDelete: Option[Cancellable] = None

  ...

  override def onStart = {
    cancellableTokenDelete = Some(
      Akka.system.scheduler.schedule(0.seconds, 15.seconds) {
        discardExpiredTokens
      }
    )
  }

  override def onStop = {
    cancellableTokenDelete.foreach(_.cancel)
  }
}

object AuthPlugin {

  ...

  def discardExpiredTokens: Future[Unit] = {
    tokenTraceService.removeExpired.recover {
      case NonFatal(e) => Logger.error("error discarding expired tokens", e)
    }.map { _ => }
  }
}

即使 15 秒后 discardExpiredTokens 还没有完成,它仍然会被调度程序再次调用...但这不是我要找的。

就是说,当上一个调用仍在执行时,如何防止调度程序调用 discardExpiredTokens?我需要一种机制,让我绕过对 discardExpiredTokens 的调用,直到 Mutex 之类的东西没有被释放。

对于实现此目的的一种非常简单的方法,如果您使用 scheduleOnce 而不是 schedule,那么计划操作中的最后一次调用可能是再次调用 scheduleOnce

http://doc.akka.io/docs/akka/snapshot/scala/scheduler.html