如何在R中执行并行异步POST API调用?

时间:2017-08-08 16:41:45

标签: r amazon-web-services asynchronous post future

我在AWS Lambda上创建了一个API端点,我使用POST请求(使用JSON数据输入)调用该端点以获得响应结果(作为JSON数据输出)。

现在我需要使用API​​处理100万个data.tables。一个API执行大约需要600毫秒,AWS Lambda每秒最多允许3000个请求。为了更快地执行,我想在我的系统中使用所有64个内核来生成64个并发请求,但我不希望这些请求等到它们在生成下一个64个请求之前得到响应(结果)之后等等(基本上我想达到3000请求门槛)。为此,我需要异步生成请求,每个请求不等待它的响应,一旦生成响应,将其附加到大型列表或data.table

我查看了 curl Rcurl future / / strong>和 doFuture 包文档,但无法查看找到解决这个问题的任何东西。感谢任何帮助

我在this post上发现了一个类似的问题,但答案并不完整。

要在异步foreach(或类似功能的函数)中运行的示例伪代码:

output = foreach(i = 1:n) %dopar%
{
  x = input[i]
  body = toJSON(x)
  url = "https://exampleURL.amazonaws.com/dev/LambdaTest"
  response = as.data.table(fromJSON(content(POST(url,
                                                 body = body,
                                                 content_type_json()))))
  return(response)
}

此处数据是包含 n 子集的data.table,需要单独传递。

1 个答案:

答案 0 :(得分:0)

您可以使用crul包。它有两个异步接口,Async用于许多处理相同的URL,AsyncVaried可以在任何配置中构建HTTP请求,然后将它们传递给AsyncVaried来处理那些

上的异步请求
library(crul)

形成请求

req1 <- HttpRequest$new(
  url = "https://httpbin.org/post", 
  headers = list(`Content-Type` = "application/json")
)$post(body = jsonlite::toJSON(iris[1,]))
req2 <- HttpRequest$new(
  url = "https://httpbin.org/post", 
  headers = list(`Content-Type` = "application/json")
)$post(body = jsonlite::toJSON(iris[2,]))

创建AsyncVaried对象

out <- AsyncVaried$new(req1, req2)

请求

out$request()

获取状态代码,标题等。

out$status_code()

获取json响应并解析为R列表

lapply(out$parse(), jsonlite::fromJSON)