玩WS API:限制请求率 [英] Play WS API: throttling request rates

查看:68
本文介绍了玩WS API:限制请求率的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用异步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]]

这要求您具有WSClientActorSystem组件以及作用域中的隐式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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆