我想在Scala中使用RateLimiter來限制方法調用的頻率。如何在Scala中實現速率限制器?
我需要類似於番石榴實現的東西: http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/util/concurrent/RateLimiter.html
我知道我可以本地使用番石榴,但我想知道是否有Scala中的一個更好的本地解決方案,帶有或不帶有阿卡
我想在Scala中使用RateLimiter來限制方法調用的頻率。如何在Scala中實現速率限制器?
我需要類似於番石榴實現的東西: http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/util/concurrent/RateLimiter.html
我知道我可以本地使用番石榴,但我想知道是否有Scala中的一個更好的本地解決方案,帶有或不帶有阿卡
就我個人而言,我會用番石榴。但是,你可以創造你自己的,沒有太多的困難使用期貨。
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
來阻止。如果你想要的東西除了至少有幾毫秒的間隔以外,你只需要改變一點數學和/或跟蹤更多的狀態。
這篇博文(Throttling Messages in Akka 2)有幫助嗎?
我寫了some wrappers around Guava's RateLimiter
,允許您將任何函數轉換爲速率限制版本。如果Guava的RateLimiter實際上是他們的選擇,請不要懷疑。它是acquire()
調用阻塞了線程,即使它不會阻塞線程,你有一個公平的機會,你可能會引入一些可能會打擊你的堆的頂部。
我知道,但我正在尋找一個更簡單的解決方案。謝謝。 –