1

如果这是非常明显的事情,我只是想念,请接受我的道歉。我有一个 perl 脚本,它以每分钟超过 100 次调用的突发速率访问 Asana restful API。当我对其进行压力测试时,我偶尔会达到他们的速率限制并看到错误 429。我从阅读 Asana 的文档中知道它会返回一个“重试后”响应标头,但我终生无法弄清楚如何检索/打开/读取此标头。您可以提供的任何建议将不胜感激。

编辑:我的代码附在下面。当然,我已经删除了敏感信息,例如我的 API 密钥和项目编号,但核心代码在这里。如果我只运行一次,它每分钟不会产生足够的调用来触发错误。我必须同时运行它大约 3-4 次才能产生错误。有人可能会说“不要那样做”。虽然正确,但这个练习的重点是产生错误,所以同时运行四次是好的。

当您使用有效的 API 密钥和项目编号执行此操作时,有时您会收到此错误:

{"errors":[{"message":"You have made too many requests recently. Please, be chill."}]}

我的问题是如何检索显然包含重试后字段以及几秒钟的标题。每次返回错误时,我可能会采取 20 秒的延迟构建,但我更愿意更优雅地处理错误。

#!/usr/local/bin/perl
my $counter = 0;
my $AsanaAPIcode = "...";
my $AsanaProjectID = "...";
my $AsanaFullString = 'curl -u ' . $AsanaAPIcode . ': https://app.asana.com/api/1.0/projects/' . $AsanaProjectID . '?opt_fields=archived';
my $APIoutput = `$AsanaFullString`;
print $APIoutput;
my $startTime = time;
my $totalCount = 200;
while ($counter<=$totalCount) {
  print $counter . "\n";
  $APIoutput = `$AsanaFullString`;
  print $APIoutput . "\n";
  $counter++;
}
my $endTime = time;
my $totalTime = $endTime - $startTime;
print "Total time = " . $totalTime . " seconds.\n";
print $totalCount / ($totalTime / 60) . " API calls per minute.\n";
print "end";
4

3 回答 3

1

'Retry-After' 在 HTTP 响应中,它被 curl 的反引号调用丢失。

一个笨重的解决方案是使用'curl -D'(--dump-headers),它将所有 HTTP 标头放入响应中,然后您必须对其进行解析和删除。

更好的解决方案是使用 LWP 库 (perldoc LWP::UserAgent)。显然我无法在没有 API 密钥的情况下测试此代码...我认为您可以将这些代码注入 URL(https://name:password@app.asana.com/api...)

use LWP::UserAgent;
use LWP::Protocol::https;
my $agent = LWP::UserAgent->new(); # check LWP docs for extra params
my $request = LWP::Request->new( 'https://app.asana.com/api/1.0/projects/' . $AsanaProjectID . '?opt_fields=archived' )
my $response = $ua->request($request);
if ($response->code == 429) {
  my $retry = $response->header('Retry-After');
  ...
}

或者...您可以尝试使用 CPAN 进行 WWW::Asana 之类的操作。 http://search.cpan.org/dist/WWW-Asana/

于 2012-11-29T09:44:09.993 回答
0

有一个 CPAN 模块WWW::Asana,它可以正确处理速率限制响应。

于 2013-01-17T02:10:27.650 回答
0

我们在使用 Klok 的 Asana 连接器时遇到了问题。我们联系了 Asana 的人员,他们愿意将“重试后”数量添加到响应正文中。因此,您现在可以从“retry_after”属性中获取它:

{
 "errors":[{"message":"You have made too many requests recently. Please, be chill."}],
 "retry_after":30
 }

这对我们帮助很大,因为我们使用的是 Adob​​e AIR 2.x,它不允许我们访问错误响应的响应标头。

于 2013-01-17T01:40:28.813 回答