RateLimiter 的未来
Future with RateLimiter
假设我有一个像这样的简单阻塞 HTTP 客户端:
def httpGet(url: URL): Future[String] = ???
现在我想用httpGet
来调用有请求速率限制的服务器;例如1000 requests/sec。由于标准库不提供速率限制器,我将使用 RateLimiter of Guava:
import com.google.common.util.concurrent.RateLimiter
import scala.concurrent.{ExecutionContext, Future, blocking}
def throttled[A](fut: => Future[A], rateLimiter: RateLimiter)
(implicit ec: ExecutionContext): Future[A] = {
Future(blocking(rateLimiter.acquire())).flatMap(_ => fut)
}
implicit val ec = ExecutionContext.global
val rateLimiter = RateLimiter.create(permitsPerSeconds = 1000.0)
val throttledFuture = throttled(httpGet(url), rateLimiter)
有意义吗?
您会使用另一个执行上下文来执行 rateLimiter.acquire()
吗?
既然你在 acquire
周围使用 blocking
,没关系,IMO。
根据调用 httpGet
的线程中完成的工作量,如果您使用的是 Scala 2.13,可能值得考虑使用 parasitic
执行上下文。
样式 nit,但可能值得利用 Scala 的能力来使用 {
围绕单个参数列表:
def throttled[A](rateLimiter: RateLimiter)(fut: => Future[A])(implicit ec: ExecutionContext): Future[A]
val throttledFuture = throttled(rateLimiter) { httpGet(url) }
假设我有一个像这样的简单阻塞 HTTP 客户端:
def httpGet(url: URL): Future[String] = ???
现在我想用httpGet
来调用有请求速率限制的服务器;例如1000 requests/sec。由于标准库不提供速率限制器,我将使用 RateLimiter of Guava:
import com.google.common.util.concurrent.RateLimiter
import scala.concurrent.{ExecutionContext, Future, blocking}
def throttled[A](fut: => Future[A], rateLimiter: RateLimiter)
(implicit ec: ExecutionContext): Future[A] = {
Future(blocking(rateLimiter.acquire())).flatMap(_ => fut)
}
implicit val ec = ExecutionContext.global
val rateLimiter = RateLimiter.create(permitsPerSeconds = 1000.0)
val throttledFuture = throttled(httpGet(url), rateLimiter)
有意义吗?
您会使用另一个执行上下文来执行 rateLimiter.acquire()
吗?
既然你在 acquire
周围使用 blocking
,没关系,IMO。
根据调用 httpGet
的线程中完成的工作量,如果您使用的是 Scala 2.13,可能值得考虑使用 parasitic
执行上下文。
样式 nit,但可能值得利用 Scala 的能力来使用 {
围绕单个参数列表:
def throttled[A](rateLimiter: RateLimiter)(fut: => Future[A])(implicit ec: ExecutionContext): Future[A]
val throttledFuture = throttled(rateLimiter) { httpGet(url) }