gpt4 book ai didi

scala - 带有 RateLimiter 的 ExecutionContext

转载 作者:行者123 更新时间:2023-12-03 22:59:04 24 4
gpt4 key购买 nike

假设我有一个 HTTP 客户端来调用具有请求速率限制的服务器,例如1000 个请求/秒。我在 ExecutionContext 中实现了速率限制器像这样:
使用 RateLimiter 创建了一个有界阻塞队列 Guava

class MyBlockingQueue[A](capacity: Int, permitsPerSecond: Int) 
extends ArrayBlockingQueue[A](capacity) {

private val rateLimiter = RateLimiter.create(permitsPerSecond.toDouble)

override def take(): A = {
rateLimiter.acquire()
super.take()
}

override def poll(timeout: Long, unit: TimeUnit): A = {
rateLimiter.tryAcquire(timeout, unit) // todo: fix it
super.poll(timeout, unit)
}
}
创建了一个 ExecutionContext来自 ThreadPoolExecutor有了这个队列。
def createRateLimitingExecutionContext(numThreads: Int,
capacity: Int,
permitsPerSecond: Int): ExecutionContext = {
val queue = new MyBlockingQueue[Runnable](capacity, permitsPerSecond)
val executor = new ThreadPoolExecutor(numThreads, numThreads, 0L, TimeUnit.MILLISECONDS, queue)
ExecutionContext.fromExecutor(executor)
}
现在我可以创建一个 ExecutionContext具有速率限制并将其传递给客户端:
implicit val ec = createRateLimitingThreadPoolExecutionContext(
numThreads = 100,
capacity = 1000,
permitsPerSecond = 1000
)
httpGet("http://myserver.com/xyz") // create Futures with "ec"
是否有意义 ?你会如何测试这个 ExecutionContext ?

最佳答案

看起来还不错,除了自定义执行上下文应该是显式的和/或在 httpGet 中管理或其封闭类,而不是全局隐式。
因为否则,当你写这样的东西时,例如:

    httpGet(foo)
.recover("")
.map(_.split(","))
.map(_.map(_.toInt))
.map(_.max)
.foreach(println)
您最终消耗了 6(!) 个许可,而不是一个——也就是说,这相当于您提出了 6 个请求,这可能不是您想要的。

关于scala - 带有 RateLimiter 的 ExecutionContext,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67502492/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com