Scala 播放WS-API:限制请求速率

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或其他需要生成

我正在使用async Play WS Scala API查询RESTful服务。我想知道如何处理一个
列表
,其中包含通过
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