[英]Lagom. Throttling for external service
我正在玩Lagom,它看起來不錯,但我完全迷失了一個問題。
讓我說我依賴外部HTTP服務,它只允許10個請求/秒,在其他情況下甚至可以禁止:)我googled,但沒有找到任何工作的例子。 我可以在無類型的actor中包裝服務並為其添加速率限制器,但我不明白如何在Akka Typed或Lagom服務之上實現它。
也許有人已經解決了這個問題? 謝謝!
你想要一個令牌桶 。 Akka-Streams內置Flow.throttle,但聽起來你正在使用原始akka,所以不能使用它。 在Akka中存在令牌桶實現,但遺憾的是它沒有提供任何使用指導,我自己也沒有使用它。
對於我自己的用例(不是Akka而是使用Scala Futures),我編寫了自己的令牌桶。 它允許我根據指定的限制引用Future的觸發。 它是針對monix調度程序編碼的,但是為了這個目的,它與Akka調度非常相似:
import java.util.concurrent.ConcurrentLinkedQueue
import monix.execution.Scheduler.Implicits.global
import monix.execution.atomic.AtomicInt
import scala.concurrent.{Future, Promise}
import scala.concurrent.duration._
case class RateLimiter(duration: FiniteDuration, maxInvocations: Int) {
@volatile var permits: Int = maxInvocations
val queue = new ConcurrentLinkedQueue[() => Any]()
global.scheduleAtFixedRate(duration, duration) {
this synchronized {
permits = maxInvocations
while (!queue.isEmpty && permits > 0) {
Option(queue.poll()).foreach { fun =>
permits -= 1
fun.apply()
}
}
}
}
def apply[T](f: => Future[T]): Future[T] =
this synchronized {
if (permits > 0) {
permits -= 1
f
} else {
val res = Promise[T]()
queue.add(() => { res.completeWith(f) })
res.future
}
}
}
用法是
val limiter = RateLimiter(1.second, 10)
limiter {
someWebService.asyncCall()
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.