Scala 播放WS-API:限制请求速率
我正在使用async Play WS Scala API查询RESTful服务。我想知道如何处理一个Scala 播放WS-API:限制请求速率,scala,web-services,playframework,playframework-2.0,Scala,Web Services,Playframework,Playframework 2.0,我正在使用async Play WS Scala API查询RESTful服务。我想知道如何处理一个列表,其中包含通过WSClient调用的请求URL,但每秒不超过一个请求(该服务允许每个客户端每秒“仅”一个请求)。从逻辑的角度来看,这个想法是从列表中获取一个元素(URL),发出请求,然后等待一定的时间,然后再继续处理列表中的下一个元素 在像Play这样的非阻塞异步框架中使用好的旧Thread.sleep,肯定是个坏主意 对于ScheduledThreadPoolExecutor或其他需要生成
列表
,其中包含通过WSClient
调用的请求URL,但每秒不超过一个请求(该服务允许每个客户端每秒“仅”一个请求)。从逻辑的角度来看,这个想法是从列表中获取一个元素(URL),发出请求,然后等待一定的时间,然后再继续处理列表中的下一个元素
- 在像Play这样的非阻塞异步框架中使用好的旧
,肯定是个坏主意Thread.sleep
- 对于
或其他需要生成新线程的方法,情况可能也是如此ScheduledThreadPoolExecutor
如何在不影响异步和“尽可能少的线程”特性的情况下限制请求速率?Akka有一个方便的调度程序功能: 因为Akka已经在游戏中,所以您不需要导入任何其他内容。
它不是最干净的,也不容易测试,但您可以这样做:
val webserviceCall : Runnable = new Runnable {
override def run(): Unit = {
// do webservice call work
// figure out if you need to make more webservice calls, and if you do:
actorSystem.scheduler.scheduleOnce(0 seconds, 1 seconds, webserviceCall)
}
}
actorSystem.scheduler.scheduleOnce(0 seconds, webserviceCall)
或者,您可以使用某人不久前制作的Akka消息调节器:
我以前使用过它(我想它是去年的Akka 2.3),但不确定它是否还能工作。假设您有一个要获取的URL列表:
val urls = List(
"http://www.google.com",
"http://stackoverflow.com",
"http://www.bing.com"
)
在Play 2.5.x中,我们可以按顺序处理这些调用,并在每次调用之间使用akka.pattern.after
强制异步延迟。我们将flatMap
Web服务调用的Future
结果在一秒钟后返回相同的值
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
在Play 2.4.x及更早版本中,您可以使用
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))
}
}
什么版本的游戏?游戏版本2.5.3