如何在Scala中实现速率限制器?

时间:2012-09-27 09:06:33

标签: scala guava akka

我想在Scala中使用RateLimiter来限制方法调用的频率。

我需要类似于Guava实现的东西: http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/util/concurrent/RateLimiter.html

我知道我可以原生使用Guava,但我想知道Scala中是否有更好的原生解决方案,无论是否有Akka

3 个答案:

答案 0 :(得分:4)

就个人而言,我会使用番石榴。但是你可以使用未来创造属于你自己的困境。

class RateLimiter(delayMs: Int) {
  private[this] var last: Long = System.currentTimeMillis
  private[this] val done = scala.actors.Futures.alarm(0)
  def request = {
    val now = System.currentTimeMillis
    val elapsed = synchronized {
      val elapsed = now - last
      last = if (elapsed < delayMs) last+delayMs else now
      elapsed
    }
    if (elapsed < delayMs) scala.actors.Futures.alarm(delayMs-elapsed)
    else done
  }
}

然后,为要限制访问的每个方法或方法集创建限制器,并通过调用request()启动方法;如果需要,这将使用Future来阻止。如果你想要的东西不是间隔至少那么多毫秒,你只需要改变一点数学和/或跟踪更多的状态。

答案 1 :(得分:1)

这篇博文(Throttling Messages in Akka 2)是否有任何帮助?

答案 2 :(得分:0)

我写了some wrappers around Guava's RateLimiter,允许您将任何功能转换为速率限制版本。如果Guava的RateLimiter实际上是他们的方式,那就有一些疑问。它的acquire()调用阻塞了线程,即使它不会阻塞线程,你很可能会引入一些可能会破坏你的堆栈的东西。