玩WS API:限制请求率 [英] Play WS API: throttling request rates
问题描述
我正在使用异步Play WS Scala API来查询RESTful服务.我不知道如何处理一个包含要通过WSClient
调用的请求URL的List
,但每秒处理的请求数不超过一个(该服务每个客户端每秒仅允许"1"个请求).从逻辑的角度来看,这个想法是从列表中获取一个元素(URL),发出请求,然后等待一定的时间,然后再继续处理列表中的下一个元素.
I'm using the async Play WS Scala API to query a RESTful service. I wonder how I could process a List
containing request URLs to be called via WSClient
, but not more than one request per second (the service allows "only" 1 request per second per client). From a logical standpoint, the idea is to get an element (URL) from the list, make a request, then wait a certain amount of time before proceeding with the next element in the list.
- 在像Play这样的非阻塞和异步框架中使用好的旧版
Thread.sleep
肯定不是一个好主意. - 对于
ScheduledThreadPoolExecutor
之类的东西或其他需要产生新线程的方法,情况可能同样如此.
- using good old
Thread.sleep
in a non-blocking and asynchronous framework like Play is certainly a bad idea. - the same is probably true for things like
ScheduledThreadPoolExecutor
or other methods that require to spawn new threads.
如何在不影响Play的异步和尽可能少线程"性质的情况下限制请求速率?
How could I throttle the request rate without having a negative impact on the asynchronous and "as-less-threads-as-possible" nature of Play?
推荐答案
假设您有观看要获取的URL列表:
Suppose you have a list of URLs you watch to fetch:
val urls = List(
"http://www.google.com",
"http://stackoverflow.com",
"http://www.bing.com"
)
在Play 2.5.x中,我们可以顺序处理这些内容,并使用akka.pattern.after
强制每个调用之间进行异步延迟.我们flatMap
调用某个Web服务的Future
结果将在一秒钟后返回 same 值.
In Play 2.5.x, we can process these sequentially, and use akka.pattern.after
to force an asynchronous delay between each call. We flatMap
the Future
result of a webservice call to something that will return the same value after one second.
Future.traverse(urls) { url =>
wsClient.url(url).get().flatMap { result =>
// potentially process `result` here
akka.pattern.after(1.second, actorSystem.scheduler)(Future.successful(result))
}
} // returns Future[List[WSResponse]]
这要求您具有WSClient
和ActorSystem
组件以及作用域中的隐式ExecutionContext
.
This requires that you have a WSClient
and ActorSystem
component available, as well as in implicit ExecutionContext
in scope.
在Play 2.4.x和更早版本中,您可以使用Promise.timeout
进行同样的操作:
In Play 2.4.x and earlier, you could do the same using Promise.timeout
:
Future.traverse(urls) { url =>
wsClient.url(url).get().flatMap { result =>
// potentially process `result` here
Promise.timeout(result, 1.second)
akka.pattern.after(1.second, actorSystem.scheduler)(Future.successful(result))
}
}
这篇关于玩WS API:限制请求率的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!