我想在 Scala 中使用 RateLimiter 来限制方法调用的频率。
我需要类似于 Guava 实现的东西: http ://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/util/concurrent/RateLimiter.html
我知道我可以在本地使用 Guava,但我想知道 Scala 中是否有更好的本地解决方案,有或没有 Akka
我想在 Scala 中使用 RateLimiter 来限制方法调用的频率。
我需要类似于 Guava 实现的东西: http ://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/util/concurrent/RateLimiter.html
我知道我可以在本地使用 Guava,但我想知道 Scala 中是否有更好的本地解决方案,有或没有 Akka
就个人而言,我会使用番石榴。但是您可以使用期货轻松创建自己的。
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()
;来启动该方法。如果需要,这将使用 aFuture
来阻止。如果你想要的不是至少这么多毫秒的间隔,你只需要改变一点数学和/或跟踪更多的状态。
我围绕 GuavaRateLimiter
编写了一些包装器,以允许您将任何函数转换为其速率限制版本。怀疑 Guava 的 RateLimiter 是否真的是他们的路要走。它的acquire()
调用正在阻塞线程,即使它不会阻塞线程,你很有可能会引入一些可能会炸毁堆顶的东西。