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

查看:17
本文介绍了Play 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 webservice 调用的Future结果,在一秒后返回相同值.

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))
  }
}

这篇关于Play WS API:限制请求率的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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